diff options
| author | Yuan Fu | 2022-08-29 11:41:10 -0700 |
|---|---|---|
| committer | Yuan Fu | 2022-08-29 11:41:10 -0700 |
| commit | 77d5a0cf9fc4a6dc44f0c6ee5e3295e0eea08273 (patch) | |
| tree | 969937ec44ce5ddf9447b074aa15314e0b9e8e95 /src/eval.c | |
| parent | e98b4715bb986524bde9356b62429af9786ae716 (diff) | |
| parent | df2f6fb7fc4b79834ae40db8be2ccdc1e4a273f1 (diff) | |
| download | emacs-77d5a0cf9fc4a6dc44f0c6ee5e3295e0eea08273.tar.gz emacs-77d5a0cf9fc4a6dc44f0c6ee5e3295e0eea08273.zip | |
Merge remote-tracking branch 'origin/master' into feature/tree-sitter
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 86 |
1 files changed, 76 insertions, 10 deletions
diff --git a/src/eval.c b/src/eval.c index 45ddbab2a2c..6ea7a473f60 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -57,6 +57,12 @@ Lisp_Object Vrun_hooks; | |||
| 57 | /* FIXME: We should probably get rid of this! */ | 57 | /* FIXME: We should probably get rid of this! */ |
| 58 | Lisp_Object Vsignaling_function; | 58 | Lisp_Object Vsignaling_function; |
| 59 | 59 | ||
| 60 | /* The handler structure which will catch errors in Lisp hooks called | ||
| 61 | from redisplay. We do not use it for this; we compare it with the | ||
| 62 | handler which is about to be used in signal_or_quit, and if it | ||
| 63 | matches, cause a backtrace to be generated. */ | ||
| 64 | static struct handler *redisplay_deep_handler; | ||
| 65 | |||
| 60 | /* These would ordinarily be static, but they need to be visible to GDB. */ | 66 | /* These would ordinarily be static, but they need to be visible to GDB. */ |
| 61 | bool backtrace_p (union specbinding *) EXTERNALLY_VISIBLE; | 67 | bool backtrace_p (union specbinding *) EXTERNALLY_VISIBLE; |
| 62 | Lisp_Object *backtrace_args (union specbinding *) EXTERNALLY_VISIBLE; | 68 | Lisp_Object *backtrace_args (union specbinding *) EXTERNALLY_VISIBLE; |
| @@ -246,6 +252,7 @@ init_eval (void) | |||
| 246 | lisp_eval_depth = 0; | 252 | lisp_eval_depth = 0; |
| 247 | /* This is less than the initial value of num_nonmacro_input_events. */ | 253 | /* This is less than the initial value of num_nonmacro_input_events. */ |
| 248 | when_entered_debugger = -1; | 254 | when_entered_debugger = -1; |
| 255 | redisplay_deep_handler = NULL; | ||
| 249 | } | 256 | } |
| 250 | 257 | ||
| 251 | /* Ensure that *M is at least A + B if possible, or is its maximum | 258 | /* Ensure that *M is at least A + B if possible, or is its maximum |
| @@ -333,7 +340,8 @@ call_debugger (Lisp_Object arg) | |||
| 333 | /* Interrupting redisplay and resuming it later is not safe under | 340 | /* Interrupting redisplay and resuming it later is not safe under |
| 334 | all circumstances. So, when the debugger returns, abort the | 341 | all circumstances. So, when the debugger returns, abort the |
| 335 | interrupted redisplay by going back to the top-level. */ | 342 | interrupted redisplay by going back to the top-level. */ |
| 336 | if (debug_while_redisplaying) | 343 | if (debug_while_redisplaying |
| 344 | && !EQ (Vdebugger, Qdebug_early)) | ||
| 337 | Ftop_level (); | 345 | Ftop_level (); |
| 338 | 346 | ||
| 339 | return unbind_to (count, val); | 347 | return unbind_to (count, val); |
| @@ -593,16 +601,19 @@ The return value is BASE-VARIABLE. */) | |||
| 593 | 601 | ||
| 594 | if (SYMBOL_CONSTANT_P (new_alias)) | 602 | if (SYMBOL_CONSTANT_P (new_alias)) |
| 595 | /* Making it an alias effectively changes its value. */ | 603 | /* Making it an alias effectively changes its value. */ |
| 596 | error ("Cannot make a constant an alias"); | 604 | error ("Cannot make a constant an alias: %s", |
| 605 | SDATA (SYMBOL_NAME (new_alias))); | ||
| 597 | 606 | ||
| 598 | sym = XSYMBOL (new_alias); | 607 | sym = XSYMBOL (new_alias); |
| 599 | 608 | ||
| 600 | switch (sym->u.s.redirect) | 609 | switch (sym->u.s.redirect) |
| 601 | { | 610 | { |
| 602 | case SYMBOL_FORWARDED: | 611 | case SYMBOL_FORWARDED: |
| 603 | error ("Cannot make an internal variable an alias"); | 612 | error ("Cannot make a built-in variable an alias: %s", |
| 613 | SDATA (SYMBOL_NAME (new_alias))); | ||
| 604 | case SYMBOL_LOCALIZED: | 614 | case SYMBOL_LOCALIZED: |
| 605 | error ("Don't know how to make a localized variable an alias"); | 615 | error ("Don't know how to make a buffer-local variable an alias: %s", |
| 616 | SDATA (SYMBOL_NAME (new_alias))); | ||
| 606 | case SYMBOL_PLAINVAL: | 617 | case SYMBOL_PLAINVAL: |
| 607 | case SYMBOL_VARALIAS: | 618 | case SYMBOL_VARALIAS: |
| 608 | break; | 619 | break; |
| @@ -633,7 +644,8 @@ The return value is BASE-VARIABLE. */) | |||
| 633 | for (p = specpdl_ptr; p > specpdl; ) | 644 | for (p = specpdl_ptr; p > specpdl; ) |
| 634 | if ((--p)->kind >= SPECPDL_LET | 645 | if ((--p)->kind >= SPECPDL_LET |
| 635 | && (EQ (new_alias, specpdl_symbol (p)))) | 646 | && (EQ (new_alias, specpdl_symbol (p)))) |
| 636 | error ("Don't know how to make a let-bound variable an alias"); | 647 | error ("Don't know how to make a let-bound variable an alias: %s", |
| 648 | SDATA (SYMBOL_NAME (new_alias))); | ||
| 637 | } | 649 | } |
| 638 | 650 | ||
| 639 | if (sym->u.s.trapped_write == SYMBOL_TRAPPED_WRITE) | 651 | if (sym->u.s.trapped_write == SYMBOL_TRAPPED_WRITE) |
| @@ -1552,12 +1564,16 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *), | |||
| 1552 | ptrdiff_t nargs, | 1564 | ptrdiff_t nargs, |
| 1553 | Lisp_Object *args)) | 1565 | Lisp_Object *args)) |
| 1554 | { | 1566 | { |
| 1567 | struct handler *old_deep = redisplay_deep_handler; | ||
| 1555 | struct handler *c = push_handler (handlers, CONDITION_CASE); | 1568 | struct handler *c = push_handler (handlers, CONDITION_CASE); |
| 1569 | if (redisplaying_p) | ||
| 1570 | redisplay_deep_handler = c; | ||
| 1556 | if (sys_setjmp (c->jmp)) | 1571 | if (sys_setjmp (c->jmp)) |
| 1557 | { | 1572 | { |
| 1558 | Lisp_Object val = handlerlist->val; | 1573 | Lisp_Object val = handlerlist->val; |
| 1559 | clobbered_eassert (handlerlist == c); | 1574 | clobbered_eassert (handlerlist == c); |
| 1560 | handlerlist = handlerlist->next; | 1575 | handlerlist = handlerlist->next; |
| 1576 | redisplay_deep_handler = old_deep; | ||
| 1561 | return hfun (val, nargs, args); | 1577 | return hfun (val, nargs, args); |
| 1562 | } | 1578 | } |
| 1563 | else | 1579 | else |
| @@ -1565,6 +1581,7 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *), | |||
| 1565 | Lisp_Object val = bfun (nargs, args); | 1581 | Lisp_Object val = bfun (nargs, args); |
| 1566 | eassert (handlerlist == c); | 1582 | eassert (handlerlist == c); |
| 1567 | handlerlist = c->next; | 1583 | handlerlist = c->next; |
| 1584 | redisplay_deep_handler = old_deep; | ||
| 1568 | return val; | 1585 | return val; |
| 1569 | } | 1586 | } |
| 1570 | } | 1587 | } |
| @@ -1697,6 +1714,11 @@ quit (void) | |||
| 1697 | return signal_or_quit (Qquit, Qnil, true); | 1714 | return signal_or_quit (Qquit, Qnil, true); |
| 1698 | } | 1715 | } |
| 1699 | 1716 | ||
| 1717 | /* Has an error in redisplay giving rise to a backtrace occurred as | ||
| 1718 | yet in the current command? This gets reset in the command | ||
| 1719 | loop. */ | ||
| 1720 | bool backtrace_yet = false; | ||
| 1721 | |||
| 1700 | /* Signal an error, or quit. ERROR_SYMBOL and DATA are as with Fsignal. | 1722 | /* Signal an error, or quit. ERROR_SYMBOL and DATA are as with Fsignal. |
| 1701 | If KEYBOARD_QUIT, this is a quit; ERROR_SYMBOL should be | 1723 | If KEYBOARD_QUIT, this is a quit; ERROR_SYMBOL should be |
| 1702 | Qquit and DATA should be Qnil, and this function may return. | 1724 | Qquit and DATA should be Qnil, and this function may return. |
| @@ -1812,6 +1834,40 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit) | |||
| 1812 | unbind_to (count, Qnil); | 1834 | unbind_to (count, Qnil); |
| 1813 | } | 1835 | } |
| 1814 | 1836 | ||
| 1837 | /* If an error is signalled during a Lisp hook in redisplay, write a | ||
| 1838 | backtrace into the buffer *Redisplay-trace*. */ | ||
| 1839 | if (!debugger_called && !NILP (error_symbol) | ||
| 1840 | && backtrace_on_redisplay_error | ||
| 1841 | && (NILP (clause) || h == redisplay_deep_handler) | ||
| 1842 | && NILP (Vinhibit_debugger) | ||
| 1843 | && !NILP (Ffboundp (Qdebug_early))) | ||
| 1844 | { | ||
| 1845 | max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100); | ||
| 1846 | specpdl_ref count = SPECPDL_INDEX (); | ||
| 1847 | ptrdiff_t counti = specpdl_ref_to_count (count); | ||
| 1848 | AUTO_STRING (redisplay_trace, "*Redisplay_trace*"); | ||
| 1849 | Lisp_Object redisplay_trace_buffer; | ||
| 1850 | AUTO_STRING (gap, "\n\n\n\n"); /* Separates things in *Redisplay-trace* */ | ||
| 1851 | Lisp_Object delayed_warning; | ||
| 1852 | max_ensure_room (&max_specpdl_size, counti, 200); | ||
| 1853 | redisplay_trace_buffer = Fget_buffer_create (redisplay_trace, Qnil); | ||
| 1854 | current_buffer = XBUFFER (redisplay_trace_buffer); | ||
| 1855 | if (!backtrace_yet) /* Are we on the first backtrace of the command? */ | ||
| 1856 | Ferase_buffer (); | ||
| 1857 | else | ||
| 1858 | Finsert (1, &gap); | ||
| 1859 | backtrace_yet = true; | ||
| 1860 | specbind (Qstandard_output, redisplay_trace_buffer); | ||
| 1861 | specbind (Qdebugger, Qdebug_early); | ||
| 1862 | call_debugger (list2 (Qerror, Fcons (error_symbol, data))); | ||
| 1863 | unbind_to (count, Qnil); | ||
| 1864 | delayed_warning = make_string | ||
| 1865 | ("Error in a redisplay Lisp hook. See buffer *Redisplay_trace*", 61); | ||
| 1866 | |||
| 1867 | Vdelayed_warnings_list = Fcons (list2 (Qerror, delayed_warning), | ||
| 1868 | Vdelayed_warnings_list); | ||
| 1869 | } | ||
| 1870 | |||
| 1815 | if (!NILP (clause)) | 1871 | if (!NILP (clause)) |
| 1816 | { | 1872 | { |
| 1817 | Lisp_Object unwind_data | 1873 | Lisp_Object unwind_data |
| @@ -2208,7 +2264,7 @@ this does nothing and returns nil. */) | |||
| 2208 | && !AUTOLOADP (XSYMBOL (function)->u.s.function)) | 2264 | && !AUTOLOADP (XSYMBOL (function)->u.s.function)) |
| 2209 | return Qnil; | 2265 | return Qnil; |
| 2210 | 2266 | ||
| 2211 | if (!NILP (Vpurify_flag) && EQ (docstring, make_fixnum (0))) | 2267 | if (!NILP (Vpurify_flag) && BASE_EQ (docstring, make_fixnum (0))) |
| 2212 | /* `read1' in lread.c has found the docstring starting with "\ | 2268 | /* `read1' in lread.c has found the docstring starting with "\ |
| 2213 | and assumed the docstring will be provided by Snarf-documentation, so it | 2269 | and assumed the docstring will be provided by Snarf-documentation, so it |
| 2214 | passed us 0 instead. But that leads to accidental sharing in purecopy's | 2270 | passed us 0 instead. But that leads to accidental sharing in purecopy's |
| @@ -2229,7 +2285,7 @@ un_autoload (Lisp_Object oldqueue) | |||
| 2229 | while (CONSP (queue)) | 2285 | while (CONSP (queue)) |
| 2230 | { | 2286 | { |
| 2231 | Lisp_Object first = XCAR (queue); | 2287 | Lisp_Object first = XCAR (queue); |
| 2232 | if (CONSP (first) && EQ (XCAR (first), make_fixnum (0))) | 2288 | if (CONSP (first) && BASE_EQ (XCAR (first), make_fixnum (0))) |
| 2233 | Vfeatures = XCDR (first); | 2289 | Vfeatures = XCDR (first); |
| 2234 | else | 2290 | else |
| 2235 | Ffset (first, Fcar (Fcdr (Fget (first, Qfunction_history)))); | 2291 | Ffset (first, Fcar (Fcdr (Fget (first, Qfunction_history)))); |
| @@ -2286,8 +2342,13 @@ it defines a macro. */) | |||
| 2286 | /* This is to make sure that loadup.el gives a clear picture | 2342 | /* This is to make sure that loadup.el gives a clear picture |
| 2287 | of what files are preloaded and when. */ | 2343 | of what files are preloaded and when. */ |
| 2288 | if (will_dump_p () && !will_bootstrap_p ()) | 2344 | if (will_dump_p () && !will_bootstrap_p ()) |
| 2289 | error ("Attempt to autoload %s while preparing to dump", | 2345 | { |
| 2290 | SDATA (SYMBOL_NAME (funname))); | 2346 | /* Avoid landing here recursively while outputting the |
| 2347 | backtrace from the error. */ | ||
| 2348 | gflags.will_dump_ = false; | ||
| 2349 | error ("Attempt to autoload %s while preparing to dump", | ||
| 2350 | SDATA (SYMBOL_NAME (funname))); | ||
| 2351 | } | ||
| 2291 | 2352 | ||
| 2292 | CHECK_SYMBOL (funname); | 2353 | CHECK_SYMBOL (funname); |
| 2293 | 2354 | ||
| @@ -3464,7 +3525,7 @@ specbind (Lisp_Object symbol, Lisp_Object value) | |||
| 3464 | specpdl_ptr->let.where = Fcurrent_buffer (); | 3525 | specpdl_ptr->let.where = Fcurrent_buffer (); |
| 3465 | 3526 | ||
| 3466 | eassert (sym->u.s.redirect != SYMBOL_LOCALIZED | 3527 | eassert (sym->u.s.redirect != SYMBOL_LOCALIZED |
| 3467 | || (EQ (SYMBOL_BLV (sym)->where, Fcurrent_buffer ()))); | 3528 | || (BASE_EQ (SYMBOL_BLV (sym)->where, Fcurrent_buffer ()))); |
| 3468 | 3529 | ||
| 3469 | if (sym->u.s.redirect == SYMBOL_LOCALIZED) | 3530 | if (sym->u.s.redirect == SYMBOL_LOCALIZED) |
| 3470 | { | 3531 | { |
| @@ -4282,6 +4343,11 @@ Does not apply if quit is handled by a `condition-case'. */); | |||
| 4282 | DEFVAR_BOOL ("debug-on-next-call", debug_on_next_call, | 4343 | DEFVAR_BOOL ("debug-on-next-call", debug_on_next_call, |
| 4283 | doc: /* Non-nil means enter debugger before next `eval', `apply' or `funcall'. */); | 4344 | doc: /* Non-nil means enter debugger before next `eval', `apply' or `funcall'. */); |
| 4284 | 4345 | ||
| 4346 | DEFVAR_BOOL ("backtrace-on-redisplay-error", backtrace_on_redisplay_error, | ||
| 4347 | doc: /* Non-nil means create a backtrace if a lisp error occurs in redisplay. | ||
| 4348 | The backtrace is written to buffer *Redisplay-trace*. */); | ||
| 4349 | backtrace_on_redisplay_error = false; | ||
| 4350 | |||
| 4285 | DEFVAR_BOOL ("debugger-may-continue", debugger_may_continue, | 4351 | DEFVAR_BOOL ("debugger-may-continue", debugger_may_continue, |
| 4286 | doc: /* Non-nil means debugger may continue execution. | 4352 | doc: /* Non-nil means debugger may continue execution. |
| 4287 | This is nil when the debugger is called under circumstances where it | 4353 | This is nil when the debugger is called under circumstances where it |