Mercurial > hg > xemacs-beta
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 |