]> git.eshelyaron.com Git - emacs.git/commitdiff
Abolish max-specpdl-size (bug#57911)
authorMattias Engdegård <mattiase@acm.org>
Mon, 19 Sep 2022 08:55:09 +0000 (10:55 +0200)
committerMattias Engdegård <mattiase@acm.org>
Mon, 19 Sep 2022 17:30:03 +0000 (19:30 +0200)
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.

27 files changed:
admin/grammars/Makefile.in
doc/lispintro/emacs-lisp-intro.texi
doc/lispref/control.texi
doc/lispref/edebug.texi
doc/lispref/eval.texi
doc/lispref/variables.texi
doc/misc/calc.texi
etc/NEWS
leim/Makefile.in
lisp/Makefile.in
lisp/calc/calc-stuff.el
lisp/calc/calc.el
lisp/cedet/semantic/ede-grammar.el
lisp/cedet/semantic/grammar.el
lisp/cus-start.el
lisp/emacs-lisp/comp.el
lisp/emacs-lisp/edebug.el
lisp/emacs-lisp/regexp-opt.el
lisp/eshell/esh-mode.el
lisp/loadup.el
lisp/mh-e/mh-e.el
lisp/net/shr.el
lisp/play/hanoi.el
lisp/progmodes/cperl-mode.el
lisp/subr.el
src/eval.c
src/fileio.c

index 4ca88982cdec3297849a1a06d2d7ae78f35f05c6..178c79b7a02b2a35b1013652c68c36aa91c88f63 100644 (file)
@@ -35,7 +35,7 @@ unexport EMACSDATA EMACSDOC EMACSLOADPATH EMACSPATH
 
 EMACS = ${top_builddir}/src/emacs
 emacs = "${EMACS}" -batch --no-site-file --no-site-lisp \
-  --eval '(setq max-specpdl-size 5000)' --eval '(setq load-prefer-newer t)'
+  --eval '(setq load-prefer-newer t)'
 
 make_bovine = ${emacs} -l semantic/bovine/grammar -f bovine-batch-make-parser
 make_wisent = ${emacs} -l semantic/wisent/grammar -f wisent-batch-make-parser
index 47a5a870fde82cbbaf2a1bcbe9d62701bcd9fc78..df8fa2f8e79d3231d496e5fbc1629c18c152fa21 100644 (file)
@@ -10100,9 +10100,8 @@ resources; as it happens, methods that people find easy---that are
 frugal of mental resources---sometimes use considerable computer
 resources.  Emacs was designed to run on machines that we now consider
 limited and its default settings are conservative.  You may want to
-increase the values of @code{max-specpdl-size} and
-@code{max-lisp-eval-depth}.  In my @file{.emacs} file, I set them to
-15 and 30 times their default value.}.
+increase the value of @code{max-lisp-eval-depth}.  In my @file{.emacs}
+file, I set it to 30 times its default value.}.
 
 @menu
 * while::                       Causing a stretch of code to repeat.
index d4520ebdee5b366022ea5bdc999abc0f446ec2ef..ee2acdb002b52ea520fec830ffa973740d257d1f 100644 (file)
@@ -2366,11 +2366,6 @@ of the @var{cleanup-forms} themselves exits nonlocally (via a
 guaranteed to evaluate the rest of them.  If the failure of one of the
 @var{cleanup-forms} has the potential to cause trouble, then protect
 it with another @code{unwind-protect} around that form.
-
-The number of currently active @code{unwind-protect} forms counts,
-together with the number of local variable bindings, against the limit
-@code{max-specpdl-size} (@pxref{Definition of max-specpdl-size,, Local
-Variables}).
 @end defspec
 
   For example, here we make an invisible buffer for temporary use, and
index 56f7b7bdfad70a8d1b437d9040e56a1d7093898c..6a51489d8a4352b7a9085eea265f225e596dc2b0 100644 (file)
@@ -1032,9 +1032,8 @@ program.
 @itemize @bullet
 @item
 @vindex edebug-max-depth
-@code{max-lisp-eval-depth} (@pxref{Eval}) and @code{max-specpdl-size}
-(@pxref{Local Variables}) are both increased to reduce Edebug's impact
-on the stack.  You could, however, still run out of stack space when
+@code{max-lisp-eval-depth} (@pxref{Eval}) is increased to reduce Edebug's
+impact on the stack.  You could, however, still run out of stack space when
 using Edebug.  You can also enlarge the value of
 @code{edebug-max-depth} if Edebug reaches the limit of recursion depth
 instrumenting code that contains very large quoted lists.
index 6e29a5403f1ec97b44f45987ed20404fb3357dbe..11c321b32edc9a5ea52813eaacf99800b84256e4 100644 (file)
@@ -830,7 +830,7 @@ This variable defines the maximum depth allowed in calls to @code{eval},
 @code{apply}, and @code{funcall} before an error is signaled (with error
 message @code{"Lisp nesting exceeds max-lisp-eval-depth"}).
 
-This limit, with the associated error when it is exceeded, is one way
+This limit, with the associated error when it is exceeded, is how
 Emacs Lisp avoids infinite recursion on an ill-defined function.  If
 you increase the value of @code{max-lisp-eval-depth} too much, such
 code 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
 reached.  Entry to the Lisp debugger increases the value, if there is
 little room left, to make sure the debugger itself has room to
 execute.
-
-@code{max-specpdl-size} provides another limit on nesting.
-@xref{Definition of max-specpdl-size,, Local Variables}.
 @end defopt
 
 @defvar values
index 975e945b343ac67fa09ee0a8795cf09624282bd2..ccd19630bf75d2df4a064f0e0f56d0a7210852af 100644 (file)
@@ -358,27 +358,6 @@ Variables}); a few variables have terminal-local bindings
 like ordinary local bindings, but they are localized depending on
 where you are in Emacs.
 
