aboutsummaryrefslogtreecommitdiffstats
path: root/src/buffer.c
diff options
context:
space:
mode:
authorStefan Monnier2018-03-23 11:29:06 -0400
committerNoam Postavsky2018-06-03 12:48:14 -0400
commited962f2b8a2f63c7dbf31ec5df3c915703dd571d (patch)
tree880aa4dab830e5e7699e6eace5c0a1097a091baa /src/buffer.c
parent3ba5fc2bbec3f0f64c7afc1b05c9016710805463 (diff)
downloademacs-ed962f2b8a2f63c7dbf31ec5df3c915703dd571d.tar.gz
emacs-ed962f2b8a2f63c7dbf31ec5df3c915703dd571d.zip
Fix bug#30846, along with misc cleanups found along the way
* test/src/data-tests.el (data-tests-kill-all-local-variables): New test. * src/buffer.c (swap_out_buffer_local_variables): Remove. Fuse the body of its loop into that of reset_buffer_local_variables. (Fkill_buffer, Fkill_all_local_variables): Don't call it any more. (reset_buffer_local_variables): Make sure the buffer's local binding is swapped out before removing it from the alist (bug#30846). Call watchers before actually killing the var. * src/data.c (Fmake_local_variable): Simplify. Use swap_in_global_binding to swap out any local binding, instead of a mix of find_symbol_value followed by messing with where&found. Don't call swap_in_symval_forwarding since the currently swapped binding is never one we've modified. (Fkill_local_variable): Use swap_in_global_binding rather than messing with where&found to try and trick find_symbol_value into doing the same. * src/alloc.c (mark_localized_symbol): 'where' can't be a frame any more. (cherry picked from commit 3ddff080341580eb6fc18d907181e9cc2301f62d)
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c55
1 files changed, 19 insertions, 36 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 9b54e4b7787..b0cee717036 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -108,7 +108,6 @@ int last_per_buffer_idx;
108static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, 108static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay,
109 bool after, Lisp_Object arg1, 109 bool after, Lisp_Object arg1,
110 Lisp_Object arg2, Lisp_Object arg3); 110 Lisp_Object arg2, Lisp_Object arg3);
111static void swap_out_buffer_local_variables (struct buffer *b);
112static void reset_buffer_local_variables (struct buffer *, bool); 111static void reset_buffer_local_variables (struct buffer *, bool);
113 112
114/* Alist of all buffer names vs the buffers. This used to be 113/* Alist of all buffer names vs the buffers. This used to be
@@ -991,10 +990,29 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too)
991 else 990 else
992 { 991 {
993 Lisp_Object tmp, last = Qnil; 992 Lisp_Object tmp, last = Qnil;
993 Lisp_Object buffer;
994 XSETBUFFER (buffer, b);
995
994 for (tmp = BVAR (b, local_var_alist); CONSP (tmp); tmp = XCDR (tmp)) 996 for (tmp = BVAR (b, local_var_alist); CONSP (tmp); tmp = XCDR (tmp))
995 { 997 {
996 Lisp_Object local_var = XCAR (XCAR (tmp)); 998 Lisp_Object local_var = XCAR (XCAR (tmp));
997 Lisp_Object prop = Fget (local_var, Qpermanent_local); 999 Lisp_Object prop = Fget (local_var, Qpermanent_local);
1000 Lisp_Object sym = local_var;
1001
1002 /* Watchers are run *before* modifying the var. */
1003 if (XSYMBOL (local_var)->u.s.trapped_write == SYMBOL_TRAPPED_WRITE)
1004 notify_variable_watchers (local_var, Qnil,
1005 Qmakunbound, Fcurrent_buffer ());
1006
1007 eassert (XSYMBOL (sym)->u.s.redirect == SYMBOL_LOCALIZED);
1008 /* Need not do anything if some other buffer's binding is
1009 now cached. */
1010 if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer))
1011 {
1012 /* Symbol is set up for this buffer's old local value:
1013 swap it out! */
1014 swap_in_global_binding (XSYMBOL (sym));
1015 }
998 1016
999 if (!NILP (prop)) 1017 if (!NILP (prop))
1000 { 1018 {
@@ -1034,10 +1052,6 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too)
1034 bset_local_var_alist (b, XCDR (tmp)); 1052 bset_local_var_alist (b, XCDR (tmp));
1035 else 1053 else
1036 XSETCDR (last, XCDR (tmp)); 1054 XSETCDR (last, XCDR (tmp));
1037
1038 if (XSYMBOL (local_var)->u.s.trapped_write == SYMBOL_TRAPPED_WRITE)
1039 notify_variable_watchers (local_var, Qnil,
1040 Qmakunbound, Fcurrent_buffer ());
1041 } 1055 }
1042 } 1056 }
1043 1057
@@ -1867,7 +1881,6 @@ cleaning up all windows currently displaying the buffer to be killed. */)
1867 won't be protected from GC. They would be protected 1881 won't be protected from GC. They would be protected
1868 if they happened to remain cached in their symbols. 1882 if they happened to remain cached in their symbols.
1869 This gets rid of them for certain. */ 1883 This gets rid of them for certain. */
1870 swap_out_buffer_local_variables (b);
1871 reset_buffer_local_variables (b, 1); 1884 reset_buffer_local_variables (b, 1);
1872 1885
1873 bset_name (b, Qnil); 1886 bset_name (b, Qnil);
@@ -2737,11 +2750,6 @@ the normal hook `change-major-mode-hook'. */)
2737{ 2750{
2738 run_hook (Qchange_major_mode_hook); 2751 run_hook (Qchange_major_mode_hook);
2739 2752
2740 /* Make sure none of the bindings in local_var_alist
2741 remain swapped in, in their symbols. */
2742
2743 swap_out_buffer_local_variables (current_buffer);
2744
2745 /* Actually eliminate all local bindings of this buffer. */ 2753 /* Actually eliminate all local bindings of this buffer. */
2746 2754
2747 reset_buffer_local_variables (current_buffer, 0); 2755 reset_buffer_local_variables (current_buffer, 0);
@@ -2753,31 +2761,6 @@ the normal hook `change-major-mode-hook'. */)
2753 return Qnil; 2761 return Qnil;
2754} 2762}
2755 2763
2756/* Make sure no local variables remain set up with buffer B
2757 for their current values. */
2758
2759static void
2760swap_out_buffer_local_variables (struct buffer *b)
2761{
2762 Lisp_Object oalist, alist, buffer;
2763
2764 XSETBUFFER (buffer, b);
2765 oalist = BVAR (b, local_var_alist);
2766
2767 for (alist = oalist; CONSP (alist); alist = XCDR (alist))
2768 {
2769 Lisp_Object sym = XCAR (XCAR (alist));
2770 eassert (XSYMBOL (sym)->u.s.redirect == SYMBOL_LOCALIZED);
2771 /* Need not do anything if some other buffer's binding is
2772 now cached. */
2773 if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer))
2774 {
2775 /* Symbol is set up for this buffer's old local value:
2776 swap it out! */
2777 swap_in_global_binding (XSYMBOL (sym));
2778 }
2779 }
2780}
2781 2764
2782/* Find all the overlays in the current buffer that contain position POS. 2765/* Find all the overlays in the current buffer that contain position POS.
2783 Return the number found, and store them in a vector in *VEC_PTR. 2766 Return the number found, and store them in a vector in *VEC_PTR.