diff options
| author | Eli Zaretskii | 2016-12-09 16:03:08 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2016-12-09 16:03:08 +0200 |
| commit | 3ef50c1ff691b0a6c2f56da76f7c1c9b572d8be8 (patch) | |
| tree | 4134d5dfa77b76e8d5312be1d84991a0e09e803b /src/eval.c | |
| parent | 54f52a1390c394f42203f39d0b4d73318203e092 (diff) | |
| download | emacs-3ef50c1ff691b0a6c2f56da76f7c1c9b572d8be8.tar.gz emacs-3ef50c1ff691b0a6c2f56da76f7c1c9b572d8be8.zip | |
Fix subtle errors with let-binding of localized variables
* src/eval.c (do_specbind): Don't require a "symbol" that is
actually a cons cell, in order to call set-default, as there are
no longer such bindings. This makes do_specbind work like the
pre-concurrency implementation in specbind for bindings of
forwarded symbols. Use specpdl_kind to access the type of the
binding.
(specpdl_kind): New function.
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 30 |
1 files changed, 14 insertions, 16 deletions
diff --git a/src/eval.c b/src/eval.c index 9657f51aadc..5383d7c3b1b 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -102,6 +102,13 @@ specpdl_symbol (union specbinding *pdl) | |||
| 102 | return pdl->let.symbol; | 102 | return pdl->let.symbol; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | static enum specbind_tag | ||
| 106 | specpdl_kind (union specbinding *pdl) | ||
| 107 | { | ||
| 108 | eassert (pdl->kind >= SPECPDL_LET); | ||
| 109 | return pdl->let.kind; | ||
| 110 | } | ||
| 111 | |||
| 105 | static Lisp_Object | 112 | static Lisp_Object |
| 106 | specpdl_old_value (union specbinding *pdl) | 113 | specpdl_old_value (union specbinding *pdl) |
| 107 | { | 114 | { |
| @@ -3170,23 +3177,15 @@ do_specbind (struct Lisp_Symbol *sym, union specbinding *bind, | |||
| 3170 | set_internal (specpdl_symbol (bind), value, Qnil, SET_INTERNAL_BIND); | 3177 | set_internal (specpdl_symbol (bind), value, Qnil, SET_INTERNAL_BIND); |
| 3171 | break; | 3178 | break; |
| 3172 | 3179 | ||
| 3173 | case SYMBOL_LOCALIZED: | ||
| 3174 | case SYMBOL_FORWARDED: | 3180 | case SYMBOL_FORWARDED: |
| 3175 | if ((sym->redirect == SYMBOL_LOCALIZED | 3181 | if (BUFFER_OBJFWDP (SYMBOL_FWD (sym)) |
| 3176 | || BUFFER_OBJFWDP (SYMBOL_FWD (sym))) | 3182 | && specpdl_kind (bind) == SPECPDL_LET_DEFAULT) |
| 3177 | && CONSP (specpdl_symbol (bind))) | ||
| 3178 | { | 3183 | { |
| 3179 | Lisp_Object where; | 3184 | Fset_default (specpdl_symbol (bind), value); |
| 3180 | 3185 | return; | |
| 3181 | where = XCAR (XCDR (specpdl_symbol (bind))); | ||
| 3182 | if (NILP (where) | ||
| 3183 | && sym->redirect == SYMBOL_FORWARDED) | ||
| 3184 | { | ||
| 3185 | Fset_default (XCAR (specpdl_symbol (bind)), value); | ||
| 3186 | return; | ||
| 3187 | } | ||
| 3188 | } | 3186 | } |
| 3189 | 3187 | /* FALLTHROUGH */ | |
| 3188 | case SYMBOL_LOCALIZED: | ||
| 3190 | set_internal (specpdl_symbol (bind), value, Qnil, SET_INTERNAL_BIND); | 3189 | set_internal (specpdl_symbol (bind), value, Qnil, SET_INTERNAL_BIND); |
| 3191 | break; | 3190 | break; |
| 3192 | 3191 | ||
| @@ -3361,8 +3360,7 @@ do_one_unbind (union specbinding *this_binding, bool unwinding) | |||
| 3361 | break; | 3360 | break; |
| 3362 | case SPECPDL_LET: | 3361 | case SPECPDL_LET: |
| 3363 | { /* If variable has a trivial value (no forwarding), and isn't | 3362 | { /* If variable has a trivial value (no forwarding), and isn't |
| 3364 | trapped we can just set it. No need to check for constant | 3363 | trapped, we can just set it. */ |
| 3365 | symbols here, since that was already done by specbind. */ | ||
| 3366 | Lisp_Object sym = specpdl_symbol (this_binding); | 3364 | Lisp_Object sym = specpdl_symbol (this_binding); |
| 3367 | if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL) | 3365 | if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL) |
| 3368 | { | 3366 | { |