summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/byte-opt.el
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>2007-04-24 21:56:25 +0000
committerMiles Bader <miles@gnu.org>2007-04-24 21:56:25 +0000
commit991a760232de757d71d8dbbed47ee12d81e29d53 (patch)
tree2440730c37ae3f167a50f5c3ac5eaeab9b72b7b0 /lisp/emacs-lisp/byte-opt.el
parent0bb328f8f6fce06a7fc65670c7d5c011b613e1c5 (diff)
parent3851329262d6558d5e1a93157d44777d0a39e38e (diff)
downloademacs-991a760232de757d71d8dbbed47ee12d81e29d53.tar.gz
Merge from emacs--devo--0
Patches applied: * emacs--devo--0 (patch 698-710) - Update from CVS - Merge from gnus--rel--5.10 * gnus--rel--5.10 (patch 216) - Update from CVS Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-196
Diffstat (limited to 'lisp/emacs-lisp/byte-opt.el')
-rw-r--r--lisp/emacs-lisp/byte-opt.el48
1 files changed, 26 insertions, 22 deletions
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index d0589b3eb00..be135850d56 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -557,8 +557,20 @@
;; Otherwise, no args can be considered to be for-effect,
;; even if the called function is for-effect, because we
;; don't know anything about that function.
- (cons fn (mapcar 'byte-optimize-form (cdr form)))))))
-
+ (let ((args (mapcar #'byte-optimize-form (cdr form))))
+ (if (and (get fn 'pure)
+ (byte-optimize-all-constp args))
+ (list 'quote (apply fn (mapcar #'eval args)))
+ (cons fn args)))))))
+
+(defun byte-optimize-all-constp (list)
+ "Non-nil iff all elements of LIST satisfy `byte-compile-constp'."
+ (let ((constant t))
+ (while (and list constant)
+ (unless (byte-compile-constp (car list))
+ (setq constant nil))
+ (setq list (cdr list)))
+ constant))
(defun byte-optimize-form (form &optional for-effect)
"The source-level pass of the optimizer."
@@ -1117,26 +1129,6 @@
(byte-optimize-predicate form))
form))
-;; Avoid having to write forward-... with a negative arg for speed.
-;; Fixme: don't be limited to constant args.
-(put 'backward-char 'byte-optimizer 'byte-optimize-backward-char)
-(defun byte-optimize-backward-char (form)
- (cond ((and (= 2 (safe-length form))
- (numberp (nth 1 form)))
- (list 'forward-char (eval (- (nth 1 form)))))
- ((= 1 (safe-length form))
- '(forward-char -1))
- (t form)))
-
-(put 'backward-word 'byte-optimizer 'byte-optimize-backward-word)
-(defun byte-optimize-backward-word (form)
- (cond ((and (= 2 (safe-length form))
- (numberp (nth 1 form)))
- (list 'forward-word (eval (- (nth 1 form)))))
- ((= 1 (safe-length form))
- '(forward-word -1))
- (t form)))
-
;; Fixme: delete-char -> delete-region (byte-coded)
;; optimize string-as-unibyte, string-as-multibyte, string-make-unibyte,
;; string-make-multibyte for constant args.
@@ -1266,6 +1258,18 @@
(setq side-effect-and-error-free-fns (cdr side-effect-and-error-free-fns)))
nil)
+
+;; pure functions are side-effect free functions whose values depend
+;; only on their arguments. For these functions, calls with constant
+;; arguments can be evaluated at compile time. This may shift run time
+;; errors to compile time.
+
+(let ((pure-fns
+ '(concat symbol-name regexp-opt regexp-quote string-to-syntax)))
+ (while pure-fns
+ (put (car pure-fns) 'pure t)
+ (setq pure-fns (cdr pure-fns)))
+ nil)
(defun byte-compile-splice-in-already-compiled-code (form)
;; form is (byte-code "..." [...] n)