diff options
| author | Daniel Colascione | 2014-04-21 02:34:21 -0700 |
|---|---|---|
| committer | Daniel Colascione | 2014-04-21 02:34:21 -0700 |
| commit | 985c035f2d4cf326a816fe463c400be96e358be2 (patch) | |
| tree | 8db28fe4100f4e5988824dcc956fd6a7088e98ae /lisp | |
| parent | 0c8d94555ce550d87afd6293bf5d17e864c13864 (diff) | |
| download | emacs-985c035f2d4cf326a816fe463c400be96e358be2.tar.gz emacs-985c035f2d4cf326a816fe463c400be96e358be2.zip | |
Correctly treat progn contents as toplevel forms when byte compiling
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ChangeLog | 6 | ||||
| -rw-r--r-- | lisp/emacs-lisp/bytecomp.el | 67 | ||||
| -rw-r--r-- | lisp/emacs-lisp/macroexp.el | 5 |
3 files changed, 54 insertions, 24 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index cb91bbcb4d9..3c5dc44010b 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,11 @@ | |||
| 1 | 2014-04-21 Daniel Colascione <dancol@dancol.org> | 1 | 2014-04-21 Daniel Colascione <dancol@dancol.org> |
| 2 | 2 | ||
| 3 | * emacs-lisp/bytecomp.el (byte-compile-recurse-toplevel): New | ||
| 4 | function. | ||
| 5 | (byte-compile-recurse-toplevel, | ||
| 6 | (byte-compile-initial-macro-environment, | ||
| 7 | (byte-compile-toplevel-file-form): Use it. | ||
| 8 | |||
| 3 | * emacs-lisp/cl-macs.el: | 9 | * emacs-lisp/cl-macs.el: |
| 4 | (cl--loop-let): Properly destructure `while' clauses. | 10 | (cl--loop-let): Properly destructure `while' clauses. |
| 5 | 11 | ||
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index e5f8a8cc22a..923d2067a49 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el | |||
| @@ -421,31 +421,46 @@ Filled in `cconv-analyse-form' but initialized and consulted here.") | |||
| 421 | 421 | ||
| 422 | (defvar byte-compiler-error-flag) | 422 | (defvar byte-compiler-error-flag) |
| 423 | 423 | ||
| 424 | (defun byte-compile-recurse-toplevel (form &optional non-toplevel-case) | ||
| 425 | "Implement `eval-when-compile' and `eval-and-compile'. | ||
| 426 | Return the compile-time value of FORM." | ||
| 427 | ;; Macroexpand (not macroexpand-all!) form at toplevel in case it | ||
| 428 | ;; expands into a toplevel-equivalent `progn'. See CLHS section | ||
| 429 | ;; 3.2.3.1, "Processing of Top Level Forms". The semantics are very | ||
| 430 | ;; subtle: see test/automated/bytecomp-tests.el for interesting | ||
| 431 | ;; cases. | ||
| 432 | (setf form (macroexpand form byte-compile-macro-environment)) | ||
| 433 | (if (eq (car-safe form) 'progn) | ||
| 434 | (cons 'progn | ||
| 435 | (mapcar (lambda (subform) | ||
| 436 | (byte-compile-recurse-toplevel | ||
| 437 | subform non-toplevel-case)) | ||
| 438 | (cdr form))) | ||
| 439 | (funcall non-toplevel-case form))) | ||
| 440 | |||
| 424 | (defconst byte-compile-initial-macro-environment | 441 | (defconst byte-compile-initial-macro-environment |
| 425 | '( | 442 | '( |
| 426 | ;; (byte-compiler-options . (lambda (&rest forms) | 443 | ;; (byte-compiler-options . (lambda (&rest forms) |
| 427 | ;; (apply 'byte-compiler-options-handler forms))) | 444 | ;; (apply 'byte-compiler-options-handler forms))) |
| 428 | (declare-function . byte-compile-macroexpand-declare-function) | 445 | (declare-function . byte-compile-macroexpand-declare-function) |
| 429 | (eval-when-compile . (lambda (&rest body) | 446 | (eval-when-compile . (lambda (&rest body) |
| 430 | (list | 447 | (let ((result nil)) |
| 431 | 'quote | 448 | (byte-compile-recurse-toplevel |
| 432 | (byte-compile-eval | 449 | (cons 'progn body) |
| 433 | (byte-compile-top-level | 450 | (lambda (form) |
| 434 | (byte-compile-preprocess (cons 'progn body))))))) | 451 | (setf result |
| 452 | (byte-compile-eval | ||
| 453 | (byte-compile-top-level | ||
| 454 | (byte-compile-preprocess form)))))) | ||
| 455 | (list 'quote result)))) | ||
| 435 | (eval-and-compile . (lambda (&rest body) | 456 | (eval-and-compile . (lambda (&rest body) |
| 436 | ;; Byte compile before running it. Do it piece by | 457 | (byte-compile-recurse-toplevel |
| 437 | ;; piece, in case further expressions need earlier | 458 | (cons 'progn body) |
| 438 | ;; ones to be evaluated already, as is the case in | 459 | (lambda (form) |
| 439 | ;; eieio.el. | 460 | (let ((compiled (byte-compile-top-level |
| 440 | `(progn | 461 | (byte-compile-preprocess form)))) |
| 441 | ,@(mapcar (lambda (exp) | 462 | (eval compiled) |
| 442 | (let ((cexp | 463 | compiled)))))) |
| 443 | (byte-compile-top-level | ||
| 444 | (byte-compile-preprocess | ||
| 445 | exp)))) | ||
| 446 | (eval cexp) | ||
| 447 | cexp)) | ||
| 448 | body))))) | ||
| 449 | "The default macro-environment passed to macroexpand by the compiler. | 464 | "The default macro-environment passed to macroexpand by the compiler. |
| 450 | Placing a macro here will cause a macro to have different semantics when | 465 | Placing a macro here will cause a macro to have different semantics when |
| 451 | expanded by the compiler as when expanded by the interpreter.") | 466 | expanded by the compiler as when expanded by the interpreter.") |
| @@ -2198,9 +2213,12 @@ list that represents a doc string reference. | |||
| 2198 | (t form))) | 2213 | (t form))) |
| 2199 | 2214 | ||
| 2200 | ;; byte-hunk-handlers cannot call this! | 2215 | ;; byte-hunk-handlers cannot call this! |
| 2201 | (defun byte-compile-toplevel-file-form (form) | 2216 | (defun byte-compile-toplevel-file-form (top-level-form) |
| 2202 | (let ((byte-compile-current-form nil)) ; close over this for warnings. | 2217 | (byte-compile-recurse-toplevel |
| 2203 | (byte-compile-file-form (byte-compile-preprocess form t)))) | 2218 | top-level-form |
| 2219 | (lambda (form) | ||
| 2220 | (let ((byte-compile-current-form nil)) ; close over this for warnings. | ||
| 2221 | (byte-compile-file-form (byte-compile-preprocess form t)))))) | ||
| 2204 | 2222 | ||
| 2205 | ;; byte-hunk-handlers can call this. | 2223 | ;; byte-hunk-handlers can call this. |
| 2206 | (defun byte-compile-file-form (form) | 2224 | (defun byte-compile-file-form (form) |
| @@ -2942,8 +2960,11 @@ for symbols generated by the byte compiler itself." | |||
| 2942 | interactive-only)) | 2960 | interactive-only)) |
| 2943 | (t ".")))) | 2961 | (t ".")))) |
| 2944 | (if (eq (car-safe (symbol-function (car form))) 'macro) | 2962 | (if (eq (car-safe (symbol-function (car form))) 'macro) |
| 2945 | (byte-compile-log-warning | 2963 | (progn |
| 2946 | (format "Forgot to expand macro %s" (car form)) nil :error)) | 2964 | (debug) |
| 2965 | (byte-compile-log-warning | ||
| 2966 | (format "Forgot to expand macro %s in %S" (car form) form) | ||
| 2967 | nil :error))) | ||
| 2947 | (if (and handler | 2968 | (if (and handler |
| 2948 | ;; Make sure that function exists. | 2969 | ;; Make sure that function exists. |
| 2949 | (and (functionp handler) | 2970 | (and (functionp handler) |
diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index e3a746fa69e..c2bfc891b72 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el | |||
| @@ -97,7 +97,10 @@ each clause." | |||
| 97 | (defun macroexp--compiler-macro (handler form) | 97 | (defun macroexp--compiler-macro (handler form) |
| 98 | (condition-case err | 98 | (condition-case err |
| 99 | (apply handler form (cdr form)) | 99 | (apply handler form (cdr form)) |
| 100 | (error (message "Compiler-macro error for %S: %S" (car form) err) | 100 | (error |
| 101 | (message "--------------------------------------------------") | ||
| 102 | (backtrace) | ||
| 103 | (message "Compiler-macro error for %S: %S" (car form) err) | ||
| 101 | form))) | 104 | form))) |
| 102 | 105 | ||
| 103 | (defun macroexp--funcall-if-compiled (_form) | 106 | (defun macroexp--funcall-if-compiled (_form) |