diff options
| author | Stefan Monnier | 2018-03-23 11:29:06 -0400 |
|---|---|---|
| committer | Noam Postavsky | 2018-06-03 12:48:14 -0400 |
| commit | ed962f2b8a2f63c7dbf31ec5df3c915703dd571d (patch) | |
| tree | 880aa4dab830e5e7699e6eace5c0a1097a091baa /src/data.c | |
| parent | 3ba5fc2bbec3f0f64c7afc1b05c9016710805463 (diff) | |
| download | emacs-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/data.c')
| -rw-r--r-- | src/data.c | 36 |
1 files changed, 9 insertions, 27 deletions
diff --git a/src/data.c b/src/data.c index 45b2bf73026..4bee194e296 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -1188,7 +1188,7 @@ swap_in_global_binding (struct Lisp_Symbol *symbol) | |||
| 1188 | 1188 | ||
| 1189 | /* Indicate that the global binding is set up now. */ | 1189 | /* Indicate that the global binding is set up now. */ |
| 1190 | set_blv_where (blv, Qnil); | 1190 | set_blv_where (blv, Qnil); |
| 1191 | set_blv_found (blv, 0); | 1191 | set_blv_found (blv, false); |
| 1192 | } | 1192 | } |
| 1193 | 1193 | ||
| 1194 | /* Set up the buffer-local symbol SYMBOL for validity in the current buffer. | 1194 | /* Set up the buffer-local symbol SYMBOL for validity in the current buffer. |
| @@ -1257,7 +1257,6 @@ find_symbol_value (Lisp_Object symbol) | |||
| 1257 | swap_in_symval_forwarding (sym, blv); | 1257 | swap_in_symval_forwarding (sym, blv); |
| 1258 | return blv->fwd ? do_symval_forwarding (blv->fwd) : blv_value (blv); | 1258 | return blv->fwd ? do_symval_forwarding (blv->fwd) : blv_value (blv); |
| 1259 | } | 1259 | } |
| 1260 | /* FALLTHROUGH */ | ||
| 1261 | case SYMBOL_FORWARDED: | 1260 | case SYMBOL_FORWARDED: |
| 1262 | return do_symval_forwarding (SYMBOL_FWD (sym)); | 1261 | return do_symval_forwarding (SYMBOL_FWD (sym)); |
| 1263 | default: emacs_abort (); | 1262 | default: emacs_abort (); |
| @@ -1366,7 +1365,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, | |||
| 1366 | tem1 = assq_no_quit (symbol, | 1365 | tem1 = assq_no_quit (symbol, |
| 1367 | BVAR (XBUFFER (where), local_var_alist)); | 1366 | BVAR (XBUFFER (where), local_var_alist)); |
| 1368 | set_blv_where (blv, where); | 1367 | set_blv_where (blv, where); |
| 1369 | blv->found = 1; | 1368 | blv->found = true; |
| 1370 | 1369 | ||
| 1371 | if (NILP (tem1)) | 1370 | if (NILP (tem1)) |
| 1372 | { | 1371 | { |
| @@ -1381,7 +1380,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, | |||
| 1381 | if (bindflag || !blv->local_if_set | 1380 | if (bindflag || !blv->local_if_set |
| 1382 | || let_shadows_buffer_binding_p (sym)) | 1381 | || let_shadows_buffer_binding_p (sym)) |
| 1383 | { | 1382 | { |
| 1384 | blv->found = 0; | 1383 | blv->found = false; |
| 1385 | tem1 = blv->defcell; | 1384 | tem1 = blv->defcell; |
| 1386 | } | 1385 | } |
| 1387 | /* If it's a local_if_set, being set not bound, | 1386 | /* If it's a local_if_set, being set not bound, |
| @@ -1796,7 +1795,7 @@ make_blv (struct Lisp_Symbol *sym, bool forwarded, | |||
| 1796 | blv->local_if_set = 0; | 1795 | blv->local_if_set = 0; |
| 1797 | set_blv_defcell (blv, tem); | 1796 | set_blv_defcell (blv, tem); |
| 1798 | set_blv_valcell (blv, tem); | 1797 | set_blv_valcell (blv, tem); |
| 1799 | set_blv_found (blv, 0); | 1798 | set_blv_found (blv, false); |
| 1800 | return blv; | 1799 | return blv; |
| 1801 | } | 1800 | } |
| 1802 | 1801 | ||
| @@ -1946,30 +1945,17 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */) | |||
| 1946 | CALLN (Fmessage, format, SYMBOL_NAME (variable)); | 1945 | CALLN (Fmessage, format, SYMBOL_NAME (variable)); |
| 1947 | } | 1946 | } |
| 1948 | 1947 | ||
| 1949 | /* Swap out any local binding for some other buffer, and make | 1948 | if (BUFFERP (blv->where) && current_buffer == XBUFFER (blv->where)) |
| 1950 | sure the current value is permanently recorded, if it's the | 1949 | /* Make sure the current value is permanently recorded, if it's the |
| 1951 | default value. */ | 1950 | default value. */ |
| 1952 | find_symbol_value (variable); | 1951 | swap_in_global_binding (sym); |
| 1953 | 1952 | ||
| 1954 | bset_local_var_alist | 1953 | bset_local_var_alist |
| 1955 | (current_buffer, | 1954 | (current_buffer, |
| 1956 | Fcons (Fcons (variable, XCDR (blv->defcell)), | 1955 | Fcons (Fcons (variable, XCDR (blv->defcell)), |
| 1957 | BVAR (current_buffer, local_var_alist))); | 1956 | BVAR (current_buffer, local_var_alist))); |
| 1958 | |||
| 1959 | /* Make sure symbol does not think it is set up for this buffer; | ||
| 1960 | force it to look once again for this buffer's value. */ | ||
| 1961 | if (current_buffer == XBUFFER (blv->where)) | ||
| 1962 | set_blv_where (blv, Qnil); | ||
| 1963 | set_blv_found (blv, 0); | ||
| 1964 | } | 1957 | } |
| 1965 | 1958 | ||
| 1966 | /* If the symbol forwards into a C variable, then load the binding | ||
| 1967 | for this buffer now. If C code modifies the variable before we | ||
| 1968 | load the binding in, then that new value will clobber the default | ||
| 1969 | binding the next time we unload it. */ | ||
| 1970 | if (blv->fwd) | ||
| 1971 | swap_in_symval_forwarding (sym, blv); | ||
| 1972 | |||
| 1973 | return variable; | 1959 | return variable; |
| 1974 | } | 1960 | } |
| 1975 | 1961 | ||
| @@ -2031,11 +2017,7 @@ From now on the default value will apply in this buffer. Return VARIABLE. */) | |||
| 2031 | { | 2017 | { |
| 2032 | Lisp_Object buf; XSETBUFFER (buf, current_buffer); | 2018 | Lisp_Object buf; XSETBUFFER (buf, current_buffer); |
| 2033 | if (EQ (buf, blv->where)) | 2019 | if (EQ (buf, blv->where)) |
| 2034 | { | 2020 | swap_in_global_binding (sym); |
| 2035 | set_blv_where (blv, Qnil); | ||
| 2036 | blv->found = 0; | ||
| 2037 | find_symbol_value (variable); | ||
| 2038 | } | ||
| 2039 | } | 2021 | } |
| 2040 | 2022 | ||
| 2041 | return variable; | 2023 | return variable; |