Mercurial > emacs
comparison lisp/emacs-lisp/bytecomp.el @ 50570:80ed0fdbf171
Use push, with-current-buffer, dolist, ...
(byte-compile-const-variables): New var.
(byte-compile-close-variables): Reset it.
(byte-compile-file-form-defvar, byte-compile-defvar): Update it.
(byte-compile-const-symbol-p): Now arg `value' to check defconsts.
(byte-compile-variable-ref): Use it and improve warning message.
(byte-compile-check-lambda-list): Use byte-compile-const-symbol-p.
(byte-compile-lapcode): Remove unused vars.
(byte-compile-eval): Fix thinko in handling of old-autoloads.
(byte-recompile-directory): Use the expanded form for directory.
(byte-compile-track-mouse): Use modern backquote syntax.
(byte-compile-defvar): Detect and properly handle (defconst a).
(byte-compile-defalias-warn): Remove unused arg `alias'.
(byte-compile-defalias): Update call.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Sat, 12 Apr 2003 20:28:10 +0000 |
parents | ae038951ece0 |
children | e80e4ccf1bfc |
comparison
equal
deleted
inserted
replaced
50569:f7bd4869e2a8 | 50570:80ed0fdbf171 |
---|---|
8 ;; Maintainer: FSF | 8 ;; Maintainer: FSF |
9 ;; Keywords: lisp | 9 ;; Keywords: lisp |
10 | 10 |
11 ;;; This version incorporates changes up to version 2.10 of the | 11 ;;; This version incorporates changes up to version 2.10 of the |
12 ;;; Zawinski-Furuseth compiler. | 12 ;;; Zawinski-Furuseth compiler. |
13 (defconst byte-compile-version "$Revision: 2.121 $") | 13 (defconst byte-compile-version "$Revision: 2.122 $") |
14 | 14 |
15 ;; This file is part of GNU Emacs. | 15 ;; This file is part of GNU Emacs. |
16 | 16 |
17 ;; GNU Emacs is free software; you can redistribute it and/or modify | 17 ;; GNU Emacs is free software; you can redistribute it and/or modify |
18 ;; it under the terms of the GNU General Public License as published by | 18 ;; it under the terms of the GNU General Public License as published by |
157 | 157 |
158 (require 'backquote) | 158 (require 'backquote) |
159 | 159 |
160 (or (fboundp 'defsubst) | 160 (or (fboundp 'defsubst) |
161 ;; This really ought to be loaded already! | 161 ;; This really ought to be loaded already! |
162 (load-library "byte-run")) | 162 (load "byte-run")) |
163 | 163 |
164 ;; The feature of compiling in a specific target Emacs version | 164 ;; The feature of compiling in a specific target Emacs version |
165 ;; has been turned off because compile time options are a bad idea. | 165 ;; has been turned off because compile time options are a bad idea. |
166 (defmacro byte-compile-single-version () nil) | 166 (defmacro byte-compile-single-version () nil) |
167 (defmacro byte-compile-version-cond (cond) cond) | 167 (defmacro byte-compile-version-cond (cond) cond) |
401 (defvar byte-compile-variables nil | 401 (defvar byte-compile-variables nil |
402 "List of all variables encountered during compilation of this form.") | 402 "List of all variables encountered during compilation of this form.") |
403 (defvar byte-compile-bound-variables nil | 403 (defvar byte-compile-bound-variables nil |
404 "List of variables bound in the context of the current form. | 404 "List of variables bound in the context of the current form. |
405 This list lives partly on the stack.") | 405 This list lives partly on the stack.") |
406 (defvar byte-compile-const-variables nil | |
407 "List of variables declared as constants during compilation of this file.") | |
406 (defvar byte-compile-free-references) | 408 (defvar byte-compile-free-references) |
407 (defvar byte-compile-free-assignments) | 409 (defvar byte-compile-free-assignments) |
408 | 410 |
409 (defvar byte-compiler-error-flag) | 411 (defvar byte-compiler-error-flag) |
410 | 412 |
705 "Turns lapcode into bytecode. The lapcode is destroyed." | 707 "Turns lapcode into bytecode. The lapcode is destroyed." |
706 ;; Lapcode modifications: changes the ID of a tag to be the tag's PC. | 708 ;; Lapcode modifications: changes the ID of a tag to be the tag's PC. |
707 (let ((pc 0) ; Program counter | 709 (let ((pc 0) ; Program counter |
708 op off ; Operation & offset | 710 op off ; Operation & offset |
709 (bytes '()) ; Put the output bytes here | 711 (bytes '()) ; Put the output bytes here |
710 (patchlist nil) ; List of tags and goto's to patch | 712 (patchlist nil)) ; List of tags and goto's to patch |
711 rest rel tmp) | |
712 (while lap | 713 (while lap |
713 (setq op (car (car lap)) | 714 (setq op (car (car lap)) |
714 off (cdr (car lap))) | 715 off (cdr (car lap))) |
715 (cond ((not (symbolp op)) | 716 (cond ((not (symbolp op)) |
716 (error "Non-symbolic opcode `%s'" op)) | 717 (error "Non-symbolic opcode `%s'" op)) |
790 (cond | 791 (cond |
791 ((symbolp s) | 792 ((symbolp s) |
792 (unless (memq s old-autoloads) | 793 (unless (memq s old-autoloads) |
793 (put s 'byte-compile-noruntime t))) | 794 (put s 'byte-compile-noruntime t))) |
794 ((and (consp s) (eq t (car s))) | 795 ((and (consp s) (eq t (car s))) |
795 (push s old-autoloads)) | 796 (push (cdr s) old-autoloads)) |
796 ((and (consp s) (eq 'autoload (car s))) | 797 ((and (consp s) (eq 'autoload (car s))) |
797 (put (cdr s) 'byte-compile-noruntime t))))))) | 798 (put (cdr s) 'byte-compile-noruntime t))))))) |
798 ;; Go through current-load-list for the locally defined funs. | 799 ;; Go through current-load-list for the locally defined funs. |
799 (let (old-autoloads) | 800 (let (old-autoloads) |
800 (while (and hist-nil-new (not (eq hist-nil-new hist-nil-orig))) | 801 (while (and hist-nil-new (not (eq hist-nil-new hist-nil-orig))) |
801 (let ((s (pop hist-nil-new))) | 802 (let ((s (pop hist-nil-new))) |
802 (when (and (symbolp s) (not (memq s old-autoloads))) | 803 (when (and (symbolp s) (not (memq s old-autoloads))) |
803 (put s 'byte-compile-noruntime t)) | 804 (put s 'byte-compile-noruntime t)) |
804 (when (and (consp s) (eq t (car s))) | 805 (when (and (consp s) (eq t (car s))) |
805 (push s old-autoloads)))))))))) | 806 (push (cdr s) old-autoloads)))))))))) |
806 | 807 |
807 (defun byte-compile-eval-before-compile (form) | 808 (defun byte-compile-eval-before-compile (form) |
808 "Evaluate FORM for `eval-and-compile'." | 809 "Evaluate FORM for `eval-and-compile'." |
809 (let ((hist-nil-orig current-load-list)) | 810 (let ((hist-nil-orig current-load-list)) |
810 (prog1 (eval form) | 811 (prog1 (eval form) |
1312 "the following functions are not known to be defined:" | 1313 "the following functions are not known to be defined:" |
1313 unresolved))) | 1314 unresolved))) |
1314 nil) | 1315 nil) |
1315 | 1316 |
1316 | 1317 |
1317 (defsubst byte-compile-const-symbol-p (symbol) | 1318 (defsubst byte-compile-const-symbol-p (symbol &optional value) |
1319 "Non-nil if SYMBOL is constant. | |
1320 If VALUE is nil, only return non-nil if the value of the symbol is the | |
1321 symbol itself." | |
1318 (or (memq symbol '(nil t)) | 1322 (or (memq symbol '(nil t)) |
1319 (keywordp symbol))) | 1323 (keywordp symbol) |
1324 (if value (memq symbol byte-compile-const-variables)))) | |
1320 | 1325 |
1321 (defmacro byte-compile-constp (form) | 1326 (defmacro byte-compile-constp (form) |
1322 "Return non-nil if FORM is a constant." | 1327 "Return non-nil if FORM is a constant." |
1323 `(cond ((consp ,form) (eq (car ,form) 'quote)) | 1328 `(cond ((consp ,form) (eq (car ,form) 'quote)) |
1324 ((not (symbolp ,form))) | 1329 ((not (symbolp ,form))) |
1334 ;; Copy it because the compiler may patch into the | 1339 ;; Copy it because the compiler may patch into the |
1335 ;; macroenvironment. | 1340 ;; macroenvironment. |
1336 (copy-alist byte-compile-initial-macro-environment)) | 1341 (copy-alist byte-compile-initial-macro-environment)) |
1337 (byte-compile-function-environment nil) | 1342 (byte-compile-function-environment nil) |
1338 (byte-compile-bound-variables nil) | 1343 (byte-compile-bound-variables nil) |
1344 (byte-compile-const-variables nil) | |
1339 (byte-compile-free-references nil) | 1345 (byte-compile-free-references nil) |
1340 (byte-compile-free-assignments nil) | 1346 (byte-compile-free-assignments nil) |
1341 ;; | 1347 ;; |
1342 ;; Close over these variables so that `byte-compiler-options' | 1348 ;; Close over these variables so that `byte-compiler-options' |
1343 ;; can change them on a per-file basis. | 1349 ;; can change them on a per-file basis. |
1417 nil | 1423 nil |
1418 (save-some-buffers) | 1424 (save-some-buffers) |
1419 (force-mode-line-update)) | 1425 (force-mode-line-update)) |
1420 (save-current-buffer | 1426 (save-current-buffer |
1421 (byte-goto-log-buffer) | 1427 (byte-goto-log-buffer) |
1422 (setq default-directory directory) | 1428 (setq default-directory (expand-file-name directory)) |
1423 (let ((directories (list (expand-file-name directory))) | 1429 (let ((directories (list (expand-file-name directory))) |
1424 (default-directory default-directory) | 1430 (default-directory default-directory) |
1425 (skip-count 0) | 1431 (skip-count 0) |
1426 (fail-count 0) | 1432 (fail-count 0) |
1427 (file-count 0) | 1433 (file-count 0) |
1730 ;; if the buffer contains multibyte characters. | 1736 ;; if the buffer contains multibyte characters. |
1731 (and filename (byte-compile-fix-header filename inbuffer outbuffer)))) | 1737 (and filename (byte-compile-fix-header filename inbuffer outbuffer)))) |
1732 outbuffer)) | 1738 outbuffer)) |
1733 | 1739 |
1734 (defun byte-compile-fix-header (filename inbuffer outbuffer) | 1740 (defun byte-compile-fix-header (filename inbuffer outbuffer) |
1735 (save-excursion | 1741 (with-current-buffer outbuffer |
1736 (set-buffer outbuffer) | |
1737 ;; See if the buffer has any multibyte characters. | 1742 ;; See if the buffer has any multibyte characters. |
1738 (when (< (point-max) (position-bytes (point-max))) | 1743 (when (< (point-max) (position-bytes (point-max))) |
1739 (when (byte-compile-version-cond byte-compile-compatibility) | 1744 (when (byte-compile-version-cond byte-compile-compatibility) |
1740 (error "Version-18 compatibility not valid with multibyte characters")) | 1745 (error "Version-18 compatibility not valid with multibyte characters")) |
1741 (goto-char (point-min)) | 1746 (goto-char (point-min)) |
1875 (print-gensym t)) | 1880 (print-gensym t)) |
1876 (princ "\n" outbuffer) | 1881 (princ "\n" outbuffer) |
1877 (prin1 form outbuffer) | 1882 (prin1 form outbuffer) |
1878 nil))) | 1883 nil))) |
1879 | 1884 |
1885 (defvar print-gensym-alist) ;Used before print-circle existed. | |
1886 | |
1880 (defun byte-compile-output-docform (preface name info form specindex quoted) | 1887 (defun byte-compile-output-docform (preface name info form specindex quoted) |
1881 "Print a form with a doc string. INFO is (prefix doc-index postfix). | 1888 "Print a form with a doc string. INFO is (prefix doc-index postfix). |
1882 If PREFACE and NAME are non-nil, print them too, | 1889 If PREFACE and NAME are non-nil, print them too, |
1883 before INFO and the FORM but after the doc string itself. | 1890 before INFO and the FORM but after the doc string itself. |
1884 If SPECINDEX is non-nil, it is the index in FORM | 1891 If SPECINDEX is non-nil, it is the index in FORM |
1925 ;; For compatibility with code before print-circle, | 1932 ;; For compatibility with code before print-circle, |
1926 ;; use a cons cell to say that we want | 1933 ;; use a cons cell to say that we want |
1927 ;; print-gensym-alist not to be cleared | 1934 ;; print-gensym-alist not to be cleared |
1928 ;; between calls to print functions. | 1935 ;; between calls to print functions. |
1929 (print-gensym '(t)) | 1936 (print-gensym '(t)) |
1930 ;; print-gensym-alist was used before print-circle existed. | 1937 print-gensym-alist ; was used before print-circle existed. |
1931 print-gensym-alist | |
1932 (print-continuous-numbering t) | 1938 (print-continuous-numbering t) |
1933 print-number-table | 1939 print-number-table |
1934 (index 0)) | 1940 (index 0)) |
1935 (prin1 (car form) outbuffer) | 1941 (prin1 (car form) outbuffer) |
1936 (while (setq form (cdr form)) | 1942 (while (setq form (cdr form)) |
2020 ;; so make-docfile can recognise them. Most other things can be output | 2026 ;; so make-docfile can recognise them. Most other things can be output |
2021 ;; as byte-code. | 2027 ;; as byte-code. |
2022 | 2028 |
2023 (put 'defsubst 'byte-hunk-handler 'byte-compile-file-form-defsubst) | 2029 (put 'defsubst 'byte-hunk-handler 'byte-compile-file-form-defsubst) |
2024 (defun byte-compile-file-form-defsubst (form) | 2030 (defun byte-compile-file-form-defsubst (form) |
2025 (cond ((assq (nth 1 form) byte-compile-unresolved-functions) | 2031 (when (assq (nth 1 form) byte-compile-unresolved-functions) |
2026 (setq byte-compile-current-form (nth 1 form)) | 2032 (setq byte-compile-current-form (nth 1 form)) |
2027 (byte-compile-warn "defsubst %s was used before it was defined" | 2033 (byte-compile-warn "defsubst %s was used before it was defined" |
2028 (nth 1 form)))) | 2034 (nth 1 form))) |
2029 (byte-compile-file-form | 2035 (byte-compile-file-form |
2030 (macroexpand form byte-compile-macro-environment)) | 2036 (macroexpand form byte-compile-macro-environment)) |
2031 ;; Return nil so the form is not output twice. | 2037 ;; Return nil so the form is not output twice. |
2032 nil) | 2038 nil) |
2033 | 2039 |
2056 (defun byte-compile-file-form-defvar (form) | 2062 (defun byte-compile-file-form-defvar (form) |
2057 (if (null (nth 3 form)) | 2063 (if (null (nth 3 form)) |
2058 ;; Since there is no doc string, we can compile this as a normal form, | 2064 ;; Since there is no doc string, we can compile this as a normal form, |
2059 ;; and not do a file-boundary. | 2065 ;; and not do a file-boundary. |
2060 (byte-compile-keep-pending form) | 2066 (byte-compile-keep-pending form) |
2061 (if (memq 'free-vars byte-compile-warnings) | 2067 (when (memq 'free-vars byte-compile-warnings) |
2062 (setq byte-compile-bound-variables | 2068 (push (nth 1 form) byte-compile-dynamic-variables) |
2063 (cons (nth 1 form) byte-compile-bound-variables))) | 2069 (if (eq (car form) 'defconst) |
2070 (push (nth 1 form) byte-compile-const-variables))) | |
2064 (cond ((consp (nth 2 form)) | 2071 (cond ((consp (nth 2 form)) |
2065 (setq form (copy-sequence form)) | 2072 (setq form (copy-sequence form)) |
2066 (setcar (cdr (cdr form)) | 2073 (setcar (cdr (cdr form)) |
2067 (byte-compile-top-level (nth 2 form) nil 'file)))) | 2074 (byte-compile-top-level (nth 2 form) nil 'file)))) |
2068 form)) | 2075 form)) |
2069 | 2076 |
2070 (put 'custom-declare-variable 'byte-hunk-handler | 2077 (put 'custom-declare-variable 'byte-hunk-handler |
2071 'byte-compile-file-form-custom-declare-variable) | 2078 'byte-compile-file-form-custom-declare-variable) |
2072 (defun byte-compile-file-form-custom-declare-variable (form) | 2079 (defun byte-compile-file-form-custom-declare-variable (form) |
2073 (if (memq 'free-vars byte-compile-warnings) | 2080 (when (memq 'free-vars byte-compile-warnings) |
2074 (setq byte-compile-bound-variables | 2081 (push (nth 1 (nth 1 form)) byte-compile-bound-variables)) |
2075 (cons (nth 1 (nth 1 form)) byte-compile-bound-variables))) | |
2076 (let ((tail (nthcdr 4 form))) | 2082 (let ((tail (nthcdr 4 form))) |
2077 (while tail | 2083 (while tail |
2078 ;; If there are any (function (lambda ...)) expressions, compile | 2084 ;; If there are any (function (lambda ...)) expressions, compile |
2079 ;; those functions. | 2085 ;; those functions. |
2080 (if (and (consp (car tail)) | 2086 (if (and (consp (car tail)) |
2376 (while list | 2382 (while list |
2377 (let ((arg (car list))) | 2383 (let ((arg (car list))) |
2378 (when (symbolp arg) | 2384 (when (symbolp arg) |
2379 (byte-compile-set-symbol-position arg)) | 2385 (byte-compile-set-symbol-position arg)) |
2380 (cond ((or (not (symbolp arg)) | 2386 (cond ((or (not (symbolp arg)) |
2381 (keywordp arg) | 2387 (byte-compile-const-symbol-p arg t)) |
2382 (memq arg '(t nil))) | |
2383 (error "Invalid lambda variable %s" arg)) | 2388 (error "Invalid lambda variable %s" arg)) |
2384 ((eq arg '&rest) | 2389 ((eq arg '&rest) |
2385 (unless (cdr list) | 2390 (unless (cdr list) |
2386 (error "&rest without variable name")) | 2391 (error "&rest without variable name")) |
2387 (when (cddr list) | 2392 (when (cddr list) |
2415 ;; Discard the doc string | 2420 ;; Discard the doc string |
2416 ;; unless it is the last element of the body. | 2421 ;; unless it is the last element of the body. |
2417 (if (cdr body) | 2422 (if (cdr body) |
2418 (setq body (cdr body)))))) | 2423 (setq body (cdr body)))))) |
2419 (int (assq 'interactive body))) | 2424 (int (assq 'interactive body))) |
2420 (cond (int | 2425 ;; Process the interactive spec. |
2421 (byte-compile-set-symbol-position 'interactive) | 2426 (when int |
2422 ;; Skip (interactive) if it is in front (the most usual location). | 2427 (byte-compile-set-symbol-position 'interactive) |
2423 (if (eq int (car body)) | 2428 ;; Skip (interactive) if it is in front (the most usual location). |
2424 (setq body (cdr body))) | 2429 (if (eq int (car body)) |
2425 (cond ((consp (cdr int)) | 2430 (setq body (cdr body))) |
2426 (if (cdr (cdr int)) | 2431 (cond ((consp (cdr int)) |
2427 (byte-compile-warn "malformed interactive spec: %s" | 2432 (if (cdr (cdr int)) |
2428 (prin1-to-string int))) | 2433 (byte-compile-warn "malformed interactive spec: %s" |
2429 ;; If the interactive spec is a call to `list', | 2434 (prin1-to-string int))) |
2430 ;; don't compile it, because `call-interactively' | 2435 ;; If the interactive spec is a call to `list', |
2431 ;; looks at the args of `list'. | 2436 ;; don't compile it, because `call-interactively' |
2432 (let ((form (nth 1 int))) | 2437 ;; looks at the args of `list'. |
2433 (while (memq (car-safe form) '(let let* progn save-excursion)) | 2438 (let ((form (nth 1 int))) |
2434 (while (consp (cdr form)) | 2439 (while (memq (car-safe form) '(let let* progn save-excursion)) |
2435 (setq form (cdr form))) | 2440 (while (consp (cdr form)) |
2436 (setq form (car form))) | 2441 (setq form (cdr form))) |
2437 (or (eq (car-safe form) 'list) | 2442 (setq form (car form))) |
2438 (setq int (list 'interactive | 2443 (or (eq (car-safe form) 'list) |
2439 (byte-compile-top-level (nth 1 int))))))) | 2444 (setq int (list 'interactive |
2440 ((cdr int) | 2445 (byte-compile-top-level (nth 1 int))))))) |
2441 (byte-compile-warn "malformed interactive spec: %s" | 2446 ((cdr int) |
2442 (prin1-to-string int)))))) | 2447 (byte-compile-warn "malformed interactive spec: %s" |
2448 (prin1-to-string int))))) | |
2449 ;; Process the body. | |
2443 (let ((compiled (byte-compile-top-level (cons 'progn body) nil 'lambda))) | 2450 (let ((compiled (byte-compile-top-level (cons 'progn body) nil 'lambda))) |
2451 ;; Build the actual byte-coded function. | |
2444 (if (and (eq 'byte-code (car-safe compiled)) | 2452 (if (and (eq 'byte-code (car-safe compiled)) |
2445 (not (byte-compile-version-cond | 2453 (not (byte-compile-version-cond |
2446 byte-compile-compatibility))) | 2454 byte-compile-compatibility))) |
2447 (apply 'make-byte-code | 2455 (apply 'make-byte-code |
2448 (append (list arglist) | 2456 (append (list arglist) |
2669 (byte-compile-out 'byte-call (length (cdr form)))) | 2677 (byte-compile-out 'byte-call (length (cdr form)))) |
2670 | 2678 |
2671 (defun byte-compile-variable-ref (base-op var) | 2679 (defun byte-compile-variable-ref (base-op var) |
2672 (when (symbolp var) | 2680 (when (symbolp var) |
2673 (byte-compile-set-symbol-position var)) | 2681 (byte-compile-set-symbol-position var)) |
2674 (if (or (not (symbolp var)) (byte-compile-const-symbol-p var)) | 2682 (if (or (not (symbolp var)) |
2675 (byte-compile-warn (if (eq base-op 'byte-varbind) | 2683 (byte-compile-const-symbol-p var (not (eq base-op 'byte-varref)))) |
2676 "attempt to let-bind %s %s" | 2684 (byte-compile-warn |
2677 "variable reference to %s %s") | 2685 (cond ((eq base-op 'byte-varbind) "attempt to let-bind %s %s") |
2678 (if (symbolp var) "constant" "nonvariable") | 2686 ((eq base-op 'byte-varset) "variable assignment to %s %s") |
2679 (prin1-to-string var)) | 2687 (t "variable reference to %s %s")) |
2688 (if (symbolp var) "constant" "nonvariable") | |
2689 (prin1-to-string var)) | |
2680 (if (and (get var 'byte-obsolete-variable) | 2690 (if (and (get var 'byte-obsolete-variable) |
2681 (memq 'obsolete byte-compile-warnings)) | 2691 (memq 'obsolete byte-compile-warnings)) |
2682 (let* ((ob (get var 'byte-obsolete-variable)) | 2692 (let* ((ob (get var 'byte-obsolete-variable)) |
2683 (when (cdr ob))) | 2693 (when (cdr ob))) |
2684 (byte-compile-warn "%s is an obsolete variable%s; %s" var | 2694 (byte-compile-warn "%s is an obsolete variable%s; %s" var |
2686 (if (stringp (car ob)) | 2696 (if (stringp (car ob)) |
2687 (car ob) | 2697 (car ob) |
2688 (format "use %s instead." (car ob)))))) | 2698 (format "use %s instead." (car ob)))))) |
2689 (if (memq 'free-vars byte-compile-warnings) | 2699 (if (memq 'free-vars byte-compile-warnings) |
2690 (if (eq base-op 'byte-varbind) | 2700 (if (eq base-op 'byte-varbind) |
2691 (setq byte-compile-bound-variables | 2701 (push var byte-compile-bound-variables) |
2692 (cons var byte-compile-bound-variables)) | |
2693 (or (boundp var) | 2702 (or (boundp var) |
2694 (memq var byte-compile-bound-variables) | 2703 (memq var byte-compile-bound-variables) |
2695 (if (eq base-op 'byte-varset) | 2704 (if (eq base-op 'byte-varset) |
2696 (or (memq var byte-compile-free-assignments) | 2705 (or (memq var byte-compile-free-assignments) |
2697 (progn | 2706 (progn |
2698 (byte-compile-warn "assignment to free variable %s" var) | 2707 (byte-compile-warn "assignment to free variable %s" var) |
2699 (setq byte-compile-free-assignments | 2708 (push var byte-compile-free-assignments))) |
2700 (cons var byte-compile-free-assignments)))) | |
2701 (or (memq var byte-compile-free-references) | 2709 (or (memq var byte-compile-free-references) |
2702 (progn | 2710 (progn |
2703 (byte-compile-warn "reference to free variable %s" var) | 2711 (byte-compile-warn "reference to free variable %s" var) |
2704 (setq byte-compile-free-references | 2712 (push var byte-compile-free-references)))))))) |
2705 (cons var byte-compile-free-references))))))))) | |
2706 (let ((tmp (assq var byte-compile-variables))) | 2713 (let ((tmp (assq var byte-compile-variables))) |
2707 (or tmp | 2714 (unless tmp |
2708 (setq tmp (list var) | 2715 (setq tmp (list var)) |
2709 byte-compile-variables (cons tmp byte-compile-variables))) | 2716 (push tmp byte-compile-variables)) |
2710 (byte-compile-out base-op tmp))) | 2717 (byte-compile-out base-op tmp))) |
2711 | 2718 |
2712 (defmacro byte-compile-get-constant (const) | 2719 (defmacro byte-compile-get-constant (const) |
2713 `(or (if (stringp ,const) | 2720 `(or (if (stringp ,const) |
2714 (assoc ,const byte-compile-constants) | 2721 (assoc ,const byte-compile-constants) |
2968 (args (copy-sequence (cdr form)))) | 2975 (args (copy-sequence (cdr form)))) |
2969 (byte-compile-form (car args)) | 2976 (byte-compile-form (car args)) |
2970 (setq args (cdr args)) | 2977 (setq args (cdr args)) |
2971 (or args (setq args '(0) | 2978 (or args (setq args '(0) |
2972 opcode (get '+ 'byte-opcode))) | 2979 opcode (get '+ 'byte-opcode))) |
2973 (while args | 2980 (dolist (arg args) |
2974 (byte-compile-form (car args)) | 2981 (byte-compile-form arg) |
2975 (byte-compile-out opcode 0) | 2982 (byte-compile-out opcode 0))) |
2976 (setq args (cdr args)))) | |
2977 (byte-compile-constant (eval form)))) | 2983 (byte-compile-constant (eval form)))) |
2978 | 2984 |
2979 | 2985 |
2980 ;; more complicated compiler macros | 2986 ;; more complicated compiler macros |
2981 | 2987 |
3357 | 3363 |
3358 | 3364 |
3359 (defun byte-compile-let (form) | 3365 (defun byte-compile-let (form) |
3360 ;; First compute the binding values in the old scope. | 3366 ;; First compute the binding values in the old scope. |
3361 (let ((varlist (car (cdr form)))) | 3367 (let ((varlist (car (cdr form)))) |
3362 (while varlist | 3368 (dolist (var varlist) |
3363 (if (consp (car varlist)) | 3369 (if (consp var) |
3364 (byte-compile-form (car (cdr (car varlist)))) | 3370 (byte-compile-form (car (cdr var))) |
3365 (byte-compile-push-constant nil)) | 3371 (byte-compile-push-constant nil)))) |
3366 (setq varlist (cdr varlist)))) | |
3367 (let ((byte-compile-bound-variables byte-compile-bound-variables) ;new scope | 3372 (let ((byte-compile-bound-variables byte-compile-bound-variables) ;new scope |
3368 (varlist (reverse (car (cdr form))))) | 3373 (varlist (reverse (car (cdr form))))) |
3369 (while varlist | 3374 (dolist (var varlist) |
3370 (byte-compile-variable-ref 'byte-varbind (if (consp (car varlist)) | 3375 (byte-compile-variable-ref 'byte-varbind (if (consp var) (car var) var))) |
3371 (car (car varlist)) | |
3372 (car varlist))) | |
3373 (setq varlist (cdr varlist))) | |
3374 (byte-compile-body-do-effect (cdr (cdr form))) | 3376 (byte-compile-body-do-effect (cdr (cdr form))) |
3375 (byte-compile-out 'byte-unbind (length (car (cdr form)))))) | 3377 (byte-compile-out 'byte-unbind (length (car (cdr form)))))) |
3376 | 3378 |
3377 (defun byte-compile-let* (form) | 3379 (defun byte-compile-let* (form) |
3378 (let ((byte-compile-bound-variables byte-compile-bound-variables) ;new scope | 3380 (let ((byte-compile-bound-variables byte-compile-bound-variables) ;new scope |
3379 (varlist (copy-sequence (car (cdr form))))) | 3381 (varlist (copy-sequence (car (cdr form))))) |
3380 (while varlist | 3382 (dolist (var varlist) |
3381 (if (atom (car varlist)) | 3383 (if (atom var) |
3382 (byte-compile-push-constant nil) | 3384 (byte-compile-push-constant nil) |
3383 (byte-compile-form (car (cdr (car varlist)))) | 3385 (byte-compile-form (car (cdr var))) |
3384 (setcar varlist (car (car varlist)))) | 3386 (setq var (car var))) |
3385 (byte-compile-variable-ref 'byte-varbind (car varlist)) | 3387 (byte-compile-variable-ref 'byte-varbind var)) |
3386 (setq varlist (cdr varlist))) | |
3387 (byte-compile-body-do-effect (cdr (cdr form))) | 3388 (byte-compile-body-do-effect (cdr (cdr form))) |
3388 (byte-compile-out 'byte-unbind (length (car (cdr form)))))) | 3389 (byte-compile-out 'byte-unbind (length (car (cdr form)))))) |
3389 | 3390 |
3390 | 3391 |
3391 (byte-defop-compiler-1 /= byte-compile-negated) | 3392 (byte-defop-compiler-1 /= byte-compile-negated) |
3435 (byte-compile-form-do-effect (car (cdr form))) | 3436 (byte-compile-form-do-effect (car (cdr form))) |
3436 (byte-compile-out 'byte-unbind 1)) | 3437 (byte-compile-out 'byte-unbind 1)) |
3437 | 3438 |
3438 (defun byte-compile-track-mouse (form) | 3439 (defun byte-compile-track-mouse (form) |
3439 (byte-compile-form | 3440 (byte-compile-form |
3440 (list | 3441 `(funcall '(lambda nil |
3441 'funcall | 3442 (track-mouse ,@(byte-compile-top-level-body (cdr form))))))) |
3442 (list 'quote | |
3443 (list 'lambda nil | |
3444 (cons 'track-mouse | |
3445 (byte-compile-top-level-body (cdr form)))))))) | |
3446 | 3443 |
3447 (defun byte-compile-condition-case (form) | 3444 (defun byte-compile-condition-case (form) |
3448 (let* ((var (nth 1 form)) | 3445 (let* ((var (nth 1 form)) |
3449 (byte-compile-bound-variables | 3446 (byte-compile-bound-variables |
3450 (if var (cons var byte-compile-bound-variables) | 3447 (if var (cons var byte-compile-bound-variables) |
3556 (let ((fun (nth 0 form)) | 3553 (let ((fun (nth 0 form)) |
3557 (var (nth 1 form)) | 3554 (var (nth 1 form)) |
3558 (value (nth 2 form)) | 3555 (value (nth 2 form)) |
3559 (string (nth 3 form))) | 3556 (string (nth 3 form))) |
3560 (byte-compile-set-symbol-position fun) | 3557 (byte-compile-set-symbol-position fun) |
3561 (when (> (length form) 4) | 3558 (when (or (> (length form) 4) |
3559 (and (eq fun 'defconst) (null (cddr form)))) | |
3562 (byte-compile-warn | 3560 (byte-compile-warn |
3563 "%s %s called with %d arguments, but accepts only %s" | 3561 "%s called with %d arguments, but accepts only %s" |
3564 fun var (length (cdr form)) 3)) | 3562 fun (length (cdr form)) "2-3")) |
3565 (when (memq 'free-vars byte-compile-warnings) | 3563 (when (memq 'free-vars byte-compile-warnings) |
3566 (setq byte-compile-bound-variables | 3564 (push var byte-compile-dynamic-variables) |
3567 (cons var byte-compile-bound-variables))) | 3565 (if (eq fun 'defconst) |
3566 (push var byte-compile-const-variables))) | |
3568 (byte-compile-body-do-effect | 3567 (byte-compile-body-do-effect |
3569 (list | 3568 (list |
3570 ;; Put the defined variable in this library's load-history entry | 3569 ;; Put the defined variable in this library's load-history entry |
3571 ;; just as a real defvar would, but only in top-level forms. | 3570 ;; just as a real defvar would, but only in top-level forms. |
3572 (when (and (cddr form) (null byte-compile-current-form)) | 3571 (when (and (cddr form) (null byte-compile-current-form)) |
3578 `(put ',var 'variable-documentation ,string)) | 3577 `(put ',var 'variable-documentation ,string)) |
3579 (if (cddr form) ; `value' provided | 3578 (if (cddr form) ; `value' provided |
3580 (if (eq fun 'defconst) | 3579 (if (eq fun 'defconst) |
3581 ;; `defconst' sets `var' unconditionally. | 3580 ;; `defconst' sets `var' unconditionally. |
3582 (let ((tmp (make-symbol "defconst-tmp-var"))) | 3581 (let ((tmp (make-symbol "defconst-tmp-var"))) |
3583 `(let ((,tmp ,value)) | 3582 `(funcall '(lambda (,tmp) (defconst ,var ,tmp)) |
3584 (eval '(defconst ,var ,tmp)))) | 3583 ,value)) |
3585 ;; `defvar' sets `var' only when unbound. | 3584 ;; `defvar' sets `var' only when unbound. |
3586 `(if (not (boundp ',var)) (setq ,var ,value)))) | 3585 `(if (not (boundp ',var)) (setq ,var ,value))) |
3586 (when (eq fun 'defconst) | |
3587 ;; This will signal an appropriate error at runtime. | |
3588 `(eval ',form))) | |
3587 `',var)))) | 3589 `',var)))) |
3588 | 3590 |
3589 (defun byte-compile-autoload (form) | 3591 (defun byte-compile-autoload (form) |
3590 (byte-compile-set-symbol-position 'autoload) | 3592 (byte-compile-set-symbol-position 'autoload) |
3591 (and (byte-compile-constp (nth 1 form)) | 3593 (and (byte-compile-constp (nth 1 form)) |
3614 (consp (nth 2 form)) | 3616 (consp (nth 2 form)) |
3615 (eq (car (nth 2 form)) 'quote) | 3617 (eq (car (nth 2 form)) 'quote) |
3616 (consp (cdr (nth 2 form))) | 3618 (consp (cdr (nth 2 form))) |
3617 (symbolp (nth 1 (nth 2 form)))) | 3619 (symbolp (nth 1 (nth 2 form)))) |
3618 (progn | 3620 (progn |
3619 (byte-compile-defalias-warn (nth 1 (nth 1 form)) | 3621 (byte-compile-defalias-warn (nth 1 (nth 1 form))) |
3620 (nth 1 (nth 2 form))) | |
3621 (setq byte-compile-function-environment | 3622 (setq byte-compile-function-environment |
3622 (cons (cons (nth 1 (nth 1 form)) | 3623 (cons (cons (nth 1 (nth 1 form)) |
3623 (nth 1 (nth 2 form))) | 3624 (nth 1 (nth 2 form))) |
3624 byte-compile-function-environment)))) | 3625 byte-compile-function-environment)))) |
3625 (byte-compile-normal-call form)) | 3626 (byte-compile-normal-call form)) |
3626 | 3627 |
3627 ;; Turn off warnings about prior calls to the function being defalias'd. | 3628 ;; Turn off warnings about prior calls to the function being defalias'd. |
3628 ;; This could be smarter and compare those calls with | 3629 ;; This could be smarter and compare those calls with |
3629 ;; the function it is being aliased to. | 3630 ;; the function it is being aliased to. |
3630 (defun byte-compile-defalias-warn (new alias) | 3631 (defun byte-compile-defalias-warn (new) |
3631 (let ((calls (assq new byte-compile-unresolved-functions))) | 3632 (let ((calls (assq new byte-compile-unresolved-functions))) |
3632 (if calls | 3633 (if calls |
3633 (setq byte-compile-unresolved-functions | 3634 (setq byte-compile-unresolved-functions |
3634 (delq calls byte-compile-unresolved-functions))))) | 3635 (delq calls byte-compile-unresolved-functions))))) |
3635 | 3636 |
3652 (error "Compiler bug: depth conflict at tag %d" (car (cdr tag)))) | 3653 (error "Compiler bug: depth conflict at tag %d" (car (cdr tag)))) |
3653 (setq byte-compile-depth (cdr (cdr tag)))) | 3654 (setq byte-compile-depth (cdr (cdr tag)))) |
3654 (setcdr (cdr tag) byte-compile-depth))) | 3655 (setcdr (cdr tag) byte-compile-depth))) |
3655 | 3656 |
3656 (defun byte-compile-goto (opcode tag) | 3657 (defun byte-compile-goto (opcode tag) |
3657 (setq byte-compile-output (cons (cons opcode tag) byte-compile-output)) | 3658 (push (cons opcode tag) byte-compile-output) |
3658 (setcdr (cdr tag) (if (memq opcode byte-goto-always-pop-ops) | 3659 (setcdr (cdr tag) (if (memq opcode byte-goto-always-pop-ops) |
3659 (1- byte-compile-depth) | 3660 (1- byte-compile-depth) |
3660 byte-compile-depth)) | 3661 byte-compile-depth)) |
3661 (setq byte-compile-depth (and (not (eq opcode 'byte-goto)) | 3662 (setq byte-compile-depth (and (not (eq opcode 'byte-goto)) |
3662 (1- byte-compile-depth)))) | 3663 (1- byte-compile-depth)))) |
3663 | 3664 |
3664 (defun byte-compile-out (opcode offset) | 3665 (defun byte-compile-out (opcode offset) |
3665 (setq byte-compile-output (cons (cons opcode offset) byte-compile-output)) | 3666 (push (cons opcode offset) byte-compile-output) |
3666 (cond ((eq opcode 'byte-call) | 3667 (cond ((eq opcode 'byte-call) |
3667 (setq byte-compile-depth (- byte-compile-depth offset))) | 3668 (setq byte-compile-depth (- byte-compile-depth offset))) |
3668 ((eq opcode 'byte-return) | 3669 ((eq opcode 'byte-return) |
3669 ;; This is actually an unnecessary case, because there should be | 3670 ;; This is actually an unnecessary case, because there should be |
3670 ;; no more opcodes behind byte-return. | 3671 ;; no more opcodes behind byte-return. |