Mercurial > emacs
changeset 50919:bbe405e5721e
(specpdl_ptr): Declare volatile.
(unbind_to): Copy the whole binding and decrement specpdl_ptr
before doing the work of unbinding it.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Fri, 09 May 2003 14:01:12 +0000 |
parents | d1b8ac33a632 |
children | 997593980303 |
files | src/eval.c |
diffstat | 1 files changed, 20 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/src/eval.c Fri May 09 13:58:38 2003 +0000 +++ b/src/eval.c Fri May 09 14:01:12 2003 +0000 @@ -117,7 +117,7 @@ /* 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 @@ while (specpdl_ptr != specpdl + count) { - --specpdl_ptr; - - if (specpdl_ptr->func != 0) - (*specpdl_ptr->func) (specpdl_ptr->old_value); + /* 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. */ + + 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 @@ 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); } }