;;; bytecomp.el --- compilation of Lisp code into byte code.
-;;; Copyright (C) 1985, 1986, 1987, 1992, 1994 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1986, 1987, 1992, 1994 Free Software Foundation, Inc.
;; Author: Jamie Zawinski <jwz@lucid.com>
;; Hallvard Furuseth <hbf@ulrik.uio.no>
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
;;; Commentary:
;;; Code:
-;;; ========================================================================
-;;; Entry points:
-;;; byte-recompile-directory, byte-compile-file,
-;;; batch-byte-compile, batch-byte-recompile-directory,
-;;; byte-compile, compile-defun,
-;;; display-call-tree
-;;; (byte-compile-buffer and byte-compile-and-load-file were turned off
-;;; because they are not terribly useful and get in the way of completion.)
-
-;;; This version of the byte compiler has the following improvements:
-;;; + optimization of compiled code:
-;;; - removal of unreachable code;
-;;; - removal of calls to side-effectless functions whose return-value
-;;; is unused;
-;;; - compile-time evaluation of safe constant forms, such as (consp nil)
-;;; and (ash 1 6);
-;;; - open-coding of literal lambdas;
-;;; - peephole optimization of emitted code;
-;;; - trivial functions are left uncompiled for speed.
-;;; + support for inline functions;
-;;; + compile-time evaluation of arbitrary expressions;
-;;; + compile-time warning messages for:
-;;; - functions being redefined with incompatible arglists;
-;;; - functions being redefined as macros, or vice-versa;
-;;; - functions or macros defined multiple times in the same file;
-;;; - functions being called with the incorrect number of arguments;
-;;; - functions being called which are not defined globally, in the
-;;; file, or as autoloads;
-;;; - assignment and reference of undeclared free variables;
-;;; - various syntax errors;
-;;; + correct compilation of nested defuns, defmacros, defvars and defsubsts;
-;;; + correct compilation of top-level uses of macros;
-;;; + the ability to generate a histogram of functions called.
-
-;;; User customization variables:
-;;;
-;;; byte-compile-verbose Whether to report the function currently being
-;;; compiled in the minibuffer;
-;;; byte-optimize Whether to do optimizations; this may be
-;;; t, nil, 'source, or 'byte;
-;;; byte-optimize-log Whether to report (in excruciating detail)
-;;; exactly which optimizations have been made.
-;;; This may be t, nil, 'source, or 'byte;
-;;; byte-compile-error-on-warn Whether to stop compilation when a warning is
-;;; produced;
-;;; byte-compile-delete-errors Whether the optimizer may delete calls or
-;;; variable references that are side-effect-free
-;;; except that they may return an error.
-;;; byte-compile-generate-call-tree Whether to generate a histogram of
-;;; function calls. This can be useful for
-;;; finding unused functions, as well as simple
-;;; performance metering.
-;;; byte-compile-warnings List of warnings to issue, or t. May contain
-;;; 'free-vars (references to variables not in the
-;;; current lexical scope)
-;;; 'unresolved (calls to unknown functions)
-;;; 'callargs (lambda calls with args that don't
-;;; match the lambda's definition)
-;;; 'redefine (function cell redefined from
-;;; a macro to a lambda or vice versa,
-;;; or redefined to take other args)
-;;; 'obsolete (obsolete variables and functions)
-;;; byte-compile-compatibility Whether the compiler should
-;;; generate .elc files which can be loaded into
-;;; generic emacs 18.
-;;; emacs-lisp-file-regexp Regexp for the extension of source-files;
-;;; see also the function byte-compile-dest-file.
-
-;;; New Features:
-;;;
-;;; o The form `defsubst' is just like `defun', except that the function
-;;; generated will be open-coded in compiled code which uses it. This
-;;; means that no function call will be generated, it will simply be
-;;; spliced in. Lisp functions calls are very slow, so this can be a
-;;; big win.
-;;;
-;;; You can generally accomplish the same thing with `defmacro', but in
-;;; that case, the defined procedure can't be used as an argument to
-;;; mapcar, etc.
-;;;
-;;; o You can also open-code one particular call to a function without
-;;; open-coding all calls. Use the 'inline' form to do this, like so:
-;;;
-;;; (inline (foo 1 2 3)) ;; `foo' will be open-coded
-;;; or...
-;;; (inline ;; `foo' and `baz' will be
-;;; (foo 1 2 3 (bar 5)) ;; open-coded, but `bar' will not.
-;;; (baz 0))
-;;;
-;;; o It is possible to open-code a function in the same file it is defined
-;;; in without having to load that file before compiling it. the
-;;; byte-compiler has been modified to remember function definitions in
-;;; the compilation environment in the same way that it remembers macro
-;;; definitions.
-;;;
-;;; o Forms like ((lambda ...) ...) are open-coded.
-;;;
-;;; o The form `eval-when-compile' is like progn, except that the body
-;;; is evaluated at compile-time. When it appears at top-level, this
-;;; is analogous to the Common Lisp idiom (eval-when (compile) ...).
-;;; When it does not appear at top-level, it is similar to the
-;;; Common Lisp #. reader macro (but not in interpreted code).
-;;;
-;;; o The form `eval-and-compile' is similar to eval-when-compile, but
-;;; the whole form is evalled both at compile-time and at run-time.
-;;;
-;;; o The command compile-defun is analogous to eval-defun.
-;;;
-;;; o If you run byte-compile-file on a filename which is visited in a
-;;; buffer, and that buffer is modified, you are asked whether you want
-;;; to save the buffer before compiling.
-;;;
-;;; o byte-compiled files now start with the string `;ELC'.
-;;; Some versions of `file' can be customized to recognize that.
+;; ========================================================================
+;; Entry points:
+;; byte-recompile-directory, byte-compile-file,
+;; batch-byte-compile, batch-byte-recompile-directory,
+;; byte-compile, compile-defun,
+;; display-call-tree
+;; (byte-compile-buffer and byte-compile-and-load-file were turned off
+;; because they are not terribly useful and get in the way of completion.)
+
+;; This version of the byte compiler has the following improvements:
+;; + optimization of compiled code:
+;; - removal of unreachable code;
+;; - removal of calls to side-effectless functions whose return-value
+;; is unused;
+;; - compile-time evaluation of safe constant forms, such as (consp nil)
+;; and (ash 1 6);
+;; - open-coding of literal lambdas;
+;; - peephole optimization of emitted code;
+;; - trivial functions are left uncompiled for speed.
+;; + support for inline functions;
+;; + compile-time evaluation of arbitrary expressions;
+;; + compile-time warning messages for:
+;; - functions being redefined with incompatible arglists;
+;; - functions being redefined as macros, or vice-versa;
+;; - functions or macros defined multiple times in the same file;
+;; - functions being called with the incorrect number of arguments;
+;; - functions being called which are not defined globally, in the
+;; file, or as autoloads;
+;; - assignment and reference of undeclared free variables;
+;; - various syntax errors;
+;; + correct compilation of nested defuns, defmacros, defvars and defsubsts;
+;; + correct compilation of top-level uses of macros;
+;; + the ability to generate a histogram of functions called.
+
+;; User customization variables:
+;;
+;; byte-compile-verbose Whether to report the function currently being
+;; compiled in the minibuffer;
+;; byte-optimize Whether to do optimizations; this may be
+;; t, nil, 'source, or 'byte;
+;; byte-optimize-log Whether to report (in excruciating detail)
+;; exactly which optimizations have been made.
+;; This may be t, nil, 'source, or 'byte;
+;; byte-compile-error-on-warn Whether to stop compilation when a warning is
+;; produced;
+;; byte-compile-delete-errors Whether the optimizer may delete calls or
+;; variable references that are side-effect-free
+;; except that they may return an error.
+;; byte-compile-generate-call-tree Whether to generate a histogram of
+;; function calls. This can be useful for
+;; finding unused functions, as well as simple
+;; performance metering.
+;; byte-compile-warnings List of warnings to issue, or t. May contain
+;; 'free-vars (references to variables not in the
+;; current lexical scope)
+;; 'unresolved (calls to unknown functions)
+;; 'callargs (lambda calls with args that don't
+;; match the lambda's definition)
+;; 'redefine (function cell redefined from
+;; a macro to a lambda or vice versa,
+;; or redefined to take other args)
+;; 'obsolete (obsolete variables and functions)
+;; byte-compile-compatibility Whether the compiler should
+;; generate .elc files which can be loaded into
+;; generic emacs 18.
+;; emacs-lisp-file-regexp Regexp for the extension of source-files;
+;; see also the function byte-compile-dest-file.
+
+;; New Features:
+;;
+;; o The form `defsubst' is just like `defun', except that the function
+;; generated will be open-coded in compiled code which uses it. This
+;; means that no function call will be generated, it will simply be
+;; spliced in. Lisp functions calls are very slow, so this can be a
+;; big win.
+;;
+;; You can generally accomplish the same thing with `defmacro', but in
+;; that case, the defined procedure can't be used as an argument to
+;; mapcar, etc.
+;;
+;; o You can also open-code one particular call to a function without
+;; open-coding all calls. Use the 'inline' form to do this, like so:
+;;
+;; (inline (foo 1 2 3)) ;; `foo' will be open-coded
+;; or...
+;; (inline ;; `foo' and `baz' will be
+;; (foo 1 2 3 (bar 5)) ;; open-coded, but `bar' will not.
+;; (baz 0))
+;;
+;; o It is possible to open-code a function in the same file it is defined
+;; in without having to load that file before compiling it. the
+;; byte-compiler has been modified to remember function definitions in
+;; the compilation environment in the same way that it remembers macro
+;; definitions.
+;;
+;; o Forms like ((lambda ...) ...) are open-coded.
+;;
+;; o The form `eval-when-compile' is like progn, except that the body
+;; is evaluated at compile-time. When it appears at top-level, this
+;; is analogous to the Common Lisp idiom (eval-when (compile) ...).
+;; When it does not appear at top-level, it is similar to the
+;; Common Lisp #. reader macro (but not in interpreted code).
+;;
+;; o The form `eval-and-compile' is similar to eval-when-compile, but
+;; the whole form is evalled both at compile-time and at run-time.
+;;
+;; o The command compile-defun is analogous to eval-defun.
+;;
+;; o If you run byte-compile-file on a filename which is visited in a
+;; buffer, and that buffer is modified, you are asked whether you want
+;; to save the buffer before compiling.
+;;
+;; o byte-compiled files now start with the string `;ELC'.
+;; Some versions of `file' can be customized to recognize that.
(require 'backquote)
(defun byte-compile-arglist-signatures-congruent-p (old new)
(not (or
(> (car new) (car old)) ; requires more args now
- (and (null (cdr old)) ; tooks rest-args, doesn't any more
+ (and (null (cdr old)) ; took rest-args, doesn't any more
(cdr new))
(and (cdr new) (cdr old) ; can't take as many args now
(< (cdr new) (cdr old)))
\f
;;;###autoload
-(defun byte-recompile-directory (directory &optional arg)
+(defun byte-force-recompile (directory)
+ "Recompile every `.el' file in DIRECTORY that already has a `.elc' file.
+Files in subdirectories of DIRECTORY are processed also."
+ (interactive "DByte force recompile (directory): ")
+ (byte-recompile-directory directory nil t))
+
+;;;###autoload
+(defun byte-recompile-directory (directory &optional arg force)
"Recompile every `.el' file in DIRECTORY that needs recompilation.
This is if a `.elc' file exists but is older than the `.el' file.
Files in subdirectories of DIRECTORY are processed also.
for each such `.el' file, whether to compile it. Prefix argument 0 means
don't ask and compile the file anyway.
-A nonzero prefix argument also means ask about each subdirectory."
+A nonzero prefix argument also means ask about each subdirectory.
+
+If the third argument FORCE is non-nil,
+recompile every `.el' file that already has a `.elc' file."
(interactive "DByte recompile directory: \nP")
(if arg
(setq arg (prefix-numeric-value arg)))
(if (and (not (member (car files) '("." ".." "RCS" "CVS")))
(file-directory-p source)
(not (file-symlink-p source)))
+ ;; This file is a subdirectory. Handle them differently.
(if (or (null arg)
(eq 0 arg)
(y-or-n-p (concat "Check " source "? ")))
(setq directories
(nconc directories (list source))))
+ ;; It is an ordinary file. Decide whether to compile it.
(if (and (string-match emacs-lisp-file-regexp source)
(not (auto-save-file-name-p source))
(setq dest (byte-compile-dest-file source))
(if (file-exists-p dest)
- (file-newer-than-file-p source dest)
+ ;; File was already compiled.
+ (or force (file-newer-than-file-p source dest))
+ ;; No compiled file exists yet.
(and arg
(or (eq 0 arg)
(y-or-n-p (concat "Compile " source "? "))))))
(float-output-format nil)
(case-fold-search nil)
(print-length nil)
+ (print-level nil)
;; Simulate entry to byte-compile-top-level
(byte-compile-constants nil)
(byte-compile-variables nil)
;; Compile pending forms at end of file.
(byte-compile-flush-pending)
(byte-compile-warn-about-unresolved-functions)
- ;; SHould we always do this? When calling multiple files, it
+ ;; Should we always do this? When calling multiple files, it
;; would be useful to delay this warning until all have
;; been compiled.
(setq byte-compile-unresolved-functions nil))))
;; Insert the doc string, and make it a comment with #@LENGTH.
(and (>= (nth 1 info) 0)
dynamic-docstrings
+ (not byte-compile-compatibility)
(progn
;; Make the doc string start at beginning of line
;; for make-docfile's sake.
;; If the interactive spec is a call to `list',
;; don't compile it, because `call-interactively'
;; looks at the args of `list'.
- (or (eq (car-safe (nth 1 int)) 'list)
- (setq int (list 'interactive
- (byte-compile-top-level (nth 1 int))))))
+ (let ((form (nth 1 int)))
+ (while (or (eq (car-safe form) 'let)
+ (eq (car-safe form) 'let*)
+ (eq (car-safe form) 'save-excursion))
+ (while (consp (cdr form))
+ (setq form (cdr form)))
+ (setq form (car form)))
+ (or (eq (car-safe form) 'list)
+ (setq int (list 'interactive
+ (byte-compile-top-level (nth 1 int)))))))
((cdr int)
(byte-compile-warn "malformed interactive spec: %s"
(prin1-to-string int))))))
;; Compile a function that accepts one or more args and is right-associative.
+;; We do it by left-associativity so that the operations
+;; are done in the same order as in interpreted code.
(defun byte-compile-associative (form)
(if (cdr form)
- (let ((opcode (get (car form) 'byte-opcode)))
- ;; To compile all the args first may enable some optimizations.
- (mapcar 'byte-compile-form (setq form (cdr form)))
- (while (setq form (cdr form))
- (byte-compile-out opcode 0)))
+ (let ((opcode (get (car form) 'byte-opcode))
+ (args (copy-sequence (cdr form))))
+ (byte-compile-form (car args))
+ (setq args (cdr args))
+ (while args
+ (byte-compile-form (car args))
+ (byte-compile-out opcode 0)
+ (setq args (cdr args))))
(byte-compile-constant (eval form))))
\f