aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias EngdegÄrd2022-09-19 10:55:09 +0200
committerMattias EngdegÄrd2022-09-19 19:30:03 +0200
commit60102016e416e5c19fa5945aeb80693dac7ff2e6 (patch)
tree69979ff773d7031634e7bc4f4388abc4ae104717 /src
parenta7c65fc6660878e244432a5b25fb3a4ff20e8604 (diff)
downloademacs-60102016e416e5c19fa5945aeb80693dac7ff2e6.tar.gz
emacs-60102016e416e5c19fa5945aeb80693dac7ff2e6.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/eval.c60
-rw-r--r--src/fileio.c5
2 files changed, 6 insertions, 59 deletions
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)
211void 211void
212init_eval_once (void) 212init_eval_once (void)
213{ 213{
214 /* Don't forget to update docs 214 /* Don't forget to update docs (lispref node "Eval"). */
215 (lispref nodes "Local Variables" and "Eval"). */
216 max_specpdl_size = 2500;
217 max_lisp_eval_depth = 1600; 215 max_lisp_eval_depth = 1600;
218 Vrun_hooks = Qnil; 216 Vrun_hooks = Qnil;
219 pdumper_do_now_and_after_load (init_eval_once_for_pdumper); 217 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)
265static void 263static void
266restore_stack_limits (Lisp_Object data) 264restore_stack_limits (Lisp_Object data)
267{ 265{
268 integer_to_intmax (XCAR (data), &max_specpdl_size); 266 integer_to_intmax (data, &max_lisp_eval_depth);
269 integer_to_intmax (XCDR (data), &max_lisp_eval_depth);
270} 267}
271 268
272/* Call the Lisp debugger, giving it argument ARG. */ 269/* Call the Lisp debugger, giving it argument ARG. */
@@ -278,9 +275,6 @@ call_debugger (Lisp_Object arg)
278 specpdl_ref count = SPECPDL_INDEX (); 275 specpdl_ref count = SPECPDL_INDEX ();
279 Lisp_Object val; 276 Lisp_Object val;
280 intmax_t old_depth = max_lisp_eval_depth; 277 intmax_t old_depth = max_lisp_eval_depth;
281 /* Do not allow max_specpdl_size less than actual depth (Bug#16603). */
282 ptrdiff_t counti = specpdl_ref_to_count (count);
283 intmax_t old_max = max (max_specpdl_size, counti);
284 278
285 /* The previous value of 40 is too small now that the debugger 279 /* The previous value of 40 is too small now that the debugger
286 prints using cl-prin1 instead of prin1. Printing lists nested 8 280 prints using cl-prin1 instead of prin1. Printing lists nested 8
@@ -288,20 +282,8 @@ call_debugger (Lisp_Object arg)
288 currently requires 77 additional frames. See bug#31919. */ 282 currently requires 77 additional frames. See bug#31919. */
289 max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100); 283 max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100);
290 284
291 /* While debugging Bug#16603, previous value of 100 was found
292 too small to avoid specpdl overflow in the debugger itself. */
293 max_ensure_room (&max_specpdl_size, counti, 200);
294
295 if (old_max == counti)
296 {
297 /* We can enter the debugger due to specpdl overflow (Bug#16603). */
298 specpdl_ptr--;
299 grow_specpdl ();
300 }
301
302 /* Restore limits after leaving the debugger. */ 285 /* Restore limits after leaving the debugger. */
303 record_unwind_protect (restore_stack_limits, 286 record_unwind_protect (restore_stack_limits, make_int (old_depth));
304 Fcons (make_int (old_max), make_int (old_depth)));
305 287
306#ifdef HAVE_WINDOW_SYSTEM 288#ifdef HAVE_WINDOW_SYSTEM
307 if (display_hourglass_p) 289 if (display_hourglass_p)
@@ -933,12 +915,9 @@ usage: (let* VARLIST BODY...) */)
933 lexenv = Vinternal_interpreter_environment; 915 lexenv = Vinternal_interpreter_environment;
934 916
935 Lisp_Object varlist = XCAR (args); 917 Lisp_Object varlist = XCAR (args);
936 while (CONSP (varlist)) 918 FOR_EACH_TAIL (varlist)
937 { 919 {
938 maybe_quit ();
939
940 elt = XCAR (varlist); 920 elt = XCAR (varlist);
941 varlist = XCDR (varlist);
942 if (SYMBOLP (elt)) 921 if (SYMBOLP (elt))
943 { 922 {
944 var = elt; 923 var = elt;
@@ -1752,8 +1731,6 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
1752 { 1731 {
1753 /* Edebug takes care of restoring these variables when it exits. */ 1732 /* Edebug takes care of restoring these variables when it exits. */
1754 max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 20); 1733 max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 20);
1755 ptrdiff_t counti = specpdl_ref_to_count (SPECPDL_INDEX ());
1756 max_ensure_room (&max_specpdl_size, counti, 40);
1757 1734
1758 call2 (Vsignal_hook_function, error_symbol, data); 1735 call2 (Vsignal_hook_function, error_symbol, data);
1759 } 1736 }
@@ -1822,8 +1799,6 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
1822 { 1799 {
1823 max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100); 1800 max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100);
1824 specpdl_ref count = SPECPDL_INDEX (); 1801 specpdl_ref count = SPECPDL_INDEX ();
1825 ptrdiff_t counti = specpdl_ref_to_count (count);
1826 max_ensure_room (&max_specpdl_size, counti, 200);
1827 specbind (Qdebugger, Qdebug_early); 1802 specbind (Qdebugger, Qdebug_early);
1828 call_debugger (list2 (Qerror, Fcons (error_symbol, data))); 1803 call_debugger (list2 (Qerror, Fcons (error_symbol, data)));
1829 unbind_to (count, Qnil); 1804 unbind_to (count, Qnil);
@@ -1839,12 +1814,10 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
1839 { 1814 {
1840 max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100); 1815 max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100);
1841 specpdl_ref count = SPECPDL_INDEX (); 1816 specpdl_ref count = SPECPDL_INDEX ();
1842 ptrdiff_t counti = specpdl_ref_to_count (count);
1843 AUTO_STRING (redisplay_trace, "*Redisplay_trace*"); 1817 AUTO_STRING (redisplay_trace, "*Redisplay_trace*");
1844 Lisp_Object redisplay_trace_buffer; 1818 Lisp_Object redisplay_trace_buffer;
1845 AUTO_STRING (gap, "\n\n\n\n"); /* Separates things in *Redisplay-trace* */ 1819 AUTO_STRING (gap, "\n\n\n\n"); /* Separates things in *Redisplay-trace* */
1846 Lisp_Object delayed_warning; 1820 Lisp_Object delayed_warning;
1847 max_ensure_room (&max_specpdl_size, counti, 200);
1848 redisplay_trace_buffer = Fget_buffer_create (redisplay_trace, Qnil); 1821 redisplay_trace_buffer = Fget_buffer_create (redisplay_trace, Qnil);
1849 current_buffer = XBUFFER (redisplay_trace_buffer); 1822 current_buffer = XBUFFER (redisplay_trace_buffer);
1850 if (!backtrace_yet) /* Are we on the first backtrace of the command? */ 1823 if (!backtrace_yet) /* Are we on the first backtrace of the command? */
@@ -2376,17 +2349,12 @@ grow_specpdl_allocation (void)
2376 eassert (specpdl_ptr == specpdl_end); 2349 eassert (specpdl_ptr == specpdl_end);
2377 2350
2378 specpdl_ref count = SPECPDL_INDEX (); 2351 specpdl_ref count = SPECPDL_INDEX ();
2379 ptrdiff_t max_size = min (max_specpdl_size, PTRDIFF_MAX - 1000); 2352 ptrdiff_t max_size = PTRDIFF_MAX - 1000;
2380 union specbinding *pdlvec = specpdl - 1; 2353 union specbinding *pdlvec = specpdl - 1;
2381 ptrdiff_t size = specpdl_end - specpdl; 2354 ptrdiff_t size = specpdl_end - specpdl;
2382 ptrdiff_t pdlvecsize = size + 1; 2355 ptrdiff_t pdlvecsize = size + 1;
2383 if (max_size <= size) 2356 if (max_size <= size)
2384 { 2357 xsignal0 (Qexcessive_variable_binding); /* Can't happen, essentially. */
2385 if (max_specpdl_size < 400)
2386 max_size = max_specpdl_size = 400;
2387 if (max_size <= size)
2388 xsignal0 (Qexcessive_variable_binding);
2389 }
2390 pdlvec = xpalloc (pdlvec, &pdlvecsize, 1, max_size + 1, sizeof *specpdl); 2358 pdlvec = xpalloc (pdlvec, &pdlvecsize, 1, max_size + 1, sizeof *specpdl);
2391 specpdl = pdlvec + 1; 2359 specpdl = pdlvec + 1;
2392 specpdl_end = specpdl + pdlvecsize - 1; 2360 specpdl_end = specpdl + pdlvecsize - 1;
@@ -4229,22 +4197,6 @@ Lisp_Object backtrace_top_function (void)
4229void 4197void
4230syms_of_eval (void) 4198syms_of_eval (void)
4231{ 4199{
4232 DEFVAR_INT ("max-specpdl-size", max_specpdl_size,
4233 doc: /* Limit on number of Lisp variable bindings and `unwind-protect's.
4234
4235If Lisp code tries to use more bindings than this amount, an error is
4236signaled.
4237
4238You can safely increase this variable substantially if the default
4239value proves inconveniently small. However, if you increase it too
4240much, Emacs could run out of memory trying to make the stack bigger.
4241Note that this limit may be silently increased by the debugger if
4242`debug-on-error' or `debug-on-quit' is set.
4243
4244\"spec\" is short for \"special variables\", i.e., dynamically bound
4245variables. \"PDL\" is short for \"push-down list\", which is an old
4246term for \"stack\". */);
4247
4248 DEFVAR_INT ("max-lisp-eval-depth", max_lisp_eval_depth, 4200 DEFVAR_INT ("max-lisp-eval-depth", max_lisp_eval_depth,
4249 doc: /* Limit on depth in `eval', `apply' and `funcall' before error. 4201 doc: /* Limit on depth in `eval', `apply' and `funcall' before error.
4250 4202
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. */)
6019 bool old_message_p = 0; 6019 bool old_message_p = 0;
6020 struct auto_save_unwind auto_save_unwind; 6020 struct auto_save_unwind auto_save_unwind;
6021 6021
6022 intmax_t sum = INT_ADD_WRAPV (specpdl_end - specpdl, 40, &sum)
6023 ? INTMAX_MAX : sum;
6024 if (max_specpdl_size < sum)
6025 max_specpdl_size = sum;
6026
6027 if (minibuf_level) 6022 if (minibuf_level)
6028 no_message = Qt; 6023 no_message = Qt;
6029 6024