diff options
| author | Stefan Monnier | 2013-11-05 11:29:58 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2013-11-05 11:29:58 -0500 |
| commit | 70de5e86d84fc12c6115153c3d6276243cf2b995 (patch) | |
| tree | ef217abb628c34bf0f8af42bf866c56419f95953 /src | |
| parent | 03177f98c9c755b98e25ad9c51bd4945798e77e4 (diff) | |
| download | emacs-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/ChangeLog | 9 | ||||
| -rw-r--r-- | src/eval.c | 20 | ||||
| -rw-r--r-- | src/lisp.h | 5 |
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 @@ | |||
| 1 | 2013-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 | |||
| 1 | 2013-11-05 Eli Zaretskii <eliz@gnu.org> | 10 | 2013-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 | ||
| 240 | static struct handler handlerlist_sentinel; | ||
| 241 | |||
| 240 | void | 242 | void |
| 241 | init_eval (void) | 243 | init_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); \ |