summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/bytecomp.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emacs-lisp/bytecomp.el')
-rw-r--r--lisp/emacs-lisp/bytecomp.el76
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)