diff options
| author | Stefan Monnier | 2017-07-14 00:32:34 -0400 |
|---|---|---|
| committer | Noam Postavsky | 2017-08-07 18:54:49 -0400 |
| commit | cc30d77ecdd1b9155ade3d0656a84a0839ee2795 (patch) | |
| tree | a0b0c1180b8152284d10420d4189eb7cebdbc7d7 | |
| parent | 00f7e31110a27e568529192d7441d9631b9096bc (diff) | |
| download | emacs-cc30d77ecdd1b9155ade3d0656a84a0839ee2795.tar.gz emacs-cc30d77ecdd1b9155ade3d0656a84a0839ee2795.zip | |
Let `define-symbol-prop' take effect during compilation
* src/fns.c (syms_of_fns): New variable `overriding-plist-environment'.
(Fget): Consult it.
* lisp/emacs-lisp/bytecomp.el (byte-compile-close-variables): Let-bind
it to nil.
(byte-compile-define-symbol-prop): New function, handles compilation
of top-level `define-symbol-prop' and `function-put' calls by putting
the symbol setting into `overriding-plist-environment'.
Co-authored-by: Noam Postavsky <npostavs@gmail.com>
| -rw-r--r-- | lisp/emacs-lisp/bytecomp.el | 29 | ||||
| -rw-r--r-- | src/fns.c | 11 | ||||
| -rw-r--r-- | test/lisp/emacs-lisp/bytecomp-tests.el | 17 |
3 files changed, 57 insertions, 0 deletions
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 5fa7389e431..9e14c91c953 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el | |||
| @@ -1572,6 +1572,7 @@ extra args." | |||
| 1572 | ;; macroenvironment. | 1572 | ;; macroenvironment. |
| 1573 | (copy-alist byte-compile-initial-macro-environment)) | 1573 | (copy-alist byte-compile-initial-macro-environment)) |
| 1574 | (byte-compile--outbuffer nil) | 1574 | (byte-compile--outbuffer nil) |
| 1575 | (overriding-plist-environment nil) | ||
| 1575 | (byte-compile-function-environment nil) | 1576 | (byte-compile-function-environment nil) |
| 1576 | (byte-compile-bound-variables nil) | 1577 | (byte-compile-bound-variables nil) |
| 1577 | (byte-compile-lexical-variables nil) | 1578 | (byte-compile-lexical-variables nil) |
| @@ -4714,6 +4715,34 @@ binding slots have been popped." | |||
| 4714 | 'byte-hunk-handler 'byte-compile-form-make-variable-buffer-local) | 4715 | 'byte-hunk-handler 'byte-compile-form-make-variable-buffer-local) |
| 4715 | (defun byte-compile-form-make-variable-buffer-local (form) | 4716 | (defun byte-compile-form-make-variable-buffer-local (form) |
| 4716 | (byte-compile-keep-pending form 'byte-compile-normal-call)) | 4717 | (byte-compile-keep-pending form 'byte-compile-normal-call)) |
| 4718 | |||
| 4719 | (put 'function-put 'byte-hunk-handler 'byte-compile-define-symbol-prop) | ||
| 4720 | (put 'define-symbol-prop 'byte-hunk-handler 'byte-compile-define-symbol-prop) | ||
| 4721 | (defun byte-compile-define-symbol-prop (form) | ||
| 4722 | (pcase form | ||
| 4723 | ((and `(,op ,fun ,prop ,val) | ||
| 4724 | (guard (and (macroexp-const-p fun) | ||
| 4725 | (macroexp-const-p prop) | ||
| 4726 | (or (macroexp-const-p val) | ||
| 4727 | ;; Also accept anonymous functions, since | ||
| 4728 | ;; we're at top-level which implies they're | ||
| 4729 | ;; also constants. | ||
| 4730 | (pcase val (`(function (lambda . ,_)) t)))))) | ||
| 4731 | (byte-compile-push-constant op) | ||
| 4732 | (byte-compile-form fun) | ||
| 4733 | (byte-compile-form prop) | ||
| 4734 | (let* ((fun (eval fun)) | ||
| 4735 | (prop (eval prop)) | ||
| 4736 | (val (if (macroexp-const-p val) | ||
| 4737 | (eval val) | ||
| 4738 | (byte-compile-lambda (cadr val))))) | ||
| 4739 | (push `(,fun | ||
| 4740 | . (,prop ,val ,@(alist-get fun overriding-plist-environment))) | ||
| 4741 | overriding-plist-environment) | ||
| 4742 | (byte-compile-push-constant val) | ||
| 4743 | (byte-compile-out 'byte-call 3))) | ||
| 4744 | |||
| 4745 | (_ (byte-compile-keep-pending form)))) | ||
| 4717 | 4746 | ||
| 4718 | ;;; tags | 4747 | ;;; tags |
| 4719 | 4748 | ||
| @@ -1987,6 +1987,10 @@ This is the last value stored with `(put SYMBOL PROPNAME VALUE)'. */) | |||
| 1987 | (Lisp_Object symbol, Lisp_Object propname) | 1987 | (Lisp_Object symbol, Lisp_Object propname) |
| 1988 | { | 1988 | { |
| 1989 | CHECK_SYMBOL (symbol); | 1989 | CHECK_SYMBOL (symbol); |
| 1990 | Lisp_Object propval = Fplist_get (CDR (Fassq (symbol, Voverriding_plist_environment)), | ||
| 1991 | propname); | ||
| 1992 | if (!NILP (propval)) | ||
| 1993 | return propval; | ||
| 1990 | return Fplist_get (XSYMBOL (symbol)->plist, propname); | 1994 | return Fplist_get (XSYMBOL (symbol)->plist, propname); |
| 1991 | } | 1995 | } |
| 1992 | 1996 | ||
| @@ -5163,6 +5167,13 @@ syms_of_fns (void) | |||
| 5163 | DEFSYM (Qcursor_in_echo_area, "cursor-in-echo-area"); | 5167 | DEFSYM (Qcursor_in_echo_area, "cursor-in-echo-area"); |
| 5164 | DEFSYM (Qwidget_type, "widget-type"); | 5168 | DEFSYM (Qwidget_type, "widget-type"); |
| 5165 | 5169 | ||
| 5170 | DEFVAR_LISP ("overriding-plist-environment", Voverriding_plist_environment, | ||
| 5171 | doc: /* An alist overrides the plists of the symbols which it lists. | ||
| 5172 | Used by the byte-compiler to apply `define-symbol-prop' during | ||
| 5173 | compilation. */); | ||
| 5174 | Voverriding_plist_environment = Qnil; | ||
| 5175 | DEFSYM (Qoverriding_plist_environment, "overriding-plist-environment"); | ||
| 5176 | |||
| 5166 | staticpro (&string_char_byte_cache_string); | 5177 | staticpro (&string_char_byte_cache_string); |
| 5167 | string_char_byte_cache_string = Qnil; | 5178 | string_char_byte_cache_string = Qnil; |
| 5168 | 5179 | ||
diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el b/test/lisp/emacs-lisp/bytecomp-tests.el index d15bd8b6e65..8ef2ce70251 100644 --- a/test/lisp/emacs-lisp/bytecomp-tests.el +++ b/test/lisp/emacs-lisp/bytecomp-tests.el | |||
| @@ -545,6 +545,23 @@ literals (Bug#20852)." | |||
| 545 | This functionality has been obsolete for more than 10 years already | 545 | This functionality has been obsolete for more than 10 years already |
| 546 | and will be removed soon. See (elisp)Backquote in the manual."))))))) | 546 | and will be removed soon. See (elisp)Backquote in the manual."))))))) |
| 547 | 547 | ||
| 548 | |||
| 549 | (ert-deftest bytecomp-tests-function-put () | ||
| 550 | "Check `function-put' operates during compilation." | ||
| 551 | (should (boundp 'lread--old-style-backquotes)) | ||
| 552 | (bytecomp-tests--with-temp-file source | ||
| 553 | (dolist (form '((function-put 'bytecomp-tests--foo 'foo 1) | ||
| 554 | (function-put 'bytecomp-tests--foo 'bar 2) | ||
| 555 | (defmacro bytecomp-tests--foobar () | ||
| 556 | `(cons ,(function-get 'bytecomp-tests--foo 'foo) | ||
| 557 | ,(function-get 'bytecomp-tests--foo 'bar))) | ||
| 558 | (defvar bytecomp-tests--foobar 1) | ||
| 559 | (setq bytecomp-tests--foobar (bytecomp-tests--foobar)))) | ||
| 560 | (print form (current-buffer))) | ||
| 561 | (write-region (point-min) (point-max) source nil 'silent) | ||
| 562 | (byte-compile-file source t) | ||
| 563 | (should (equal bytecomp-tests--foobar (cons 1 2))))) | ||
| 564 | |||
| 548 | ;; Local Variables: | 565 | ;; Local Variables: |
| 549 | ;; no-byte-compile: t | 566 | ;; no-byte-compile: t |
| 550 | ;; End: | 567 | ;; End: |