aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/eval.c64
1 files changed, 36 insertions, 28 deletions
diff --git a/src/eval.c b/src/eval.c
index e000ea622c5..6ee3d89cb3f 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2923,35 +2923,42 @@ specbind (symbol, value)
2923 } 2923 }
2924 else 2924 else
2925 { 2925 {
2926 Lisp_Object valcontents;
2927
2926 ovalue = find_symbol_value (symbol); 2928 ovalue = find_symbol_value (symbol);
2927 specpdl_ptr->func = 0; 2929 specpdl_ptr->func = 0;
2928 specpdl_ptr->old_value = ovalue; 2930 specpdl_ptr->old_value = ovalue;
2929 2931
2930 if (BUFFER_LOCAL_VALUEP (XSYMBOL (symbol)->value) 2932 valcontents = XSYMBOL (symbol)->value;
2931 || SOME_BUFFER_LOCAL_VALUEP (XSYMBOL (symbol)->value) 2933
2932 || BUFFER_OBJFWDP (XSYMBOL (symbol)->value)) 2934 if (BUFFER_LOCAL_VALUEP (valcontents)
2935 || SOME_BUFFER_LOCAL_VALUEP (valcontents)
2936 || BUFFER_OBJFWDP (valcontents))
2933 { 2937 {
2934 Lisp_Object current_buffer, binding_buffer; 2938 Lisp_Object where;
2935 2939
2936 /* For a local variable, record both the symbol and which 2940 /* For a local variable, record both the symbol and which
2937 buffer's value we are saving. */ 2941 buffer's or frame's value we are saving. */
2938 current_buffer = Fcurrent_buffer (); 2942 if (!NILP (Flocal_variable_p (symbol, Qnil)))
2939 binding_buffer = current_buffer; 2943 where = Fcurrent_buffer ();
2940 2944 else if (!BUFFER_OBJFWDP (valcontents)
2941 /* If the variable is not local in this buffer, 2945 && XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame)
2942 we are saving the global value, so restore that. */ 2946 where = XBUFFER_LOCAL_VALUE (valcontents)->frame;
2943 if (NILP (Flocal_variable_p (symbol, binding_buffer))) 2947 else
2944 binding_buffer = Qnil; 2948 where = Qnil;
2945 specpdl_ptr->symbol 2949
2946 = Fcons (symbol, Fcons (binding_buffer, current_buffer)); 2950 /* We're not using the `unused' slot in the specbinding
2951 structure because this would mean we have to do more
2952 work for simple variables. */
2953 specpdl_ptr->symbol = Fcons (symbol, where);
2947 2954
2948 /* If SYMBOL is a per-buffer variable which doesn't have a 2955 /* If SYMBOL is a per-buffer variable which doesn't have a
2949 buffer-local value here, make the `let' change the global 2956 buffer-local value here, make the `let' change the global
2950 value by changing the value of SYMBOL in all buffers not 2957 value by changing the value of SYMBOL in all buffers not
2951 having their own value. This is consistent with what 2958 having their own value. This is consistent with what
2952 happens with other buffer-local variables. */ 2959 happens with other buffer-local variables. */
2953 if (NILP (binding_buffer) 2960 if (NILP (where)
2954 && BUFFER_OBJFWDP (XSYMBOL (symbol)->value)) 2961 && BUFFER_OBJFWDP (valcontents))
2955 { 2962 {
2956 ++specpdl_ptr; 2963 ++specpdl_ptr;
2957 Fset_default (symbol, value); 2964 Fset_default (symbol, value);
@@ -2996,30 +3003,31 @@ unbind_to (count, value)
2996 while (specpdl_ptr != specpdl + count) 3003 while (specpdl_ptr != specpdl + count)
2997 { 3004 {
2998 --specpdl_ptr; 3005 --specpdl_ptr;
2999 3006
3000 if (specpdl_ptr->func != 0) 3007 if (specpdl_ptr->func != 0)
3001 (*specpdl_ptr->func) (specpdl_ptr->old_value); 3008 (*specpdl_ptr->func) (specpdl_ptr->old_value);
3002 /* Note that a "binding" of nil is really an unwind protect, 3009 /* Note that a "binding" of nil is really an unwind protect,
3003 so in that case the "old value" is a list of forms to evaluate. */ 3010 so in that case the "old value" is a list of forms to evaluate. */
3004 else if (NILP (specpdl_ptr->symbol)) 3011 else if (NILP (specpdl_ptr->symbol))
3005 Fprogn (specpdl_ptr->old_value); 3012 Fprogn (specpdl_ptr->old_value);
3006 /* If the symbol is a list, it is really (SYMBOL BINDING_BUFFER 3013 /* If the symbol is a list, it is really (SYMBOL . WHERE) where
3007 . CURRENT_BUFFER) and it indicates we bound a variable that 3014 WHERE is either nil, a buffer, or a frame. If WHERE is a
3008 has buffer-local bindings. BINDING_BUFFER nil means that the 3015 buffer or frame, this indicates we bound a variable that had
3009 variable had the default value when it was bound. */ 3016 a buffer-local or frmae-local binding.. WHERE nil means that
3017 the variable had the default value when it was bound. */
3010 else if (CONSP (specpdl_ptr->symbol)) 3018 else if (CONSP (specpdl_ptr->symbol))
3011 { 3019 {
3012 Lisp_Object symbol, buffer; 3020 Lisp_Object symbol, where;
3013 3021
3014 symbol = XCAR (specpdl_ptr->symbol); 3022 symbol = XCAR (specpdl_ptr->symbol);
3015 buffer = XCAR (XCDR (specpdl_ptr->symbol)); 3023 where = XCDR (specpdl_ptr->symbol);
3016 3024
3017 /* Handle restoring a default value. */ 3025 if (NILP (where))
3018 if (NILP (buffer))
3019 Fset_default (symbol, specpdl_ptr->old_value); 3026 Fset_default (symbol, specpdl_ptr->old_value);
3020 /* Handle restoring a value saved from a live buffer. */ 3027 else if (BUFFERP (where))
3021 else 3028 set_internal (symbol, specpdl_ptr->old_value, XBUFFER (where), 1);
3022 set_internal (symbol, specpdl_ptr->old_value, XBUFFER (buffer), 1); 3029 else
3030 set_internal (symbol, specpdl_ptr->old_value, NULL, 1);
3023 } 3031 }
3024 else 3032 else
3025 { 3033 {