-@defopt max-specpdl-size
-@anchor{Definition of max-specpdl-size}
-@cindex variable limit error
-@cindex evaluation error
-@cindex infinite recursion
-This variable defines the limit on the total number of local variable
-bindings and @code{unwind-protect} cleanups (@pxref{Cleanups,,
-Cleaning Up from Nonlocal Exits}) that are allowed before Emacs
-signals an error (with data @code{"Variable binding depth exceeds
-max-specpdl-size"}).
-
-This limit, with the associated error when it is exceeded, is one way
-that Lisp avoids infinite recursion on an ill-defined function.
-@code{max-lisp-eval-depth} provides another limit on depth of nesting.
-@xref{Definition of max-lisp-eval-depth,, Eval}.
-
-The default value is 2500.  Entry to the Lisp debugger increases the
-value, if there is little room left, to make sure the debugger itself
-has room to execute.
-@end defopt
-
 @node Void Variables
 @section When a Variable is Void
 @cindex @code{void-variable} error
index 98f59b89c0175423418176208865d92073f48503..89a340e73435ce66c3c0138019f8e68f4a7fffca 100644 (file)
@@ -10392,7 +10392,6 @@ memory than it would otherwise, but it's guaranteed to fix the problem.
 @cindex Recursion depth
 @cindex ``Computation got stuck'' message
 @cindex @code{max-lisp-eval-depth}
-@cindex @code{max-specpdl-size}
 Calc uses recursion in many of its calculations.  Emacs Lisp keeps a
 variable @code{max-lisp-eval-depth} which limits the amount of recursion
 possible 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
 decreases this limit by a factor of two, down to a minimum value of 200.
 The default value is 1000.
 
-These commands also double or halve @code{max-specpdl-size}, another
-internal Lisp recursion limit.  The minimum value for this limit is 600.
-
 @node Caches
 @subsection Caches
 
index a739d74b65017fd031269490c251c69d249e5e72..723bdd7c75deef6aa0df4e9d0a5be459d7b6f091 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -3806,6 +3806,12 @@ the same but works by modifying LIST destructively.
 ---
 ** 'string-split' is now an alias for 'split-string'.
 
++++
+** The variable 'max-specpdl-size' has been made obsolete.
+Now 'max-lisp-eval-depth' alone is used for limiting Lisp recursion
+and stack usage.  'max-specpdl-size' is still present as a plain
+variable for compatibility but its limiting powers have been taken away.
+
 \f
 * Changes in Emacs 29.1 on Non-Free Operating Systems
 
index 29b9f3b2f868caa3e39c4e7ab4e6e92a71bc45dc..fbd733b7f66b61c2b9f01e29580f0b1b240e7577 100644 (file)
@@ -128,7 +128,6 @@ leim-list.el: ${leimdir}/leim-list.el
 ${leimdir}/leim-list.el: ${srcdir}/leim-ext.el ${TIT_MISC}
        $(AM_V_GEN)rm -f $@
        $(AM_V_at)${RUN_EMACS} -l international/quail \
-         --eval "(setq max-specpdl-size 5000)" \
          --eval "(update-leim-list-file (unmsys--file-name \"${leimdir}\"))"
        $(AM_V_at)sed -n -e '/^[^;]/p' -e 's/^;\(;*\)inc /;\1 /p' < $< >> $@
 
@@ -139,7 +138,6 @@ ${leimdir}/ja-dic/ja-dic.el: | $(leimdir)/ja-dic
 generate-ja-dic: ${leimdir}/ja-dic/ja-dic.el
 ${leimdir}/ja-dic/ja-dic.el: $(srcdir)/SKK-DIC/SKK-JISYO.L
        $(AM_V_GEN)$(RUN_EMACS) -batch -l ja-dic-cnv \
-         --eval "(setq max-specpdl-size 5000)" \
          -f batch-skkdic-convert -dir "$(leimdir)/ja-dic" $(JA_DIC_NO_REDUCTION_OPTION) "$<"
 
 ${srcdir}/../lisp/language/pinyin.el: ${srcdir}/MISC-DIC/pinyin.map
index c73a623cce9d4f21db88c89a44e7a312c2af8977..bcf4a3146d4ee71e176544e7ddc13c71afef001c 100644 (file)
@@ -70,9 +70,7 @@ BYTE_COMPILE_FLAGS = \
   --eval "(setq load-prefer-newer t byte-compile-warnings 'all)" \
        $(BYTE_COMPILE_EXTRA_FLAGS)
 # ... but we must prefer .elc files for those in the early bootstrap.
-# A larger `max-specpdl-size' is needed for emacs-lisp/comp.el.
-compile-first: BYTE_COMPILE_FLAGS = \
-  --eval '(setq max-specpdl-size 5000)' $(BYTE_COMPILE_EXTRA_FLAGS)
+compile-first: BYTE_COMPILE_FLAGS = $(BYTE_COMPILE_EXTRA_FLAGS)
 
 # Files to compile before others during a bootstrap.  This is done to
 # speed up the bootstrap process.  They're ordered by size, so we use
@@ -342,8 +340,8 @@ compile-first: $(COMPILE_FIRST)
 
 .PHONY: compile-targets
 # TARGETS is set dynamically in the recursive call from 'compile-main'.
-# Do not build comp.el unless necessary not to exceed max-specpdl-size and
-# max-lisp-eval-depth in normal builds.
+# Do not build comp.el unless necessary not to exceed max-lisp-eval-depth
+# in normal builds.
 ifneq ($(HAVE_NATIVE_COMP),yes)
 compile-targets: $(filter-out ./emacs-lisp/comp-cstr.elc,$(filter-out ./emacs-lisp/comp.elc,$(TARGETS)))
 else
index 0e8ea42bedc9a62c3756e64557b0cd1dca55190b..758b92018439d1e6ace64f8a5d2d2cda2718aea1 100644 (file)
@@ -52,18 +52,14 @@ With a prefix, push that prefix as a number onto the stack."
        (calc-less-recursion-depth n)
      (let ((n (if n (prefix-numeric-value n) 2)))
        (if (> n 1)
-          (setq max-specpdl-size (* max-specpdl-size n)
-                max-lisp-eval-depth (* max-lisp-eval-depth n))))
+          (setq max-lisp-eval-depth (* max-lisp-eval-depth n))))
      (message "max-lisp-eval-depth is now %d" max-lisp-eval-depth))))
 
 (defun calc-less-recursion-depth (n)
   (interactive "P")
   (let ((n (if n (prefix-numeric-value n) 2)))
     (if (> n 1)
-       (setq max-specpdl-size
-             (max (/ max-specpdl-size n) 600)
-             max-lisp-eval-depth
-             (max (/ max-lisp-eval-depth n) 200))))
+       (setq max-lisp-eval-depth (max (/ max-lisp-eval-depth n) 200))))
   (message "max-lisp-eval-depth is now %d" max-lisp-eval-depth))
 
 
