aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPhilipp Stephani2017-04-22 18:04:29 +0200
committerPhilipp2017-05-06 21:29:08 +0200
commita3e9694078e24d19db860aa4ff8dec8bc34b59b7 (patch)
tree235bf0857ebe0011ffd0b9cbef5f8daa242efbc1 /src
parent5e47c2e52b9b7616668c5586084e0128b231272a (diff)
downloademacs-a3e9694078e24d19db860aa4ff8dec8bc34b59b7.tar.gz
emacs-a3e9694078e24d19db860aa4ff8dec8bc34b59b7.zip
Introduce new misc type for module function
This resolves a couple of FIXMEs in emacs-module.c. * src/lisp.h (MODULE_FUNCTIONP, XMODULE_FUNCTION): New functions. * src/alloc.c (make_module_function): New function. (mark_object): GC support. * src/data.c (Ftype_of, syms_of_data): Handle module function type. * src/print.c (print_object): Print support for new type. * src/emacs-module.c (module_make_function, Finternal_module_call): Use new module function type, remove FIXMEs. (module_format_fun_env): Adapt and give it external linkage. * test/src/emacs-module-tests.el (module-function-object): Add unit test.
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c7
-rw-r--r--src/data.c3
-rw-r--r--src/emacs-module.c48
-rw-r--r--src/lisp.h39
-rw-r--r--src/print.c5
5 files changed, 63 insertions, 39 deletions
diff --git a/src/alloc.c b/src/alloc.c
index ab6b2960af0..cecd9f55058 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -3943,6 +3943,12 @@ make_user_ptr (void (*finalizer) (void *), void *p)
3943 return obj; 3943 return obj;
3944} 3944}
3945 3945
3946/* Create a new module function environment object. */
3947Lisp_Object
3948make_module_function ()
3949{
3950 return allocate_misc (Lisp_Misc_Module_Function);
3951}
3946#endif 3952#endif
3947 3953
3948static void 3954static void
@@ -6634,6 +6640,7 @@ mark_object (Lisp_Object arg)
6634 6640
6635#ifdef HAVE_MODULES 6641#ifdef HAVE_MODULES
6636 case Lisp_Misc_User_Ptr: 6642 case Lisp_Misc_User_Ptr:
6643 case Lisp_Misc_Module_Function:
6637 XMISCANY (obj)->gcmarkbit = true; 6644 XMISCANY (obj)->gcmarkbit = true;
6638 break; 6645 break;
6639#endif 6646#endif
diff --git a/src/data.c b/src/data.c
index 141b26ccf35..44f7ba0e881 100644
--- a/src/data.c
+++ b/src/data.c
@@ -233,6 +233,8 @@ 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;
236 case Lisp_Misc_User_Ptr: 238 case Lisp_Misc_User_Ptr:
237 return Quser_ptr; 239 return Quser_ptr;
238#endif 240#endif
@@ -3729,6 +3731,7 @@ syms_of_data (void)
3729 DEFSYM (Qoverlay, "overlay"); 3731 DEFSYM (Qoverlay, "overlay");
3730 DEFSYM (Qfinalizer, "finalizer"); 3732 DEFSYM (Qfinalizer, "finalizer");
3731#ifdef HAVE_MODULES 3733#ifdef HAVE_MODULES
3734 DEFSYM (Qmodule_function, "module-function");
3732 DEFSYM (Quser_ptr, "user-ptr"); 3735 DEFSYM (Quser_ptr, "user-ptr");
3733#endif 3736#endif
3734 DEFSYM (Qfloat, "float"); 3737 DEFSYM (Qfloat, "float");
diff --git a/src/emacs-module.c b/src/emacs-module.c
index 1b445dcc3b2..cd025a1396e 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -62,10 +62,6 @@ enum
62/* Function prototype for the module init function. */ 62/* Function prototype for the module init function. */
63typedef int (*emacs_init_function) (struct emacs_runtime *); 63typedef int (*emacs_init_function) (struct emacs_runtime *);
64 64
65/* Function prototype for the module Lisp functions. */
66typedef emacs_value (*emacs_subr) (emacs_env *, ptrdiff_t,
67 emacs_value [], void *);
68
69/* Function prototype for module user-pointer finalizers. These 65/* Function prototype for module user-pointer finalizers. These
70 should not throw C++ exceptions, so emacs-module.h declares the 66 should not throw C++ exceptions, so emacs-module.h declares the
71 corresponding interfaces with EMACS_NOEXCEPT. There is only C code 67 corresponding interfaces with EMACS_NOEXCEPT. There is only C code
@@ -102,7 +98,6 @@ struct emacs_runtime_private
102 98
103struct module_fun_env; 99struct module_fun_env;
104 100
105static Lisp_Object module_format_fun_env (const struct module_fun_env *);
106static Lisp_Object value_to_lisp (emacs_value); 101static Lisp_Object value_to_lisp (emacs_value);
107static emacs_value lisp_to_value (Lisp_Object); 102static emacs_value lisp_to_value (Lisp_Object);
108static enum emacs_funcall_exit module_non_local_exit_check (emacs_env *); 103static enum emacs_funcall_exit module_non_local_exit_check (emacs_env *);
@@ -184,22 +179,6 @@ static emacs_value const module_nil = 0;
184 do { } while (false) 179 do { } while (false)
185 180
186 181
187/* Function environments. */
188
189/* A function environment is an auxiliary structure used by
190 `module_make_function' to store information about a module
191 function. It is stored in a save pointer and retrieved by
192 `internal--module-call'. Its members correspond to the arguments
193 given to `module_make_function'. */
194
195struct module_fun_env
196{
197 ptrdiff_t min_arity, max_arity;
198 emacs_subr subr;
199 void *data;
200};
201
202
203/* Implementation of runtime and environment functions. 182/* Implementation of runtime and environment functions.
204 183
205 These should abide by the following rules: 184 These should abide by the following rules:
@@ -382,14 +361,13 @@ module_make_function (emacs_env *env, ptrdiff_t min_arity, ptrdiff_t max_arity,
382 : min_arity <= max_arity))) 361 : min_arity <= max_arity)))
383 xsignal2 (Qinvalid_arity, make_number (min_arity), make_number (max_arity)); 362 xsignal2 (Qinvalid_arity, make_number (min_arity), make_number (max_arity));
384 363
385 /* FIXME: This should be freed when envobj is GC'd. */ 364 Lisp_Object envobj = make_module_function ();
386 struct module_fun_env *envptr = xmalloc (sizeof *envptr); 365 struct Lisp_Module_Function *envptr = XMODULE_FUNCTION (envobj);
387 envptr->min_arity = min_arity; 366 envptr->min_arity = min_arity;
388 envptr->max_arity = max_arity; 367 envptr->max_arity = max_arity;
389 envptr->subr = subr; 368 envptr->subr = subr;
390 envptr->data = data; 369 envptr->data = data;
391 370
392 Lisp_Object envobj = make_save_ptr (envptr);
393 Lisp_Object doc = Qnil; 371 Lisp_Object doc = Qnil;
394 if (documentation) 372 if (documentation)
395 { 373 {
@@ -677,17 +655,8 @@ usage: (module-call ENVOBJ &rest ARGLIST) */)
677 (ptrdiff_t nargs, Lisp_Object *arglist) 655 (ptrdiff_t nargs, Lisp_Object *arglist)
678{ 656{
679 Lisp_Object envobj = arglist[0]; 657 Lisp_Object envobj = arglist[0];
680 /* FIXME: Rather than use a save_value, we should create a new object type. 658 CHECK_TYPE (MODULE_FUNCTIONP (envobj), Qmodule_function_p, envobj);
681 Making save_value visible to Lisp is wrong. */ 659 struct Lisp_Module_Function *envptr = XMODULE_FUNCTION (envobj);
682 CHECK_TYPE (SAVE_VALUEP (envobj), Qsave_value_p, envobj);
683 struct Lisp_Save_Value *save_value = XSAVE_VALUE (envobj);
684 CHECK_TYPE (save_type (save_value, 0) == SAVE_POINTER, Qsave_pointer_p, envobj);
685 /* FIXME: We have no reason to believe that XSAVE_POINTER (envobj, 0)
686 is a module_fun_env pointer. If some other part of Emacs also
687 exports save_value objects to Elisp, than we may be getting here this
688 other kind of save_value which will likely hold something completely
689 different in this field. */
690 struct module_fun_env *envptr = XSAVE_POINTER (envobj, 0);
691 EMACS_INT len = nargs - 1; 660 EMACS_INT len = nargs - 1;
692 eassume (0 <= envptr->min_arity); 661 eassume (0 <= envptr->min_arity);
693 if (! (envptr->min_arity <= len 662 if (! (envptr->min_arity <= len
@@ -976,10 +945,12 @@ module_handle_throw (emacs_env *env, Lisp_Object tag_val)
976 945
977/* Return a string object that contains a user-friendly 946/* Return a string object that contains a user-friendly
978 representation of the function environment. */ 947 representation of the function environment. */
979static Lisp_Object 948Lisp_Object
980module_format_fun_env (const struct module_fun_env *env) 949module_format_fun_env (const struct Lisp_Module_Function *env)
981{ 950{
982 /* Try to print a function name if possible. */ 951 /* Try to print a function name if possible. */
952 /* FIXME: Move this function into print.c, then use prin1-to-string
953 above. */
983 const char *path, *sym; 954 const char *path, *sym;
984 static char const noaddr_format[] = "#<module function at %p>"; 955 static char const noaddr_format[] = "#<module function at %p>";
985 char buffer[sizeof noaddr_format + INT_STRLEN_BOUND (intptr_t) + 256]; 956 char buffer[sizeof noaddr_format + INT_STRLEN_BOUND (intptr_t) + 256];
@@ -1048,8 +1019,7 @@ syms_of_module (void)
1048 code or modules should not access it. */ 1019 code or modules should not access it. */
1049 Funintern (Qmodule_refs_hash, Qnil); 1020 Funintern (Qmodule_refs_hash, Qnil);
1050 1021
1051 DEFSYM (Qsave_value_p, "save-value-p"); 1022 DEFSYM (Qmodule_function_p, "module-function-p");
1052 DEFSYM (Qsave_pointer_p, "save-pointer-p");
1053 1023
1054 defsubr (&Smodule_load); 1024 defsubr (&Smodule_load);
1055 1025
diff --git a/src/lisp.h b/src/lisp.h
index daf57ed906f..5d4c64a2e50 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -464,6 +464,7 @@ 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,
467 Lisp_Misc_User_Ptr, 468 Lisp_Misc_User_Ptr,
468#endif 469#endif
469 /* Currently floats are not a misc type, 470 /* Currently floats are not a misc type,
@@ -2385,6 +2386,28 @@ struct Lisp_User_Ptr
2385 void (*finalizer) (void *); 2386 void (*finalizer) (void *);
2386 void *p; 2387 void *p;
2387}; 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};
2388#endif 2411#endif
2389 2412
2390/* A finalizer sentinel. */ 2413/* A finalizer sentinel. */
@@ -2437,6 +2460,7 @@ union Lisp_Misc
2437 struct Lisp_Finalizer u_finalizer; 2460 struct Lisp_Finalizer u_finalizer;
2438#ifdef HAVE_MODULES 2461#ifdef HAVE_MODULES
2439 struct Lisp_User_Ptr u_user_ptr; 2462 struct Lisp_User_Ptr u_user_ptr;
2463 struct Lisp_Module_Function u_module_function;
2440#endif 2464#endif
2441 }; 2465 };
2442 2466
@@ -2485,6 +2509,19 @@ XUSER_PTR (Lisp_Object a)
2485 eassert (USER_PTRP (a)); 2509 eassert (USER_PTRP (a));
2486 return XUNTAG (a, Lisp_Misc); 2510 return XUNTAG (a, Lisp_Misc);
2487} 2511}
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}
2488#endif 2525#endif
2489 2526
2490 2527
@@ -3889,8 +3926,10 @@ extern bool let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol);
3889#ifdef HAVE_MODULES 3926#ifdef HAVE_MODULES
3890/* Defined in alloc.c. */ 3927/* Defined in alloc.c. */
3891extern Lisp_Object make_user_ptr (void (*finalizer) (void *), void *p); 3928extern Lisp_Object make_user_ptr (void (*finalizer) (void *), void *p);
3929extern Lisp_Object make_module_function (void);
3892 3930
3893/* Defined in emacs-module.c. */ 3931/* Defined in emacs-module.c. */
3932extern Lisp_Object module_format_fun_env (const struct Lisp_Module_Function *);
3894extern void syms_of_module (void); 3933extern void syms_of_module (void);
3895#endif 3934#endif
3896 3935
diff --git a/src/print.c b/src/print.c
index 872103bd4c2..7e411a80c88 100644
--- a/src/print.c
+++ b/src/print.c
@@ -2103,6 +2103,11 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
2103 printchar ('>', printcharfun); 2103 printchar ('>', printcharfun);
2104 break; 2104 break;
2105 } 2105 }
2106
2107 case Lisp_Misc_Module_Function:
2108 print_string (module_format_fun_env (XMODULE_FUNCTION (obj)),
2109 printcharfun);
2110 break;
2106#endif 2111#endif
2107 2112
2108 case Lisp_Misc_Finalizer: 2113 case Lisp_Misc_Finalizer: