From 60102016e416e5c19fa5945aeb80693dac7ff2e6 Mon Sep 17 00:00:00 2001 From: Mattias EngdegÄrd Date: Mon, 19 Sep 2022 10:55:09 +0200 Subject: Abolish max-specpdl-size (bug#57911) The max-lisp-eval-depth limit is sufficient to prevent unbounded stack growth including the specbind stack; simplify matters for the user by not having them to worry about two different limits. This change turns max-specpdl-size into a harmless variable with no effects, to keep existing code happy. * lisp/subr.el (max-specpdl-size): Define as an ordinary (but obsolete) dynamic variable. * admin/grammars/Makefile.in: * doc/lispintro/emacs-lisp-intro.texi (Loops & Recursion): * doc/lispref/control.texi (Cleanups): * doc/lispref/edebug.texi (Checking Whether to Stop): * doc/lispref/eval.texi (Eval): * doc/lispref/variables.texi (Local Variables): * doc/misc/calc.texi (Recursion Depth): Update documentation. * etc/NEWS: Announce. * src/eval.c (FletX): Use safe iteration to guard against circular bindings list. (syms_of_eval): Remove old max-specpdl-size definition. (init_eval_once, restore_stack_limits, call_debugger) (signal_or_quit, grow_specpdl_allocation): * leim/Makefile.in: * lisp/Makefile.in: * lisp/calc/calc-stuff.el (calc-more-recursion-depth) (calc-less-recursion-depth): * lisp/calc/calc.el (calc-do): * lisp/cedet/semantic/ede-grammar.el (ede-proj-makefile-insert-rules): * lisp/cedet/semantic/grammar.el (semantic-grammar-batch-build-one-package): * lisp/cus-start.el (standard): * lisp/emacs-lisp/comp.el (comp--native-compile): * lisp/emacs-lisp/edebug.el (edebug-max-depth): (edebug-read-and-maybe-wrap-form, edebug-default-enter): * lisp/emacs-lisp/regexp-opt.el (regexp-opt): * lisp/eshell/esh-mode.el (eshell-mode): * lisp/loadup.el (max-specpdl-size): * lisp/mh-e/mh-e.el (mh-invisible-headers): * lisp/net/shr.el (shr-insert-document, shr-descend): * lisp/play/hanoi.el (hanoi-internal): * lisp/progmodes/cperl-mode.el: * src/fileio.c (Fdo_auto_save): Remove references to and modifications of max-specpdl-size. --- src/eval.c | 60 ++++++------------------------------------------------------ src/fileio.c | 5 ----- 2 files changed, 6 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/src/eval.c b/src/eval.c index bd414fb8687..7da1d8fb989 100644 --- a/src/eval.c +++ b/src/eval.c @@ -211,9 +211,7 @@ backtrace_thread_next (struct thread_state *tstate, union specbinding *pdl) void init_eval_once (void) { - /* Don't forget to update docs - (lispref nodes "Local Variables" and "Eval"). */ - max_specpdl_size = 2500; + /* Don't forget to update docs (lispref node "Eval"). */ max_lisp_eval_depth = 1600; Vrun_hooks = Qnil; pdumper_do_now_and_after_load (init_eval_once_for_pdumper); @@ -265,8 +263,7 @@ max_ensure_room (intmax_t *m, intmax_t a, intmax_t b) static void restore_stack_limits (Lisp_Object data) { - integer_to_intmax (XCAR (data), &max_specpdl_size); - integer_to_intmax (XCDR (data), &max_lisp_eval_depth); + integer_to_intmax (data, &max_lisp_eval_depth); } /* Call the Lisp debugger, giving it argument ARG. */ @@ -278,9 +275,6 @@ call_debugger (Lisp_Object arg) specpdl_ref count = SPECPDL_INDEX (); Lisp_Object val; intmax_t old_depth = max_lisp_eval_depth; - /* Do not allow max_specpdl_size less than actual depth (Bug#16603). */ - ptrdiff_t counti = specpdl_ref_to_count (count); - intmax_t old_max = max (max_specpdl_size, counti); /* The previous value of 40 is too small now that the debugger prints using cl-prin1 instead of prin1. Printing lists nested 8 @@ -288,20 +282,8 @@ call_debugger (Lisp_Object arg) currently requires 77 additional frames. See bug#31919. */ max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100); - /* While debugging Bug#16603, previous value of 100 was found - too small to avoid specpdl overflow in the debugger itself. */ - max_ensure_room (&max_specpdl_size, counti, 200); - - if (old_max == counti) - { - /* We can enter the debugger due to specpdl overflow (Bug#16603). */ - specpdl_ptr--; - grow_specpdl (); - } - /* Restore limits after leaving the debugger. */ - record_unwind_protect (restore_stack_limits, - Fcons (make_int (old_max), make_int (old_depth))); + record_unwind_protect (restore_stack_limits, make_int (old_depth)); #ifdef HAVE_WINDOW_SYSTEM if (display_hourglass_p) @@ -933,12 +915,9 @@ usage: (let* VARLIST BODY...) */) lexenv = Vinternal_interpreter_environment; Lisp_Object varlist = XCAR (args); - while (CONSP (varlist)) + FOR_EACH_TAIL (varlist) { - maybe_quit (); - elt = XCAR (varlist); - varlist = XCDR (varlist); if (SYMBOLP (elt)) { var = elt; @@ -1752,8 +1731,6 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit) { /* Edebug takes care of restoring these variables when it exits. */ max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 20); - ptrdiff_t counti = specpdl_ref_to_count (SPECPDL_INDEX ()); - max_ensure_room (&max_specpdl_size, counti, 40); call2 (Vsignal_hook_function, error_symbol, data); } @@ -1822,8 +1799,6 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit) { max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100); specpdl_ref count = SPECPDL_INDEX (); - ptrdiff_t counti = specpdl_ref_to_count (count); - max_ensure_room (&max_specpdl_size, counti, 200); specbind (Qdebugger, Qdebug_early); call_debugger (list2 (Qerror, Fcons (error_symbol, data))); unbind_to (count, Qnil); @@ -1839,12 +1814,10 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit) { max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100); specpdl_ref count = SPECPDL_INDEX (); - ptrdiff_t counti = specpdl_ref_to_count (count); AUTO_STRING (redisplay_trace, "*Redisplay_trace*"); Lisp_Object redisplay_trace_buffer; AUTO_STRING (gap, "\n\n\n\n"); /* Separates things in *Redisplay-trace* */ Lisp_Object delayed_warning; - max_ensure_room (&max_specpdl_size, counti, 200); redisplay_trace_buffer = Fget_buffer_create (redisplay_trace, Qnil); current_buffer = XBUFFER (redisplay_trace_buffer); if (!backtrace_yet) /* Are we on the first backtrace of the command? */ @@ -2376,17 +2349,12 @@ grow_specpdl_allocation (void) eassert (specpdl_ptr == specpdl_end); specpdl_ref count = SPECPDL_INDEX (); - ptrdiff_t max_size = min (max_specpdl_size, PTRDIFF_MAX - 1000); + ptrdiff_t max_size = PTRDIFF_MAX - 1000; union specbinding *pdlvec = specpdl - 1; ptrdiff_t size = specpdl_end - specpdl; ptrdiff_t pdlvecsize = size + 1; if (max_size <= size) - { - if (max_specpdl_size < 400) - max_size = max_specpdl_size = 400; - if (max_size <= size) - xsignal0 (Qexcessive_variable_binding); - } + xsignal0 (Qexcessive_variable_binding); /* Can't happen, essentially. */ pdlvec = xpalloc (pdlvec, &pdlvecsize, 1, max_size + 1, sizeof *specpdl); specpdl = pdlvec + 1; specpdl_end = specpdl + pdlvecsize - 1; @@ -4229,22 +4197,6 @@ Lisp_Object backtrace_top_function (void) void syms_of_eval (void) { - DEFVAR_INT ("max-specpdl-size", max_specpdl_size, - doc: /* Limit on number of Lisp variable bindings and `unwind-protect's. - -If Lisp code tries to use more bindings than this amount, an error is -signaled. - -You can safely increase this variable substantially if the default -value proves inconveniently small. However, if you increase it too -much, Emacs could run out of memory trying to make the stack bigger. -Note that this limit may be silently increased by the debugger if -`debug-on-error' or `debug-on-quit' is set. - -\"spec\" is short for \"special variables\", i.e., dynamically bound -variables. \"PDL\" is short for \"push-down list\", which is an old -term for \"stack\". */); - DEFVAR_INT ("max-lisp-eval-depth", max_lisp_eval_depth, doc: /* Limit on depth in `eval', `apply' and `funcall' before error. diff --git a/src/fileio.c b/src/fileio.c index 6efea8ac369..dd7f85ec97f 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -6019,11 +6019,6 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */) bool old_message_p = 0; struct auto_save_unwind auto_save_unwind; - intmax_t sum = INT_ADD_WRAPV (specpdl_end - specpdl, 40, &sum) - ? INTMAX_MAX : sum; - if (max_specpdl_size < sum) - max_specpdl_size = sum; - if (minibuf_level) no_message = Qt; -- cgit v1.2.1