(specpdl_ptr): Declare volatile.

(unbind_to): Copy the whole binding and decrement specpdl_ptr
before doing the work of unbinding it.
This commit is contained in:
Richard M. Stallman 2003-05-09 14:01:12 +00:00
parent 4e91a530f9
commit 611a8f8c1f

View file

@ -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);
}
}