aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2022-02-19 14:55:39 -0500
committerStefan Monnier2022-02-19 14:55:39 -0500
commitecaedf2117cb015ad4028e4d6fc7058608c98096 (patch)
tree41e49c535e70a67f8842f61b7acc5ce8dcb741a4 /src
parent43237f3d27897e2a0c6de745770802d0ba40e3a5 (diff)
downloademacs-ecaedf2117cb015ad4028e4d6fc7058608c98096.tar.gz
emacs-ecaedf2117cb015ad4028e4d6fc7058608c98096.zip
(specpdl_unrewind): Fix corner case
* src/lisp.h (enum specbind_tag): New elem SPECPDL_NOP. * src/eval.c (specpdl_unrewind): Zap entries that can't be applied any more, and simplify. (default_toplevel_binding, lexbound_p, Fbacktrace__locals): Simplify. (do_one_unbind, mark_specpdl): Handle SPECPDL_NOP.
Diffstat (limited to 'src')
-rw-r--r--src/eval.c83
-rw-r--r--src/lisp.h1
2 files changed, 17 insertions, 67 deletions
diff --git a/src/eval.c b/src/eval.c
index d3342289fbb..294d79e67a0 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -664,23 +664,7 @@ default_toplevel_binding (Lisp_Object symbol)
664 binding = pdl; 664 binding = pdl;
665 break; 665 break;
666 666
667 case SPECPDL_UNWIND: 667 default: break;
668 case SPECPDL_UNWIND_ARRAY:
669 case SPECPDL_UNWIND_PTR:
670 case SPECPDL_UNWIND_INT:
671 case SPECPDL_UNWIND_INTMAX:
672 case SPECPDL_UNWIND_EXCURSION:
673 case SPECPDL_UNWIND_VOID:
674 case SPECPDL_BACKTRACE:
675#ifdef HAVE_MODULES
676 case SPECPDL_MODULE_RUNTIME:
677 case SPECPDL_MODULE_ENVIRONMENT:
678#endif
679 case SPECPDL_LET_LOCAL:
680 break;
681
682 default:
683 emacs_abort ();
684 } 668 }
685 } 669 }
686 return binding; 670 return binding;
@@ -707,23 +691,7 @@ lexbound_p (Lisp_Object symbol)
707 } 691 }
708 break; 692 break;
709 693
710 case SPECPDL_UNWIND: 694 default: break;
711 case SPECPDL_UNWIND_ARRAY:
712 case SPECPDL_UNWIND_PTR:
713 case SPECPDL_UNWIND_INT:
714 case SPECPDL_UNWIND_INTMAX:
715 case SPECPDL_UNWIND_EXCURSION:
716 case SPECPDL_UNWIND_VOID:
717 case SPECPDL_BACKTRACE:
718#ifdef HAVE_MODULES
719 case SPECPDL_MODULE_RUNTIME:
720 case SPECPDL_MODULE_ENVIRONMENT:
721#endif
722 case SPECPDL_LET_LOCAL:
723 break;
724
725 default:
726 emacs_abort ();
727 } 695 }
728 } 696 }
729 return false; 697 return false;
@@ -3721,6 +3689,7 @@ do_one_unbind (union specbinding *this_binding, bool unwinding,
3721 this_binding->unwind_excursion.window); 3689 this_binding->unwind_excursion.window);
3722 break; 3690 break;
3723 case SPECPDL_BACKTRACE: 3691 case SPECPDL_BACKTRACE:
3692 case SPECPDL_NOP:
3724 break; 3693 break;
3725#ifdef HAVE_MODULES 3694#ifdef HAVE_MODULES
3726 case SPECPDL_MODULE_RUNTIME: 3695 case SPECPDL_MODULE_RUNTIME:
@@ -4044,17 +4013,6 @@ specpdl_unrewind (union specbinding *pdl, int distance, bool vars_only)
4044 save_excursion_restore (marker, window); 4013 save_excursion_restore (marker, window);
4045 } 4014 }
4046 break; 4015 break;
4047 case SPECPDL_UNWIND_ARRAY:
4048 case SPECPDL_UNWIND_PTR:
4049 case SPECPDL_UNWIND_INT:
4050 case SPECPDL_UNWIND_INTMAX:
4051 case SPECPDL_UNWIND_VOID:
4052 case SPECPDL_BACKTRACE:
4053#ifdef HAVE_MODULES
4054 case SPECPDL_MODULE_RUNTIME:
4055 case SPECPDL_MODULE_ENVIRONMENT:
4056#endif
4057 break;
4058 case SPECPDL_LET: 4016 case SPECPDL_LET:
4059 { /* If variable has a trivial value (no forwarding), we can 4017 { /* If variable has a trivial value (no forwarding), we can
4060 just set it. No need to check for constant symbols here, 4018 just set it. No need to check for constant symbols here,
@@ -4097,14 +4055,16 @@ specpdl_unrewind (union specbinding *pdl, int distance, bool vars_only)
4097 SET_INTERNAL_THREAD_SWITCH); 4055 SET_INTERNAL_THREAD_SWITCH);
4098 } 4056 }
4099 else 4057 else
4100 /* FIXME: If the var is not local any more, we failed 4058 /* If the var is not local any more, it can't be undone nor
4101 to swap the old and new values. As long as the var remains 4059 redone, so just zap it.
4102 non-local, this is fine, but if it ever reverts to being 4060 This is important in case the buffer re-gains a local value
4103 local we may end up using this entry "in the wrong 4061 before we unrewind again, in which case we'd risk applying
4104 direction". */ 4062 this entry in the wrong direction. */
4105 {} 4063 tmp->kind = SPECPDL_NOP;
4106 } 4064 }
4107 break; 4065 break;
4066
4067 default: break;
4108 } 4068 }
4109 } 4069 }
4110} 4070}
@@ -4195,22 +4155,7 @@ NFRAMES and BASE specify the activation frame to use, as in `backtrace-frame'.
4195 } 4155 }
4196 break; 4156 break;
4197 4157
4198 case SPECPDL_UNWIND: 4158 default: break;
4199 case SPECPDL_UNWIND_ARRAY:
4200 case SPECPDL_UNWIND_PTR:
4201 case SPECPDL_UNWIND_INT:
4202 case SPECPDL_UNWIND_INTMAX:
4203 case SPECPDL_UNWIND_EXCURSION:
4204 case SPECPDL_UNWIND_VOID:
4205 case SPECPDL_BACKTRACE:
4206#ifdef HAVE_MODULES
4207 case SPECPDL_MODULE_RUNTIME:
4208 case SPECPDL_MODULE_ENVIRONMENT:
4209#endif
4210 break;
4211
4212 default:
4213 emacs_abort ();
4214 } 4159 }
4215 } 4160 }
4216 } 4161 }
@@ -4274,8 +4219,12 @@ mark_specpdl (union specbinding *first, union specbinding *ptr)
4274 case SPECPDL_UNWIND_INT: 4219 case SPECPDL_UNWIND_INT:
4275 case SPECPDL_UNWIND_INTMAX: 4220 case SPECPDL_UNWIND_INTMAX:
4276 case SPECPDL_UNWIND_VOID: 4221 case SPECPDL_UNWIND_VOID:
4222 case SPECPDL_NOP:
4277 break; 4223 break;
4278 4224
4225 /* While other loops that scan the specpdl use "default: break;"
4226 for simplicity, here we explicitly list all cases and abort
4227 if we find an unexpected value, as a sanity check. */
4279 default: 4228 default:
4280 emacs_abort (); 4229 emacs_abort ();
4281 } 4230 }
diff --git a/src/lisp.h b/src/lisp.h
index 19788ef07cc..deeca9bc86b 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3284,6 +3284,7 @@ enum specbind_tag {
3284 SPECPDL_UNWIND_EXCURSION, /* Likewise, on an excursion. */ 3284 SPECPDL_UNWIND_EXCURSION, /* Likewise, on an excursion. */
3285 SPECPDL_UNWIND_VOID, /* Likewise, with no arg. */ 3285 SPECPDL_UNWIND_VOID, /* Likewise, with no arg. */
3286 SPECPDL_BACKTRACE, /* An element of the backtrace. */ 3286 SPECPDL_BACKTRACE, /* An element of the backtrace. */
3287 SPECPDL_NOP, /* A filler. */
3287#ifdef HAVE_MODULES 3288#ifdef HAVE_MODULES
3288 SPECPDL_MODULE_RUNTIME, /* A live module runtime. */ 3289 SPECPDL_MODULE_RUNTIME, /* A live module runtime. */
3289 SPECPDL_MODULE_ENVIRONMENT, /* A live module environment. */ 3290 SPECPDL_MODULE_ENVIRONMENT, /* A live module environment. */