diff options
| author | Gemini Lasswell | 2018-10-14 12:12:04 -0700 |
|---|---|---|
| committer | Gemini Lasswell | 2018-10-29 11:05:00 -0700 |
| commit | 0e484c66fd63877230c3dfa97f2ce9dda71ad88b (patch) | |
| tree | a7cf3670fdd67ce433329744c4e73f3b9214cd39 | |
| parent | b9c60200259a562f4762e8debf4646319d7a9332 (diff) | |
| download | emacs-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.c | 7 | ||||
| -rw-r--r-- | test/src/eval-tests.el | 30 |
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). | |||
| 2820 | usage: (funcall FUNCTION &rest ARGUMENTS) */) | 2820 | usage: (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. | ||
| 144 | Check that byte-compiled objects being executed by exec-byte-code | ||
| 145 | are 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 |