aboutsummaryrefslogtreecommitdiffstats
path: root/src/emacs-module.c
diff options
context:
space:
mode:
authorPhilipp Stephani2018-02-11 21:38:22 +0100
committerPhilipp Stephani2020-01-03 19:24:10 +0100
commit48ffef5ef4b34799941a033591ea827d40025939 (patch)
tree67b00c1bc546f3c9ef601c10db634da3094f7f57 /src/emacs-module.c
parent2b6d702e5d2d572640c6bcd43f54138bacbe7ac8 (diff)
downloademacs-48ffef5ef4b34799941a033591ea827d40025939.tar.gz
emacs-48ffef5ef4b34799941a033591ea827d40025939.zip
Implement finalizers for module functions (Bug#30373)
* src/module-env-28.h: Add new module environment functions to module environment for Emacs 28. * src/emacs-module.h.in: Document that 'emacs_finalizer' also works for function finalizers. * src/emacs-module.c (CHECK_MODULE_FUNCTION): New function. (struct Lisp_Module_Function): Add finalizer data member. (module_make_function): Initialize finalizer. (module_get_function_finalizer) (module_set_function_finalizer): New module environment functions. (module_finalize_function): New function. (initialize_environment): Initialize new environment functions. * src/alloc.c (cleanup_vector): Call potential module function finalizer during garbage collection. * test/data/emacs-module/mod-test.c (signal_error): New helper function. (memory_full): Use it. (finalizer): New example function finalizer. (Fmod_test_make_function_with_finalizer) (Fmod_test_function_finalizer_calls): New test module functions. (emacs_module_init): Define them. * test/src/emacs-module-tests.el (module/function-finalizer): New unit test. * doc/lispref/internals.texi (Module Functions): Document new functionality. (Module Misc): Move description of 'emacs_finalizer' type to 'Module Functions' node, and add a reference to it. * etc/NEWS: Mention new functionality.
Diffstat (limited to 'src/emacs-module.c')
-rw-r--r--src/emacs-module.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/emacs-module.c b/src/emacs-module.c
index bbb0e3dadd9..3855a33f254 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -327,6 +327,12 @@ static bool module_assertions = false;
327 MODULE_HANDLE_NONLOCAL_EXIT (error_retval) 327 MODULE_HANDLE_NONLOCAL_EXIT (error_retval)
328 328
329static void 329static void
330CHECK_MODULE_FUNCTION (Lisp_Object obj)
331{
332 CHECK_TYPE (MODULE_FUNCTIONP (obj), Qmodule_function_p, obj);
333}
334
335static void
330CHECK_USER_PTR (Lisp_Object obj) 336CHECK_USER_PTR (Lisp_Object obj)
331{ 337{
332 CHECK_TYPE (USER_PTRP (obj), Quser_ptrp, obj); 338 CHECK_TYPE (USER_PTRP (obj), Quser_ptrp, obj);
@@ -478,6 +484,7 @@ struct Lisp_Module_Function
478 ptrdiff_t min_arity, max_arity; 484 ptrdiff_t min_arity, max_arity;
479 emacs_function subr; 485 emacs_function subr;
480 void *data; 486 void *data;
487 emacs_finalizer finalizer;
481} GCALIGNED_STRUCT; 488} GCALIGNED_STRUCT;
482 489
483static struct Lisp_Module_Function * 490static struct Lisp_Module_Function *
@@ -511,6 +518,7 @@ module_make_function (emacs_env *env, ptrdiff_t min_arity, ptrdiff_t max_arity,
511 function->max_arity = max_arity; 518 function->max_arity = max_arity;
512 function->subr = func; 519 function->subr = func;
513 function->data = data; 520 function->data = data;
521 function->finalizer = NULL;
514 522
515 if (docstring) 523 if (docstring)
516 function->documentation = build_string_from_utf8 (docstring); 524 function->documentation = build_string_from_utf8 (docstring);
@@ -522,6 +530,32 @@ module_make_function (emacs_env *env, ptrdiff_t min_arity, ptrdiff_t max_arity,
522 return lisp_to_value (env, result); 530 return lisp_to_value (env, result);
523} 531}
524 532
533static emacs_finalizer
534module_get_function_finalizer (emacs_env *env, emacs_value arg)
535{
536 MODULE_FUNCTION_BEGIN (NULL);
537 Lisp_Object lisp = value_to_lisp (arg);
538 CHECK_MODULE_FUNCTION (lisp);
539 return XMODULE_FUNCTION (lisp)->finalizer;
540}
541
542static void
543module_set_function_finalizer (emacs_env *env, emacs_value arg,
544 emacs_finalizer fin)
545{
546 MODULE_FUNCTION_BEGIN ();
547 Lisp_Object lisp = value_to_lisp (arg);
548 CHECK_MODULE_FUNCTION (lisp);
549 XMODULE_FUNCTION (lisp)->finalizer = fin;
550}
551
552void
553module_finalize_function (const struct Lisp_Module_Function *func)
554{
555 if (func->finalizer != NULL)
556 func->finalizer (func->data);
557}
558
525static emacs_value 559static emacs_value
526module_funcall (emacs_env *env, emacs_value func, ptrdiff_t nargs, 560module_funcall (emacs_env *env, emacs_value func, ptrdiff_t nargs,
527 emacs_value *args) 561 emacs_value *args)
@@ -1329,6 +1363,8 @@ initialize_environment (emacs_env *env, struct emacs_env_private *priv)
1329 env->make_time = module_make_time; 1363 env->make_time = module_make_time;
1330 env->extract_big_integer = module_extract_big_integer; 1364 env->extract_big_integer = module_extract_big_integer;
1331 env->make_big_integer = module_make_big_integer; 1365 env->make_big_integer = module_make_big_integer;
1366 env->get_function_finalizer = module_get_function_finalizer;
1367 env->set_function_finalizer = module_set_function_finalizer;
1332 Vmodule_environments = Fcons (make_mint_ptr (env), Vmodule_environments); 1368 Vmodule_environments = Fcons (make_mint_ptr (env), Vmodule_environments);
1333 return env; 1369 return env;
1334} 1370}