aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Stephani2017-06-05 13:05:51 +0200
committerPhilipp Stephani2017-06-05 15:10:24 +0200
commit5d29c0f006d071008eba8d235db917d5c8b271bb (patch)
tree4203cbc6db953bf258432b64b8437d535a925f8c
parent9f496c591d457b511a42c0f63e0d2d923cda0247 (diff)
downloademacs-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.c45
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);
96static enum emacs_funcall_exit module_non_local_exit_check (emacs_env *); 96static enum emacs_funcall_exit module_non_local_exit_check (emacs_env *);
97static void check_main_thread (void); 97static void check_main_thread (void);
98static void initialize_environment (emacs_env *, struct emacs_env_private *); 98static void initialize_environment (emacs_env *, struct emacs_env_private *);
99static void finalize_environment (emacs_env *, struct emacs_env_private *); 99static void finalize_environment (emacs_env *);
100static void finalize_environment_unwind (void *);
101static void finalize_runtime_unwind (void *);
100static void module_handle_signal (emacs_env *, Lisp_Object); 102static void module_handle_signal (emacs_env *, Lisp_Object);
101static void module_handle_throw (emacs_env *, Lisp_Object); 103static void module_handle_throw (emacs_env *, Lisp_Object);
102static void module_non_local_exit_signal_1 (emacs_env *, Lisp_Object, Lisp_Object); 104static 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
650Lisp_Object 654Lisp_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. */
914static void 909static void
915finalize_environment (emacs_env *env, struct emacs_env_private *priv) 910finalize_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
916static void
917finalize_environment_unwind (void *env)
918{
919 finalize_environment (env);
920}
921
922static void
923finalize_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