Commit eb700b82 authored by Gerd Moellmann's avatar Gerd Moellmann
Browse files

(specbind): If SYMBOL has a frame-local binding, record

the frame on the binding stack.  Change format of entries for
local bindings on the binding stack to '(SYMBOL . WHERE)'.
(unbind_to): Handle unbinding a frame-local variable.
parent 3326dc20
...@@ -2923,35 +2923,42 @@ specbind (symbol, value) ...@@ -2923,35 +2923,42 @@ specbind (symbol, value)
} }
else else
{ {
Lisp_Object valcontents;
ovalue = find_symbol_value (symbol); ovalue = find_symbol_value (symbol);
specpdl_ptr->func = 0; specpdl_ptr->func = 0;
specpdl_ptr->old_value = ovalue; specpdl_ptr->old_value = ovalue;
if (BUFFER_LOCAL_VALUEP (XSYMBOL (symbol)->value) valcontents = XSYMBOL (symbol)->value;
|| SOME_BUFFER_LOCAL_VALUEP (XSYMBOL (symbol)->value)
|| BUFFER_OBJFWDP (XSYMBOL (symbol)->value)) if (BUFFER_LOCAL_VALUEP (valcontents)
|| SOME_BUFFER_LOCAL_VALUEP (valcontents)
|| BUFFER_OBJFWDP (valcontents))
{ {
Lisp_Object current_buffer, binding_buffer; Lisp_Object where;
/* For a local variable, record both the symbol and which /* For a local variable, record both the symbol and which
buffer's value we are saving. */ buffer's or frame's value we are saving. */
current_buffer = Fcurrent_buffer (); if (!NILP (Flocal_variable_p (symbol, Qnil)))
binding_buffer = current_buffer; where = Fcurrent_buffer ();
else if (!BUFFER_OBJFWDP (valcontents)
/* If the variable is not local in this buffer, && XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame)
we are saving the global value, so restore that. */ where = XBUFFER_LOCAL_VALUE (valcontents)->frame;
if (NILP (Flocal_variable_p (symbol, binding_buffer))) else
binding_buffer = Qnil; where = Qnil;
specpdl_ptr->symbol
= Fcons (symbol, Fcons (binding_buffer, current_buffer)); /* We're not using the `unused' slot in the specbinding
structure because this would mean we have to do more
work for simple variables. */
specpdl_ptr->symbol = Fcons (symbol, where);
/* If SYMBOL is a per-buffer variable which doesn't have a /* If SYMBOL is a per-buffer variable which doesn't have a
buffer-local value here, make the `let' change the global buffer-local value here, make the `let' change the global
value by changing the value of SYMBOL in all buffers not value by changing the value of SYMBOL in all buffers not
having their own value. This is consistent with what having their own value. This is consistent with what
happens with other buffer-local variables. */ happens with other buffer-local variables. */
if (NILP (binding_buffer) if (NILP (where)
&& BUFFER_OBJFWDP (XSYMBOL (symbol)->value)) && BUFFER_OBJFWDP (valcontents))
{ {
++specpdl_ptr; ++specpdl_ptr;
Fset_default (symbol, value); Fset_default (symbol, value);
...@@ -2996,30 +3003,31 @@ unbind_to (count, value) ...@@ -2996,30 +3003,31 @@ unbind_to (count, value)
while (specpdl_ptr != specpdl + count) while (specpdl_ptr != specpdl + count)
{ {
--specpdl_ptr; --specpdl_ptr;
if (specpdl_ptr->func != 0) if (specpdl_ptr->func != 0)
(*specpdl_ptr->func) (specpdl_ptr->old_value); (*specpdl_ptr->func) (specpdl_ptr->old_value);
/* Note that a "binding" of nil is really an unwind protect, /* Note that a "binding" of nil is really an unwind protect,
so in that case the "old value" is a list of forms to evaluate. */ so in that case the "old value" is a list of forms to evaluate. */
else if (NILP (specpdl_ptr->symbol)) else if (NILP (specpdl_ptr->symbol))
Fprogn (specpdl_ptr->old_value); Fprogn (specpdl_ptr->old_value);
/* If the symbol is a list, it is really (SYMBOL BINDING_BUFFER /* If the symbol is a list, it is really (SYMBOL . WHERE) where
. CURRENT_BUFFER) and it indicates we bound a variable that WHERE is either nil, a buffer, or a frame. If WHERE is a
has buffer-local bindings. BINDING_BUFFER nil means that the buffer or frame, this indicates we bound a variable that had
variable had the default value when it was bound. */ a buffer-local or frmae-local binding.. WHERE nil means that
the variable had the default value when it was bound. */
else if (CONSP (specpdl_ptr->symbol)) else if (CONSP (specpdl_ptr->symbol))
{ {
Lisp_Object symbol, buffer; Lisp_Object symbol, where;
symbol = XCAR (specpdl_ptr->symbol); symbol = XCAR (specpdl_ptr->symbol);
buffer = XCAR (XCDR (specpdl_ptr->symbol)); where = XCDR (specpdl_ptr->symbol);
/* Handle restoring a default value. */ if (NILP (where))
if (NILP (buffer))
Fset_default (symbol, specpdl_ptr->old_value); Fset_default (symbol, specpdl_ptr->old_value);
/* Handle restoring a value saved from a live buffer. */ else if (BUFFERP (where))
else set_internal (symbol, specpdl_ptr->old_value, XBUFFER (where), 1);
set_internal (symbol, specpdl_ptr->old_value, XBUFFER (buffer), 1); else
set_internal (symbol, specpdl_ptr->old_value, NULL, 1);
} }
else else
{ {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment