aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/ChangeLog9
-rw-r--r--src/eval.c20
-rw-r--r--src/lisp.h5
3 files changed, 29 insertions, 5 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index e47f6a63740..e23af26f543 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,12 @@
12013-11-05 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * eval.c (handlerlist_sentinel): New variable (bug#15802).
4 (init_eval): Use it to ensure handlerlist is non-NULL.
5 (unwind_to_catch): Make sure we never set handlerlist to NULL.
6 (Fsignal): Adjust NULLness test of handlerlist.
7
8 * lisp.h (PUSH_HANDLER): Assume handlerlist is non-NULL.
9
12013-11-05 Eli Zaretskii <eliz@gnu.org> 102013-11-05 Eli Zaretskii <eliz@gnu.org>
2 11
3 * callproc.c (call_process): Call prepare_to_modify_buffer before 12 * callproc.c (call_process): Call prepare_to_modify_buffer before
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
diff --git a/src/lisp.h b/src/lisp.h
index 863b0842f59..b70ca9e9f7c 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2873,14 +2873,13 @@ struct handler
2873 2873
2874/* Fill in the components of c, and put it on the list. */ 2874/* Fill in the components of c, and put it on the list. */
2875#define PUSH_HANDLER(c, tag_ch_val, handlertype) \ 2875#define PUSH_HANDLER(c, tag_ch_val, handlertype) \
2876 if (handlerlist && handlerlist->nextfree) \ 2876 if (handlerlist->nextfree) \
2877 (c) = handlerlist->nextfree; \ 2877 (c) = handlerlist->nextfree; \
2878 else \ 2878 else \
2879 { \ 2879 { \
2880 (c) = xmalloc (sizeof (struct handler)); \ 2880 (c) = xmalloc (sizeof (struct handler)); \
2881 (c)->nextfree = NULL; \ 2881 (c)->nextfree = NULL; \
2882 if (handlerlist) \ 2882 handlerlist->nextfree = (c); \
2883 handlerlist->nextfree = (c); \
2884 } \ 2883 } \
2885 (c)->type = (handlertype); \ 2884 (c)->type = (handlertype); \
2886 (c)->tag_or_ch = (tag_ch_val); \ 2885 (c)->tag_or_ch = (tag_ch_val); \