aboutsummaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
authorStefan Monnier2013-11-05 11:29:58 -0500
committerStefan Monnier2013-11-05 11:29:58 -0500
commit70de5e86d84fc12c6115153c3d6276243cf2b995 (patch)
treeef217abb628c34bf0f8af42bf866c56419f95953 /src/eval.c
parent03177f98c9c755b98e25ad9c51bd4945798e77e4 (diff)
downloademacs-70de5e86d84fc12c6115153c3d6276243cf2b995.tar.gz
emacs-70de5e86d84fc12c6115153c3d6276243cf2b995.zip
* src/eval.c (handlerlist_sentinel): New variable.
(init_eval): Use it to ensure handlerlist is non-NULL. (unwind_to_catch): Make sure we never set handlerlist to NULL. (Fsignal): Adjust NULLness test of handlerlist. * src/lisp.h (PUSH_HANDLER): Assume handlerlist is non-NULL. Fixes: debbugs:15802
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/eval.c b/src/eval.c
index a25dc1b5aa9..d3fcec5aef4 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -237,11 +237,22 @@ init_eval_once (void)
237 Vrun_hooks = Qnil; 237 Vrun_hooks = Qnil;
238} 238}
239 239
240static struct handler handlerlist_sentinel;
241
240void 242void
241init_eval (void) 243init_eval (void)
242{ 244{
243 specpdl_ptr = specpdl; 245 specpdl_ptr = specpdl;
244 handlerlist = NULL; 246 { /* Put a dummy catcher at top-level so that handlerlist is never NULL.
247 This is important since handlerlist->nextfree holds the freelist
248 which would otherwise leak every time we unwind back to top-level. */
249 struct handler *c;
250 handlerlist = handlerlist_sentinel.nextfree = &handlerlist_sentinel;
251 PUSH_HANDLER (c, Qunbound, CATCHER);
252 eassert (c == &handlerlist_sentinel);
253 handlerlist_sentinel.nextfree = NULL;
254 handlerlist_sentinel.next = NULL;
255 }
245 Vquit_flag = Qnil; 256 Vquit_flag = Qnil;
246 debug_on_next_call = 0; 257 debug_on_next_call = 0;
247 lisp_eval_depth = 0; 258 lisp_eval_depth = 0;
@@ -1129,6 +1140,8 @@ unwind_to_catch (struct handler *catch, Lisp_Object value)
1129{ 1140{
1130 bool last_time; 1141 bool last_time;
1131 1142
1143 eassert (catch->next);
1144
1132 /* Save the value in the tag. */ 1145 /* Save the value in the tag. */
1133 catch->val = value; 1146 catch->val = value;
1134 1147
@@ -1542,7 +1555,10 @@ See also the function `condition-case'. */)
1542 } 1555 }
1543 else 1556 else
1544 { 1557 {
1545 if (handlerlist != 0) 1558 if (handlerlist != &handlerlist_sentinel)
1559 /* FIXME: This will come right back here if there's no `top-level'
1560 catcher. A better solution would be to abort here, and instead
1561 add a catch-all condition handler so we never come here. */
1546 Fthrow (Qtop_level, Qt); 1562 Fthrow (Qtop_level, Qt);
1547 } 1563 }
1548 1564