diff options
Diffstat (limited to 'lisp/emacs-lisp/bytecomp.el')
-rw-r--r-- | lisp/emacs-lisp/bytecomp.el | 76 |
1 files changed, 66 insertions, 10 deletions
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 13b72196565..9a5491b10fc 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -562,6 +562,29 @@ Each element is (INDEX . VALUE)") (defvar byte-compile-depth 0 "Current depth of execution stack.") (defvar byte-compile-maxdepth 0 "Maximum depth of execution stack.") +;; These are use by comp.el to spill data out of here +(cl-defstruct byte-to-native-function + "Named or anonymous function defined a top level." + name c-name data) +(cl-defstruct byte-to-native-top-level + "All other top level forms." + form) +(defvar byte-native-compiling nil + "Non nil while native compiling.") +(defvar byte-native-for-bootstrap nil + "Non nil while compiling for bootstrap." + ;; During boostrap we produce both the .eln and the .elc together. + ;; Because the make target is the later this has to be produced as + ;; last to be resilient against build interruptions. +) +(defvar byte-to-native-lap nil + "A-list to accumulate LAP. +Each pair is (NAME . LAP)") +(defvar byte-to-native-top-level-forms nil + "List of top level forms.") +(defvar byte-to-native-output-file nil + "Temporary file containing the byte-compilation output.") + ;;; The byte codes; this information is duplicated in bytecomp.c @@ -1071,6 +1094,8 @@ message buffer `default-directory'." (defvar byte-compile-current-file nil) (defvar byte-compile-current-group nil) (defvar byte-compile-current-buffer nil) +(defvar byte-compile-not-top-level nil ; We'll evolve this for naming lambdas + "Non nil if compiling something that is not top-level.") ;; Log something that isn't a warning. (defmacro byte-compile-log (format-string &rest args) @@ -2018,8 +2043,16 @@ The value is non-nil if there were no errors, nil if errors." ;; emacs-lisp files in the build tree are ;; recompiled). Previously this was accomplished by ;; deleting target-file before writing it. - (rename-file tempfile target-file t)) - (or noninteractive (message "Wrote %s" target-file))) + (if byte-native-compiling + (if byte-native-for-bootstrap + ;; Defer elc final renaming. + (setf byte-to-native-output-file + (cons tempfile target-file)) + (delete-file tempfile)) + (rename-file tempfile target-file t))) + (or noninteractive + byte-native-compiling + (message "Wrote %s" target-file))) ;; This is just to give a better error message than write-region (let ((exists (file-exists-p target-file))) (signal (if exists 'file-error 'file-missing) @@ -2193,6 +2226,10 @@ Call from the source buffer." ;; defalias calls are output directly by byte-compile-file-form-defmumble; ;; it does not pay to first build the defalias in defmumble and then parse ;; it here. + (when byte-native-compiling + ;; Spill output for the native compiler here + (push (make-byte-to-native-top-level :form form) + byte-to-native-top-level-forms)) (let ((print-escape-newlines t) (print-length nil) (print-level nil) @@ -2326,7 +2363,8 @@ list that represents a doc string reference. (defun byte-compile-flush-pending () (if byte-compile-output - (let ((form (byte-compile-out-toplevel t 'file))) + (let* ((byte-compile-current-form nil) + (form (byte-compile-out-toplevel t 'file))) (cond ((eq (car-safe form) 'progn) (mapc 'byte-compile-output-file-form (cdr form))) (form @@ -2646,6 +2684,13 @@ not to take responsibility for the actual compilation of the code." ;; If there's no doc string, provide -1 as the "doc string ;; index" so that no element will be treated as a doc string. (if (not (stringp (documentation code t))) -1 4))) + (when byte-native-compiling + ;; Spill output for the native compiler here. + (push (if macro + (make-byte-to-native-top-level + :form `(defalias ',name '(macro . ,code) nil)) + (make-byte-to-native-function :name name :data code)) + byte-to-native-top-level-forms)) ;; Output the form by hand, that's much simpler than having ;; b-c-output-file-form analyze the defalias. (byte-compile-output-docform @@ -2873,6 +2918,7 @@ for symbols generated by the byte compiler itself." ;; args of `list'. Actually, compile it to get warnings, ;; but don't use the result. (let* ((form (nth 1 int)) + (byte-compile-not-top-level t) (newform (byte-compile-top-level form))) (while (memq (car-safe form) '(let let* progn save-excursion)) (while (consp (cdr form)) @@ -3070,9 +3116,16 @@ for symbols generated by the byte compiler itself." (not (delq nil (mapcar 'consp (cdr (car body)))))))) (setq rest (cdr rest))) rest)) - (let ((byte-compile-vector (byte-compile-constants-vector))) - (list 'byte-code (byte-compile-lapcode byte-compile-output) - byte-compile-vector byte-compile-maxdepth))) + (let* ((byte-compile-vector (byte-compile-constants-vector)) + (out (list 'byte-code (byte-compile-lapcode byte-compile-output) + byte-compile-vector byte-compile-maxdepth))) + (when (and byte-native-compiling + (or (null byte-compile-not-top-level) + (eq byte-native-compiling 'free-func))) + ;; Spill LAP for the native compiler here + (push (cons byte-compile-current-form byte-compile-output) + byte-to-native-lap)) + out)) ;; it's a trivial function ((cdr body) (cons 'progn (nreverse body))) ((car body))))) @@ -3122,7 +3175,8 @@ for symbols generated by the byte compiler itself." ;; byte-compile--for-effect flag too.) ;; (defun byte-compile-form (form &optional for-effect) - (let ((byte-compile--for-effect for-effect)) + (let ((byte-compile--for-effect for-effect) + (byte-compile-not-top-level t)) (cond ((not (consp form)) (cond ((or (not (symbolp form)) (macroexp--const-symbol-p form)) @@ -3896,7 +3950,8 @@ discarding." ;; and (funcall (function foo)) will lose with autoloads. (defun byte-compile-function-form (form) - (let ((f (nth 1 form))) + (let ((f (nth 1 form)) + (byte-compile-not-top-level t)) (when (and (symbolp f) (byte-compile-warning-enabled-p 'callargs f)) (byte-compile-function-warn f t (byte-compile-fdefinition f nil))) @@ -5093,7 +5148,8 @@ Use with caution." (message "Can't find %s to refresh preloaded Lisp files" argv0) (dolist (f (reverse load-history)) (setq f (car f)) - (if (string-match "elc\\'" f) (setq f (substring f 0 -1))) + (when (string-match "el[cn]\\'" f) + (setq f (substring f 0 -1))) (when (and (file-readable-p f) (file-newer-than-file-p f emacs-file) ;; Don't reload the source version of the files below @@ -5102,7 +5158,7 @@ Use with caution." ;; so it can cause recompilation to fail. (not (member (file-name-nondirectory f) '("pcase.el" "bytecomp.el" "macroexp.el" - "cconv.el" "byte-opt.el")))) + "cconv.el" "byte-opt.el" "comp.el")))) (message "Reloading stale %s" (file-name-nondirectory f)) (condition-case nil (load f 'noerror nil 'nosuffix) |