diff options
| author | Philipp Stephani | 2017-04-22 18:04:29 +0200 |
|---|---|---|
| committer | Philipp | 2017-05-06 21:29:08 +0200 |
| commit | a3e9694078e24d19db860aa4ff8dec8bc34b59b7 (patch) | |
| tree | 235bf0857ebe0011ffd0b9cbef5f8daa242efbc1 /src | |
| parent | 5e47c2e52b9b7616668c5586084e0128b231272a (diff) | |
| download | emacs-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.c | 7 | ||||
| -rw-r--r-- | src/data.c | 3 | ||||
| -rw-r--r-- | src/emacs-module.c | 48 | ||||
| -rw-r--r-- | src/lisp.h | 39 | ||||
| -rw-r--r-- | src/print.c | 5 |
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. */ | ||
| 3947 | Lisp_Object | ||
| 3948 | make_module_function () | ||
| 3949 | { | ||
| 3950 | return allocate_misc (Lisp_Misc_Module_Function); | ||
| 3951 | } | ||
| 3946 | #endif | 3952 | #endif |
| 3947 | 3953 | ||
| 3948 | static void | 3954 | static 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. */ |
| 63 | typedef int (*emacs_init_function) (struct emacs_runtime *); | 63 | typedef int (*emacs_init_function) (struct emacs_runtime *); |
| 64 | 64 | ||
| 65 | /* Function prototype for the module Lisp functions. */ | ||
| 66 | typedef 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 | ||
| 103 | struct module_fun_env; | 99 | struct module_fun_env; |
| 104 | 100 | ||
| 105 | static Lisp_Object module_format_fun_env (const struct module_fun_env *); | ||
| 106 | static Lisp_Object value_to_lisp (emacs_value); | 101 | static Lisp_Object value_to_lisp (emacs_value); |
| 107 | static emacs_value lisp_to_value (Lisp_Object); | 102 | static emacs_value lisp_to_value (Lisp_Object); |
| 108 | static enum emacs_funcall_exit module_non_local_exit_check (emacs_env *); | 103 | static 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 | |||
| 195 | struct 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. */ |
| 979 | static Lisp_Object | 948 | Lisp_Object |
| 980 | module_format_fun_env (const struct module_fun_env *env) | 949 | module_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. */ | ||
| 2393 | typedef 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 | |||
| 2404 | struct 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 | |||
| 2513 | INLINE bool | ||
| 2514 | MODULE_FUNCTIONP (Lisp_Object o) | ||
| 2515 | { | ||
| 2516 | return MISCP (o) && XMISCTYPE (o) == Lisp_Misc_Module_Function; | ||
| 2517 | } | ||
| 2518 | |||
| 2519 | INLINE struct Lisp_Module_Function * | ||
| 2520 | XMODULE_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. */ |
| 3891 | extern Lisp_Object make_user_ptr (void (*finalizer) (void *), void *p); | 3928 | extern Lisp_Object make_user_ptr (void (*finalizer) (void *), void *p); |
| 3929 | extern Lisp_Object make_module_function (void); | ||
| 3892 | 3930 | ||
| 3893 | /* Defined in emacs-module.c. */ | 3931 | /* Defined in emacs-module.c. */ |
| 3932 | extern Lisp_Object module_format_fun_env (const struct Lisp_Module_Function *); | ||
| 3894 | extern void syms_of_module (void); | 3933 | extern 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: |