aboutsummaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
authorPhilipp Stephani2017-05-13 16:29:40 +0200
committerPhilipp Stephani2017-05-20 15:32:52 +0200
commit31fded0370c3aa6d2c4370cae21cdb7475873483 (patch)
treeacf2a7fda2d1b801b3aaf4cc9f168d3b6da77ec0 /src/eval.c
parent6c7bf039e9c2e6daf548a95204740eeaf4c61abd (diff)
downloademacs-31fded0370c3aa6d2c4370cae21cdb7475873483.tar.gz
emacs-31fded0370c3aa6d2c4370cae21cdb7475873483.zip
Reimplement module functions
Instead of a lambda, create a new type containing all data required to call the function, and support it in the evaluator. Because this type now also needs to store the function documentation, it is too big for Lisp_Misc; use a pseudovector instead. That also has the nice benefit that we don't have to add special support to the garbage collector. Since the new type is user-visible, give it a predicate. Now we can easily support 'help-function-args' and 'func-arity'; add unit tests for these. * src/lisp.h (allocate_module_function, MODULE_FUNCTIONP) (XMODULE_FUNCTION): New pseudovector type 'module function'. * src/eval.c (FUNCTIONP): Also treat module functions as functions. (funcall_lambda, Ffuncall, eval_sub): Add support for calling module functions. (Ffunc_arity): Add support for detecting the arity of module functions. * src/emacs-module.c (module_make_function): Adapt to new structure. Return module function object directly instead of wrapping it in a lambda; remove FIXME. (funcall_module): New function to call module functions. Replaces `internal--module-call' and is called directly from eval.c. (syms_of_module): Remove internal helper function, which is no longer needed. (module_function_arity): New helper function. * src/data.c (Ftype_of): Adapt to new implementation. (Fmodule_function_p, syms_of_data): New user-visible function. Now that module functions are first-class objects, they deserve a predicate. Define it even if not compiled with --enable-modules so that Lisp code doesn't have to check for the function's existence. * src/doc.c (Fdocumentation): Support module functions. * src/print.c (print_object): Adapt to new implementation. * src/alloc.c (mark_object): Specialized garbage collector support is no longer needed. * lisp/help.el (help-function-arglist): Support module functions. While there, simplify the arity calculation by using `func-arity', which does the right thing for all kinds of functions. * test/data/emacs-module/mod-test.c: Amend docstring so we can test the argument list. * test/src/emacs-module-tests.el (mod-test-sum-docstring): Adapt to new docstring. (mod-test-non-local-exit-signal-test): Because `internal--module-call' is gone, the backtrace has changed and no longer leaks the implementation. (module--func-arity): New test for `func-arity'. (module--help-function-arglist): New test for `help-function-arglist'.
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c17
1 files changed, 13 insertions, 4 deletions
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))