diff options
| author | Philipp Stephani | 2017-06-05 13:05:51 +0200 |
|---|---|---|
| committer | Philipp Stephani | 2017-06-05 15:10:24 +0200 |
| commit | 5d29c0f006d071008eba8d235db917d5c8b271bb (patch) | |
| tree | 4203cbc6db953bf258432b64b8437d535a925f8c | |
| parent | 9f496c591d457b511a42c0f63e0d2d923cda0247 (diff) | |
| download | emacs-5d29c0f006d071008eba8d235db917d5c8b271bb.tar.gz emacs-5d29c0f006d071008eba8d235db917d5c8b271bb.zip | |
Use unwind protection to clean up data structures in modules
Reuse existing functionality and simplify the code a bit.
* src/emacs-module.c (Fmodule_load): Use unwind protection to clean up
runtime object.
(funcall_module): Use unwind protection to clean up environment
object.
(finalize_environment): Simplify signature.
(finalize_environment_unwind, finalize_runtime_unwind): New functions.
| -rw-r--r-- | src/emacs-module.c | 45 |
1 files changed, 26 insertions, 19 deletions
diff --git a/src/emacs-module.c b/src/emacs-module.c index 71e04d869e9..bebfe594426 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c | |||
| @@ -96,7 +96,9 @@ static emacs_value lisp_to_value (Lisp_Object); | |||
| 96 | static enum emacs_funcall_exit module_non_local_exit_check (emacs_env *); | 96 | static enum emacs_funcall_exit module_non_local_exit_check (emacs_env *); |
| 97 | static void check_main_thread (void); | 97 | static void check_main_thread (void); |
| 98 | static void initialize_environment (emacs_env *, struct emacs_env_private *); | 98 | static void initialize_environment (emacs_env *, struct emacs_env_private *); |
| 99 | static void finalize_environment (emacs_env *, struct emacs_env_private *); | 99 | static void finalize_environment (emacs_env *); |
| 100 | static void finalize_environment_unwind (void *); | ||
| 101 | static void finalize_runtime_unwind (void *); | ||
| 100 | static void module_handle_signal (emacs_env *, Lisp_Object); | 102 | static void module_handle_signal (emacs_env *, Lisp_Object); |
| 101 | static void module_handle_throw (emacs_env *, Lisp_Object); | 103 | static void module_handle_throw (emacs_env *, Lisp_Object); |
| 102 | static void module_non_local_exit_signal_1 (emacs_env *, Lisp_Object, Lisp_Object); | 104 | static void module_non_local_exit_signal_1 (emacs_env *, Lisp_Object, Lisp_Object); |
| @@ -634,8 +636,10 @@ DEFUN ("module-load", Fmodule_load, Smodule_load, 1, 1, 0, | |||
| 634 | .private_members = &rt, | 636 | .private_members = &rt, |
| 635 | .get_environment = module_get_environment | 637 | .get_environment = module_get_environment |
| 636 | }; | 638 | }; |
| 639 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 640 | record_unwind_protect_ptr (finalize_runtime_unwind, &pub); | ||
| 641 | |||
| 637 | int r = module_init (&pub); | 642 | int r = module_init (&pub); |
| 638 | finalize_environment (&rt.pub, &priv); | ||
| 639 | 643 | ||
| 640 | if (r != 0) | 644 | if (r != 0) |
| 641 | { | 645 | { |
| @@ -644,7 +648,7 @@ DEFUN ("module-load", Fmodule_load, Smodule_load, 1, 1, 0, | |||
| 644 | xsignal2 (Qmodule_init_failed, file, make_number (r)); | 648 | xsignal2 (Qmodule_init_failed, file, make_number (r)); |
| 645 | } | 649 | } |
| 646 | 650 | ||
| 647 | return Qt; | 651 | return unbind_to (count, Qt); |
| 648 | } | 652 | } |
| 649 | 653 | ||
| 650 | Lisp_Object | 654 | Lisp_Object |
| @@ -659,6 +663,8 @@ funcall_module (Lisp_Object function, ptrdiff_t nargs, Lisp_Object *arglist) | |||
| 659 | emacs_env pub; | 663 | emacs_env pub; |
| 660 | struct emacs_env_private priv; | 664 | struct emacs_env_private priv; |
| 661 | initialize_environment (&pub, &priv); | 665 | initialize_environment (&pub, &priv); |
| 666 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 667 | record_unwind_protect_ptr (finalize_environment_unwind, &pub); | ||
| 662 | 668 | ||
| 663 | USE_SAFE_ALLOCA; | 669 | USE_SAFE_ALLOCA; |
| 664 | ATTRIBUTE_MAY_ALIAS emacs_value *args; | 670 | ATTRIBUTE_MAY_ALIAS emacs_value *args; |
| @@ -683,22 +689,11 @@ funcall_module (Lisp_Object function, ptrdiff_t nargs, Lisp_Object *arglist) | |||
| 683 | switch (priv.pending_non_local_exit) | 689 | switch (priv.pending_non_local_exit) |
| 684 | { | 690 | { |
| 685 | case emacs_funcall_exit_return: | 691 | case emacs_funcall_exit_return: |
| 686 | finalize_environment (&pub, &priv); | 692 | return unbind_to (count, value_to_lisp (ret)); |
| 687 | return value_to_lisp (ret); | ||
| 688 | case emacs_funcall_exit_signal: | 693 | case emacs_funcall_exit_signal: |
| 689 | { | 694 | xsignal (priv.non_local_exit_symbol, priv.non_local_exit_data); |
| 690 | Lisp_Object symbol = priv.non_local_exit_symbol; | ||
| 691 | Lisp_Object data = priv.non_local_exit_data; | ||
| 692 | finalize_environment (&pub, &priv); | ||
| 693 | xsignal (symbol, data); | ||
| 694 | } | ||
| 695 | case emacs_funcall_exit_throw: | 695 | case emacs_funcall_exit_throw: |
| 696 | { | 696 | Fthrow (priv.non_local_exit_symbol, priv.non_local_exit_data); |
| 697 | Lisp_Object tag = priv.non_local_exit_symbol; | ||
| 698 | Lisp_Object value = priv.non_local_exit_data; | ||
| 699 | finalize_environment (&pub, &priv); | ||
| 700 | Fthrow (tag, value); | ||
| 701 | } | ||
| 702 | default: | 697 | default: |
| 703 | eassume (false); | 698 | eassume (false); |
| 704 | } | 699 | } |
| @@ -912,13 +907,25 @@ initialize_environment (emacs_env *env, struct emacs_env_private *priv) | |||
| 912 | /* Must be called before the lifetime of the environment object | 907 | /* Must be called before the lifetime of the environment object |
| 913 | ends. */ | 908 | ends. */ |
| 914 | static void | 909 | static void |
| 915 | finalize_environment (emacs_env *env, struct emacs_env_private *priv) | 910 | finalize_environment (emacs_env *env) |
| 916 | { | 911 | { |
| 917 | eassert (env->private_members == priv); | ||
| 918 | eassert (XSAVE_POINTER (XCAR (Vmodule_environments), 0) == env); | 912 | eassert (XSAVE_POINTER (XCAR (Vmodule_environments), 0) == env); |
| 919 | Vmodule_environments = XCDR (Vmodule_environments); | 913 | Vmodule_environments = XCDR (Vmodule_environments); |
| 920 | } | 914 | } |
| 921 | 915 | ||
| 916 | static void | ||
| 917 | finalize_environment_unwind (void *env) | ||
| 918 | { | ||
| 919 | finalize_environment (env); | ||
| 920 | } | ||
| 921 | |||
| 922 | static void | ||
| 923 | finalize_runtime_unwind (void* raw_ert) | ||
| 924 | { | ||
| 925 | struct emacs_runtime *ert = raw_ert; | ||
| 926 | finalize_environment (&ert->private_members->pub); | ||
| 927 | } | ||
| 928 | |||
| 922 | 929 | ||
| 923 | /* Non-local exit handling. */ | 930 | /* Non-local exit handling. */ |
| 924 | 931 | ||