summaryrefslogtreecommitdiff
path: root/src/emacs-module.c
diff options
context:
space:
mode:
authorPhilipp Stephani <phst@google.com>2017-06-05 13:05:51 +0200
committerPhilipp Stephani <phst@google.com>2017-06-05 15:10:24 +0200
commit5d29c0f006d071008eba8d235db917d5c8b271bb (patch)
tree4203cbc6db953bf258432b64b8437d535a925f8c /src/emacs-module.c
parent9f496c591d457b511a42c0f63e0d2d923cda0247 (diff)
downloademacs-5d29c0f006d071008eba8d235db917d5c8b271bb.tar.gz
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.
Diffstat (limited to 'src/emacs-module.c')
-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);
static enum emacs_funcall_exit module_non_local_exit_check (emacs_env *);
static void check_main_thread (void);
static void initialize_environment (emacs_env *, struct emacs_env_private *);
-static void finalize_environment (emacs_env *, struct emacs_env_private *);
+static void finalize_environment (emacs_env *);
+static void finalize_environment_unwind (void *);
+static void finalize_runtime_unwind (void *);
static void module_handle_signal (emacs_env *, Lisp_Object);
static void module_handle_throw (emacs_env *, Lisp_Object);
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,
.private_members = &rt,
.get_environment = module_get_environment
};
+ ptrdiff_t count = SPECPDL_INDEX ();
+ record_unwind_protect_ptr (finalize_runtime_unwind, &pub);
+
int r = module_init (&pub);
- finalize_environment (&rt.pub, &priv);
if (r != 0)
{
@@ -644,7 +648,7 @@ DEFUN ("module-load", Fmodule_load, Smodule_load, 1, 1, 0,
xsignal2 (Qmodule_init_failed, file, make_number (r));
}
- return Qt;
+ return unbind_to (count, Qt);
}
Lisp_Object
@@ -659,6 +663,8 @@ funcall_module (Lisp_Object function, ptrdiff_t nargs, Lisp_Object *arglist)
emacs_env pub;
struct emacs_env_private priv;
initialize_environment (&pub, &priv);
+ ptrdiff_t count = SPECPDL_INDEX ();
+ record_unwind_protect_ptr (finalize_environment_unwind, &pub);
USE_SAFE_ALLOCA;
ATTRIBUTE_MAY_ALIAS emacs_value *args;
@@ -683,22 +689,11 @@ funcall_module (Lisp_Object function, ptrdiff_t nargs, Lisp_Object *arglist)
switch (priv.pending_non_local_exit)
{
case emacs_funcall_exit_return:
- finalize_environment (&pub, &priv);
- return value_to_lisp (ret);
+ return unbind_to (count, value_to_lisp (ret));
case emacs_funcall_exit_signal:
- {
- Lisp_Object symbol = priv.non_local_exit_symbol;
- Lisp_Object data = priv.non_local_exit_data;
- finalize_environment (&pub, &priv);
- xsignal (symbol, data);
- }
+ xsignal (priv.non_local_exit_symbol, priv.non_local_exit_data);
case emacs_funcall_exit_throw:
- {
- Lisp_Object tag = priv.non_local_exit_symbol;
- Lisp_Object value = priv.non_local_exit_data;
- finalize_environment (&pub, &priv);
- Fthrow (tag, value);
- }
+ Fthrow (priv.non_local_exit_symbol, priv.non_local_exit_data);
default:
eassume (false);
}
@@ -912,13 +907,25 @@ initialize_environment (emacs_env *env, struct emacs_env_private *priv)
/* Must be called before the lifetime of the environment object
ends. */
static void
-finalize_environment (emacs_env *env, struct emacs_env_private *priv)
+finalize_environment (emacs_env *env)
{
- eassert (env->private_members == priv);
eassert (XSAVE_POINTER (XCAR (Vmodule_environments), 0) == env);
Vmodule_environments = XCDR (Vmodule_environments);
}
+static void
+finalize_environment_unwind (void *env)
+{
+ finalize_environment (env);
+}
+
+static void
+finalize_runtime_unwind (void* raw_ert)
+{
+ struct emacs_runtime *ert = raw_ert;
+ finalize_environment (&ert->private_members->pub);
+}
+
/* Non-local exit handling. */