aboutsummaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--admin/grammars/Makefile.in2
-rw-r--r--doc/lispintro/emacs-lisp-intro.texi5
-rw-r--r--doc/lispref/control.texi5
-rw-r--r--doc/lispref/edebug.texi5
-rw-r--r--doc/lispref/eval.texi5
-rw-r--r--doc/lispref/variables.texi21
-rw-r--r--doc/misc/calc.texi4
-rw-r--r--etc/NEWS6
-rw-r--r--leim/Makefile.in2
-rw-r--r--lisp/Makefile.in8
-rw-r--r--lisp/calc/calc-stuff.el8
-rw-r--r--lisp/calc/calc.el3
-rw-r--r--lisp/cedet/semantic/ede-grammar.el7
-rw-r--r--lisp/cedet/semantic/grammar.el1
-rw-r--r--lisp/cus-start.el1
-rw-r--r--lisp/emacs-lisp/comp.el1
-rw-r--r--lisp/emacs-lisp/edebug.el6
-rw-r--r--lisp/emacs-lisp/regexp-opt.el1
-rw-r--r--lisp/eshell/esh-mode.el1
-rw-r--r--lisp/loadup.el4
-rw-r--r--lisp/mh-e/mh-e.el4
-rw-r--r--lisp/net/shr.el62
-rw-r--r--lisp/play/hanoi.el5
-rw-r--r--lisp/progmodes/cperl-mode.el1
-rw-r--r--lisp/subr.el8
-rw-r--r--src/eval.c60
-rw-r--r--src/fileio.c5
27 files changed, 68 insertions, 173 deletions
diff --git a/admin/grammars/Makefile.in b/admin/grammars/Makefile.in
index 4ca88982cde..178c79b7a02 100644
--- a/admin/grammars/Makefile.in
+++ b/admin/grammars/Makefile.in
@@ -35,7 +35,7 @@ unexport EMACSDATA EMACSDOC EMACSLOADPATH EMACSPATH
35 35
36EMACS = ${top_builddir}/src/emacs 36EMACS = ${top_builddir}/src/emacs
37emacs = "${EMACS}" -batch --no-site-file --no-site-lisp \ 37emacs = "${EMACS}" -batch --no-site-file --no-site-lisp \
38 --eval '(setq max-specpdl-size 5000)' --eval '(setq load-prefer-newer t)' 38 --eval '(setq load-prefer-newer t)'
39 39
40make_bovine = ${emacs} -l semantic/bovine/grammar -f bovine-batch-make-parser 40make_bovine = ${emacs} -l semantic/bovine/grammar -f bovine-batch-make-parser
41make_wisent = ${emacs} -l semantic/wisent/grammar -f wisent-batch-make-parser 41make_wisent = ${emacs} -l semantic/wisent/grammar -f wisent-batch-make-parser
diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi
index 47a5a870fde..df8fa2f8e79 100644
--- a/doc/lispintro/emacs-lisp-intro.texi
+++ b/doc/lispintro/emacs-lisp-intro.texi
@@ -10100,9 +10100,8 @@ resources; as it happens, methods that people find easy---that are
10100frugal of mental resources---sometimes use considerable computer 10100frugal of mental resources---sometimes use considerable computer
10101resources. Emacs was designed to run on machines that we now consider 10101resources. Emacs was designed to run on machines that we now consider
10102limited and its default settings are conservative. You may want to 10102limited and its default settings are conservative. You may want to
10103increase the values of @code{max-specpdl-size} and 10103increase the value of @code{max-lisp-eval-depth}. In my @file{.emacs}
10104@code{max-lisp-eval-depth}. In my @file{.emacs} file, I set them to 10104file, I set it to 30 times its default value.}.
1010515 and 30 times their default value.}.
10106 10105
10107@menu 10106@menu
10108* while:: Causing a stretch of code to repeat. 10107* while:: Causing a stretch of code to repeat.
diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi
index d4520ebdee5..ee2acdb002b 100644
--- a/doc/lispref/control.texi
+++ b/doc/lispref/control.texi
@@ -2366,11 +2366,6 @@ of the @var{cleanup-forms} themselves exits nonlocally (via a
2366guaranteed to evaluate the rest of them. If the failure of one of the 2366guaranteed to evaluate the rest of them. If the failure of one of the
2367@var{cleanup-forms} has the potential to cause trouble, then protect 2367@var{cleanup-forms} has the potential to cause trouble, then protect
2368it with another @code{unwind-protect} around that form. 2368it with another @code{unwind-protect} around that form.
2369
2370The number of currently active @code{unwind-protect} forms counts,
2371together with the number of local variable bindings, against the limit
2372@code{max-specpdl-size} (@pxref{Definition of max-specpdl-size,, Local
2373Variables}).
2374@end defspec 2369@end defspec
2375 2370
2376 For example, here we make an invisible buffer for temporary use, and 2371 For example, here we make an invisible buffer for temporary use, and
diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi
index 56f7b7bdfad..6a51489d8a4 100644
--- a/doc/lispref/edebug.texi
+++ b/doc/lispref/edebug.texi
@@ -1032,9 +1032,8 @@ program.
1032@itemize @bullet 1032@itemize @bullet
1033@item 1033@item
1034@vindex edebug-max-depth 1034@vindex edebug-max-depth
1035@code{max-lisp-eval-depth} (@pxref{Eval}) and @code{max-specpdl-size} 1035@code{max-lisp-eval-depth} (@pxref{Eval}) is increased to reduce Edebug's
1036(@pxref{Local Variables}) are both increased to reduce Edebug's impact 1036impact on the stack. You could, however, still run out of stack space when
1037on the stack. You could, however, still run out of stack space when
1038using Edebug. You can also enlarge the value of 1037using Edebug. You can also enlarge the value of
1039@code{edebug-max-depth} if Edebug reaches the limit of recursion depth 1038@code{edebug-max-depth} if Edebug reaches the limit of recursion depth
1040instrumenting code that contains very large quoted lists. 1039instrumenting code that contains very large quoted lists.
diff --git a/doc/lispref/eval.texi b/doc/lispref/eval.texi
index 6e29a5403f1..11c321b32ed 100644
--- a/doc/lispref/eval.texi
+++ b/doc/lispref/eval.texi
@@ -830,7 +830,7 @@ This variable defines the maximum depth allowed in calls to @code{eval},
830@code{apply}, and @code{funcall} before an error is signaled (with error 830@code{apply}, and @code{funcall} before an error is signaled (with error
831message @code{"Lisp nesting exceeds max-lisp-eval-depth"}). 831message @code{"Lisp nesting exceeds max-lisp-eval-depth"}).
832 832
833This limit, with the associated error when it is exceeded, is one way 833This limit, with the associated error when it is exceeded, is how
834Emacs Lisp avoids infinite recursion on an ill-defined function. If 834Emacs Lisp avoids infinite recursion on an ill-defined function. If
835you increase the value of @code{max-lisp-eval-depth} too much, such 835you increase the value of @code{max-lisp-eval-depth} too much, such
836code can cause stack overflow instead. On some systems, this overflow 836code can cause stack overflow instead. On some systems, this overflow
@@ -851,9 +851,6 @@ less than 100, Lisp will reset it to 100 if the given value is
851reached. Entry to the Lisp debugger increases the value, if there is 851reached. Entry to the Lisp debugger increases the value, if there is
852little room left, to make sure the debugger itself has room to 852little room left, to make sure the debugger itself has room to
853execute. 853execute.
854
855@code{max-specpdl-size} provides another limit on nesting.
856@xref{Definition of max-specpdl-size,, Local Variables}.
857@end defopt 854@end defopt
858 855
859@defvar values 856@defvar values
diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi
index 975e945b343..ccd19630bf7 100644
--- a/doc/lispref/variables.texi
+++ b/doc/lispref/variables.texi
@@ -358,27 +358,6 @@ Variables}); a few variables have terminal-local bindings
358like ordinary local bindings, but they are localized depending on 358like ordinary local bindings, but they are localized depending on
359where you are in Emacs. 359where you are in Emacs.
360 360
361@defopt max-specpdl-size
362@anchor{Definition of max-specpdl-size}
363@cindex variable limit error
364@cindex evaluation error
365@cindex infinite recursion
366This variable defines the limit on the total number of local variable
367bindings and @code{unwind-protect} cleanups (@pxref{Cleanups,,
368Cleaning Up from Nonlocal Exits}) that are allowed before Emacs
369signals an error (with data @code{"Variable binding depth exceeds
370max-specpdl-size"}).
371
372This limit, with the associated error when it is exceeded, is one way
373that Lisp avoids infinite recursion on an ill-defined function.
374@code{max-lisp-eval-depth} provides another limit on depth of nesting.
375@xref{Definition of max-lisp-eval-depth,, Eval}.
376
377The default value is 2500. Entry to the Lisp debugger increases the
378value, if there is little room left, to make sure the debugger itself
379has room to execute.
380@end defopt
381
382@node Void Variables 361@node Void Variables
383@section When a Variable is Void 362@section When a Variable is Void
384@cindex @code{void-variable} error 363@cindex @code{void-variable} error
diff --git a/doc/misc/calc.texi b/doc/misc/calc.texi
index 98f59b89c01..89a340e7343 100644
--- a/doc/misc/calc.texi
+++ b/doc/misc/calc.texi
@@ -10392,7 +10392,6 @@ memory than it would otherwise, but it's guaranteed to fix the problem.
10392@cindex Recursion depth 10392@cindex Recursion depth
10393@cindex ``Computation got stuck'' message 10393@cindex ``Computation got stuck'' message
10394@cindex @code{max-lisp-eval-depth} 10394@cindex @code{max-lisp-eval-depth}
10395@cindex @code{max-specpdl-size}
10396Calc uses recursion in many of its calculations. Emacs Lisp keeps a 10395Calc uses recursion in many of its calculations. Emacs Lisp keeps a
10397variable @code{max-lisp-eval-depth} which limits the amount of recursion 10396variable @code{max-lisp-eval-depth} which limits the amount of recursion
10398possible in an attempt to recover from program bugs. If a calculation 10397possible in an attempt to recover from program bugs. If a calculation
@@ -10406,9 +10405,6 @@ is also an @kbd{I M} (@code{calc-less-recursion-depth}) command which
10406decreases this limit by a factor of two, down to a minimum value of 200. 10405decreases this limit by a factor of two, down to a minimum value of 200.
10407The default value is 1000. 10406The default value is 1000.
10408 10407
10409These commands also double or halve @code{max-specpdl-size}, another
10410internal Lisp recursion limit. The minimum value for this limit is 600.
10411
10412@node Caches 10408@node Caches
10413@subsection Caches 10409@subsection Caches
10414 10410
diff --git a/etc/NEWS b/etc/NEWS
index a739d74b650..723bdd7c75d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -3806,6 +3806,12 @@ the same but works by modifying LIST destructively.
3806--- 3806---
3807** 'string-split' is now an alias for 'split-string'. 3807** 'string-split' is now an alias for 'split-string'.
3808 3808
3809+++
3810** The variable 'max-specpdl-size' has been made obsolete.
3811Now 'max-lisp-eval-depth' alone is used for limiting Lisp recursion
3812and stack usage. 'max-specpdl-size' is still present as a plain
3813variable for compatibility but its limiting powers have been taken away.
3814
3809 3815
3810* Changes in Emacs 29.1 on Non-Free Operating Systems 3816* Changes in Emacs 29.1 on Non-Free Operating Systems
3811 3817
diff --git a/leim/Makefile.in b/leim/Makefile.in
index 29b9f3b2f86..fbd733b7f66 100644
--- a/leim/Makefile.in
+++ b/leim/Makefile.in
@@ -128,7 +128,6 @@ leim-list.el: ${leimdir}/leim-list.el
128${leimdir}/leim-list.el: ${srcdir}/leim-ext.el ${TIT_MISC} 128${leimdir}/leim-list.el: ${srcdir}/leim-ext.el ${TIT_MISC}
129 $(AM_V_GEN)rm -f $@ 129 $(AM_V_GEN)rm -f $@
130 $(AM_V_at)${RUN_EMACS} -l international/quail \ 130 $(AM_V_at)${RUN_EMACS} -l international/quail \
131 --eval "(setq max-specpdl-size 5000)" \
132 --eval "(update-leim-list-file (unmsys--file-name \"${leimdir}\"))" 131 --eval "(update-leim-list-file (unmsys--file-name \"${leimdir}\"))"
133 $(AM_V_at)sed -n -e '/^[^;]/p' -e 's/^;\(;*\)inc /;\1 /p' < $< >> $@ 132 $(AM_V_at)sed -n -e '/^[^;]/p' -e 's/^;\(;*\)inc /;\1 /p' < $< >> $@
134 133
@@ -139,7 +138,6 @@ ${leimdir}/ja-dic/ja-dic.el: | $(leimdir)/ja-dic
139generate-ja-dic: ${leimdir}/ja-dic/ja-dic.el 138generate-ja-dic: ${leimdir}/ja-dic/ja-dic.el
140${leimdir}/ja-dic/ja-dic.el: $(srcdir)/SKK-DIC/SKK-JISYO.L 139${leimdir}/ja-dic/ja-dic.el: $(srcdir)/SKK-DIC/SKK-JISYO.L
141 $(AM_V_GEN)$(RUN_EMACS) -batch -l ja-dic-cnv \ 140 $(AM_V_GEN)$(RUN_EMACS) -batch -l ja-dic-cnv \
142 --eval "(setq max-specpdl-size 5000)" \
143 -f batch-skkdic-convert -dir "$(leimdir)/ja-dic" $(JA_DIC_NO_REDUCTION_OPTION) "$<" 141 -f batch-skkdic-convert -dir "$(leimdir)/ja-dic" $(JA_DIC_NO_REDUCTION_OPTION) "$<"
144 142
145${srcdir}/../lisp/language/pinyin.el: ${srcdir}/MISC-DIC/pinyin.map 143${srcdir}/../lisp/language/pinyin.el: ${srcdir}/MISC-DIC/pinyin.map
diff --git a/lisp/Makefile.in b/lisp/Makefile.in
index c73a623cce9..bcf4a3146d4 100644
--- a/lisp/Makefile.in
+++ b/lisp/Makefile.in
@@ -70,9 +70,7 @@ BYTE_COMPILE_FLAGS = \
70 --eval "(setq load-prefer-newer t byte-compile-warnings 'all)" \ 70 --eval "(setq load-prefer-newer t byte-compile-warnings 'all)" \
71 $(BYTE_COMPILE_EXTRA_FLAGS) 71 $(BYTE_COMPILE_EXTRA_FLAGS)
72# ... but we must prefer .elc files for those in the early bootstrap. 72# ... but we must prefer .elc files for those in the early bootstrap.
73# A larger `max-specpdl-size' is needed for emacs-lisp/comp.el. 73compile-first: BYTE_COMPILE_FLAGS = $(BYTE_COMPILE_EXTRA_FLAGS)
74compile-first: BYTE_COMPILE_FLAGS = \
75 --eval '(setq max-specpdl-size 5000)' $(BYTE_COMPILE_EXTRA_FLAGS)
76 74
77# Files to compile before others during a bootstrap. This is done to 75# Files to compile before others during a bootstrap. This is done to
78# speed up the bootstrap process. They're ordered by size, so we use 76# speed up the bootstrap process. They're ordered by size, so we use
@@ -342,8 +340,8 @@ compile-first: $(COMPILE_FIRST)
342 340
343.PHONY: compile-targets 341.PHONY: compile-targets
344# TARGETS is set dynamically in the recursive call from 'compile-main'. 342# TARGETS is set dynamically in the recursive call from 'compile-main'.
345# Do not build comp.el unless necessary not to exceed max-specpdl-size and 343# Do not build comp.el unless necessary not to exceed max-lisp-eval-depth
346# max-lisp-eval-depth in normal builds. 344# in normal builds.
347ifneq ($(HAVE_NATIVE_COMP),yes) 345ifneq ($(HAVE_NATIVE_COMP),yes)
348compile-targets: $(filter-out ./emacs-lisp/comp-cstr.elc,$(filter-out ./emacs-lisp/comp.elc,$(TARGETS))) 346compile-targets: $(filter-out ./emacs-lisp/comp-cstr.elc,$(filter-out ./emacs-lisp/comp.elc,$(TARGETS)))
349else 347else
diff --git a/lisp/calc/calc-stuff.el b/lisp/calc/calc-stuff.el
index 0e8ea42bedc..758b9201843 100644
--- a/lisp/calc/calc-stuff.el
+++ b/lisp/calc/calc-stuff.el
@@ -52,18 +52,14 @@ With a prefix, push that prefix as a number onto the stack."
52 (calc-less-recursion-depth n) 52 (calc-less-recursion-depth n)
53 (let ((n (if n (prefix-numeric-value n) 2))) 53 (let ((n (if n (prefix-numeric-value n) 2)))
54 (if (> n 1) 54 (if (> n 1)
55 (setq max-specpdl-size (* max-specpdl-size n) 55 (setq max-lisp-eval-depth (* max-lisp-eval-depth n))))
56 max-lisp-eval-depth (* max-lisp-eval-depth n))))
57 (message "max-lisp-eval-depth is now %d" max-lisp-eval-depth)))) 56 (message "max-lisp-eval-depth is now %d" max-lisp-eval-depth))))
58 57
59(defun calc-less-recursion-depth (n) 58(defun calc-less-recursion-depth (n)
60 (interactive "P") 59 (interactive "P")
61 (let ((n (if n (prefix-numeric-value n) 2))) 60 (let ((n (if n (prefix-numeric-value n) 2)))
62 (if (> n 1) 61 (if (> n 1)
63 (setq max-specpdl-size 62 (setq max-lisp-eval-depth (max (/ max-lisp-eval-depth n) 200))))
64 (max (/ max-specpdl-size n) 600)
65 max-lisp-eval-depth
66 (max (/ max-lisp-eval-depth n) 200))))
67 (message "max-lisp-eval-depth is now %d" max-lisp-eval-depth)) 63 (message "max-lisp-eval-depth is now %d" max-lisp-eval-depth))
68 64
69 65
diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el
index 5077c8c8528..c0f87ad3d42 100644
--- a/lisp/calc/calc.el
+++ b/lisp/calc/calc.el
@@ -1625,8 +1625,7 @@ See calc-keypad for details."
1625 (error 1625 (error
1626 (if (and (eq (car err) 'error) 1626 (if (and (eq (car err) 'error)
1627 (stringp (nth 1 err)) 1627 (stringp (nth 1 err))
1628 (string-match "max-specpdl-size\\|max-lisp-eval-depth" 1628 (string-search "max-lisp-eval-depth" (nth 1 err)))
1629 (nth 1 err)))
1630 (error (substitute-command-keys 1629 (error (substitute-command-keys
1631 "Computation got stuck or ran too long. Type \\`M' to increase the limit")) 1630 "Computation got stuck or ran too long. Type \\`M' to increase the limit"))
1632 (setq calc-aborted-prefix nil) 1631 (setq calc-aborted-prefix nil)
diff --git a/lisp/cedet/semantic/ede-grammar.el b/lisp/cedet/semantic/ede-grammar.el
index ff9f991ff4a..40ff8fc86d3 100644
--- a/lisp/cedet/semantic/ede-grammar.el
+++ b/lisp/cedet/semantic/ede-grammar.el
@@ -177,10 +177,9 @@ Lays claim to all -by.el, and -wy.el files."
177 177
178(cl-defmethod ede-proj-makefile-insert-rules :after ((this semantic-ede-proj-target-grammar)) 178(cl-defmethod ede-proj-makefile-insert-rules :after ((this semantic-ede-proj-target-grammar))
179 "Insert rules needed by THIS target. 179 "Insert rules needed by THIS target.
180This raises `max-specpdl-size' and `max-lisp-eval-depth', which can be 180This raises `max-lisp-eval-depth', which can be needed for the compilation
181needed for the compilation of the resulting parsers." 181of the resulting parsers."
182 (insert (format "%s: EMACSFLAGS+= --eval '(setq max-specpdl-size 1500 \ 182 (insert (format "%s: EMACSFLAGS+= --eval '(setq max-lisp-eval-depth 700)'\n"
183max-lisp-eval-depth 700)'\n"
184 (oref this name)))) 183 (oref this name))))
185 184
186(cl-defmethod ede-proj-makefile-insert-dist-dependencies ((this semantic-ede-proj-target-grammar)) 185(cl-defmethod ede-proj-makefile-insert-dist-dependencies ((this semantic-ede-proj-target-grammar))
diff --git a/lisp/cedet/semantic/grammar.el b/lisp/cedet/semantic/grammar.el
index 72037f47108..8ba0e346fff 100644
--- a/lisp/cedet/semantic/grammar.el
+++ b/lisp/cedet/semantic/grammar.el
@@ -1009,7 +1009,6 @@ Return non-nil if there were no errors, nil if errors."
1009 packagename (byte-compile-dest-file packagename)) 1009 packagename (byte-compile-dest-file packagename))
1010 (let (;; Some complex grammar table expressions need a few 1010 (let (;; Some complex grammar table expressions need a few
1011 ;; more resources than the default. 1011 ;; more resources than the default.
1012 (max-specpdl-size (max 3000 max-specpdl-size))
1013 (max-lisp-eval-depth (max 1000 max-lisp-eval-depth)) 1012 (max-lisp-eval-depth (max 1000 max-lisp-eval-depth))
1014 ) 1013 )
1015 ;; byte compile the resultant file 1014 ;; byte compile the resultant file
diff --git a/lisp/cus-start.el b/lisp/cus-start.el
index 0e1cb4589da..d7fb56c9854 100644
--- a/lisp/cus-start.el
+++ b/lisp/cus-start.el
@@ -251,7 +251,6 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of
251 ;; emacs.c 251 ;; emacs.c
252 (report-emacs-bug-address emacsbug string) 252 (report-emacs-bug-address emacsbug string)
253 ;; eval.c 253 ;; eval.c
254 (max-specpdl-size limits integer)
255 (max-lisp-eval-depth limits integer) 254 (max-lisp-eval-depth limits integer)
256 (max-mini-window-height limits 255 (max-mini-window-height limits
257 (choice (const :tag "quarter screen" nil) 256 (choice (const :tag "quarter screen" nil)
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index a9087313b18..35acbff9b17 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -4044,7 +4044,6 @@ the deferred compilation mechanism."
4044 (list "Not a function symbol or file" function-or-file))) 4044 (list "Not a function symbol or file" function-or-file)))
4045 (catch 'no-native-compile 4045 (catch 'no-native-compile
4046 (let* ((print-symbols-bare t) 4046 (let* ((print-symbols-bare t)
4047 (max-specpdl-size (max max-specpdl-size 5000))
4048 (data function-or-file) 4047 (data function-or-file)
4049 (comp-native-compiling t) 4048 (comp-native-compiling t)
4050 (byte-native-qualities nil) 4049 (byte-native-qualities nil)
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index 31c05057bfa..67704bdb51c 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -129,7 +129,7 @@ contains an infinite loop. When Edebug is instrumenting code
129containing very large quoted lists, it may reach this limit and give 129containing very large quoted lists, it may reach this limit and give
130the error message \"Too deep - perhaps infinite loop in spec?\". 130the error message \"Too deep - perhaps infinite loop in spec?\".
131Make this limit larger to countermand that, but you may also need to 131Make this limit larger to countermand that, but you may also need to
132increase `max-lisp-eval-depth' and `max-specpdl-size'." 132increase `max-lisp-eval-depth'."
133 :type 'integer 133 :type 'integer
134 :version "26.1") 134 :version "26.1")
135 135
@@ -1107,8 +1107,7 @@ purpose by adding an entry to this alist, and setting
1107 edebug-best-error 1107 edebug-best-error
1108 edebug-error-point 1108 edebug-error-point
1109 ;; Do this once here instead of several times. 1109 ;; Do this once here instead of several times.
1110 (max-lisp-eval-depth (+ 800 max-lisp-eval-depth)) 1110 (max-lisp-eval-depth (+ 800 max-lisp-eval-depth)))
1111 (max-specpdl-size (+ 2000 max-specpdl-size)))
1112 (let ((no-match 1111 (let ((no-match
1113 (catch 'no-match 1112 (catch 'no-match
1114 (setq result (edebug-read-and-maybe-wrap-form1)) 1113 (setq result (edebug-read-and-maybe-wrap-form1))
@@ -2317,7 +2316,6 @@ and run its entry function, and set up `edebug-before' and
2317 ;; but not inside an unwind-protect. 2316 ;; but not inside an unwind-protect.
2318 ;; Doing it here also keeps it from growing too large. 2317 ;; Doing it here also keeps it from growing too large.
2319 (max-lisp-eval-depth (+ 100 max-lisp-eval-depth)) ; too much?? 2318 (max-lisp-eval-depth (+ 100 max-lisp-eval-depth)) ; too much??
2320 (max-specpdl-size (+ 200 max-specpdl-size))
2321 2319
2322 (debugger edebug-debugger) ; only while edebug is active. 2320 (debugger edebug-debugger) ; only while edebug is active.
2323 (edebug-outside-debug-on-error debug-on-error) 2321 (edebug-outside-debug-on-error debug-on-error)
diff --git a/lisp/emacs-lisp/regexp-opt.el b/lisp/emacs-lisp/regexp-opt.el
index cae5dd00d1d..4d5a39458d2 100644
--- a/lisp/emacs-lisp/regexp-opt.el
+++ b/lisp/emacs-lisp/regexp-opt.el
@@ -133,7 +133,6 @@ usually more efficient than that of a simplified version:
133 (save-match-data 133 (save-match-data
134 ;; Recurse on the sorted list. 134 ;; Recurse on the sorted list.
135 (let* ((max-lisp-eval-depth 10000) 135 (let* ((max-lisp-eval-depth 10000)
136 (max-specpdl-size 10000)
137 (completion-ignore-case nil) 136 (completion-ignore-case nil)
138 (completion-regexp-list nil) 137 (completion-regexp-list nil)
139 (open (cond ((stringp paren) paren) (paren "\\("))) 138 (open (cond ((stringp paren) paren) (paren "\\(")))
diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el
index 69069183a3f..8f11e6f04a4 100644
--- a/lisp/eshell/esh-mode.el
+++ b/lisp/eshell/esh-mode.el
@@ -331,7 +331,6 @@ and the hook `eshell-exit-hook'."
331 (setq-local require-final-newline nil) 331 (setq-local require-final-newline nil)
332 332
333 (setq-local max-lisp-eval-depth (max 3000 max-lisp-eval-depth)) 333 (setq-local max-lisp-eval-depth (max 3000 max-lisp-eval-depth))
334 (setq-local max-specpdl-size (max 6000 max-lisp-eval-depth))
335 334
336 (setq-local eshell-last-input-start (point-marker)) 335 (setq-local eshell-last-input-start (point-marker))
337 (setq-local eshell-last-input-end (point-marker)) 336 (setq-local eshell-last-input-end (point-marker))
diff --git a/lisp/loadup.el b/lisp/loadup.el
index 634a3314361..c01c827a75e 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -244,9 +244,7 @@
244(load "language/indonesian") 244(load "language/indonesian")
245 245
246(load "indent") 246(load "indent")
247(let ((max-specpdl-size (max max-specpdl-size 1800))) 247(load "emacs-lisp/cl-generic")
248 ;; A particularly demanding file to load; 1600 does not seem to be enough.
249 (load "emacs-lisp/cl-generic"))
250(load "simple") 248(load "simple")
251(load "emacs-lisp/seq") 249(load "emacs-lisp/seq")
252(load "emacs-lisp/nadvice") 250(load "emacs-lisp/nadvice")
diff --git a/lisp/mh-e/mh-e.el b/lisp/mh-e/mh-e.el
index 0ad934107d3..9a04d890973 100644
--- a/lisp/mh-e/mh-e.el
+++ b/lisp/mh-e/mh-e.el
@@ -2831,9 +2831,7 @@ removed and entries from `mh-invisible-header-fields' are added."
2831 (setq mh-invisible-header-fields-compiled 2831 (setq mh-invisible-header-fields-compiled
2832 (concat 2832 (concat
2833 "^" 2833 "^"
2834 ;; workaround for insufficient default 2834 (regexp-opt fields t)))
2835 (let ((max-specpdl-size 1000))
2836 (regexp-opt fields t))))
2837 (setq mh-invisible-header-fields-compiled nil)))) 2835 (setq mh-invisible-header-fields-compiled nil))))
2838 2836
2839;; Compile invisible header fields. 2837;; Compile invisible header fields.
diff --git a/lisp/net/shr.el b/lisp/net/shr.el
index 54ce9b1a41c..d56420eb02e 100644
--- a/lisp/net/shr.el
+++ b/lisp/net/shr.el
@@ -373,7 +373,6 @@ DOM should be a parse tree as generated by
373 shr-width 373 shr-width
374 (* shr-width (frame-char-width))) 374 (* shr-width (frame-char-width)))
375 (shr--window-width))) 375 (shr--window-width)))
376 (max-specpdl-size max-specpdl-size)
377 (shr--link-targets nil) 376 (shr--link-targets nil)
378 (hscroll (window-hscroll)) 377 (hscroll (window-hscroll))
379 ;; `bidi-display-reordering' is supposed to be only used for 378 ;; `bidi-display-reordering' is supposed to be only used for
@@ -625,41 +624,34 @@ size, and full-buffer size."
625 (shr-stylesheet shr-stylesheet) 624 (shr-stylesheet shr-stylesheet)
626 (shr-depth (1+ shr-depth)) 625 (shr-depth (1+ shr-depth))
627 (start (point))) 626 (start (point)))
628 ;; shr uses many frames per nested node. 627 (when style
629 (if (and (> shr-depth (/ max-specpdl-size 15)) 628 (if (string-match-p "color\\|display\\|border-collapse" style)
630 (not (and shr-offer-extend-specpdl 629 (setq shr-stylesheet (nconc (shr-parse-style style)
631 (y-or-n-p "Too deeply nested to render properly; increase `max-specpdl-size'?") 630 shr-stylesheet))
632 (setq max-specpdl-size (* max-specpdl-size 2))))) 631 (setq style nil)))
633 (setq shr-warning 632 ;; If we have a display:none, then just ignore this part of the DOM.
634 "Not rendering the complete page because of too-deep nesting") 633 (unless (or (equal (cdr (assq 'display shr-stylesheet)) "none")
634 (and shr-discard-aria-hidden
635 (equal (dom-attr dom 'aria-hidden) "true")))
636 ;; We don't use shr-indirect-call here, since shr-descend is
637 ;; the central bit of shr.el, and should be as fast as
638 ;; possible. Having one more level of indirection with its
639 ;; negative effect on performance is deemed unjustified in
640 ;; this case.
641 (cond (external
642 (funcall external dom))
643 ((fboundp function)
644 (funcall function dom))
645 (t
646 (shr-generic dom)))
647 (when-let ((id (dom-attr dom 'id)))
648 (push (cons id (set-marker (make-marker) start)) shr--link-targets))
649 ;; If style is set, then this node has set the color.
635 (when style 650 (when style
636 (if (string-match-p "color\\|display\\|border-collapse" style) 651 (shr-colorize-region
637 (setq shr-stylesheet (nconc (shr-parse-style style) 652 start (point)
638 shr-stylesheet)) 653 (cdr (assq 'color shr-stylesheet))
639 (setq style nil))) 654 (cdr (assq 'background-color shr-stylesheet)))))))
640 ;; If we have a display:none, then just ignore this part of the DOM.
641 (unless (or (equal (cdr (assq 'display shr-stylesheet)) "none")
642 (and shr-discard-aria-hidden
643 (equal (dom-attr dom 'aria-hidden) "true")))
644 ;; We don't use shr-indirect-call here, since shr-descend is
645 ;; the central bit of shr.el, and should be as fast as
646 ;; possible. Having one more level of indirection with its
647 ;; negative effect on performance is deemed unjustified in
648 ;; this case.
649 (cond (external
650 (funcall external dom))
651 ((fboundp function)
652 (funcall function dom))
653 (t
654 (shr-generic dom)))
655 (when-let ((id (dom-attr dom 'id)))
656 (push (cons id (set-marker (make-marker) start)) shr--link-targets))
657 ;; If style is set, then this node has set the color.
658 (when style
659 (shr-colorize-region
660 start (point)
661 (cdr (assq 'color shr-stylesheet))
662 (cdr (assq 'background-color shr-stylesheet))))))))
663 655
664(defun shr-fill-text (text) 656(defun shr-fill-text (text)
665 (if (zerop (length text)) 657 (if (zerop (length text))
diff --git a/lisp/play/hanoi.el b/lisp/play/hanoi.el
index 58fb82b6ed0..1a4b6dbeb11 100644
--- a/lisp/play/hanoi.el
+++ b/lisp/play/hanoi.el
@@ -149,10 +149,9 @@ BITS must be of length nrings. Start at START-TIME."
149 (setq show-trailing-whitespace nil) 149 (setq show-trailing-whitespace nil)
150 (unwind-protect 150 (unwind-protect
151 (let* 151 (let*
152 (;; These lines can cause Emacs to crash if you ask for too 152 (;; This line can cause Emacs to crash if you ask for too
153 ;; many rings. If you uncomment them, on most systems you 153 ;; many rings. If you uncomment it, on most systems you
154 ;; can get 10,000+ rings. 154 ;; can get 10,000+ rings.
155 ;;(max-specpdl-size (max max-specpdl-size (* nrings 15)))
156 ;;(max-lisp-eval-depth (max max-lisp-eval-depth (+ nrings 20))) 155 ;;(max-lisp-eval-depth (max max-lisp-eval-depth (+ nrings 20)))
157 (vert (not hanoi-horizontal-flag)) 156 (vert (not hanoi-horizontal-flag))
158 (pole-width (length (format "%d" (max 0 (1- nrings))))) 157 (pole-width (length (format "%d" (max 0 (1- nrings)))))
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index 614ee60fa03..c3704a05dbb 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -3718,7 +3718,6 @@ This is part of `cperl-find-pods-heres' (below)."
3718 overshoot 3718 overshoot
3719 warning-message))) 3719 warning-message)))
3720 3720
3721;; Debugging this may require (setq max-specpdl-size 2000)...
3722(defun cperl-find-pods-heres (&optional min max non-inter end ignore-max end-of-here-doc) 3721(defun cperl-find-pods-heres (&optional min max non-inter end ignore-max end-of-here-doc)
3723 "Scan the buffer for hard-to-parse Perl constructions. 3722 "Scan the buffer for hard-to-parse Perl constructions.
3724If `cperl-pod-here-fontify' is non-nil after evaluation, 3723If `cperl-pod-here-fontify' is non-nil after evaluation,
diff --git a/lisp/subr.el b/lisp/subr.el
index d7cdc28abba..59f9308f31e 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1859,6 +1859,14 @@ be a list of the form returned by `event-start' and `event-end'."
1859;; in warnings when using `values' in let-bindings. 1859;; in warnings when using `values' in let-bindings.
1860;;(make-obsolete-variable 'values "no longer used" "28.1") 1860;;(make-obsolete-variable 'values "no longer used" "28.1")
1861 1861
1862(defvar max-specpdl-size 2500
1863 "Former limit on specbindings, now without effect.
1864This variable used to limit the size of the specpdl stack which,
1865among other things, holds dynamic variable bindings and `unwind-protect'
1866activations. To prevent runaway recursion, use `max-lisp-eval-depth'
1867instead; it will indirectly limit the specpdl stack size as well.")
1868(make-obsolete-variable 'max-specpdl-size nil "29.1")
1869
1862 1870
1863;;;; Alternate names for functions - these are not being phased out. 1871;;;; Alternate names for functions - these are not being phased out.
1864 1872
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