diff options
| author | Stefan Monnier | 2015-05-13 18:39:49 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2015-05-13 18:39:49 -0400 |
| commit | 37ab2245f27d83f0faa3c0d9277088433bc4efaf (patch) | |
| tree | ca0330d08da78d52d07d3f715316bc57cd6bba41 | |
| parent | 8d69f38a94fd1584a1ee6fc33f39c8f1ff9eaf59 (diff) | |
| download | emacs-37ab2245f27d83f0faa3c0d9277088433bc4efaf.tar.gz emacs-37ab2245f27d83f0faa3c0d9277088433bc4efaf.zip | |
* lisp/loadup.el ("emacs-lisp/cl-generic"): Preload
* src/lisp.mk (lisp): Add emacs-lisp/cl-generic.elc.
* lisp/emacs-lisp/cl-generic.el (cl-generic-define-method):
Avoid defalias for closures which are not immutable.
(cl--generic-prefill-dispatchers): New macro. Use it to prefill the
dispatchers table with various entries.
* lisp/emacs-lisp/ert.el (emacs-lisp-mode-hook):
* lisp/emacs-lisp/seq.el (emacs-lisp-mode-hook): Use add-hook.
| -rw-r--r-- | lisp/emacs-lisp/cl-generic.el | 50 | ||||
| -rw-r--r-- | lisp/emacs-lisp/ert.el | 4 | ||||
| -rw-r--r-- | lisp/emacs-lisp/seq.el | 2 | ||||
| -rw-r--r-- | lisp/loadup.el | 1 | ||||
| -rw-r--r-- | src/lisp.mk | 1 |
5 files changed, 43 insertions, 15 deletions
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index f6595d3035b..a2716ef87ee 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el | |||
| @@ -438,7 +438,16 @@ which case this method will be invoked when the argument is `eql' to VAL. | |||
| 438 | ;; the generic function. | 438 | ;; the generic function. |
| 439 | current-load-list) | 439 | current-load-list) |
| 440 | ;; For aliases, cl--generic-name gives us the actual name. | 440 | ;; For aliases, cl--generic-name gives us the actual name. |
| 441 | (defalias (cl--generic-name generic) gfun)))) | 441 | (funcall |
| 442 | (if purify-flag | ||
| 443 | ;; BEWARE! Don't purify this function definition, since that leads | ||
| 444 | ;; to memory corruption if the hash-tables it holds are modified | ||
| 445 | ;; (the GC doesn't trace those pointers). | ||
| 446 | #'fset | ||
| 447 | ;; But do use `defalias' in the normal case, so that it interacts | ||
| 448 | ;; properly with nadvice, e.g. for tracing/debug-on-entry. | ||
| 449 | #'defalias) | ||
| 450 | (cl--generic-name generic) gfun)))) | ||
| 442 | 451 | ||
| 443 | (defmacro cl--generic-with-memoization (place &rest code) | 452 | (defmacro cl--generic-with-memoization (place &rest code) |
| 444 | (declare (indent 1) (debug t)) | 453 | (declare (indent 1) (debug t)) |
| @@ -696,6 +705,25 @@ methods.") | |||
| 696 | (if (eq specializer t) (list cl--generic-t-generalizer) | 705 | (if (eq specializer t) (list cl--generic-t-generalizer) |
| 697 | (error "Unknown specializer %S" specializer))) | 706 | (error "Unknown specializer %S" specializer))) |
| 698 | 707 | ||
| 708 | (defmacro cl--generic-prefill-dispatchers (arg-or-context specializer) | ||
| 709 | (unless (integerp arg-or-context) | ||
| 710 | (setq arg-or-context `(&context . ,arg-or-context))) | ||
| 711 | (unless (fboundp 'cl--generic-get-dispatcher) | ||
| 712 | (require 'cl-generic)) | ||
| 713 | (let ((fun (cl--generic-get-dispatcher | ||
| 714 | `(,arg-or-context ,@(cl-generic-generalizers specializer) | ||
| 715 | ,cl--generic-t-generalizer)))) | ||
| 716 | ;; Recompute dispatch at run-time, since the generalizers may be slightly | ||
| 717 | ;; different (e.g. byte-compiled rather than interpreted). | ||
| 718 | ;; FIXME: There is a risk that the run-time generalizer is not equivalent | ||
| 719 | ;; to the compile-time one, in which case `fun' may not be correct | ||
| 720 | ;; any more! | ||
| 721 | `(let ((dispatch `(,',arg-or-context | ||
| 722 | ,@(cl-generic-generalizers ',specializer) | ||
| 723 | ,cl--generic-t-generalizer))) | ||
| 724 | ;; (message "Prefilling for %S with \n%S" dispatch ',fun) | ||
| 725 | (puthash dispatch ',fun cl--generic-dispatchers)))) | ||
| 726 | |||
| 699 | (cl-defmethod cl-generic-combine-methods (generic methods) | 727 | (cl-defmethod cl-generic-combine-methods (generic methods) |
| 700 | "Standard support for :after, :before, :around, and `:extra NAME' qualifiers." | 728 | "Standard support for :after, :before, :around, and `:extra NAME' qualifiers." |
| 701 | (cl--generic-standard-method-combination generic methods)) | 729 | (cl--generic-standard-method-combination generic methods)) |
| @@ -869,17 +897,6 @@ Can only be used from within the lexical body of a primary or around method." | |||
| 869 | 80 (lambda (name) `(gethash (car-safe ,name) cl--generic-head-used)) | 897 | 80 (lambda (name) `(gethash (car-safe ,name) cl--generic-head-used)) |
| 870 | (lambda (tag) (if (eq (car-safe tag) 'head) (list tag))))) | 898 | (lambda (tag) (if (eq (car-safe tag) 'head) (list tag))))) |
| 871 | 899 | ||
| 872 | ;; Pre-fill the cl--generic-dispatchers table. | ||
| 873 | ;; We have two copies of `(0 ...)' but we can't share them via `let' because | ||
| 874 | ;; they're not used at the same time (one is compile-time, one is run-time). | ||
| 875 | (puthash `(0 ,cl--generic-head-generalizer ,cl--generic-t-generalizer) | ||
| 876 | (eval-when-compile | ||
| 877 | (unless (fboundp 'cl--generic-get-dispatcher) | ||
| 878 | (require 'cl-generic)) | ||
| 879 | (cl--generic-get-dispatcher | ||
| 880 | `(0 ,cl--generic-head-generalizer ,cl--generic-t-generalizer))) | ||
| 881 | cl--generic-dispatchers) | ||
| 882 | |||
| 883 | (cl-defmethod cl-generic-generalizers :extra "head" (specializer) | 900 | (cl-defmethod cl-generic-generalizers :extra "head" (specializer) |
| 884 | "Support for the `(head VAL)' specializers." | 901 | "Support for the `(head VAL)' specializers." |
| 885 | ;; We have to implement `head' here using the :extra qualifier, | 902 | ;; We have to implement `head' here using the :extra qualifier, |
| @@ -890,6 +907,8 @@ Can only be used from within the lexical body of a primary or around method." | |||
| 890 | (gethash (cadr specializer) cl--generic-head-used) specializer) | 907 | (gethash (cadr specializer) cl--generic-head-used) specializer) |
| 891 | (list cl--generic-head-generalizer))) | 908 | (list cl--generic-head-generalizer))) |
| 892 | 909 | ||
| 910 | (cl--generic-prefill-dispatchers 0 (head eql)) | ||
| 911 | |||
| 893 | ;;; Support for (eql <val>) specializers. | 912 | ;;; Support for (eql <val>) specializers. |
| 894 | 913 | ||
| 895 | (defvar cl--generic-eql-used (make-hash-table :test #'eql)) | 914 | (defvar cl--generic-eql-used (make-hash-table :test #'eql)) |
| @@ -904,6 +923,9 @@ Can only be used from within the lexical body of a primary or around method." | |||
| 904 | (puthash (cadr specializer) specializer cl--generic-eql-used) | 923 | (puthash (cadr specializer) specializer cl--generic-eql-used) |
| 905 | (list cl--generic-eql-generalizer)) | 924 | (list cl--generic-eql-generalizer)) |
| 906 | 925 | ||
| 926 | (cl--generic-prefill-dispatchers 0 (eql nil)) | ||
| 927 | (cl--generic-prefill-dispatchers window-system (eql nil)) | ||
| 928 | |||
| 907 | ;;; Support for cl-defstructs specializers. | 929 | ;;; Support for cl-defstructs specializers. |
| 908 | 930 | ||
| 909 | (defun cl--generic-struct-tag (name) | 931 | (defun cl--generic-struct-tag (name) |
| @@ -960,6 +982,8 @@ Can only be used from within the lexical body of a primary or around method." | |||
| 960 | (list cl--generic-struct-generalizer)))) | 982 | (list cl--generic-struct-generalizer)))) |
| 961 | (cl-call-next-method))) | 983 | (cl-call-next-method))) |
| 962 | 984 | ||
| 985 | (cl--generic-prefill-dispatchers 0 cl--generic-generalizer) | ||
| 986 | |||
| 963 | ;;; Dispatch on "system types". | 987 | ;;; Dispatch on "system types". |
| 964 | 988 | ||
| 965 | (defconst cl--generic-typeof-types | 989 | (defconst cl--generic-typeof-types |
| @@ -998,6 +1022,8 @@ Can only be used from within the lexical body of a primary or around method." | |||
| 998 | (list cl--generic-typeof-generalizer))) | 1022 | (list cl--generic-typeof-generalizer))) |
| 999 | (cl-call-next-method))) | 1023 | (cl-call-next-method))) |
| 1000 | 1024 | ||
| 1025 | (cl--generic-prefill-dispatchers 0 integer) | ||
| 1026 | |||
| 1001 | ;; Local variables: | 1027 | ;; Local variables: |
| 1002 | ;; generated-autoload-file: "cl-loaddefs.el" | 1028 | ;; generated-autoload-file: "cl-loaddefs.el" |
| 1003 | ;; End: | 1029 | ;; End: |
diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index 8dc8261365f..b678e122c11 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el | |||
| @@ -2537,7 +2537,7 @@ To be used in the ERT results buffer." | |||
| 2537 | (add-to-list 'minor-mode-alist '(ert--current-run-stats | 2537 | (add-to-list 'minor-mode-alist '(ert--current-run-stats |
| 2538 | (:eval | 2538 | (:eval |
| 2539 | (ert--tests-running-mode-line-indicator)))) | 2539 | (ert--tests-running-mode-line-indicator)))) |
| 2540 | (add-to-list 'emacs-lisp-mode-hook 'ert--activate-font-lock-keywords) | 2540 | (add-hook 'emacs-lisp-mode-hook #'ert--activate-font-lock-keywords) |
| 2541 | 2541 | ||
| 2542 | (defun ert--unload-function () | 2542 | (defun ert--unload-function () |
| 2543 | "Unload function to undo the side-effects of loading ert.el." | 2543 | "Unload function to undo the side-effects of loading ert.el." |
| @@ -2548,7 +2548,7 @@ To be used in the ERT results buffer." | |||
| 2548 | nil) | 2548 | nil) |
| 2549 | 2549 | ||
| 2550 | (defvar ert-unload-hook '()) | 2550 | (defvar ert-unload-hook '()) |
| 2551 | (add-hook 'ert-unload-hook 'ert--unload-function) | 2551 | (add-hook 'ert-unload-hook #'ert--unload-function) |
| 2552 | 2552 | ||
| 2553 | 2553 | ||
| 2554 | (provide 'ert) | 2554 | (provide 'ert) |
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 5553de658b2..0aa0f095969 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el | |||
| @@ -442,7 +442,7 @@ If no element is found, return nil." | |||
| 442 | (unless (fboundp 'elisp--font-lock-flush-elisp-buffers) | 442 | (unless (fboundp 'elisp--font-lock-flush-elisp-buffers) |
| 443 | ;; In Emacs≥25, (via elisp--font-lock-flush-elisp-buffers and a few others) | 443 | ;; In Emacs≥25, (via elisp--font-lock-flush-elisp-buffers and a few others) |
| 444 | ;; we automatically highlight macros. | 444 | ;; we automatically highlight macros. |
| 445 | (add-to-list 'emacs-lisp-mode-hook #'seq--activate-font-lock-keywords)) | 445 | (add-hook 'emacs-lisp-mode-hook #'seq--activate-font-lock-keywords)) |
| 446 | 446 | ||
| 447 | (provide 'seq) | 447 | (provide 'seq) |
| 448 | ;;; seq.el ends here | 448 | ;;; seq.el ends here |
diff --git a/lisp/loadup.el b/lisp/loadup.el index 0746f95c1b9..828b19e85e3 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el | |||
| @@ -193,6 +193,7 @@ | |||
| 193 | (load "language/cham") | 193 | (load "language/cham") |
| 194 | 194 | ||
| 195 | (load "indent") | 195 | (load "indent") |
| 196 | (load "emacs-lisp/cl-generic") | ||
| 196 | (load "frame") | 197 | (load "frame") |
| 197 | (load "startup") | 198 | (load "startup") |
| 198 | (load "term/tty-colors") | 199 | (load "term/tty-colors") |
diff --git a/src/lisp.mk b/src/lisp.mk index ee2a07c0fd7..8eb86b7429e 100644 --- a/src/lisp.mk +++ b/src/lisp.mk | |||
| @@ -113,6 +113,7 @@ lisp = \ | |||
| 113 | $(lispsource)/language/cham.elc \ | 113 | $(lispsource)/language/cham.elc \ |
| 114 | $(lispsource)/indent.elc \ | 114 | $(lispsource)/indent.elc \ |
| 115 | $(lispsource)/window.elc \ | 115 | $(lispsource)/window.elc \ |
| 116 | $(lispsource)/emacs-lisp/cl-generic.elc \ | ||
| 116 | $(lispsource)/frame.elc \ | 117 | $(lispsource)/frame.elc \ |
| 117 | $(lispsource)/term/tty-colors.elc \ | 118 | $(lispsource)/term/tty-colors.elc \ |
| 118 | $(lispsource)/font-core.elc \ | 119 | $(lispsource)/font-core.elc \ |