aboutsummaryrefslogtreecommitdiffstats
path: root/src/lisp.h
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/lisp.h
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/lisp.h')
-rw-r--r--src/lisp.h94
1 files changed, 56 insertions, 38 deletions
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