index 5077c8c8528dad70f72e729b48189b63d8e1ec53..c0f87ad3d4244fc0250b2c8ee8001b3d5f14e726 100644 (file)
@@ -1625,8 +1625,7 @@ See calc-keypad for details."
          (error
           (if (and (eq (car err) 'error)
                    (stringp (nth 1 err))
-                   (string-match "max-specpdl-size\\|max-lisp-eval-depth"
-                                 (nth 1 err)))
+                   (string-search "max-lisp-eval-depth" (nth 1 err)))
                (error (substitute-command-keys
                        "Computation got stuck or ran too long.  Type \\`M' to increase the limit"))
             (setq calc-aborted-prefix nil)
index ff9f991ff4a5749c44e09e906edcea62d3009ef3..40ff8fc86d3d7ce1661c4a5f138a25859a1a5816 100644 (file)
@@ -177,10 +177,9 @@ Lays claim to all -by.el, and -wy.el files."
 
 (cl-defmethod ede-proj-makefile-insert-rules :after ((this semantic-ede-proj-target-grammar))
     "Insert rules needed by THIS target.
-This raises `max-specpdl-size' and `max-lisp-eval-depth', which can be
-needed for the compilation of the resulting parsers."
-    (insert (format "%s: EMACSFLAGS+= --eval '(setq max-specpdl-size 1500 \
-max-lisp-eval-depth 700)'\n"
+This raises `max-lisp-eval-depth', which can be needed for the compilation
+of the resulting parsers."
+    (insert (format "%s: EMACSFLAGS+= --eval '(setq max-lisp-eval-depth 700)'\n"
                    (oref this name))))
 
 (cl-defmethod ede-proj-makefile-insert-dist-dependencies ((this semantic-ede-proj-target-grammar))
index 72037f471081b45fae9785f790a3c1a2df6ba4d8..8ba0e346fff1edd36028bded8a6a2db9be2fe1bb 100644 (file)
@@ -1009,7 +1009,6 @@ Return non-nil if there were no errors, nil if errors."
              packagename (byte-compile-dest-file packagename))
             (let (;; Some complex grammar table expressions need a few
                   ;; more resources than the default.
-                  (max-specpdl-size    (max 3000 max-specpdl-size))
                   (max-lisp-eval-depth (max 1000 max-lisp-eval-depth))
                   )
               ;; byte compile the resultant file
index 0e1cb4589da759ddb62a959d238c25f6398d2699..d7fb56c98543c28712a9f6740a90906bd9ea767e 100644 (file)
@@ -251,7 +251,6 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of
             ;; emacs.c
             (report-emacs-bug-address emacsbug string)
             ;; eval.c
-            (max-specpdl-size limits integer)
             (max-lisp-eval-depth limits integer)
             (max-mini-window-height limits
                                     (choice (const :tag "quarter screen" nil)
index a9087313b18cecc93cf4e1d19f2dcca4d6011611..35acbff9b17519c91abd71c1402fee3371ee9fd8 100644 (file)
@@ -4044,7 +4044,6 @@ the deferred compilation mechanism."
             (list "Not a function symbol or file" function-or-file)))
   (catch 'no-native-compile
     (let* ((print-symbols-bare t)
-           (max-specpdl-size (max max-specpdl-size 5000))
            (data function-or-file)
            (comp-native-compiling t)
            (byte-native-qualities nil)
index 31c05057bfaa842950a5da82dad5372a26a84f26..67704bdb51cb2b93684e54ea392b4c7a49f260e9 100644 (file)
@@ -129,7 +129,7 @@ contains an infinite loop.  When Edebug is instrumenting code
 containing very large quoted lists, it may reach this limit and give
 the error message \"Too deep - perhaps infinite loop in spec?\".
 Make this limit larger to countermand that, but you may also need to
-increase `max-lisp-eval-depth' and `max-specpdl-size'."
+increase `max-lisp-eval-depth'."
   :type 'integer
   :version "26.1")
 
@@ -1107,8 +1107,7 @@ purpose by adding an entry to this alist, and setting
        edebug-best-error
        edebug-error-point
        ;; Do this once here instead of several times.
-       (max-lisp-eval-depth (+ 800 max-lisp-eval-depth))
-       (max-specpdl-size (+ 2000 max-specpdl-size)))
+       (max-lisp-eval-depth (+ 800 max-lisp-eval-depth)))
     (let ((no-match
            (catch 'no-match
              (setq result (edebug-read-and-maybe-wrap-form1))
@@ -2317,7 +2316,6 @@ and run its entry function, and set up `edebug-before' and
               ;; but not inside an unwind-protect.
               ;; Doing it here also keeps it from growing too large.
               (max-lisp-eval-depth (+ 100 max-lisp-eval-depth)) ; too much??
-              (max-specpdl-size (+ 200 max-specpdl-size))
 
               (debugger edebug-debugger) ; only while edebug is active.
               (edebug-outside-debug-on-error debug-on-error)
index cae5dd00d1df11fb7a68dfcd59b5b191aa10dfc6..4d5a39458d2dfa26ceff5a93ea785b42989fbdee 100644 (file)
@@ -133,7 +133,6 @@ usually more efficient than that of a simplified version:
   (save-match-data
     ;; Recurse on the sorted list.
     (let* ((max-lisp-eval-depth 10000)
-          (max-specpdl-size 10000)
           (completion-ignore-case nil)
           (completion-regexp-list nil)
           (open (cond ((stringp paren) paren) (paren "\\(")))
index 69069183a3fd7a0774263e8726ecf1110526da0f..8f11e6f04a41f7e86b7f2fd8000a365f787d4b6b 100644 (file)
@@ -331,7 +331,6 @@ and the hook `eshell-exit-hook'."
   (setq-local require-final-newline nil)
 
   (setq-local max-lisp-eval-depth (max 3000 max-lisp-eval-depth))
-  (setq-local max-specpdl-size (max 6000 max-lisp-eval-depth))
 
   (setq-local eshell-last-input-start (point-marker))
   (setq-local eshell-last-input-end (point-marker))
index 634a33143610feb071676889596d281a5a556010..c01c827a75e05251422b54b7abd9acee29614c77 100644 (file)
 (load "language/indonesian")
 
 (load "indent")
-(let ((max-specpdl-size (max max-specpdl-size 1800)))
-  ;; A particularly demanding file to load; 1600 does not seem to be enough.
-  (load "emacs-lisp/cl-generic"))
+(load "emacs-lisp/cl-generic")
 (load "simple")
 (load "emacs-lisp/seq")
 (load "emacs-lisp/nadvice")
index 0ad934107d3bf8ab69595fa723286e38861bd86b..9a04d8909732c6e8fd72e1537cd79de68f578065 100644 (file)
@@ -2831,9 +2831,7 @@ removed and entries from `mh-invisible-header-fields' are added."
         (setq mh-invisible-header-fields-compiled
               (concat
                "^"
-               ;; workaround for insufficient default
-               (let ((max-specpdl-size 1000))
-                 (regexp-opt fields t))))
+               (regexp-opt fields t)))
       (setq mh-invisible-header-fields-compiled nil))))
 
 ;; Compile invisible header fields.
index 54ce9b1a41ce14dd89d338730f1b357e6244758a..d56420eb02e2218bb725f4388f801328f456fb54 100644 (file)
@@ -373,7 +373,6 @@ DOM should be a parse tree as generated by
                 shr-width
               (* shr-width (frame-char-width)))
            (shr--window-width)))
