aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGemini Lasswell2018-10-14 12:12:04 -0700
committerGemini Lasswell2018-10-29 11:05:00 -0700
commit0e484c66fd63877230c3dfa97f2ce9dda71ad88b (patch)
treea7cf3670fdd67ce433329744c4e73f3b9214cd39
parentb9c60200259a562f4762e8debf4646319d7a9332 (diff)
downloademacs-0e484c66fd63877230c3dfa97f2ce9dda71ad88b.tar.gz
emacs-0e484c66fd63877230c3dfa97f2ce9dda71ad88b.zip
Keep a stack reference to bytecode objects being executed (Bug#33014)
* src/eval.c (Ffuncall): Make local variable 'fun' volatile. * test/src/eval-tests.el (eval-tests-byte-code-being-evaluated-is-protected-from-gc): Add regression test for Bug#33014. (eval-tests-33014-var): New variable. (eval-tests-33014-func, eval-tests-33014-redefine): New functions.
-rw-r--r--src/eval.c7
-rw-r--r--test/src/eval-tests.el30
2 files changed, 35 insertions, 2 deletions
diff --git a/src/eval.c b/src/eval.c
index a51d0c90831..32cfda24d8c 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2820,8 +2820,11 @@ Thus, (funcall \\='cons \\='x \\='y) returns (x . y).
2820usage: (funcall FUNCTION &rest ARGUMENTS) */) 2820usage: (funcall FUNCTION &rest ARGUMENTS) */)
2821 (ptrdiff_t nargs, Lisp_Object *args) 2821 (ptrdiff_t nargs, Lisp_Object *args)
2822{ 2822{
2823 Lisp_Object fun, original_fun; 2823 /* Use 'volatile' here to cause optimizing compilers to keep a
2824 Lisp_Object funcar; 2824 reference on the stack to the function's bytecode object. See
2825 Bug#33014. */
2826 Lisp_Object volatile fun;
2827 Lisp_Object original_fun, funcar;
2825 ptrdiff_t numargs = nargs - 1; 2828 ptrdiff_t numargs = nargs - 1;
2826 Lisp_Object val; 2829 Lisp_Object val;
2827 ptrdiff_t count; 2830 ptrdiff_t count;
diff --git a/test/src/eval-tests.el b/test/src/eval-tests.el
index 281d959b530..0c242913e7a 100644
--- a/test/src/eval-tests.el
+++ b/test/src/eval-tests.el
@@ -139,4 +139,34 @@ crash/abort/malloc assert failure on the next test."
139 (defvaralias 'eval-tests--foo-alias 'eval-tests--foo) 139 (defvaralias 'eval-tests--foo-alias 'eval-tests--foo)
140 'no-warning))))) 140 'no-warning)))))
141 141
142(ert-deftest eval-tests-byte-code-being-evaluated-is-protected-from-gc ()
143 "Regression test for Bug#33014.
144Check that byte-compiled objects being executed by exec-byte-code
145are found on the stack and therefore not garbage collected."
146 (should (string= (eval-tests-33014-func)
147 "before after: ok foo: (e) bar: (a b c d e) baz: a bop: c")))
148
149(defvar eval-tests-33014-var "ok")
150(defun eval-tests-33014-func ()
151 "A function which has a non-trivial constants vector when byte-compiled."
152 (let ((result "before "))
153 (eval-tests-33014-redefine)
154 (garbage-collect)
155 (setq result (concat result (format "after: %s" eval-tests-33014-var)))
156 (let ((vals '(0 1 2 3))
157 (things '(a b c d e)))
158 (dolist (val vals)
159 (setq result
160 (concat result " "
161 (cond
162 ((= val 0) (format "foo: %s" (last things)))
163 ((= val 1) (format "bar: %s" things))
164 ((= val 2) (format "baz: %s" (car things)))
165 (t (format "bop: %s" (nth 2 things))))))))
166 result))
167
168(defun eval-tests-33014-redefine ()
169 "Remove the Lisp reference to the byte-compiled object."
170 (setf (symbol-function #'eval-tests-33014-func) nil))
171
142;;; eval-tests.el ends here 172;;; eval-tests.el ends here