aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2012-09-04 13:40:25 -0400
committerStefan Monnier2012-09-04 13:40:25 -0400
commit972debf2e7381b4fd2c70f9c1fd585d8bd137917 (patch)
tree6e9da9768df8fc4e29ce881a6b64e91806a7a564
parent1088b9226e7dac7314dab52ef0696a5f540900cd (diff)
downloademacs-972debf2e7381b4fd2c70f9c1fd585d8bd137917.tar.gz
emacs-972debf2e7381b4fd2c70f9c1fd585d8bd137917.zip
Macro-expand interpreted code during load.
* src/lread.c (readevalloop): Call internal-macroexpand-for-load to perform eager (load-time) macro-expansion. * src/lisp.mk (lisp): Add macroexp. * lisp/loadup.el: Load macroexp. Remove hack. * lisp/emacs-lisp/macroexp.el (macroexp--eval-if-compile): New function. (macroexp--expand-all): Use it to get better warnings. (macroexp--backtrace, macroexp--trim-backtrace-frame) (internal-macroexpand-for-load): New functions. (macroexp--pending-eager-loads): New var. (emacs-startup-hook): New hack to replace one in loadup.el. * lisp/emacs-lisp/cl-macs.el (cl--compiler-macro-list*) (cl--compiler-macro-cXXr): Move to top, before they can be used. (cl-psetf): Simplify. (cl-defstruct): Add indent rule.
-rw-r--r--etc/NEWS7
-rw-r--r--lisp/ChangeLog24
-rw-r--r--lisp/emacs-lisp/cl-loaddefs.el28
-rw-r--r--lisp/emacs-lisp/cl-macs.el56
-rw-r--r--lisp/emacs-lisp/macroexp.el110
-rw-r--r--lisp/emacs-lisp/pcase.el2
-rw-r--r--lisp/loadup.el28
-rw-r--r--src/ChangeLog6
-rw-r--r--src/lisp.mk1
-rw-r--r--src/lread.c13
10 files changed, 206 insertions, 69 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 16e078fa639..e4a612f6a9e 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -601,6 +601,13 @@ are deprecated and will be removed eventually.
601 601
602* Lisp changes in Emacs 24.3 602* Lisp changes in Emacs 24.3
603 603
604** Interpreted files get eagerly macro-expanded during load.
605This can significantly speed up execution of non-byte-compiled code, but can
606also bump into harmless and previously unnoticed cyclic dependencies.
607These should not be fatal: they will simply cause the macro-calls to be left
608for later expansion (as before), but will also result in a warning describing
609the cycle.
610
604** New minor mode `read-only-mode' to replace toggle-read-only (now obsolete). 611** New minor mode `read-only-mode' to replace toggle-read-only (now obsolete).
605 612
606** New functions `autoloadp' and `autoload-do-load'. 613** New functions `autoloadp' and `autoload-do-load'.
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 4707834fe6b..64dda45276c 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,17 @@
12012-09-04 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * loadup.el: Load macroexp. Remove hack.
4 * emacs-lisp/macroexp.el (macroexp--eval-if-compile): New function.
5 (macroexp--expand-all): Use it to get better warnings.
6 (macroexp--backtrace, macroexp--trim-backtrace-frame)
7 (internal-macroexpand-for-load): New functions.
8 (macroexp--pending-eager-loads): New var.
9 (emacs-startup-hook): New hack to replace one in loadup.el.
10 * emacs-lisp/cl-macs.el (cl--compiler-macro-list*)
11 (cl--compiler-macro-cXXr): Move to top, before they can be used.
12 (cl-psetf): Simplify.
13 (cl-defstruct): Add indent rule.
14
12012-09-04 Lars Ingebrigtsen <larsi@gnus.org> 152012-09-04 Lars Ingebrigtsen <larsi@gnus.org>
2 16
3 * mail/smtpmail.el (smtpmail-send-it): Prefer the From: header 17 * mail/smtpmail.el (smtpmail-send-it): Prefer the From: header
@@ -21,10 +35,8 @@
21 (temp-buffer-window-show-hook): New hooks. 35 (temp-buffer-window-show-hook): New hooks.
22 (temp-buffer-window-setup, temp-buffer-window-show) 36 (temp-buffer-window-setup, temp-buffer-window-show)
23 (with-temp-buffer-window): New functions. 37 (with-temp-buffer-window): New functions.
24 (fit-window-to-buffer): Remove unused optional argument 38 (fit-window-to-buffer): Remove unused optional argument OVERRIDE.
25 OVERRIDE. 39 (special-display-popup-frame): Make sure the window used shows BUFFER.
26 (special-display-popup-frame): Make sure the window used shows
27 BUFFER.
28 40
29 * help.el (temp-buffer-resize-mode): Fix doc-string. 41 * help.el (temp-buffer-resize-mode): Fix doc-string.
30 (resize-temp-buffer-window): New optional argument WINDOW. 42 (resize-temp-buffer-window): New optional argument WINDOW.
@@ -166,8 +178,8 @@
1662012-08-29 Michael Albinus <michael.albinus@gmx.de> 1782012-08-29 Michael Albinus <michael.albinus@gmx.de>
167 179
168 * eshell/esh-ext.el (eshell-external-command): Do not examine 180 * eshell/esh-ext.el (eshell-external-command): Do not examine
169 remote shell scripts. See 181 remote shell scripts.
170 <https://bugs.launchpad.net/ubuntu/+source/emacs23/+bug/1035790>. 182 See <https://bugs.launchpad.net/ubuntu/+source/emacs23/+bug/1035790>.
171 183
172 * net/tramp-sh.el (tramp-remote-path): Add "/sbin" and 184 * net/tramp-sh.el (tramp-remote-path): Add "/sbin" and
173 "/usr/local/sbin". 185 "/usr/local/sbin".
diff --git a/lisp/emacs-lisp/cl-loaddefs.el b/lisp/emacs-lisp/cl-loaddefs.el
index 470ca17d3a0..7d70d22c9cd 100644
--- a/lisp/emacs-lisp/cl-loaddefs.el
+++ b/lisp/emacs-lisp/cl-loaddefs.el
@@ -249,8 +249,7 @@ Remove from SYMBOL's plist the property PROPNAME and its value.
249 249
250;;;*** 250;;;***
251 251
252;;;### (autoloads (cl--compiler-macro-cXXr cl--compiler-macro-list* 252;;;### (autoloads (cl--compiler-macro-adjoin cl-defsubst cl-compiler-macroexpand
253;;;;;; cl--compiler-macro-adjoin cl-defsubst cl-compiler-macroexpand
254;;;;;; cl-define-compiler-macro cl-assert cl-check-type cl-typep 253;;;;;; cl-define-compiler-macro cl-assert cl-check-type cl-typep
255;;;;;; cl-deftype cl-defstruct cl-callf2 cl-callf cl-letf* cl-letf 254;;;;;; cl-deftype cl-defstruct cl-callf2 cl-callf cl-letf* cl-letf
256;;;;;; cl-rotatef cl-shiftf cl-remf cl-psetf cl-declare cl-the cl-locally 255;;;;;; cl-rotatef cl-shiftf cl-remf cl-psetf cl-declare cl-the cl-locally
@@ -260,9 +259,20 @@ Remove from SYMBOL's plist the property PROPNAME and its value.
260;;;;;; cl-do cl-loop cl-return-from cl-return cl-block cl-etypecase 259;;;;;; cl-do cl-loop cl-return-from cl-return cl-block cl-etypecase
261;;;;;; cl-typecase cl-ecase cl-case cl-load-time-value cl-eval-when 260;;;;;; cl-typecase cl-ecase cl-case cl-load-time-value cl-eval-when
262;;;;;; cl-destructuring-bind cl-function cl-defmacro cl-defun cl-gentemp 261;;;;;; cl-destructuring-bind cl-function cl-defmacro cl-defun cl-gentemp
263;;;;;; cl-gensym) "cl-macs" "cl-macs.el" "9676d5517e8b9246c09fe78984c68bef") 262;;;;;; cl-gensym cl--compiler-macro-cXXr cl--compiler-macro-list*)
263;;;;;; "cl-macs" "cl-macs.el" "e09b4be5072a8b52d40af6e073876e76")
264;;; Generated autoloads from cl-macs.el 264;;; Generated autoloads from cl-macs.el
265 265
266(autoload 'cl--compiler-macro-list* "cl-macs" "\
267
268
269\(fn FORM ARG &rest OTHERS)" nil nil)
270
271(autoload 'cl--compiler-macro-cXXr "cl-macs" "\
272
273
274\(fn FORM X)" nil nil)
275
266(autoload 'cl-gensym "cl-macs" "\ 276(autoload 'cl-gensym "cl-macs" "\
267Generate a new uninterned symbol. 277Generate a new uninterned symbol.
268The name is made by appending a number to PREFIX, default \"G\". 278The name is made by appending a number to PREFIX, default \"G\".
@@ -659,6 +669,8 @@ value, that slot cannot be set via `setf'.
659 669
660(put 'cl-defstruct 'doc-string-elt '2) 670(put 'cl-defstruct 'doc-string-elt '2)
661 671
672(put 'cl-defstruct 'lisp-indent-function '1)
673
662(autoload 'cl-deftype "cl-macs" "\ 674(autoload 'cl-deftype "cl-macs" "\
663Define NAME as a new data type. 675Define NAME as a new data type.
664The type name can then be used in `cl-typecase', `cl-check-type', etc. 676The type name can then be used in `cl-typecase', `cl-check-type', etc.
@@ -722,16 +734,6 @@ surrounded by (cl-block NAME ...).
722 734
723\(fn FORM A LIST &rest KEYS)" nil nil) 735\(fn FORM A LIST &rest KEYS)" nil nil)
724 736
725(autoload 'cl--compiler-macro-list* "cl-macs" "\
726
727
728\(fn FORM ARG &rest OTHERS)" nil nil)
729
730(autoload 'cl--compiler-macro-cXXr "cl-macs" "\
731
732
733\(fn FORM X)" nil nil)
734
735;;;*** 737;;;***
736 738
737;;;### (autoloads (cl-tree-equal cl-nsublis cl-sublis cl-nsubst-if-not 739;;;### (autoloads (cl-tree-equal cl-nsublis cl-sublis cl-nsubst-if-not
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 9a59aa0c6db..aba412cc8f5 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -58,6 +58,33 @@
58 58
59;;; Initialization. 59;;; Initialization.
60 60
61;; Place compiler macros at the beginning, otherwise uses of the corresponding
62;; functions can lead to recursive-loads that prevent the calls from
63;; being optimized.
64
65;;;###autoload
66(defun cl--compiler-macro-list* (_form arg &rest others)
67 (let* ((args (reverse (cons arg others)))
68 (form (car args)))
69 (while (setq args (cdr args))
70 (setq form `(cons ,(car args) ,form)))
71 form))
72
73;;;###autoload
74(defun cl--compiler-macro-cXXr (form x)
75 (let* ((head (car form))
76 (n (symbol-name (car form)))
77 (i (- (length n) 2)))
78 (if (not (string-match "c[ad]+r\\'" n))
79 (if (and (fboundp head) (symbolp (symbol-function head)))
80 (cl--compiler-macro-cXXr (cons (symbol-function head) (cdr form))
81 x)
82 (error "Compiler macro for cXXr applied to non-cXXr form"))
83 (while (> i (match-beginning 0))
84 (setq x (list (if (eq (aref n i) ?a) 'car 'cdr) x))
85 (setq i (1- i)))
86 x)))
87
61;;; Some predicates for analyzing Lisp forms. 88;;; Some predicates for analyzing Lisp forms.
62;; These are used by various 89;; These are used by various
63;; macro expanders to optimize the results in certain common cases. 90;; macro expanders to optimize the results in certain common cases.
@@ -1905,8 +1932,6 @@ See Info node `(cl)Declarations' for details."
1905 (cl-do-proclaim (pop specs) nil))) 1932 (cl-do-proclaim (pop specs) nil)))
1906 nil) 1933 nil)
1907 1934
1908
1909
1910;;; The standard modify macros. 1935;;; The standard modify macros.
1911 1936
1912;; `setf' is now part of core Elisp, defined in gv.el. 1937;; `setf' is now part of core Elisp, defined in gv.el.
@@ -1929,7 +1954,7 @@ before assigning any PLACEs to the corresponding values.
1929 (or p (error "Odd number of arguments to cl-psetf")) 1954 (or p (error "Odd number of arguments to cl-psetf"))
1930 (pop p)) 1955 (pop p))
1931 (if simple 1956 (if simple
1932 `(progn (setf ,@args) nil) 1957 `(progn (setq ,@args) nil)
1933 (setq args (reverse args)) 1958 (setq args (reverse args))
1934 (let ((expr `(setf ,(cadr args) ,(car args)))) 1959 (let ((expr `(setf ,(cadr args) ,(car args))))
1935 (while (setq args (cddr args)) 1960 (while (setq args (cddr args))
@@ -2119,7 +2144,7 @@ one keyword is supported, `:read-only'. If this has a non-nil
2119value, that slot cannot be set via `setf'. 2144value, that slot cannot be set via `setf'.
2120 2145
2121\(fn NAME SLOTS...)" 2146\(fn NAME SLOTS...)"
2122 (declare (doc-string 2) 2147 (declare (doc-string 2) (indent 1)
2123 (debug 2148 (debug
2124 (&define ;Makes top-level form not be wrapped. 2149 (&define ;Makes top-level form not be wrapped.
2125 [&or symbolp 2150 [&or symbolp
@@ -2597,14 +2622,6 @@ surrounded by (cl-block NAME ...).
2597 `(if (cl-member ,a ,list ,@keys) ,list (cons ,a ,list)) 2622 `(if (cl-member ,a ,list ,@keys) ,list (cons ,a ,list))
2598 form)) 2623 form))
2599 2624
2600;;;###autoload
2601(defun cl--compiler-macro-list* (_form arg &rest others)
2602 (let* ((args (reverse (cons arg others)))
2603 (form (car args)))
2604 (while (setq args (cdr args))
2605 (setq form `(cons ,(car args) ,form)))
2606 form))
2607
2608(defun cl--compiler-macro-get (_form sym prop &optional def) 2625(defun cl--compiler-macro-get (_form sym prop &optional def)
2609 (if def 2626 (if def
2610 `(cl-getf (symbol-plist ,sym) ,prop ,def) 2627 `(cl-getf (symbol-plist ,sym) ,prop ,def)
@@ -2616,21 +2633,6 @@ surrounded by (cl-block NAME ...).
2616 (cl--make-type-test temp (cl--const-expr-val type))) 2633 (cl--make-type-test temp (cl--const-expr-val type)))
2617 form)) 2634 form))
2618 2635
2619;;;###autoload
2620(defun cl--compiler-macro-cXXr (form x)
2621 (let* ((head (car form))
2622 (n (symbol-name (car form)))
2623 (i (- (length n) 2)))
2624 (if (not (string-match "c[ad]+r\\'" n))
2625 (if (and (fboundp head) (symbolp (symbol-function head)))
2626 (cl--compiler-macro-cXXr (cons (symbol-function head) (cdr form))
2627 x)
2628 (error "Compiler macro for cXXr applied to non-cXXr form"))
2629 (while (> i (match-beginning 0))
2630 (setq x (list (if (eq (aref n i) ?a) 'car 'cdr) x))
2631 (setq i (1- i)))
2632 x)))
2633
2634(dolist (y '(cl-first cl-second cl-third cl-fourth 2636(dolist (y '(cl-first cl-second cl-third cl-fourth
2635 cl-fifth cl-sixth cl-seventh 2637 cl-fifth cl-sixth cl-seventh
2636 cl-eighth cl-ninth cl-tenth 2638 cl-eighth cl-ninth cl-tenth
diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index 70eab149837..394225d697e 100644
--- a/lisp/emacs-lisp/macroexp.el
+++ b/lisp/emacs-lisp/macroexp.el
@@ -100,6 +100,17 @@ each clause."
100 (error (message "Compiler-macro error for %S: %S" (car form) err) 100 (error (message "Compiler-macro error for %S: %S" (car form) err)
101 form))) 101 form)))
102 102
103(defun macroexp--eval-if-compile (&rest _forms)
104 "Pseudo function used internally by macroexp to delay warnings.
105The purpose is to delay warnings to bytecomp.el, so they can use things
106like `byte-compile-log-warning' to get better file-and-line-number data
107and also to avoid outputting the warning during normal execution."
108 nil)
109(put 'macroexp--eval-if-compile 'byte-compile
110 (lambda (form)
111 (mapc (lambda (x) (funcall (eval x))) (cdr form))
112 (byte-compile-constant nil)))
113
103(defun macroexp--expand-all (form) 114(defun macroexp--expand-all (form)
104 "Expand all macros in FORM. 115 "Expand all macros in FORM.
105This is an internal version of `macroexpand-all'. 116This is an internal version of `macroexpand-all'.
@@ -112,14 +123,17 @@ Assumes the caller has bound `macroexpand-all-environment'."
112 (macroexpand (macroexp--all-forms form 1) 123 (macroexpand (macroexp--all-forms form 1)
113 macroexpand-all-environment) 124 macroexpand-all-environment)
114 ;; Normal form; get its expansion, and then expand arguments. 125 ;; Normal form; get its expansion, and then expand arguments.
115 (let ((new-form (macroexpand form macroexpand-all-environment))) 126 (let ((new-form
116 (when (and (not (eq form new-form)) ;It was a macro call. 127 (macroexpand form macroexpand-all-environment)))
117 (car-safe form) 128 (setq form
118 (symbolp (car form)) 129 (if (and (not (eq form new-form)) ;It was a macro call.
119 (get (car form) 'byte-obsolete-info) 130 (car-safe form)
120 (fboundp 'byte-compile-warn-obsolete)) 131 (symbolp (car form))
121 (byte-compile-warn-obsolete (car form))) 132 (get (car form) 'byte-obsolete-info))
122 (setq form new-form)) 133 `(progn (macroexp--eval-if-compile
134 (lambda () (byte-compile-warn-obsolete ',(car form))))
135 ,new-form)
136 new-form)))
123 (pcase form 137 (pcase form
124 (`(cond . ,clauses) 138 (`(cond . ,clauses)
125 (macroexp--cons 'cond (macroexp--all-clauses clauses) form)) 139 (macroexp--cons 'cond (macroexp--all-clauses clauses) form))
@@ -323,6 +337,86 @@ symbol itself."
323 "Return non-nil if EXP can be copied without extra cost." 337 "Return non-nil if EXP can be copied without extra cost."
324 (or (symbolp exp) (macroexp-const-p exp))) 338 (or (symbolp exp) (macroexp-const-p exp)))
325 339
340;;; Load-time macro-expansion.
341
342;; Because macro-expansion used to be more lazy, eager macro-expansion
343;; tends to bump into previously harmless/unnoticeable cyclic-dependencies.
344;; So, we have to delay macro-expansion like we used to when we detect
345;; such a cycle, and we also want to help coders resolve those cycles (since
346;; they can be non-obvious) by providing a usefully trimmed backtrace
347;; (hopefully) highlighting the problem.
348
349(defun macroexp--backtrace ()
350 "Return the Elisp backtrace, more recent frames first."
351 (let ((bt ())
352 (i 0))
353 (while
354 (let ((frame (backtrace-frame i)))
355 (when frame
356 (push frame bt)
357 (setq i (1+ i)))))
358 (nreverse bt)))
359
360(defun macroexp--trim-backtrace-frame (frame)
361 (pcase frame
362 (`(,_ macroexpand (,head . ,_) . ,_) `(macroexpand (,head …)))
363 (`(,_ internal-macroexpand-for-load (,head ,second . ,_) . ,_)
364 (if (or (symbolp second)
365 (and (eq 'quote (car-safe second))
366 (symbolp (cadr second))))
367 `(macroexpand-all (,head ,second …))
368 '(macroexpand-all …)))
369 (`(,_ load-with-code-conversion ,name . ,_)
370 `(load ,(file-name-nondirectory name)))))
371
372(defvar macroexp--pending-eager-loads nil
373 "Stack of files currently undergoing eager macro-expansion.")
374
375(defun internal-macroexpand-for-load (form)
376 ;; Called from the eager-macroexpansion in readevalloop.
377 (cond
378 ;; Don't repeat the same warning for every top-level element.
379 ((eq 'skip (car macroexp--pending-eager-loads)) form)
380 ;; If we detect a cycle, skip macro-expansion for now, and output a warning
381 ;; with a trimmed backtrace.
382 ((and load-file-name (member load-file-name macroexp--pending-eager-loads))
383 (let* ((bt (delq nil
384 (mapcar #'macroexp--trim-backtrace-frame
385 (macroexp--backtrace))))
386 (elem `(load ,(file-name-nondirectory load-file-name)))
387 (tail (member elem (cdr (member elem bt)))))
388 (if tail (setcdr tail (list '…)))
389 (if (eq (car-safe (car bt)) 'macroexpand-all) (setq bt (cdr bt)))
390 (message "Warning: Eager macro-expansion skipped due to cycle:\n %s"
391 (mapconcat #'prin1-to-string (nreverse bt) " => "))
392 (push 'skip macroexp--pending-eager-loads)
393 form))
394 (t
395 (condition-case err
396 (let ((macroexp--pending-eager-loads
397 (cons load-file-name macroexp--pending-eager-loads)))
398 (macroexpand-all form))
399 (error
400 ;; Hopefully this shouldn't happen thanks to the cycle detection,
401 ;; but in case it does happen, let's catch the error and give the
402 ;; code a chance to macro-expand later.
403 (message "Eager macro-expansion failure: %S" err)
404 form)))))
405
406;; ¡¡¡ Big Ugly Hack !!!
407;; src/bootstrap-emacs is mostly used to compile .el files, so it needs
408;; macroexp, bytecomp, cconv, and byte-opt to be fast. Generally this is done
409;; by compiling those files first, but this only makes a difference if those
410;; files are not preloaded. But macroexp.el is preloaded so we reload it if
411;; the current version is interpreted and there's a compiled version available.
412(eval-when-compile
413 (add-hook 'emacs-startup-hook
414 (lambda ()
415 (and (not (byte-code-function-p
416 (symbol-function 'macroexpand-all)))
417 (locate-library "macroexp.elc")
418 (load "macroexp.elc")))))
419
326(provide 'macroexp) 420(provide 'macroexp)
327 421
328;;; macroexp.el ends here 422;;; macroexp.el ends here
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index 4aeed7e4d0e..09e47b69b91 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -60,6 +60,8 @@
60;; is in a loop, the repeated macro-expansion becomes terribly costly, so we 60;; is in a loop, the repeated macro-expansion becomes terribly costly, so we
61;; memoize previous macro expansions to try and avoid recomputing them 61;; memoize previous macro expansions to try and avoid recomputing them
62;; over and over again. 62;; over and over again.
63;; FIXME: Now that macroexpansion is also performed when loading an interpreted
64;; file, this is not a real problem any more.
63(defconst pcase--memoize (make-hash-table :weakness 'key :test 'eq)) 65(defconst pcase--memoize (make-hash-table :weakness 'key :test 'eq))
64;; (defconst pcase--memoize-1 (make-hash-table :test 'eq)) 66;; (defconst pcase--memoize-1 (make-hash-table :test 'eq))
65;; (defconst pcase--memoize-2 (make-hash-table :weakness 'key :test 'equal)) 67;; (defconst pcase--memoize-2 (make-hash-table :weakness 'key :test 'equal))
diff --git a/lisp/loadup.el b/lisp/loadup.el
index a460fcab339..d389427bafd 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -102,6 +102,19 @@
102(setq load-source-file-function 'load-with-code-conversion) 102(setq load-source-file-function 'load-with-code-conversion)
103(load "files") 103(load "files")
104 104
105;; Load-time macro-expansion can only take effect after setting
106;; load-source-file-function because of where it is called in lread.c.
107(load "emacs-lisp/macroexp")
108(if (byte-code-function-p (symbol-function 'macroexpand-all))
109 nil
110 ;; Since loaddefs is not yet loaded, macroexp's uses of pcase will simply
111 ;; fail until pcase is explicitly loaded. This also means that we have to
112 ;; disable eager macro-expansion while loading pcase.
113 (let ((macroexp--pending-eager-loads '(skip)))
114 (load "emacs-lisp/pcase"))
115 ;; Re-load macroexp so as to eagerly macro-expand its uses of pcase.
116 (load "emacs-lisp/macroexp"))
117
105(load "cus-face") 118(load "cus-face")
106(load "faces") ; after here, `defface' may be used. 119(load "faces") ; after here, `defface' may be used.
107 120
@@ -266,21 +279,6 @@
266;For other systems, you must edit ../src/Makefile.in. 279;For other systems, you must edit ../src/Makefile.in.
267(load "site-load" t) 280(load "site-load" t)
268 281
269;; ¡¡¡ Big Ugly Hack !!!
270;; src/bootstrap-emacs is mostly used to compile .el files, so it needs
271;; macroexp, bytecomp, cconv, and byte-opt to be fast. Generally this is done
272;; by compiling those files first, but this only makes a difference if those
273;; files are not preloaded. As it so happens, macroexp.el tends to be
274;; accidentally preloaded in src/bootstrap-emacs because cl.el and cl-macs.el
275;; require it. So let's unload it here, if needed, to make sure the
276;; byte-compiled version is used.
277(if (or (not (fboundp 'macroexpand-all))
278 (byte-code-function-p (symbol-function 'macroexpand-all)))
279 nil
280 (fmakunbound 'macroexpand-all)
281 (setq features (delq 'macroexp features))
282 (autoload 'macroexpand-all "macroexp"))
283
284;; Determine which last version number to use 282;; Determine which last version number to use
285;; based on the executables that now exist. 283;; based on the executables that now exist.
286(if (and (or (equal (nth 3 command-line-args) "dump") 284(if (and (or (equal (nth 3 command-line-args) "dump")
diff --git a/src/ChangeLog b/src/ChangeLog
index 1dd307b16de..b2634c4fdc4 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
12012-09-04 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * lread.c (readevalloop): Call internal-macroexpand-for-load to perform
4 eager (load-time) macro-expansion.
5 * lisp.mk (lisp): Add macroexp.
6
12012-09-04 Paul Eggert <eggert@cs.ucla.edu> 72012-09-04 Paul Eggert <eggert@cs.ucla.edu>
2 8
3 Simplify redefinition of 'abort' (Bug#12316). 9 Simplify redefinition of 'abort' (Bug#12316).
diff --git a/src/lisp.mk b/src/lisp.mk
index 162d8819917..3d60e07dea3 100644
--- a/src/lisp.mk
+++ b/src/lisp.mk
@@ -65,6 +65,7 @@ lisp = \
65 $(lispsource)/format.elc \ 65 $(lispsource)/format.elc \
66 $(lispsource)/bindings.elc \ 66 $(lispsource)/bindings.elc \
67 $(lispsource)/files.elc \ 67 $(lispsource)/files.elc \
68 $(lispsource)/emacs-lisp/macroexp.elc \
68 $(lispsource)/cus-face.elc \ 69 $(lispsource)/cus-face.elc \
69 $(lispsource)/faces.elc \ 70 $(lispsource)/faces.elc \
70 $(lispsource)/button.elc \ 71 $(lispsource)/button.elc \
diff --git a/src/lread.c b/src/lread.c
index c15c8da3f7b..4f3a93b16b4 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1680,6 +1680,17 @@ readevalloop (Lisp_Object readcharfun,
1680 int whole_buffer = 0; 1680 int whole_buffer = 0;
1681 /* 1 on the first time around. */ 1681 /* 1 on the first time around. */
1682 int first_sexp = 1; 1682 int first_sexp = 1;
1683 Lisp_Object macroexpand = intern ("internal-macroexpand-for-load");
1684
1685 if (NILP (Ffboundp (macroexpand))
1686 /* Don't macroexpand in .elc files, since it should have been done
1687 already. We actually don't know whether we're in a .elc file or not,
1688 so we use circumstancial evidence: .el files normally go through
1689 Vload_source_file_function -> load-with-code-conversion
1690 -> eval-buffer. */
1691 || EQ (readcharfun, Qget_file_char)
1692 || EQ (readcharfun, Qget_emacs_mule_file_char))
1693 macroexpand = Qnil;
1683 1694
1684 if (MARKERP (readcharfun)) 1695 if (MARKERP (readcharfun))
1685 { 1696 {
@@ -1809,6 +1820,8 @@ readevalloop (Lisp_Object readcharfun,
1809 unbind_to (count1, Qnil); 1820 unbind_to (count1, Qnil);
1810 1821
1811 /* Now eval what we just read. */ 1822 /* Now eval what we just read. */
1823 if (!NILP (macroexpand))
1824 val = call1 (macroexpand, val);
1812 val = eval_sub (val); 1825 val = eval_sub (val);
1813 1826
1814 if (printflag) 1827 if (printflag)