-        (max-specpdl-size max-specpdl-size)
         (shr--link-targets nil)
         (hscroll (window-hscroll))
         ;; `bidi-display-reordering' is supposed to be only used for
@@ -625,41 +624,34 @@ size, and full-buffer size."
        (shr-stylesheet shr-stylesheet)
        (shr-depth (1+ shr-depth))
        (start (point)))
-    ;; shr uses many frames per nested node.
-    (if (and (> shr-depth (/ max-specpdl-size 15))
-             (not (and shr-offer-extend-specpdl
-                       (y-or-n-p "Too deeply nested to render properly; increase `max-specpdl-size'?")
-                       (setq max-specpdl-size (* max-specpdl-size 2)))))
-        (setq shr-warning
-              "Not rendering the complete page because of too-deep nesting")
+    (when style
+      (if (string-match-p "color\\|display\\|border-collapse" style)
+         (setq shr-stylesheet (nconc (shr-parse-style style)
+                                     shr-stylesheet))
+       (setq style nil)))
+    ;; If we have a display:none, then just ignore this part of the DOM.
+    (unless (or (equal (cdr (assq 'display shr-stylesheet)) "none")
+                (and shr-discard-aria-hidden
+                     (equal (dom-attr dom 'aria-hidden) "true")))
+      ;; We don't use shr-indirect-call here, since shr-descend is
+      ;; the central bit of shr.el, and should be as fast as
+      ;; possible.  Having one more level of indirection with its
+      ;; negative effect on performance is deemed unjustified in
+      ;; this case.
+      (cond (external
+             (funcall external dom))
+            ((fboundp function)
+             (funcall function dom))
+            (t
+             (shr-generic dom)))
+      (when-let ((id (dom-attr dom 'id)))
+        (push (cons id (set-marker (make-marker) start)) shr--link-targets))
+      ;; If style is set, then this node has set the color.
       (when style
-       (if (string-match-p "color\\|display\\|border-collapse" style)
-           (setq shr-stylesheet (nconc (shr-parse-style style)
-                                       shr-stylesheet))
-         (setq style nil)))
-      ;; If we have a display:none, then just ignore this part of the DOM.
-      (unless (or (equal (cdr (assq 'display shr-stylesheet)) "none")
-                  (and shr-discard-aria-hidden
-                       (equal (dom-attr dom 'aria-hidden) "true")))
-        ;; We don't use shr-indirect-call here, since shr-descend is
-        ;; the central bit of shr.el, and should be as fast as
-        ;; possible.  Having one more level of indirection with its
-        ;; negative effect on performance is deemed unjustified in
-        ;; this case.
-        (cond (external
-               (funcall external dom))
-              ((fboundp function)
-               (funcall function dom))
-              (t
-               (shr-generic dom)))
-        (when-let ((id (dom-attr dom 'id)))
-          (push (cons id (set-marker (make-marker) start)) shr--link-targets))
-       ;; If style is set, then this node has set the color.
-       (when style
-         (shr-colorize-region
-          start (point)
-          (cdr (assq 'color shr-stylesheet))
-          (cdr (assq 'background-color shr-stylesheet))))))))
+       (shr-colorize-region
+        start (point)
+        (cdr (assq 'color shr-stylesheet))
+        (cdr (assq 'background-color shr-stylesheet)))))))
 
 (defun shr-fill-text (text)
   (if (zerop (length text))
index 58fb82b6ed0e42740dd3d68373dcc294c7d1ab0e..1a4b6dbeb114e178563d058a8eee8154c26b8c8a 100644 (file)
@@ -149,10 +149,9 @@ BITS must be of length nrings.  Start at START-TIME."
   (setq show-trailing-whitespace nil)
   (unwind-protect
       (let*
-         (;; These lines can cause Emacs to crash if you ask for too
-          ;; many rings.  If you uncomment them, on most systems you
+         (;; This line can cause Emacs to crash if you ask for too
+          ;; many rings.  If you uncomment it, on most systems you
           ;; can get 10,000+ rings.
-          ;;(max-specpdl-size (max max-specpdl-size (* nrings 15)))
           ;;(max-lisp-eval-depth (max max-lisp-eval-depth (+ nrings 20)))
           (vert (not hanoi-horizontal-flag))
           (pole-width (length (format "%d" (max 0 (1- nrings)))))
index 614ee60fa0312d3145508cdbfd35ff6555107125..c3704a05dbba93fc6cab132f904e320a2adb5c05 100644 (file)
@@ -3718,7 +3718,6 @@ This is part of `cperl-find-pods-heres' (below)."
           overshoot
           warning-message)))
 
-;; Debugging this may require (setq max-specpdl-size 2000)...
 (defun cperl-find-pods-heres (&optional min max non-inter end ignore-max end-of-here-doc)
   "Scan the buffer for hard-to-parse Perl constructions.
 If `cperl-pod-here-fontify' is non-nil after evaluation,
index d7cdc28abbad9b379b81aa17a8a461c48a85b733..59f9308f31e728068c737730563ac66cfec423c0 100644 (file)
@@ -1859,6 +1859,14 @@ be a list of the form returned by `event-start' and `event-end'."
 ;; in warnings when using `values' in let-bindings.
 ;;(make-obsolete-variable 'values "no longer used" "28.1")
 
+(defvar max-specpdl-size 2500
+  "Former limit on specbindings, now without effect.
+This variable used to limit the size of the specpdl stack which,
+among other things, holds dynamic variable bindings and `unwind-protect'
+activations.  To prevent runaway recursion, use `max-lisp-eval-depth'
+instead; it will indirectly limit the specpdl stack size as well.")
+(make-obsolete-variable 'max-specpdl-size nil "29.1")
+
 \f
 ;;;; Alternate names for functions - these are not being phased out.
 
index bd414fb86875cd58580aacdb16f4503d0ab25103..7da1d8fb98998da451ae3128055375667ae2ae64 100644 (file)
@@ -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.
 
index 6efea8ac369b914db147c441e986d610bac0506c..dd7f85ec97f5b16bc7fbed30c7f822545b37a8ca 100644 (file)
@@ -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;