From 611a8f8c1fd311aa28e94b870e7ec2c2ab059353 Mon Sep 17 00:00:00 2001 From: "Richard M. Stallman" Date: Fri, 9 May 2003 14:01:12 +0000 Subject: [PATCH] (specpdl_ptr): Declare volatile. (unbind_to): Copy the whole binding and decrement specpdl_ptr before doing the work of unbinding it. --- src/eval.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/eval.c b/src/eval.c index 0310e165919..cb8bd9d0ffe 100644 --- a/src/eval.c +++ b/src/eval.c @@ -117,7 +117,7 @@ struct specbinding *specpdl; /* Pointer to first unused element in specpdl. */ -struct specbinding *specpdl_ptr; +volatile struct specbinding *specpdl_ptr; /* Maximum size allowed for specpdl allocation */ @@ -3070,10 +3070,16 @@ unbind_to (count, value) while (specpdl_ptr != specpdl + count) { - --specpdl_ptr; + /* Copy the binding, and decrement specpdl_ptr, before we do + the work to unbind it. We decrement first + so that an error in unbinding won't try to unbind + the same entry again, and we copy the binding first + in case more bindings are made during some of the code we run. */ - if (specpdl_ptr->func != 0) - (*specpdl_ptr->func) (specpdl_ptr->old_value); + struct specbinding this_binding = *--specpdl_ptr; + + if (this_binding.func != 0) + (*this_binding.func) (this_binding.old_value); /* If the symbol is a list, it is really (SYMBOL WHERE . CURRENT-BUFFER) where WHERE is either nil, a buffer, or a frame. If WHERE is a buffer or frame, this indicates we @@ -3081,29 +3087,29 @@ unbind_to (count, value) binding. WHERE nil means that the variable had the default value when it was bound. CURRENT-BUFFER is the buffer that was current when the variable was bound. */ - else if (CONSP (specpdl_ptr->symbol)) + else if (CONSP (this_binding.symbol)) { Lisp_Object symbol, where; - symbol = XCAR (specpdl_ptr->symbol); - where = XCAR (XCDR (specpdl_ptr->symbol)); + symbol = XCAR (this_binding.symbol); + where = XCAR (XCDR (this_binding.symbol)); if (NILP (where)) - Fset_default (symbol, specpdl_ptr->old_value); + Fset_default (symbol, this_binding.old_value); else if (BUFFERP (where)) - set_internal (symbol, specpdl_ptr->old_value, XBUFFER (where), 1); + set_internal (symbol, this_binding.old_value, XBUFFER (where), 1); else - set_internal (symbol, specpdl_ptr->old_value, NULL, 1); + set_internal (symbol, this_binding.old_value, NULL, 1); } else { /* If variable has a trivial value (no forwarding), we can just set it. No need to check for constant symbols here, since that was already done by specbind. */ - if (!MISCP (SYMBOL_VALUE (specpdl_ptr->symbol))) - SET_SYMBOL_VALUE (specpdl_ptr->symbol, specpdl_ptr->old_value); + if (!MISCP (SYMBOL_VALUE (this_binding.symbol))) + SET_SYMBOL_VALUE (this_binding.symbol, this_binding.old_value); else - set_internal (specpdl_ptr->symbol, specpdl_ptr->old_value, 0, 1); + set_internal (this_binding.symbol, this_binding.old_value, 0, 1); } } -- 2.39.2