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.
This commit is contained in:
parent
b9c6020025
commit
0e484c66fd
2 changed files with 35 additions and 2 deletions
|
@ -2820,8 +2820,11 @@ Thus, (funcall \\='cons \\='x \\='y) returns (x . y).
|
|||
usage: (funcall FUNCTION &rest ARGUMENTS) */)
|
||||
(ptrdiff_t nargs, Lisp_Object *args)
|
||||
{
|
||||
Lisp_Object fun, original_fun;
|
||||
Lisp_Object funcar;
|
||||
/* Use 'volatile' here to cause optimizing compilers to keep a
|
||||
reference on the stack to the function's bytecode object. See
|
||||
Bug#33014. */
|
||||
Lisp_Object volatile fun;
|
||||
Lisp_Object original_fun, funcar;
|
||||
ptrdiff_t numargs = nargs - 1;
|
||||
Lisp_Object val;
|
||||
ptrdiff_t count;
|
||||
|
|
|
@ -139,4 +139,34 @@ crash/abort/malloc assert failure on the next test."
|
|||
(defvaralias 'eval-tests--foo-alias 'eval-tests--foo)
|
||||
'no-warning)))))
|
||||
|
||||
(ert-deftest eval-tests-byte-code-being-evaluated-is-protected-from-gc ()
|
||||
"Regression test for Bug#33014.
|
||||
Check that byte-compiled objects being executed by exec-byte-code
|
||||
are found on the stack and therefore not garbage collected."
|
||||
(should (string= (eval-tests-33014-func)
|
||||
"before after: ok foo: (e) bar: (a b c d e) baz: a bop: c")))
|
||||
|
||||
(defvar eval-tests-33014-var "ok")
|
||||
(defun eval-tests-33014-func ()
|
||||
"A function which has a non-trivial constants vector when byte-compiled."
|
||||
(let ((result "before "))
|
||||
(eval-tests-33014-redefine)
|
||||
(garbage-collect)
|
||||
(setq result (concat result (format "after: %s" eval-tests-33014-var)))
|
||||
(let ((vals '(0 1 2 3))
|
||||
(things '(a b c d e)))
|
||||
(dolist (val vals)
|
||||
(setq result
|
||||
(concat result " "
|
||||
(cond
|
||||
((= val 0) (format "foo: %s" (last things)))
|
||||
((= val 1) (format "bar: %s" things))
|
||||
((= val 2) (format "baz: %s" (car things)))
|
||||
(t (format "bop: %s" (nth 2 things))))))))
|
||||
result))
|
||||
|
||||
(defun eval-tests-33014-redefine ()
|
||||
"Remove the Lisp reference to the byte-compiled object."
|
||||
(setf (symbol-function #'eval-tests-33014-func) nil))
|
||||
|
||||
;;; eval-tests.el ends here
|
||||
|
|
Loading…
Add table
Reference in a new issue