aboutsummaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
authorStefan Monnier2023-12-25 22:40:02 -0500
committerStefan Monnier2025-07-15 13:49:29 -0400
commitc3f3fe136cefc4c3aed960b175053e7c048aa979 (patch)
tree0ed24837d09d9709f1bd43fba97d1d7bea14ca1a /src/eval.c
parent4c9b37660771776563cf79bb3a2b6e692aa05ca2 (diff)
downloademacs-c3f3fe136cefc4c3aed960b175053e7c048aa979.tar.gz
emacs-c3f3fe136cefc4c3aed960b175053e7c048aa979.zip
Add `redisplay_counter` to catch nested redisplays and abort outer one
The redisplay code is not re-entrant. To allow running ELisp code from within redisplay, we have some hacks (e.g. `inhibit-redisplay`) that try to avoid the resulting breakage. This commit adds another one of those hacks, which tries to get closer to the core of the problem, thereby making it "safe" to override `inhibit-redisplay`, e.g. to debug jit-lock code. * src/dispextern.h (redisplay_counter): Declare. * src/xdisp.c (redisplay_counter): Define. (redisplay_internal) Increment it. (dsafe__call): Use it, in case `inhibit-redisplay` is overridden. * src/eval.c (call_debugger): Use it as well to refine the test we already had.
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/eval.c b/src/eval.c
index 5e2b5bff796..204adb62472 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -302,6 +302,7 @@ call_debugger (Lisp_Object arg)
302 /* Resetting redisplaying_p to 0 makes sure that debug output is 302 /* Resetting redisplaying_p to 0 makes sure that debug output is
303 displayed if the debugger is invoked during redisplay. */ 303 displayed if the debugger is invoked during redisplay. */
304 debug_while_redisplaying = redisplaying_p; 304 debug_while_redisplaying = redisplaying_p;
305 int redisplay_counter_before = redisplay_counter;
305 redisplaying_p = 0; 306 redisplaying_p = 0;
306 specbind (Qdebugger_may_continue, 307 specbind (Qdebugger_may_continue,
307 debug_while_redisplaying ? Qnil : Qt); 308 debug_while_redisplaying ? Qnil : Qt);
@@ -323,9 +324,10 @@ call_debugger (Lisp_Object arg)
323 /* Interrupting redisplay and resuming it later is not safe under 324 /* Interrupting redisplay and resuming it later is not safe under
324 all circumstances. So, when the debugger returns, abort the 325 all circumstances. So, when the debugger returns, abort the
325 interrupted redisplay by going back to the top-level. */ 326 interrupted redisplay by going back to the top-level. */
326 /* FIXME: Move this to the redisplay code? */
327 if (debug_while_redisplaying 327 if (debug_while_redisplaying
328 && !EQ (Vdebugger, Qdebug_early)) 328 && redisplay_counter_before != redisplay_counter)
329 /* FIXME: Rather than jump all the way to `top-level`
330 we should exit only the current redisplay. */
329 Ftop_level (); 331 Ftop_level ();
330 332
331 return unbind_to (count, val); 333 return unbind_to (count, val);