comparison lisp/bytecomp.el @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents 8de8e3f6228a
children 576fb035e263
comparison
equal deleted inserted replaced
441:72a7cfa4a488 442:abe6d1db359e
1 ;;; bytecomp.el --- compilation of Lisp code into byte code. 1 ;;; bytecomp.el --- compilation of Lisp code into byte code.
2 2
3 ;;; Copyright (C) 1985-1987, 1991-1994 Free Software Foundation, Inc. 3 ;;; Copyright (C) 1985-1987, 1991-1994 Free Software Foundation, Inc.
4 ;;; Copyright (C) 1996 Ben Wing. 4 ;;; Copyright (C) 1996 Ben Wing.
5 5
6 ;; Author: Jamie Zawinski <jwz@jwz.org> 6 ;; Authors: Jamie Zawinski <jwz@jwz.org>
7 ;; Hallvard Furuseth <hbf@ulrik.uio.no> 7 ;; Hallvard Furuseth <hbf@ulrik.uio.no>
8 ;; Keywords: internal 8 ;; Ben Wing <ben@xemacs.org>
9 9 ;; Martin Buchholz <martin@xemacs.org>
10 ;; Subsequently modified by RMS and others. 10 ;; Richard Stallman <rms@gnu.org>
11 11 ;; Keywords: internal lisp
12 (defconst byte-compile-version (purecopy "2.26 XEmacs; 1998-10-07.")) 12
13 (defconst byte-compile-version (purecopy "2.27 XEmacs; 2000-09-12."))
13 14
14 ;; This file is part of XEmacs. 15 ;; This file is part of XEmacs.
15 16
16 ;; XEmacs is free software; you can redistribute it and/or modify it 17 ;; XEmacs is free software; you can redistribute it and/or modify it
17 ;; under the terms of the GNU General Public License as published by 18 ;; under the terms of the GNU General Public License as published by
31 ;;; Synched up with: FSF 19.30. 32 ;;; Synched up with: FSF 19.30.
32 33
33 ;;; Commentary: 34 ;;; Commentary:
34 35
35 ;; The Emacs Lisp byte compiler. This crunches lisp source into a 36 ;; The Emacs Lisp byte compiler. This crunches lisp source into a
36 ;; sort of p-code which takes up less space and can be interpreted 37 ;; sort of p-code (`bytecode') which takes up less space and can be
37 ;; faster. The user entry points are byte-compile-file, 38 ;; interpreted faster. First, the source code forms are converted to
39 ;; an intermediate form, `lapcode' [`LAP' == `Lisp Assembly Program']
40 ;; which is much easier to manipulate than bytecode. Then the lapcode
41 ;; is converted to bytecode, which can be considered to be actual
42 ;; machine language. Optimizations can occur at either the source
43 ;; level or the lapcode level.
44
45 ;; The user entry points are byte-compile-file,
38 ;; byte-recompile-directory and byte-compile-buffer. 46 ;; byte-recompile-directory and byte-compile-buffer.
39 47
40 ;;; Code: 48 ;;; Code:
41 49
42 ;;; ======================================================================== 50 ;;; ========================================================================
936 (setq byte-compiler-error-flag t) 944 (setq byte-compiler-error-flag t)
937 (byte-compile-log-1 945 (byte-compile-log-1
938 (concat "!! " 946 (concat "!! "
939 (format (if (cdr error-info) "%s (%s)" "%s") 947 (format (if (cdr error-info) "%s (%s)" "%s")
940 (get (car error-info) 'error-message) 948 (get (car error-info) 'error-message)
941 (prin1-to-string (cdr error-info)))))) 949 (prin1-to-string (cdr error-info)))))
950 (if stack-trace-on-error
951 (backtrace nil t)))
942 952
943 ;;; Used by make-obsolete. 953 ;;; Used by make-obsolete.
944 (defun byte-compile-obsolete (form) 954 (defun byte-compile-obsolete (form)
945 (let ((new (get (car form) 'byte-obsolete-info))) 955 (let ((new (get (car form) 'byte-obsolete-info)))
946 (if (memq 'obsolete byte-compile-warnings) 956 (if (memq 'obsolete byte-compile-warnings)
1318 (if (boundp 'byte-compile-warnings-beginning) 1328 (if (boundp 'byte-compile-warnings-beginning)
1319 byte-compile-warnings-beginning 1329 byte-compile-warnings-beginning
1320 (point-max byte-compile-log-buffer)))) 1330 (point-max byte-compile-log-buffer))))
1321 1331
1322 (unwind-protect 1332 (unwind-protect
1323 (condition-case error-info 1333 (call-with-condition-handler
1324 (progn ,@body) 1334 #'(lambda (error-info)
1325 (error 1335 (byte-compile-report-error error-info))
1326 (byte-compile-report-error error-info))) 1336 #'(lambda ()
1327 1337 (progn ,@body)))
1328 ;; Always set point in log to start of interesting output. 1338 ;; Always set point in log to start of interesting output.
1329 (with-current-buffer byte-compile-log-buffer 1339 (with-current-buffer byte-compile-log-buffer
1330 (let ((show-begin 1340 (let ((show-begin
1331 (progn (goto-char byte-compile-point-max-prev) 1341 (progn (goto-char byte-compile-point-max-prev)
1332 (skip-chars-forward "\^L\n") 1342 (skip-chars-forward "\^L\n")
1353 ;;;###autoload 1363 ;;;###autoload
1354 (defun byte-force-recompile (directory) 1364 (defun byte-force-recompile (directory)
1355 "Recompile every `.el' file in DIRECTORY that already has a `.elc' file. 1365 "Recompile every `.el' file in DIRECTORY that already has a `.elc' file.
1356 Files in subdirectories of DIRECTORY are processed also." 1366 Files in subdirectories of DIRECTORY are processed also."
1357 (interactive "DByte force recompile (directory): ") 1367 (interactive "DByte force recompile (directory): ")
1358 (byte-recompile-directory directory nil t)) 1368 (byte-recompile-directory directory nil nil t))
1359 1369
1360 ;;;###autoload 1370 ;;;###autoload
1361 (defun byte-recompile-directory (directory &optional arg norecursion force) 1371 (defun byte-recompile-directory (directory &optional arg norecursion force)
1362 "Recompile every `.el' file in DIRECTORY that needs recompilation. 1372 "Recompile every `.el' file in DIRECTORY that needs recompilation.
1363 This is if a `.elc' file exists but is older than the `.el' file. 1373 This is if a `.elc' file exists but is older than the `.el' file.
1984 (if (stringp (nth 3 form)) 1994 (if (stringp (nth 3 form))
1985 form 1995 form
1986 ;; No doc string, so we can compile this as a normal form. 1996 ;; No doc string, so we can compile this as a normal form.
1987 (byte-compile-keep-pending form 'byte-compile-normal-call))) 1997 (byte-compile-keep-pending form 'byte-compile-normal-call)))
1988 1998
1989 (put 'defvar 'byte-hunk-handler 'byte-compile-file-form-defvar) 1999 (put 'defvar 'byte-hunk-handler 'byte-compile-file-form-defvar-or-defconst)
1990 (put 'defconst 'byte-hunk-handler 'byte-compile-file-form-defvar) 2000 (put 'defconst 'byte-hunk-handler 'byte-compile-file-form-defvar-or-defconst)
1991 (defun byte-compile-file-form-defvar (form) 2001 (defun byte-compile-file-form-defvar-or-defconst (form)
2002 ;; (defvar|defconst VAR [VALUE [DOCSTRING]])
1992 (if (> (length form) 4) 2003 (if (> (length form) 4)
1993 (byte-compile-warn "%s used with too many args (%s)" 2004 (byte-compile-warn
1994 (car form) (nth 1 form))) 2005 "%s %s called with %d arguments, but accepts only %s"
2006 (car form) (nth 1 form) (length (cdr form)) 3))
1995 (if (and (> (length form) 3) (not (stringp (nth 3 form)))) 2007 (if (and (> (length form) 3) (not (stringp (nth 3 form))))
1996 (byte-compile-warn "Third arg to %s %s is not a string: %s" 2008 (byte-compile-warn "Third arg to %s %s is not a string: %s"
1997 (car form) (nth 1 form) (nth 3 form))) 2009 (car form) (nth 1 form) (nth 3 form)))
1998 (if (null (nth 3 form)) 2010 (if (null (nth 3 form))
1999 ;; Since there is no doc string, we can compile this as a normal form, 2011 ;; Since there is no doc string, we can compile this as a normal form,
3709 ;;; top-level forms elsewhere 3721 ;;; top-level forms elsewhere
3710 3722
3711 (byte-defop-compiler-1 defun) 3723 (byte-defop-compiler-1 defun)
3712 (byte-defop-compiler-1 defmacro) 3724 (byte-defop-compiler-1 defmacro)
3713 (byte-defop-compiler-1 defvar) 3725 (byte-defop-compiler-1 defvar)
3714 (byte-defop-compiler-1 defconst byte-compile-defvar) 3726 (byte-defop-compiler-1 defvar byte-compile-defvar-or-defconst)
3727 (byte-defop-compiler-1 defconst byte-compile-defvar-or-defconst)
3715 (byte-defop-compiler-1 autoload) 3728 (byte-defop-compiler-1 autoload)
3716 ;; According to Mly this can go now that lambda is a macro 3729 ;; According to Mly this can go now that lambda is a macro
3717 ;(byte-defop-compiler-1 lambda byte-compile-lambda-form) 3730 ;(byte-defop-compiler-1 lambda byte-compile-lambda-form)
3718 (byte-defop-compiler-1 defalias) 3731 (byte-defop-compiler-1 defalias)
3719 (byte-defop-compiler-1 define-function) 3732 (byte-defop-compiler-1 define-function)
3737 (if (eq (car-safe code) 'make-byte-code) 3750 (if (eq (car-safe code) 'make-byte-code)
3738 (list 'cons ''macro code) 3751 (list 'cons ''macro code)
3739 (list 'quote (cons 'macro (eval code)))))) 3752 (list 'quote (cons 'macro (eval code))))))
3740 (list 'quote (nth 1 form))))) 3753 (list 'quote (nth 1 form)))))
3741 3754
3742 (defun byte-compile-defvar (form) 3755 (defun byte-compile-defvar-or-defconst (form)
3743 ;; This is not used for file-level defvar/consts with doc strings: 3756 ;; This is not used for file-level defvar/defconsts with doc strings:
3744 ;; byte-compile-file-form-defvar will be used in that case. 3757 ;; byte-compile-file-form-defvar-or-defconst will be used in that case.
3745 (let ((var (nth 1 form)) 3758 ;; (defvar|defconst VAR [VALUE [DOCSTRING]])
3759 (let ((fun (nth 0 form))
3760 (var (nth 1 form))
3746 (value (nth 2 form)) 3761 (value (nth 2 form))
3747 (string (nth 3 form))) 3762 (string (nth 3 form)))
3748 (if (> (length form) 4) 3763 (when (> (length form) 4)
3749 (byte-compile-warn "%s used with too many args" (car form))) 3764 (byte-compile-warn
3750 (if (memq 'free-vars byte-compile-warnings) 3765 "%s %s called with %d arguments, but accepts only %s"
3751 (setq byte-compile-bound-variables 3766 fun var (length (cdr form)) 3))
3752 (cons (cons var byte-compile-global-bit) 3767 (when (memq 'free-vars byte-compile-warnings)
3753 byte-compile-bound-variables))) 3768 (push (cons var byte-compile-global-bit) byte-compile-bound-variables))
3754 (byte-compile-body-do-effect 3769 (byte-compile-body-do-effect
3755 (list (if (cdr (cdr form)) 3770 (list
3756 (if (eq (car form) 'defconst) 3771 ;; Put the defined variable in this library's load-history entry
3757 (list 'setq var value) 3772 ;; just as a real defvar would, but only in top-level forms.
3758 (list 'or (list 'boundp (list 'quote var)) 3773 (when (null byte-compile-current-form)
3759 (list 'setq var value)))) 3774 `(push ',var current-load-list))
3760 ;; Put the defined variable in this library's load-history entry 3775 (when (> (length form) 3)
3761 ;; just as a real defvar would. 3776 (when (and string (not (stringp string)))
3762 (list 'setq 'current-load-list 3777 (byte-compile-warn "Third arg to %s %s is not a string: %s"
3763 (list 'cons (list 'quote var) 3778 fun var string))
3764 'current-load-list)) 3779 `(put ',var 'variable-documentation ,string))
3765 (if string 3780 (if (cdr (cdr form)) ; `value' provided
3766 (list 'put (list 'quote var) ''variable-documentation string)) 3781 (if (eq fun 'defconst)
3767 (list 'quote var))))) 3782 ;; `defconst' sets `var' unconditionally.
3783 `(setq ,var ,value)
3784 ;; `defvar' sets `var' only when unbound.
3785 `(if (not (boundp ',var)) (setq ,var ,value))))
3786 `',var))))
3768 3787
3769 (defun byte-compile-autoload (form) 3788 (defun byte-compile-autoload (form)
3770 (and (byte-compile-constp (nth 1 form)) 3789 (and (byte-compile-constp (nth 1 form))
3771 (byte-compile-constp (nth 5 form)) 3790 (byte-compile-constp (nth 5 form))
3772 (memq (eval (nth 5 form)) '(t macro)) ; macro-p 3791 (memq (eval (nth 5 form)) '(t macro)) ; macro-p
4035 (defvar command-line-args-left) ;Avoid 'free variable' warning 4054 (defvar command-line-args-left) ;Avoid 'free variable' warning
4036 (if (not noninteractive) 4055 (if (not noninteractive)
4037 (error "`batch-byte-compile' is to be used only with -batch")) 4056 (error "`batch-byte-compile' is to be used only with -batch"))
4038 (let ((error nil)) 4057 (let ((error nil))
4039 (while command-line-args-left 4058 (while command-line-args-left
4040 (if (file-directory-p (expand-file-name (car command-line-args-left))) 4059 (if (null (batch-byte-compile-one-file))
4041 (let ((files (directory-files (car command-line-args-left))) 4060 (setq error t)))
4042 source dest)
4043 (while files
4044 (if (and (string-match emacs-lisp-file-regexp (car files))
4045 (not (auto-save-file-name-p (car files)))
4046 (setq source (expand-file-name
4047 (car files)
4048 (car command-line-args-left)))
4049 (setq dest (byte-compile-dest-file source))
4050 (file-exists-p dest)
4051 (file-newer-than-file-p source dest))
4052 (if (null (batch-byte-compile-1 source))
4053 (setq error t)))
4054 (setq files (cdr files))))
4055 (if (null (batch-byte-compile-1 (car command-line-args-left)))
4056 (setq error t)))
4057 (setq command-line-args-left (cdr command-line-args-left)))
4058 (message "Done") 4061 (message "Done")
4059 (kill-emacs (if error 1 0)))) 4062 (kill-emacs (if error 1 0))))
4063
4064 ;;;###autoload
4065 (defun batch-byte-compile-one-file ()
4066 "Run `byte-compile-file' on a single file remaining on the command line.
4067 Use this from the command line, with `-batch';
4068 it won't work in an interactive Emacs."
4069 ;; command-line-args-left is what is left of the command line (from
4070 ;; startup.el)
4071 (defvar command-line-args-left) ;Avoid 'free variable' warning
4072 (if (not noninteractive)
4073 (error "`batch-byte-compile-one-file' is to be used only with -batch"))
4074 (let (error
4075 (file-to-process (car command-line-args-left)))
4076 (setq command-line-args-left (cdr command-line-args-left))
4077 (if (file-directory-p (expand-file-name file-to-process))
4078 (let ((files (directory-files file-to-process))
4079 source dest)
4080 (while files
4081 (if (and (string-match emacs-lisp-file-regexp (car files))
4082 (not (auto-save-file-name-p (car files)))
4083 (setq source (expand-file-name
4084 (car files)
4085 file-to-process))
4086 (setq dest (byte-compile-dest-file source))
4087 (file-exists-p dest)
4088 (file-newer-than-file-p source dest))
4089 (if (null (batch-byte-compile-1 source))
4090 (setq error t)))
4091 (setq files (cdr files)))
4092 (null error))
4093 (batch-byte-compile-1 file-to-process))))
4060 4094
4061 (defun batch-byte-compile-1 (file) 4095 (defun batch-byte-compile-1 (file)
4062 (condition-case err 4096 (condition-case err
4063 (progn (byte-compile-file file) t) 4097 (progn (byte-compile-file file) t)
4064 (error 4098 (error