aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c8
-rw-r--r--src/data.c13
-rw-r--r--src/doc.c2
-rw-r--r--src/emacs-module.c50
-rw-r--r--src/eval.c17
-rw-r--r--src/lisp.h94
-rw-r--r--src/print.c12
7 files changed, 111 insertions, 85 deletions
diff --git a/src/alloc.c b/src/alloc.c
index faa14eebb36..b473ebd7ded 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -3942,13 +3942,6 @@ make_user_ptr (void (*finalizer) (void *), void *p)
3942 uptr->p = p; 3942 uptr->p = p;
3943 return obj; 3943 return obj;
3944} 3944}
3945
3946/* Create a new module function environment object. */
3947Lisp_Object
3948make_module_function (void)
3949{
3950 return allocate_misc (Lisp_Misc_Module_Function);
3951}
3952#endif 3945#endif
3953 3946
3954static void 3947static void
@@ -6640,7 +6633,6 @@ mark_object (Lisp_Object arg)
6640 6633
6641#ifdef HAVE_MODULES 6634#ifdef HAVE_MODULES
6642 case Lisp_Misc_User_Ptr: 6635 case Lisp_Misc_User_Ptr:
6643 case Lisp_Misc_Module_Function:
6644 XMISCANY (obj)->gcmarkbit = true; 6636 XMISCANY (obj)->gcmarkbit = true;
6645 break; 6637 break;
6646#endif 6638#endif
diff --git a/src/data.c b/src/data.c
index 4242b90e628..25859105ee0 100644
--- a/src/data.c
+++ b/src/data.c
@@ -233,8 +233,6 @@ for example, (type-of 1) returns `integer'. */)
233 case Lisp_Misc_Finalizer: 233 case Lisp_Misc_Finalizer:
234 return Qfinalizer; 234 return Qfinalizer;
235#ifdef HAVE_MODULES 235#ifdef HAVE_MODULES
236 case Lisp_Misc_Module_Function:
237 return Qmodule_function;
238 case Lisp_Misc_User_Ptr: 236 case Lisp_Misc_User_Ptr:
239 return Quser_ptr; 237 return Quser_ptr;
240#endif 238#endif
@@ -278,6 +276,8 @@ for example, (type-of 1) returns `integer'. */)
278 else 276 else
279 return t; 277 return t;
280 } 278 }
279 case PVEC_MODULE_FUNCTION:
280 return Qmodule_function;
281 /* "Impossible" cases. */ 281 /* "Impossible" cases. */
282 case PVEC_XWIDGET: 282 case PVEC_XWIDGET:
283 case PVEC_OTHER: 283 case PVEC_OTHER:
@@ -494,6 +494,14 @@ DEFUN ("byte-code-function-p", Fbyte_code_function_p, Sbyte_code_function_p,
494 return Qnil; 494 return Qnil;
495} 495}
496 496
497DEFUN ("module-function-p", Fmodule_function_p, Smodule_function_p, 1, 1, NULL,
498 doc: /* Return t if OBJECT is a function loaded from a dynamic module. */
499 attributes: const)
500 (Lisp_Object object)
501{
502 return MODULE_FUNCTIONP (object) ? Qt : Qnil;
503}
504
497DEFUN ("char-or-string-p", Fchar_or_string_p, Schar_or_string_p, 1, 1, 0, 505DEFUN ("char-or-string-p", Fchar_or_string_p, Schar_or_string_p, 1, 1, 0,
498 doc: /* Return t if OBJECT is a character or a string. */ 506 doc: /* Return t if OBJECT is a character or a string. */
499 attributes: const) 507 attributes: const)
@@ -3793,6 +3801,7 @@ syms_of_data (void)
3793 defsubr (&Smarkerp); 3801 defsubr (&Smarkerp);
3794 defsubr (&Ssubrp); 3802 defsubr (&Ssubrp);
3795 defsubr (&Sbyte_code_function_p); 3803 defsubr (&Sbyte_code_function_p);
3804 defsubr (&Smodule_function_p);
3796 defsubr (&Schar_or_string_p); 3805 defsubr (&Schar_or_string_p);
3797 defsubr (&Sthreadp); 3806 defsubr (&Sthreadp);
3798 defsubr (&Smutexp); 3807 defsubr (&Smutexp);
diff --git a/src/doc.c b/src/doc.c
index dd674e3bc05..345e18b9186 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -340,6 +340,8 @@ string is passed through `substitute-command-keys'. */)
340 fun = XCDR (fun); 340 fun = XCDR (fun);
341 if (SUBRP (fun)) 341 if (SUBRP (fun))
342 doc = make_number (XSUBR (fun)->doc); 342 doc = make_number (XSUBR (fun)->doc);
343 else if (MODULE_FUNCTIONP (fun))
344 doc = XMODULE_FUNCTION (fun)->documentation;
343 else if (COMPILEDP (fun)) 345 else if (COMPILEDP (fun))
344 { 346 {
345 if (PVSIZE (fun) <= COMPILED_DOC_STRING) 347 if (PVSIZE (fun) <= COMPILED_DOC_STRING)
diff --git a/src/emacs-module.c b/src/emacs-module.c
index 0bc1b6c384b..99be4a748ee 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -362,30 +362,24 @@ module_make_function (emacs_env *env, ptrdiff_t min_arity, ptrdiff_t max_arity,
362 : min_arity <= max_arity))) 362 : min_arity <= max_arity)))
363 xsignal2 (Qinvalid_arity, make_number (min_arity), make_number (max_arity)); 363 xsignal2 (Qinvalid_arity, make_number (min_arity), make_number (max_arity));
364 364
365 Lisp_Object envobj = make_module_function (); 365 struct Lisp_Module_Function *envptr = allocate_module_function ();
366 struct Lisp_Module_Function *envptr = XMODULE_FUNCTION (envobj);
367 envptr->min_arity = min_arity; 366 envptr->min_arity = min_arity;
368 envptr->max_arity = max_arity; 367 envptr->max_arity = max_arity;
369 envptr->subr = subr; 368 envptr->subr = subr;
370 envptr->data = data; 369 envptr->data = data;
371 370
372 Lisp_Object doc = Qnil;
373 if (documentation) 371 if (documentation)
374 { 372 {
375 AUTO_STRING (unibyte_doc, documentation); 373 AUTO_STRING (unibyte_doc, documentation);
376 doc = code_convert_string_norecord (unibyte_doc, Qutf_8, false); 374 envptr->documentation =
375 code_convert_string_norecord (unibyte_doc, Qutf_8, false);
377 } 376 }
378 377
379 /* FIXME: Use a bytecompiled object, or even better a subr. */ 378 Lisp_Object envobj;
380 Lisp_Object ret = list4 (Qlambda, 379 XSET_MODULE_FUNCTION (envobj, envptr);
381 list2 (Qand_rest, Qargs), 380 eassert (MODULE_FUNCTIONP (envobj));
382 doc,
383 list4 (Qapply,
384 list2 (Qfunction, Qinternal__module_call),
385 envobj,
386 Qargs));
387 381
388 return lisp_to_value (ret); 382 return lisp_to_value (envobj);
389} 383}
390 384
391static emacs_value 385static emacs_value
@@ -648,17 +642,11 @@ DEFUN ("module-load", Fmodule_load, Smodule_load, 1, 1, 0,
648 return Qt; 642 return Qt;
649} 643}
650 644
651DEFUN ("internal--module-call", Finternal_module_call, Sinternal_module_call, 1, MANY, 0, 645Lisp_Object
652 doc: /* Internal function to call a module function. 646funcall_module (const struct Lisp_Module_Function *const envptr,
653ENVOBJ is a save pointer to a module_fun_env structure. 647 ptrdiff_t nargs, Lisp_Object *arglist)
654ARGLIST is a list of arguments passed to SUBRPTR.
655usage: (module-call ENVOBJ &rest ARGLIST) */)
656 (ptrdiff_t nargs, Lisp_Object *arglist)
657{ 648{
658 Lisp_Object envobj = arglist[0]; 649 EMACS_INT len = nargs;
659 CHECK_TYPE (MODULE_FUNCTIONP (envobj), Qmodule_function_p, envobj);
660 struct Lisp_Module_Function *envptr = XMODULE_FUNCTION (envobj);
661 EMACS_INT len = nargs - 1;
662 eassume (0 <= envptr->min_arity); 650 eassume (0 <= envptr->min_arity);
663 if (! (envptr->min_arity <= len 651 if (! (envptr->min_arity <= len
664 && len <= (envptr->max_arity < 0 ? PTRDIFF_MAX : envptr->max_arity))) 652 && len <= (envptr->max_arity < 0 ? PTRDIFF_MAX : envptr->max_arity)))
@@ -672,12 +660,12 @@ usage: (module-call ENVOBJ &rest ARGLIST) */)
672 USE_SAFE_ALLOCA; 660 USE_SAFE_ALLOCA;
673 emacs_value *args; 661 emacs_value *args;
674 if (plain_values) 662 if (plain_values)
675 args = (emacs_value *) arglist + 1; 663 args = (emacs_value *) arglist;
676 else 664 else
677 { 665 {
678 args = SAFE_ALLOCA (len * sizeof *args); 666 args = SAFE_ALLOCA (len * sizeof *args);
679 for (ptrdiff_t i = 0; i < len; i++) 667 for (ptrdiff_t i = 0; i < len; i++)
680 args[i] = lisp_to_value (arglist[i + 1]); 668 args[i] = lisp_to_value (arglist[i]);
681 } 669 }
682 670
683 emacs_value ret = envptr->subr (&pub, len, args, envptr->data); 671 emacs_value ret = envptr->subr (&pub, len, args, envptr->data);
@@ -709,6 +697,15 @@ usage: (module-call ENVOBJ &rest ARGLIST) */)
709 } 697 }
710} 698}
711 699
700Lisp_Object
701module_function_arity (const struct Lisp_Module_Function *const function)
702{
703 const short minargs = function->min_arity;
704 const short maxargs = function->max_arity;
705 return Fcons (make_number (minargs),
706 maxargs == MANY ? Qmany : make_number (maxargs));
707}
708
712 709
713/* Helper functions. */ 710/* Helper functions. */
714 711
@@ -1025,7 +1022,4 @@ syms_of_module (void)
1025 DEFSYM (Qmodule_function_p, "module-function-p"); 1022 DEFSYM (Qmodule_function_p, "module-function-p");
1026 1023
1027 defsubr (&Smodule_load); 1024 defsubr (&Smodule_load);
1028
1029 DEFSYM (Qinternal__module_call, "internal--module-call");
1030 defsubr (&Sinternal_module_call);
1031} 1025}
diff --git a/src/eval.c b/src/eval.c
index 98d25cc4fed..f472efad52e 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2261,7 +2261,7 @@ eval_sub (Lisp_Object form)
2261 } 2261 }
2262 } 2262 }
2263 } 2263 }
2264 else if (COMPILEDP (fun)) 2264 else if (COMPILEDP (fun) || MODULE_FUNCTIONP (fun))
2265 return apply_lambda (fun, original_args, count); 2265 return apply_lambda (fun, original_args, count);
2266 else 2266 else
2267 { 2267 {
@@ -2687,7 +2687,7 @@ FUNCTIONP (Lisp_Object object)
2687 2687
2688 if (SUBRP (object)) 2688 if (SUBRP (object))
2689 return XSUBR (object)->max_args != UNEVALLED; 2689 return XSUBR (object)->max_args != UNEVALLED;
2690 else if (COMPILEDP (object)) 2690 else if (COMPILEDP (object) || MODULE_FUNCTIONP (object))
2691 return true; 2691 return true;
2692 else if (CONSP (object)) 2692 else if (CONSP (object))
2693 { 2693 {
@@ -2742,7 +2742,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
2742 2742
2743 if (SUBRP (fun)) 2743 if (SUBRP (fun))
2744 val = funcall_subr (XSUBR (fun), numargs, args + 1); 2744 val = funcall_subr (XSUBR (fun), numargs, args + 1);
2745 else if (COMPILEDP (fun)) 2745 else if (COMPILEDP (fun) || MODULE_FUNCTIONP (fun))
2746 val = funcall_lambda (fun, numargs, args + 1); 2746 val = funcall_lambda (fun, numargs, args + 1);
2747 else 2747 else
2748 { 2748 {
@@ -2892,7 +2892,8 @@ apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count)
2892 2892
2893/* Apply a Lisp function FUN to the NARGS evaluated arguments in ARG_VECTOR 2893/* Apply a Lisp function FUN to the NARGS evaluated arguments in ARG_VECTOR
2894 and return the result of evaluation. 2894 and return the result of evaluation.
2895 FUN must be either a lambda-expression or a compiled-code object. */ 2895 FUN must be either a lambda-expression, a compiled-code object,
2896 or a module function. */
2896 2897
2897static Lisp_Object 2898static Lisp_Object
2898funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, 2899funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
@@ -2949,6 +2950,10 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
2949 } 2950 }
2950 lexenv = Qnil; 2951 lexenv = Qnil;
2951 } 2952 }
2953#ifdef HAVE_MODULES
2954 else if (MODULE_FUNCTIONP (fun))
2955 return funcall_module (XMODULE_FUNCTION (fun), nargs, arg_vector);
2956#endif
2952 else 2957 else
2953 emacs_abort (); 2958 emacs_abort ();
2954 2959
@@ -3060,6 +3065,10 @@ function with `&rest' args, or `unevalled' for a special form. */)
3060 result = Fsubr_arity (function); 3065 result = Fsubr_arity (function);
3061 else if (COMPILEDP (function)) 3066 else if (COMPILEDP (function))
3062 result = lambda_arity (function); 3067 result = lambda_arity (function);
3068#ifdef HAVE_MODULES
3069 else if (MODULE_FUNCTIONP (function))
3070 result = module_function_arity (XMODULE_FUNCTION (function));
3071#endif
3063 else 3072 else
3064 { 3073 {
3065 if (NILP (function)) 3074 if (NILP (function))
diff --git a/src/lisp.h b/src/lisp.h
index de3a548cb6c..ec8a8b1c098 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -464,7 +464,6 @@ enum Lisp_Misc_Type
464 Lisp_Misc_Save_Value, 464 Lisp_Misc_Save_Value,
465 Lisp_Misc_Finalizer, 465 Lisp_Misc_Finalizer,
466#ifdef HAVE_MODULES 466#ifdef HAVE_MODULES
467 Lisp_Misc_Module_Function,
468 Lisp_Misc_User_Ptr, 467 Lisp_Misc_User_Ptr,
469#endif 468#endif
470 /* Currently floats are not a misc type, 469 /* Currently floats are not a misc type,
@@ -885,6 +884,7 @@ enum pvec_type
885 PVEC_THREAD, 884 PVEC_THREAD,
886 PVEC_MUTEX, 885 PVEC_MUTEX,
887 PVEC_CONDVAR, 886 PVEC_CONDVAR,
887 PVEC_MODULE_FUNCTION,
888 888
889 /* These should be last, check internal_equal to see why. */ 889 /* These should be last, check internal_equal to see why. */
890 PVEC_COMPILED, 890 PVEC_COMPILED,
@@ -2386,28 +2386,6 @@ struct Lisp_User_Ptr
2386 void (*finalizer) (void *); 2386 void (*finalizer) (void *);
2387 void *p; 2387 void *p;
2388}; 2388};
2389
2390#include "emacs-module.h"
2391
2392/* Function prototype for the module Lisp functions. */
2393typedef emacs_value (*emacs_subr) (emacs_env *, ptrdiff_t,
2394 emacs_value [], void *);
2395
2396/* Function environments. */
2397
2398/* A function environment is an auxiliary structure used by
2399 `module_make_function' to store information about a module
2400 function. It is stored in a save pointer and retrieved by
2401 `internal--module-call'. Its members correspond to the arguments
2402 given to `module_make_function'. */
2403
2404struct Lisp_Module_Function
2405{
2406 struct Lisp_Misc_Any base;
2407 ptrdiff_t min_arity, max_arity;
2408 emacs_subr subr;
2409 void *data;
2410};
2411#endif 2389#endif
2412 2390
2413/* A finalizer sentinel. */ 2391/* A finalizer sentinel. */
@@ -2460,7 +2438,6 @@ union Lisp_Misc
2460 struct Lisp_Finalizer u_finalizer; 2438 struct Lisp_Finalizer u_finalizer;
2461#ifdef HAVE_MODULES 2439#ifdef HAVE_MODULES
2462 struct Lisp_User_Ptr u_user_ptr; 2440 struct Lisp_User_Ptr u_user_ptr;
2463 struct Lisp_Module_Function u_module_function;
2464#endif 2441#endif
2465 }; 2442 };
2466 2443
@@ -2509,19 +2486,6 @@ XUSER_PTR (Lisp_Object a)
2509 eassert (USER_PTRP (a)); 2486 eassert (USER_PTRP (a));
2510 return XUNTAG (a, Lisp_Misc); 2487 return XUNTAG (a, Lisp_Misc);
2511} 2488}
2512
2513INLINE bool
2514MODULE_FUNCTIONP (Lisp_Object o)
2515{
2516 return MISCP (o) && XMISCTYPE (o) == Lisp_Misc_Module_Function;
2517}
2518
2519INLINE struct Lisp_Module_Function *
2520XMODULE_FUNCTION (Lisp_Object o)
2521{
2522 eassert (MODULE_FUNCTIONP (o));
2523 return XUNTAG (o, Lisp_Misc);
2524}
2525#endif 2489#endif
2526 2490
2527 2491
@@ -3923,12 +3887,66 @@ extern void get_backtrace (Lisp_Object array);
3923Lisp_Object backtrace_top_function (void); 3887Lisp_Object backtrace_top_function (void);
3924extern bool let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol); 3888extern bool let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol);
3925 3889
3890#include "emacs-module.h"
3891
3892/* Function prototype for the module Lisp functions. */
3893typedef emacs_value (*emacs_subr) (emacs_env *, ptrdiff_t,
3894 emacs_value [], void *);
3895
3896/* Function environments. */
3897
3898/* A function environment is an auxiliary structure used by
3899 `module_make_function' to store information about a module
3900 function. It is stored in a pseudovector. Its members correspond
3901 to the arguments given to `module_make_function'. */
3902
3903struct Lisp_Module_Function
3904{
3905 struct vectorlike_header header;
3906
3907 /* Fields traced by GC; these must come first. */
3908 Lisp_Object documentation;
3909
3910 /* Fields ignored by GC. */
3911 ptrdiff_t min_arity, max_arity;
3912 emacs_subr subr;
3913 void *data;
3914};
3915
3916INLINE struct Lisp_Module_Function *
3917allocate_module_function (void)
3918{
3919 return ALLOCATE_PSEUDOVECTOR (struct Lisp_Module_Function,
3920 /* Name of the first field to be
3921 ignored by GC. */
3922 min_arity,
3923 PVEC_MODULE_FUNCTION);
3924}
3925
3926INLINE bool
3927MODULE_FUNCTIONP (Lisp_Object o)
3928{
3929 return PSEUDOVECTORP (o, PVEC_MODULE_FUNCTION);
3930}
3931
3932INLINE struct Lisp_Module_Function *
3933XMODULE_FUNCTION (Lisp_Object o)
3934{
3935 eassert (MODULE_FUNCTIONP (o));
3936 return XUNTAG (o, Lisp_Vectorlike);
3937}
3938
3939#define XSET_MODULE_FUNCTION(var, ptr) \
3940 (XSETPSEUDOVECTOR (var, ptr, PVEC_MODULE_FUNCTION))
3941
3926#ifdef HAVE_MODULES 3942#ifdef HAVE_MODULES
3927/* Defined in alloc.c. */ 3943/* Defined in alloc.c. */
3928extern Lisp_Object make_user_ptr (void (*finalizer) (void *), void *p); 3944extern Lisp_Object make_user_ptr (void (*finalizer) (void *), void *p);
3929extern Lisp_Object make_module_function (void);
3930 3945
3931/* Defined in emacs-module.c. */ 3946/* Defined in emacs-module.c. */
3947extern Lisp_Object funcall_module (const struct Lisp_Module_Function *,
3948 ptrdiff_t, Lisp_Object *);
3949extern Lisp_Object module_function_arity (const struct Lisp_Module_Function *);
3932extern Lisp_Object module_format_fun_env (const struct Lisp_Module_Function *); 3950extern Lisp_Object module_format_fun_env (const struct Lisp_Module_Function *);
3933extern void syms_of_module (void); 3951extern void syms_of_module (void);
3934#endif 3952#endif
diff --git a/src/print.c b/src/print.c
index 7e411a80c88..be2e16a7499 100644
--- a/src/print.c
+++ b/src/print.c
@@ -2051,6 +2051,13 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
2051 } 2051 }
2052 break; 2052 break;
2053 2053
2054#ifdef HAVE_MODULES
2055 case PVEC_MODULE_FUNCTION:
2056 print_string (module_format_fun_env (XMODULE_FUNCTION (obj)),
2057 printcharfun);
2058 break;
2059#endif
2060
2054 case PVEC_OTHER: 2061 case PVEC_OTHER:
2055 case PVEC_FREE: 2062 case PVEC_FREE:
2056 emacs_abort (); 2063 emacs_abort ();
@@ -2103,11 +2110,6 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
2103 printchar ('>', printcharfun); 2110 printchar ('>', printcharfun);
2104 break; 2111 break;
2105 } 2112 }
2106
2107 case Lisp_Misc_Module_Function:
2108 print_string (module_format_fun_env (XMODULE_FUNCTION (obj)),
2109 printcharfun);
2110 break;
2111#endif 2113#endif
2112 2114
2113 case Lisp_Misc_Finalizer: 2115 case Lisp_Misc_Finalizer: