Function: comp--native-compile

comp--native-compile is a byte-compiled function defined in comp.el.gz.

Signature

(comp--native-compile FUNCTION-OR-FILE &optional WITH-LATE-LOAD OUTPUT)

Documentation

Compile FUNCTION-OR-FILE into native code.

When WITH-LATE-LOAD is non-nil, mark the compilation unit for late load once it finishes compiling. This serves as internal implementation of native-compile but allowing for WITH-LATE-LOAD to be controlled is in use also for the deferred compilation mechanism.

Source Code

;; Defined in /usr/src/emacs/lisp/emacs-lisp/comp.el.gz
(defun comp--native-compile (function-or-file &optional with-late-load output)
  "Compile FUNCTION-OR-FILE into native code.
When WITH-LATE-LOAD is non-nil, mark the compilation unit for late
load once it finishes compiling.
This serves as internal implementation of `native-compile' but
allowing for WITH-LATE-LOAD to be controlled is in use also for
the deferred compilation mechanism."
  (comp-ensure-native-compiler)
  (unless (or (functionp function-or-file)
              (stringp function-or-file))
    (signal 'native-compiler-error
            (list "Not a function symbol or file" function-or-file)))
  (when (or (null comp-no-spawn) comp-async-compilation)
    (catch 'no-native-compile
      (let* ((print-symbols-bare t)
             (data function-or-file)
             (comp-native-compiling t)
             (byte-native-qualities nil)
             (symbols-with-pos-enabled t)
             ;; Have byte compiler signal an error when compilation fails.
             (byte-compile-debug t)
             (comp-ctxt (make-comp-ctxt :output (when output
                                                  (expand-file-name output))
                                        :with-late-load with-late-load)))
        (comp-log "\n\n" 1)
        (unwind-protect
            (progn
              (condition-case-unless-debug err
                  (cl-loop
                   with report = nil
                   for t0 = (current-time)
                   for pass in comp-passes
                   unless (memq pass comp-disabled-passes)
                   do
                   (comp-log (format "\n(%S) Running pass %s:\n"
                                     function-or-file pass)
                             2)
                   (setf data (funcall pass data))
                   (push (cons pass (float-time (time-since t0))) report)
                   (cl-loop for f in (alist-get pass comp-post-pass-hooks)
                            do (funcall f data))
                   finally
                   (when comp-log-time-report
                     (comp-log (format "Done compiling %S" data) 0)
                     (cl-loop for (pass . time) in (reverse report)
                              do (comp-log (format "Pass %s took: %fs."
                                                   pass time)
                                           0))))
                (t
                 (let ((err-val (cdr err)))
                   ;; If we are doing an async native compilation print the
                   ;; error in the correct format so is parsable and abort.
                   (if (and comp-async-compilation
                            (not (eq (car err) 'native-compiler-error)))
                       (progn
                         (message "%S: Error %s"
                                  function-or-file
                                  (error-message-string err))
                         (kill-emacs -1))
                     ;; Otherwise re-signal it adding the compilation input.
                     ;; FIXME: We can't just insert arbitrary info in the
                     ;; error-data part of an error: the handler may expect
                     ;; specific data at specific positions!
                     (signal (car err) (if (consp err-val)
                                           (cons function-or-file err-val)
                                         ;; FIXME: `err-val' is supposed to be
                                         ;; a list, so it can only be nil here!
                                         (list function-or-file err-val)))))))
              (if (stringp function-or-file)
                  data
                ;; So we return the compiled function.
                (native-elisp-load data)))
          (when (and (not (stringp function-or-file))
                     (not output)
                     comp-ctxt
                     (comp-ctxt-output comp-ctxt)
                     (file-exists-p (comp-ctxt-output comp-ctxt)))
            ;; NOTE: Not sure if we want to remove this or being cautious.
            (cond ((eq 'windows-nt system-type)
                   ;; We may still be using the temporary .eln file.
                   (ignore-errors (delete-file (comp-ctxt-output comp-ctxt))))
                  (t (delete-file (comp-ctxt-output comp-ctxt))))))))))