commit: Update a comment with a better understanding of the optimizer, bytecomp.el
13 years, 2 months
Aidan Kehoe
changeset: 5577:0b6e7ae1e78f
tag: tip
user: Aidan Kehoe <kehoea(a)parhasard.net>
date: Tue Oct 04 09:02:14 2011 +0100
files: lisp/ChangeLog lisp/bytecomp.el
description:
Update a comment with a better understanding of the optimizer, bytecomp.el
lisp/ChangeLog addition:
2011-10-04 Aidan Kehoe <kehoea(a)parhasard.net>
* bytecomp.el (byte-compile-funcall):
Correct a comment here, explaining why the optimizer doesn't
expand (funcall #'(lambda ...)) in some contexts with inline
labels, and why it's reasonable to do it here.
diff -r 071b810ceb18 -r 0b6e7ae1e78f lisp/ChangeLog
--- a/lisp/ChangeLog Mon Oct 03 20:16:14 2011 +0100
+++ b/lisp/ChangeLog Tue Oct 04 09:02:14 2011 +0100
@@ -1,3 +1,10 @@
+2011-10-04 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * bytecomp.el (byte-compile-funcall):
+ Correct a comment here, explaining why the optimizer doesn't
+ expand (funcall #'(lambda ...)) in some contexts with inline
+ labels, and why it's reasonable to do it here.
+
2011-10-03 Aidan Kehoe <kehoea(a)parhasard.net>
* simple.el (handle-pre-motion-command-current-command-is-motion):
diff -r 071b810ceb18 -r 0b6e7ae1e78f lisp/bytecomp.el
--- a/lisp/bytecomp.el Mon Oct 03 20:16:14 2011 +0100
+++ b/lisp/bytecomp.el Tue Oct 04 09:02:14 2011 +0100
@@ -4164,9 +4164,23 @@
(not (eq (setq form (cons (cadadr form) (cddr form)))
(setq form (byte-compile-unfold-lambda form))))
(prog1 nil (setq form `(funcall #',(car form) ,@(cdr form))))))
- ;; Sometimes the optimizer fails to unfold well-formed calls of the
- ;; form (funcall #'(lambda ...)); since we need it to do this for
- ;; (declare (inline ...)) to work properly with labels, force that here.
+ ;; The byte-compile part of the #'labels implementation, above,
+ ;; happens after macroexpansion and after the source optimizer has
+ ;; done its thing. When labels are to be made inline we can have code
+ ;; that looks like (funcall #'(lambda ...) ...), when the code that
+ ;; the optimizer saw looked like (funcall #<compiled-function ...>
+ ;; ...).
+ ;;
+ ;; So, the optimizer doesn't have the opportunity to transform the
+ ;; former to (let (...) ...), and it's reasonable to do that here (since
+ ;; the labels implementation doesn't change other code that would need
+ ;; running through the optimizer; the lambda itself has already been
+ ;; through the optimizer).
+ ;;
+ ;; Equally reasonable, and conceptually a bit clearer, would be to do
+ ;; the transformation to (funcall #'(lambda ...) ...) in the
+ ;; byte-optimizer, breaking most of the #'sublis calls out of the
+ ;; byte-compile method.
(byte-compile-form form)
(mapc 'byte-compile-form (cdr form))
(byte-compile-out 'byte-call (length (cdr (cdr form))))))
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
[COMMIT] Force unfolding of (funcall #'(lambda () ...) if optimising, bytecomp.el.
13 years, 2 months
Aidan Kehoe
Yes, the root of the problem is somewhere else; I’m not at the point where I
know exactly where, though.
APPROVE COMMIT
NOTE: This patch has been committed.
# HG changeset patch
# User Aidan Kehoe <kehoea(a)parhasard.net>
# Date 1317667141 -3600
# Node ID 89cb6a66a61fd6f6ba721937f5c00b58792b14c3
# Parent d4f334808463b4785db56315e79b893d7a42b5e9
Force unfolding of (funcall #'(lambda () ...) if optimising, bytecomp.el.
lisp/ChangeLog addition:
2011-10-03 Aidan Kehoe <kehoea(a)parhasard.net>
* bytecomp.el (byte-compile-funcall):
Sometimes the optimizer shirks its responsibility and doesn't
unfold a lambda when it should. Do this here, if optimization is
turned on; this makes inlining labels more consistent and
trustworthy.
diff -r d4f334808463 -r 89cb6a66a61f lisp/ChangeLog
--- a/lisp/ChangeLog Sun Oct 02 15:32:16 2011 +0100
+++ b/lisp/ChangeLog Mon Oct 03 19:39:01 2011 +0100
@@ -1,3 +1,11 @@
+2011-10-03 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * bytecomp.el (byte-compile-funcall):
+ Sometimes the optimizer shirks its responsibility and doesn't
+ unfold a lambda when it should. Do this here, if optimization is
+ turned on; this makes inlining labels more consistent and
+ trustworthy.
+
2011-10-02 Aidan Kehoe <kehoea(a)parhasard.net>
* bytecomp.el (byte-compile-initial-macro-environment):
diff -r d4f334808463 -r 89cb6a66a61f lisp/bytecomp.el
--- a/lisp/bytecomp.el Sun Oct 02 15:32:16 2011 +0100
+++ b/lisp/bytecomp.el Mon Oct 03 19:39:01 2011 +0100
@@ -4157,8 +4157,19 @@
(byte-compile-constp (second form)))
(byte-compile-callargs-warn (cons (cl-const-expr-val (second form))
(nthcdr 2 form))))
- (mapc 'byte-compile-form (cdr form))
- (byte-compile-out 'byte-call (length (cdr (cdr form)))))
+ (if (and byte-optimize
+ (eq 'function (car-safe (cadr form)))
+ (eq 'lambda (car-safe (cadadr form)))
+ (or
+ (not (eq (setq form (cons (cadadr form) (cddr form)))
+ (setq form (byte-compile-unfold-lambda form))))
+ (prog1 nil (setq form `(funcall #',(car form) ,@(cdr form))))))
+ ;; Sometimes the optimizer fails to unfold well-formed calls of the
+ ;; form (funcall #'(lambda ...)); since we need it to do this for
+ ;; (declare (inline ...)) to work properly with labels, force that here.
+ (byte-compile-form form)
+ (mapc 'byte-compile-form (cdr form))
+ (byte-compile-out 'byte-call (length (cdr (cdr form))))))
(defun byte-compile-let (form)
--
‘Iodine deficiency was endemic in parts of the UK until, through what has been
described as “an unplanned and accidental public health triumph”, iodine was
added to cattle feed to improve milk production in the 1930s.’
(EN Pearce, Lancet, June 2011)
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
[COMMIT] Declare labels as [in]line where appropriate; use #'labels, not #'flet, tests.
13 years, 2 months
Aidan Kehoe
APPROVE COMMIT
NOTE: This patch has been committed.
# HG changeset patch
# User Aidan Kehoe <kehoea(a)parhasard.net>
# Date 1317669374 -3600
# Node ID 071b810ceb18d441cef3e92b141882ab42bc62e3
# Parent 89cb6a66a61fd6f6ba721937f5c00b58792b14c3
Declare labels as line where appropriate; use #'labels, not #'flet, tests.
lisp/ChangeLog addition:
2011-10-03 Aidan Kehoe <kehoea(a)parhasard.net>
* simple.el (handle-pre-motion-command-current-command-is-motion):
Implement #'keysyms-equal with #'labels + (declare (inline ...)),
instead of abusing macrolet to the same end.
* specifier.el (let-specifier):
* mule/mule-cmds.el (describe-language-environment):
* mule/mule-cmds.el (set-language-environment-coding-systems):
* mule/mule-x-init.el (x-use-halfwidth-roman-font):
* faces.el (Face-frob-property):
* keymap.el (key-sequence-list-description):
* lisp-mode.el (construct-lisp-mode-menu):
* loadhist.el (unload-feature):
* mouse.el (default-mouse-track-check-for-activation):
Declare various labels inline in dumped files when that reduces
the size of the dumped image. Declaring labels inline is normally
only worthwhile for inner loops and so on, but it's reasonable
exercise of the related code to have these changes in core.
tests/ChangeLog addition:
2011-10-03 Aidan Kehoe <kehoea(a)parhasard.net>
* automated/case-tests.el (uni-mappings):
* automated/database-tests.el (delete-database-files):
* automated/hash-table-tests.el (iterations):
* automated/lisp-tests.el (test1):
* automated/lisp-tests.el (a):
* automated/lisp-tests.el (cl-floor):
* automated/lisp-tests.el (foo):
* automated/lisp-tests.el (list-nreverse):
* automated/lisp-tests.el (needs-lexical-context):
* automated/mule-tests.el (featurep):
* automated/os-tests.el (original-string):
* automated/os-tests.el (with):
* automated/symbol-tests.el (check-weak-list-unique):
Replace #'flet with #'labels where appropriate in these tests,
following my own advice on style in the docstrings of those
functions.
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/ChangeLog
--- a/lisp/ChangeLog Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/ChangeLog Mon Oct 03 20:16:14 2011 +0100
@@ -1,3 +1,22 @@
+2011-10-03 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * simple.el (handle-pre-motion-command-current-command-is-motion):
+ Implement #'keysyms-equal with #'labels + (declare (inline ...)),
+ instead of abusing macrolet to the same end.
+ * specifier.el (let-specifier):
+ * mule/mule-cmds.el (describe-language-environment):
+ * mule/mule-cmds.el (set-language-environment-coding-systems):
+ * mule/mule-x-init.el (x-use-halfwidth-roman-font):
+ * faces.el (Face-frob-property):
+ * keymap.el (key-sequence-list-description):
+ * lisp-mode.el (construct-lisp-mode-menu):
+ * loadhist.el (unload-feature):
+ * mouse.el (default-mouse-track-check-for-activation):
+ Declare various labels inline in dumped files when that reduces
+ the size of the dumped image. Declaring labels inline is normally
+ only worthwhile for inner loops and so on, but it's reasonable
+ exercise of the related code to have these changes in core.
+
2011-10-03 Aidan Kehoe <kehoea(a)parhasard.net>
* bytecomp.el (byte-compile-funcall):
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/faces.el
--- a/lisp/faces.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/faces.el Mon Oct 03 20:16:14 2011 +0100
@@ -1142,6 +1142,7 @@
;; end of labels
)
+ (declare (inline global-locale nil-instantiator-ok))
;; the function itself
(let* ((ffpdev Face-frob-property-device-considered-current)
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/keymap.el
--- a/lisp/keymap.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/keymap.el Mon Oct 03 20:16:14 2011 +0100
@@ -419,6 +419,7 @@
(vector keys)))))
(labels ((event-to-list (ev)
(append (event-modifiers ev) (list (event-key ev)))))
+ (declare (inline event-to-list))
(mapvector
#'(lambda (key)
(let* ((full-key
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/lisp-mode.el
--- a/lisp/lisp-mode.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/lisp-mode.el Mon Oct 03 20:16:14 2011 +0100
@@ -45,6 +45,7 @@
(defun construct-lisp-mode-menu (popup-p emacs-lisp-p)
(labels ((popup-wrap (form)
(if popup-p `(menu-call-at-event ',form) form)))
+ (declare (inline popup-wrap))
`(,@(if emacs-lisp-p
`(["%_Byte-Compile This File" ,(popup-wrap
'emacs-lisp-byte-compile)]
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/loadhist.el
--- a/lisp/loadhist.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/loadhist.el Mon Oct 03 20:16:14 2011 +0100
@@ -178,6 +178,7 @@
(labels ((reset-aload (x)
(let ((aload (get x 'autoload)))
(if aload (fset x (cons 'autoload aload))))))
+ (declare (inline reset-aload))
(mapc
#'(lambda (x)
(cond ((stringp x) nil)
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/mouse.el
--- a/lisp/mouse.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/mouse.el Mon Oct 03 20:16:14 2011 +0100
@@ -1251,6 +1251,7 @@
(when ex
(funcall (extent-property ex property) event ex)
t))))
+ (declare (inline do-activate))
(or
(and (some #'(lambda (count button)
(and (= click-count count)
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/mule/mule-cmds.el
--- a/lisp/mule/mule-cmds.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/mule/mule-cmds.el Mon Oct 03 20:16:14 2011 +0100
@@ -838,6 +838,7 @@
(labels ((princ-list (&rest args)
(while args (princ (car args)) (setq args (cdr args)))
(princ "\n")))
+ (declare (inline princ-list))
(with-output-to-temp-buffer "*Help*"
(princ-list language-name " language environment" "\n")
(if (stringp doc)
@@ -1347,7 +1348,7 @@
(if (memq eol-type '(lf crlf cr unix dos mac))
(coding-system-change-eol-conversion codesys eol-type)
codesys)))
-
+ (declare (inline maybe-change-coding-system-with-eol))
;; initialize category mappings and priority list.
(let* ((priority (get-language-info language-name 'coding-priority))
(default-coding (car priority)))
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/mule/mule-x-init.el
--- a/lisp/mule/mule-x-init.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/mule/mule-x-init.el Mon Oct 03 20:16:14 2011 +0100
@@ -47,7 +47,7 @@
(let ((width1 (charset-font-width cs1))
(width2 (charset-font-width cs2)))
(and width1 width2 (eq (+ width1 width1) width2)))))
-
+ (declare (inline charset-font-width))
(when (eq 'x (device-type))
(let ((original-registries (charset-registries 'ascii)))
(condition-case nil
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/simple.el
--- a/lisp/simple.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/simple.el Mon Oct 03 20:16:14 2011 +0100
@@ -2084,20 +2084,19 @@
(defun handle-pre-motion-command-current-command-is-motion ()
(and (key-press-event-p last-input-event)
- (macrolet
- ((keysyms-equal (&rest args)
- `((lambda (a b)
- (when (and
- ;; As of now, none of the elements of
- ;; motion-keys-for-shifted-motion are non-symbols;
- ;; this redundant check saves a few hundred
- ;; funcalls on startup.
- (not (symbolp b))
- (characterp b))
- (setf (car char-list) b
- b (intern (concat char-list nil))))
- (eq a b))
- ,@args)))
+ (labels
+ ((keysyms-equal (a b)
+ (when (and
+ ;; As of now, none of the elements of
+ ;; motion-keys-for-shifted-motion are non-symbols;
+ ;; this redundant check saves a few hundred
+ ;; funcalls on startup.
+ (not (symbolp b))
+ (characterp b))
+ (setf (car char-list) b
+ b (intern (concat char-list nil))))
+ (eq a b)))
+ (declare (inline keysyms-equal) (special char-list))
(loop
for keysym in motion-keys-for-shifted-motion
with key = (event-key last-input-event)
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/specifier.el
--- a/lisp/specifier.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/specifier.el Mon Oct 03 20:16:14 2011 +0100
@@ -488,6 +488,7 @@
(if (or (atom x) (eq (car x) 'quote))
(list x)
(list (gensym name) x))))
+ (declare (inline gensym-frob))
;; VARLIST is a list of
;; ((SPECIFIERSYM SPECIFIER) (VALUE) (LOCALESYM LOCALE)
;; (TAG-SET) (HOW-TO-ADD))
diff -r 89cb6a66a61f -r 071b810ceb18 tests/ChangeLog
--- a/tests/ChangeLog Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/ChangeLog Mon Oct 03 20:16:14 2011 +0100
@@ -1,3 +1,22 @@
+2011-10-03 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * automated/case-tests.el (uni-mappings):
+ * automated/database-tests.el (delete-database-files):
+ * automated/hash-table-tests.el (iterations):
+ * automated/lisp-tests.el (test1):
+ * automated/lisp-tests.el (a):
+ * automated/lisp-tests.el (cl-floor):
+ * automated/lisp-tests.el (foo):
+ * automated/lisp-tests.el (list-nreverse):
+ * automated/lisp-tests.el (needs-lexical-context):
+ * automated/mule-tests.el (featurep):
+ * automated/os-tests.el (original-string):
+ * automated/os-tests.el (with):
+ * automated/symbol-tests.el (check-weak-list-unique):
+ Replace #'flet with #'labels where appropriate in these tests,
+ following my own advice on style in the docstrings of those
+ functions.
+
2011-10-02 Aidan Kehoe <kehoea(a)parhasard.net>
* automated/lisp-tests.el:
diff -r 89cb6a66a61f -r 071b810ceb18 tests/automated/case-tests.el
--- a/tests/automated/case-tests.el Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/automated/case-tests.el Mon Oct 03 20:16:14 2011 +0100
@@ -1464,8 +1464,8 @@
;; finally, make the new mapping.
(put-case-table-pair uc lc case-table))
finally return case-table)))
- (flet ((ismulti (uc lc)
- (or (gethash uc multi-hash) (gethash lc multi-hash))))
+ (labels ((ismulti (uc lc)
+ (or (gethash uc multi-hash) (gethash lc multi-hash))))
(let (
;; All lowercase
(lowermulti (with-output-to-string
diff -r 89cb6a66a61f -r 071b810ceb18 tests/automated/database-tests.el
--- a/tests/automated/database-tests.el Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/automated/database-tests.el Mon Oct 03 20:16:14 2011 +0100
@@ -34,12 +34,12 @@
(push (file-name-directory load-file-name) load-path)
(require 'test-harness))))
-(flet ((delete-database-files (filename)
- (dolist (fn (list filename
- (concat filename ".db")
- (concat filename ".pag")
- (concat filename ".dir")))
- (ignore-file-errors (delete-file fn))))
+(labels ((delete-database-files (filename)
+ (dolist (fn (list filename
+ (concat filename ".db")
+ (concat filename ".pag")
+ (concat filename ".dir")))
+ (ignore-file-errors (delete-file fn))))
(test-database (db)
(Assert (databasep db))
diff -r 89cb6a66a61f -r 071b810ceb18 tests/automated/hash-table-tests.el
--- a/tests/automated/hash-table-tests.el Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/automated/hash-table-tests.el Mon Oct 03 20:16:14 2011 +0100
@@ -145,16 +145,21 @@
(Assert (= (hash-table-count ht) (decf count))))))
(let ((iterations 5) (one 1.0) (two 2.0))
- (flet ((check-copy
- (ht)
- (let ((copy-of-ht (copy-hash-table ht)))
- (Assert (equal ht copy-of-ht))
- (Assert (not (eq ht copy-of-ht)))
- (Assert (eq (hash-table-count ht) (hash-table-count copy-of-ht)))
- (Assert (eq (hash-table-type ht) (hash-table-type copy-of-ht)))
- (Assert (eq (hash-table-size ht) (hash-table-size copy-of-ht)))
- (Assert (eql (hash-table-rehash-size ht) (hash-table-rehash-size copy-of-ht)))
- (Assert (eql (hash-table-rehash-threshold ht) (hash-table-rehash-threshold copy-of-ht))))))
+ (labels ((check-copy
+ (ht)
+ (let ((copy-of-ht (copy-hash-table ht)))
+ (Assert (equal ht copy-of-ht))
+ (Assert (not (eq ht copy-of-ht)))
+ (Assert (eq (hash-table-count ht)
+ (hash-table-count copy-of-ht)))
+ (Assert (eq (hash-table-type ht)
+ (hash-table-type copy-of-ht)))
+ (Assert (eq (hash-table-size ht)
+ (hash-table-size copy-of-ht)))
+ (Assert (eql (hash-table-rehash-size ht)
+ (hash-table-rehash-size copy-of-ht)))
+ (Assert (eql (hash-table-rehash-threshold ht)
+ (hash-table-rehash-threshold copy-of-ht))))))
(let ((ht (make-hash-table :size 100 :rehash-threshold .6 :test 'eq)))
(dotimes (j iterations)
diff -r 89cb6a66a61f -r 071b810ceb18 tests/automated/lisp-tests.el
--- a/tests/automated/lisp-tests.el Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/automated/lisp-tests.el Mon Oct 03 20:16:14 2011 +0100
@@ -570,11 +570,11 @@
(Check-Error wrong-type-argument (% 10.0 2))
(Check-Error wrong-type-argument (% 10 2.0))
-(flet ((test1 (x) (Assert (eql x (+ (% x 17) (* (/ x 17) 17))) x))
- (test2 (x) (Assert (eql (- x) (+ (% (- x) 17) (* (/ (- x) 17) 17))) x))
- (test3 (x) (Assert (eql x (+ (% (- x) 17) (* (/ (- x) 17) 17))) x))
- (test4 (x) (Assert (eql (% x -17) (- (% (- x) 17))) x))
- (test5 (x) (Assert (eql (% x -17) (% (- x) 17))) x))
+(labels ((test1 (x) (Assert (eql x (+ (% x 17) (* (/ x 17) 17))) x))
+ (test2 (x) (Assert (eql (- x) (+ (% (- x) 17) (* (/ (- x) 17) 17))) x))
+ (test3 (x) (Assert (eql x (+ (% (- x) 17) (* (/ (- x) 17) 17))) x))
+ (test4 (x) (Assert (eql (% x -17) (- (% (- x) 17))) x))
+ (test5 (x) (Assert (eql (% x -17) (% (- x) 17))) x))
(test1 most-negative-fixnum)
(if (featurep 'bignum)
(progn
@@ -859,7 +859,7 @@
(Assert (eq (rassoc "6" x) nil))
(Assert (eq (rassq "6" x) nil)))
-(flet ((a () (list '(1 . 2) 3 '(4 . 5))))
+(labels ((a () (list '(1 . 2) 3 '(4 . 5))))
(Assert (let* ((x (a)) (y (remassoc 1 x))) (and (not (eq x y)) (equal y '(3 (4 . 5))))))
(Assert (let* ((x (a)) (y (remassq 1 x))) (and (not (eq x y)) (equal y '(3 (4 . 5))))))
(Assert (let* ((x (a)) (y (remrassoc 1 x))) (and (eq x y) (equal y (a)))))
@@ -899,7 +899,7 @@
(Assert (let* ((x (a)) (y (old-delete 3 x))) (and (eq x y) (equal y '((1 . 2) (4 . 5))))))
(Assert (let* ((x (a)) (y (old-delq 3 x))) (and (eq x y) (equal y '((1 . 2) (4 . 5))))))))
-(flet ((a () (list '("1" . "2") "3" '("4" . "5"))))
+(labels ((a () (list '("1" . "2") "3" '("4" . "5"))))
(Assert (let* ((x (a)) (y (remassoc "1" x))) (and (not (eq x y)) (equal y '("3" ("4" . "5"))))))
(Assert (let* ((x (a)) (y (remassq "1" x))) (and (eq x y) (equal y (a)))))
(Assert (let* ((x (a)) (y (remrassoc "1" x))) (and (eq x y) (equal y (a)))))
@@ -1528,31 +1528,31 @@
(load test-file-name nil t nil)
(delete-file test-file-name))
-(flet ((cl-floor (x &optional y)
- (let ((q (floor x y)))
- (list q (- x (if y (* y q) q)))))
- (cl-ceiling (x &optional y)
- (let ((res (cl-floor x y)))
- (if (= (car (cdr res)) 0) res
- (list (1+ (car res)) (- (car (cdr res)) (or y 1))))))
- (cl-truncate (x &optional y)
- (if (eq (>= x 0) (or (null y) (>= y 0)))
- (cl-floor x y) (cl-ceiling x y)))
- (cl-round (x &optional y)
- (if y
- (if (and (integerp x) (integerp y))
- (let* ((hy (/ y 2))
- (res (cl-floor (+ x hy) y)))
- (if (and (= (car (cdr res)) 0)
- (= (+ hy hy) y)
- (/= (% (car res) 2) 0))
- (list (1- (car res)) hy)
- (list (car res) (- (car (cdr res)) hy))))
- (let ((q (round (/ x y))))
- (list q (- x (* q y)))))
- (if (integerp x) (list x 0)
- (let ((q (round x)))
- (list q (- x q))))))
+(labels ((cl-floor (x &optional y)
+ (let ((q (floor x y)))
+ (list q (- x (if y (* y q) q)))))
+ (cl-ceiling (x &optional y)
+ (let ((res (cl-floor x y)))
+ (if (= (car (cdr res)) 0) res
+ (list (1+ (car res)) (- (car (cdr res)) (or y 1))))))
+ (cl-truncate (x &optional y)
+ (if (eq (>= x 0) (or (null y) (>= y 0)))
+ (cl-floor x y) (cl-ceiling x y)))
+ (cl-round (x &optional y)
+ (if y
+ (if (and (integerp x) (integerp y))
+ (let* ((hy (/ y 2))
+ (res (cl-floor (+ x hy) y)))
+ (if (and (= (car (cdr res)) 0)
+ (= (+ hy hy) y)
+ (/= (% (car res) 2) 0))
+ (list (1- (car res)) hy)
+ (list (car res) (- (car (cdr res)) hy))))
+ (let ((q (round (/ x y))))
+ (list q (- x (* q y)))))
+ (if (integerp x) (list x 0)
+ (let ((q (round x)))
+ (list q (- x q))))))
(Assert-rounding (first second &key
one-floor-result two-floor-result
one-ffloor-result two-ffloor-result
@@ -2099,24 +2099,24 @@
;; Multiple value tests.
-(flet ((foo (x y)
- (floor (+ x y) y))
- (foo-zero (x y)
- (values (floor (+ x y) y)))
- (multiple-value-function-returning-t ()
- (values t pi e degrees-to-radians radians-to-degrees))
- (multiple-value-function-returning-nil ()
- (values nil pi e radians-to-degrees degrees-to-radians))
- (function-throwing-multiple-values ()
- (let* ((listing '(0 3 4 nil "string" symbol))
- (tail listing)
- elt)
- (while t
- (setq tail (cdr listing)
- elt (car listing)
- listing tail)
- (when (null elt)
- (throw 'VoN61Lo4Y (multiple-value-function-returning-t)))))))
+(labels ((foo (x y)
+ (floor (+ x y) y))
+ (foo-zero (x y)
+ (values (floor (+ x y) y)))
+ (multiple-value-function-returning-t ()
+ (values t pi e degrees-to-radians radians-to-degrees))
+ (multiple-value-function-returning-nil ()
+ (values nil pi e radians-to-degrees degrees-to-radians))
+ (function-throwing-multiple-values ()
+ (let* ((listing '(0 3 4 nil "string" symbol))
+ (tail listing)
+ elt)
+ (while t
+ (setq tail (cdr listing)
+ elt (car listing)
+ listing tail)
+ (when (null elt)
+ (throw 'VoN61Lo4Y (multiple-value-function-returning-t)))))))
(Assert
(= (+ (floor 5 3) (floor 19 4)) (+ 1 4) 5)
"Checking that multiple values are discarded correctly as func args")
@@ -2509,10 +2509,10 @@
(Assert (equal expected (merge 'list list '(1) #'<))
"checking merge's circularity checks are sane"))
-(flet ((list-nreverse (list)
- (do ((list1 list (cdr list1))
- (list2 nil (prog1 list1 (setcdr list1 list2))))
- ((atom list1) list2))))
+(labels ((list-nreverse (list)
+ (do ((list1 list (cdr list1))
+ (list2 nil (prog1 list1 (setcdr list1 list2))))
+ ((atom list1) list2))))
(let* ((integers (loop for i from 0 to 6000 collect i))
(characters (mapcan #'(lambda (integer)
(if (char-int-p integer)
@@ -2898,16 +2898,17 @@
;; behave incorrectly when compiled for the contorted-example function of
;; CLTL2, whence the following test:
-(flet ((needs-lexical-context (first second third)
- (if (eql 0 first)
- (funcall second)
- (block awkward
- (+ 5 (needs-lexical-context
- (1- first)
- third
- #'(lambda () (return-from awkward 0)))
- first)))))
- (if (compiled-function-p (symbol-function 'needs-lexical-context))
+(labels ((needs-lexical-context (first second third)
+ (if (eql 0 first)
+ (funcall second)
+ (block awkward
+ (+ 5 (needs-lexical-context
+ (1- first)
+ third
+ #'(lambda () (return-from awkward 0)))
+ first)))))
+ (if (compiled-function-p
+ (ignore-errors (indirect-function #'needs-lexical-context)))
(Known-Bug-Expect-Failure
(Assert (eql 0 (needs-lexical-context 2 nil nil))
"the function special operator doesn't create a lexical context."))
diff -r 89cb6a66a61f -r 071b810ceb18 tests/automated/mule-tests.el
--- a/tests/automated/mule-tests.el Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/automated/mule-tests.el Mon Oct 03 20:16:14 2011 +0100
@@ -647,7 +647,7 @@
finally (set-language-environment original-language-environment))
(with-temp-buffer
- (flet
+ (labels
((Assert-elc-is-escape-quoted ()
"Assert the current buffer has an escape-quoted cookie if compiled."
(save-excursion
diff -r 89cb6a66a61f -r 071b810ceb18 tests/automated/os-tests.el
--- a/tests/automated/os-tests.el Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/automated/os-tests.el Mon Oct 03 20:16:14 2011 +0100
@@ -62,13 +62,13 @@
(while cases
(setq case (car cases)
cases (cdr cases))
- (flet ((do-test (pos result)
- (erase-buffer)
- (insert original-string)
- (goto-char pos)
- (call-process-region 3 7 "tac" t t)
- (goto-char (point-min))
- (Assert (looking-at result))))
+ (labels ((do-test (pos result)
+ (erase-buffer)
+ (insert original-string)
+ (goto-char pos)
+ (call-process-region 3 7 "tac" t t)
+ (goto-char (point-min))
+ (Assert (looking-at result))))
(do-test (car case) (cdr case)))))
;; if you're in that much of a hurry you can blow cat off
;; if you've done tac, but I'm not going to bother
@@ -80,13 +80,13 @@
(while cases
(setq case (car cases)
cases (cdr cases))
- (flet ((do-test (pos result)
- (erase-buffer)
- (insert original-string)
- (goto-char pos)
- (call-process-region 3 7 "cat" t t)
- (goto-char (point-min))
- (Assert (looking-at result))))
+ (labels ((do-test (pos result)
+ (erase-buffer)
+ (insert original-string)
+ (goto-char pos)
+ (call-process-region 3 7 "cat" t t)
+ (goto-char (point-min))
+ (Assert (looking-at result))))
(do-test (car case) (cdr case)))))))
(loop
diff -r 89cb6a66a61f -r 071b810ceb18 tests/automated/symbol-tests.el
--- a/tests/automated/symbol-tests.el Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/automated/symbol-tests.el Mon Oct 03 20:16:14 2011 +0100
@@ -66,20 +66,20 @@
(Assert (not (eq interned uninterned)))
(Assert (not (equal interned uninterned)))))
-(flet ((check-weak-list-unique (weak-list &optional reversep)
- "Check that elements of WEAK-LIST are referenced only there."
- (let ((len (length (weak-list-list weak-list))))
- (if (string-match "Using the new GC algorithms."
- Installation-string)
- (Implementation-Incomplete-Expect-Failure
- (Assert (not (zerop len)))
- (garbage-collect)
- (Assert (eq (length (weak-list-list weak-list))
- (if (not reversep) 0 len))))
- (Assert (not (zerop len)))
- (garbage-collect)
- (Assert (eq (length (weak-list-list weak-list))
- (if (not reversep) 0 len)))))))
+(labels ((check-weak-list-unique (weak-list &optional reversep)
+ "Check that elements of WEAK-LIST are referenced only there."
+ (let ((len (length (weak-list-list weak-list))))
+ (if (string-match "Using the new GC algorithms."
+ Installation-string)
+ (Implementation-Incomplete-Expect-Failure
+ (Assert (not (zerop len)))
+ (garbage-collect)
+ (Assert (eq (length (weak-list-list weak-list))
+ (if (not reversep) 0 len))))
+ (Assert (not (zerop len)))
+ (garbage-collect)
+ (Assert (eq (length (weak-list-list weak-list))
+ (if (not reversep) 0 len)))))))
(let ((weak-list (make-weak-list))
(gc-cons-threshold most-positive-fixnum))
;; Symbols created with `make-symbol' and `gensym' should be fresh
diff -r 89cb6a66a61f -r 071b810ceb18 tests/automated/syntax-tests.el
--- a/tests/automated/syntax-tests.el Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/automated/syntax-tests.el Mon Oct 03 20:16:14 2011 +0100
@@ -179,10 +179,10 @@
(insert "a ( \"b (c\" (\"defg\") \")\") h\n")
;; #### This test should check *every* position.
- (flet ((backward-up-list-moves-point-from-to (start expected-end)
- (goto-char start)
- (backward-up-list 1)
- (= (point) expected-end)))
+ (labels ((backward-up-list-moves-point-from-to (start expected-end)
+ (goto-char start)
+ (backward-up-list 1)
+ (= (point) expected-end)))
(Known-Bug-Expect-Failure
;; Evgeny's case
(Assert (backward-up-list-moves-point-from-to 16 12)))
--
‘Iodine deficiency was endemic in parts of the UK until, through what has been
described as “an unplanned and accidental public health triumph”, iodine was
added to cattle feed to improve milk production in the 1930s.’
(EN Pearce, Lancet, June 2011)
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
commit: Declare labels as line where appropriate; use #'labels, not #'flet, tests.
13 years, 2 months
Aidan Kehoe
changeset: 5576:071b810ceb18
tag: tip
user: Aidan Kehoe <kehoea(a)parhasard.net>
date: Mon Oct 03 20:16:14 2011 +0100
files: lisp/ChangeLog lisp/faces.el lisp/keymap.el lisp/lisp-mode.el lisp/loadhist.el lisp/mouse.el lisp/mule/mule-cmds.el lisp/mule/mule-x-init.el lisp/simple.el lisp/specifier.el tests/ChangeLog tests/automated/case-tests.el tests/automated/database-tests.el tests/automated/hash-table-tests.el tests/automated/lisp-tests.el tests/automated/mule-tests.el tests/automated/os-tests.el tests/automated/symbol-tests.el tests/automated/syntax-tests.el
description:
Declare labels as line where appropriate; use #'labels, not #'flet, tests.
lisp/ChangeLog addition:
2011-10-03 Aidan Kehoe <kehoea(a)parhasard.net>
* simple.el (handle-pre-motion-command-current-command-is-motion):
Implement #'keysyms-equal with #'labels + (declare (inline ...)),
instead of abusing macrolet to the same end.
* specifier.el (let-specifier):
* mule/mule-cmds.el (describe-language-environment):
* mule/mule-cmds.el (set-language-environment-coding-systems):
* mule/mule-x-init.el (x-use-halfwidth-roman-font):
* faces.el (Face-frob-property):
* keymap.el (key-sequence-list-description):
* lisp-mode.el (construct-lisp-mode-menu):
* loadhist.el (unload-feature):
* mouse.el (default-mouse-track-check-for-activation):
Declare various labels inline in dumped files when that reduces
the size of the dumped image. Declaring labels inline is normally
only worthwhile for inner loops and so on, but it's reasonable
exercise of the related code to have these changes in core.
tests/ChangeLog addition:
2011-10-03 Aidan Kehoe <kehoea(a)parhasard.net>
* automated/case-tests.el (uni-mappings):
* automated/database-tests.el (delete-database-files):
* automated/hash-table-tests.el (iterations):
* automated/lisp-tests.el (test1):
* automated/lisp-tests.el (a):
* automated/lisp-tests.el (cl-floor):
* automated/lisp-tests.el (foo):
* automated/lisp-tests.el (list-nreverse):
* automated/lisp-tests.el (needs-lexical-context):
* automated/mule-tests.el (featurep):
* automated/os-tests.el (original-string):
* automated/os-tests.el (with):
* automated/symbol-tests.el (check-weak-list-unique):
Replace #'flet with #'labels where appropriate in these tests,
following my own advice on style in the docstrings of those
functions.
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/ChangeLog
--- a/lisp/ChangeLog Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/ChangeLog Mon Oct 03 20:16:14 2011 +0100
@@ -1,3 +1,22 @@
+2011-10-03 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * simple.el (handle-pre-motion-command-current-command-is-motion):
+ Implement #'keysyms-equal with #'labels + (declare (inline ...)),
+ instead of abusing macrolet to the same end.
+ * specifier.el (let-specifier):
+ * mule/mule-cmds.el (describe-language-environment):
+ * mule/mule-cmds.el (set-language-environment-coding-systems):
+ * mule/mule-x-init.el (x-use-halfwidth-roman-font):
+ * faces.el (Face-frob-property):
+ * keymap.el (key-sequence-list-description):
+ * lisp-mode.el (construct-lisp-mode-menu):
+ * loadhist.el (unload-feature):
+ * mouse.el (default-mouse-track-check-for-activation):
+ Declare various labels inline in dumped files when that reduces
+ the size of the dumped image. Declaring labels inline is normally
+ only worthwhile for inner loops and so on, but it's reasonable
+ exercise of the related code to have these changes in core.
+
2011-10-03 Aidan Kehoe <kehoea(a)parhasard.net>
* bytecomp.el (byte-compile-funcall):
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/faces.el
--- a/lisp/faces.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/faces.el Mon Oct 03 20:16:14 2011 +0100
@@ -1142,6 +1142,7 @@
;; end of labels
)
+ (declare (inline global-locale nil-instantiator-ok))
;; the function itself
(let* ((ffpdev Face-frob-property-device-considered-current)
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/keymap.el
--- a/lisp/keymap.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/keymap.el Mon Oct 03 20:16:14 2011 +0100
@@ -419,6 +419,7 @@
(vector keys)))))
(labels ((event-to-list (ev)
(append (event-modifiers ev) (list (event-key ev)))))
+ (declare (inline event-to-list))
(mapvector
#'(lambda (key)
(let* ((full-key
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/lisp-mode.el
--- a/lisp/lisp-mode.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/lisp-mode.el Mon Oct 03 20:16:14 2011 +0100
@@ -45,6 +45,7 @@
(defun construct-lisp-mode-menu (popup-p emacs-lisp-p)
(labels ((popup-wrap (form)
(if popup-p `(menu-call-at-event ',form) form)))
+ (declare (inline popup-wrap))
`(,@(if emacs-lisp-p
`(["%_Byte-Compile This File" ,(popup-wrap
'emacs-lisp-byte-compile)]
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/loadhist.el
--- a/lisp/loadhist.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/loadhist.el Mon Oct 03 20:16:14 2011 +0100
@@ -178,6 +178,7 @@
(labels ((reset-aload (x)
(let ((aload (get x 'autoload)))
(if aload (fset x (cons 'autoload aload))))))
+ (declare (inline reset-aload))
(mapc
#'(lambda (x)
(cond ((stringp x) nil)
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/mouse.el
--- a/lisp/mouse.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/mouse.el Mon Oct 03 20:16:14 2011 +0100
@@ -1251,6 +1251,7 @@
(when ex
(funcall (extent-property ex property) event ex)
t))))
+ (declare (inline do-activate))
(or
(and (some #'(lambda (count button)
(and (= click-count count)
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/mule/mule-cmds.el
--- a/lisp/mule/mule-cmds.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/mule/mule-cmds.el Mon Oct 03 20:16:14 2011 +0100
@@ -838,6 +838,7 @@
(labels ((princ-list (&rest args)
(while args (princ (car args)) (setq args (cdr args)))
(princ "\n")))
+ (declare (inline princ-list))
(with-output-to-temp-buffer "*Help*"
(princ-list language-name " language environment" "\n")
(if (stringp doc)
@@ -1347,7 +1348,7 @@
(if (memq eol-type '(lf crlf cr unix dos mac))
(coding-system-change-eol-conversion codesys eol-type)
codesys)))
-
+ (declare (inline maybe-change-coding-system-with-eol))
;; initialize category mappings and priority list.
(let* ((priority (get-language-info language-name 'coding-priority))
(default-coding (car priority)))
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/mule/mule-x-init.el
--- a/lisp/mule/mule-x-init.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/mule/mule-x-init.el Mon Oct 03 20:16:14 2011 +0100
@@ -47,7 +47,7 @@
(let ((width1 (charset-font-width cs1))
(width2 (charset-font-width cs2)))
(and width1 width2 (eq (+ width1 width1) width2)))))
-
+ (declare (inline charset-font-width))
(when (eq 'x (device-type))
(let ((original-registries (charset-registries 'ascii)))
(condition-case nil
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/simple.el
--- a/lisp/simple.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/simple.el Mon Oct 03 20:16:14 2011 +0100
@@ -2084,20 +2084,19 @@
(defun handle-pre-motion-command-current-command-is-motion ()
(and (key-press-event-p last-input-event)
- (macrolet
- ((keysyms-equal (&rest args)
- `((lambda (a b)
- (when (and
- ;; As of now, none of the elements of
- ;; motion-keys-for-shifted-motion are non-symbols;
- ;; this redundant check saves a few hundred
- ;; funcalls on startup.
- (not (symbolp b))
- (characterp b))
- (setf (car char-list) b
- b (intern (concat char-list nil))))
- (eq a b))
- ,@args)))
+ (labels
+ ((keysyms-equal (a b)
+ (when (and
+ ;; As of now, none of the elements of
+ ;; motion-keys-for-shifted-motion are non-symbols;
+ ;; this redundant check saves a few hundred
+ ;; funcalls on startup.
+ (not (symbolp b))
+ (characterp b))
+ (setf (car char-list) b
+ b (intern (concat char-list nil))))
+ (eq a b)))
+ (declare (inline keysyms-equal) (special char-list))
(loop
for keysym in motion-keys-for-shifted-motion
with key = (event-key last-input-event)
diff -r 89cb6a66a61f -r 071b810ceb18 lisp/specifier.el
--- a/lisp/specifier.el Mon Oct 03 19:39:01 2011 +0100
+++ b/lisp/specifier.el Mon Oct 03 20:16:14 2011 +0100
@@ -488,6 +488,7 @@
(if (or (atom x) (eq (car x) 'quote))
(list x)
(list (gensym name) x))))
+ (declare (inline gensym-frob))
;; VARLIST is a list of
;; ((SPECIFIERSYM SPECIFIER) (VALUE) (LOCALESYM LOCALE)
;; (TAG-SET) (HOW-TO-ADD))
diff -r 89cb6a66a61f -r 071b810ceb18 tests/ChangeLog
--- a/tests/ChangeLog Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/ChangeLog Mon Oct 03 20:16:14 2011 +0100
@@ -1,3 +1,22 @@
+2011-10-03 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * automated/case-tests.el (uni-mappings):
+ * automated/database-tests.el (delete-database-files):
+ * automated/hash-table-tests.el (iterations):
+ * automated/lisp-tests.el (test1):
+ * automated/lisp-tests.el (a):
+ * automated/lisp-tests.el (cl-floor):
+ * automated/lisp-tests.el (foo):
+ * automated/lisp-tests.el (list-nreverse):
+ * automated/lisp-tests.el (needs-lexical-context):
+ * automated/mule-tests.el (featurep):
+ * automated/os-tests.el (original-string):
+ * automated/os-tests.el (with):
+ * automated/symbol-tests.el (check-weak-list-unique):
+ Replace #'flet with #'labels where appropriate in these tests,
+ following my own advice on style in the docstrings of those
+ functions.
+
2011-10-02 Aidan Kehoe <kehoea(a)parhasard.net>
* automated/lisp-tests.el:
diff -r 89cb6a66a61f -r 071b810ceb18 tests/automated/case-tests.el
--- a/tests/automated/case-tests.el Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/automated/case-tests.el Mon Oct 03 20:16:14 2011 +0100
@@ -1464,8 +1464,8 @@
;; finally, make the new mapping.
(put-case-table-pair uc lc case-table))
finally return case-table)))
- (flet ((ismulti (uc lc)
- (or (gethash uc multi-hash) (gethash lc multi-hash))))
+ (labels ((ismulti (uc lc)
+ (or (gethash uc multi-hash) (gethash lc multi-hash))))
(let (
;; All lowercase
(lowermulti (with-output-to-string
diff -r 89cb6a66a61f -r 071b810ceb18 tests/automated/database-tests.el
--- a/tests/automated/database-tests.el Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/automated/database-tests.el Mon Oct 03 20:16:14 2011 +0100
@@ -34,12 +34,12 @@
(push (file-name-directory load-file-name) load-path)
(require 'test-harness))))
-(flet ((delete-database-files (filename)
- (dolist (fn (list filename
- (concat filename ".db")
- (concat filename ".pag")
- (concat filename ".dir")))
- (ignore-file-errors (delete-file fn))))
+(labels ((delete-database-files (filename)
+ (dolist (fn (list filename
+ (concat filename ".db")
+ (concat filename ".pag")
+ (concat filename ".dir")))
+ (ignore-file-errors (delete-file fn))))
(test-database (db)
(Assert (databasep db))
diff -r 89cb6a66a61f -r 071b810ceb18 tests/automated/hash-table-tests.el
--- a/tests/automated/hash-table-tests.el Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/automated/hash-table-tests.el Mon Oct 03 20:16:14 2011 +0100
@@ -145,16 +145,21 @@
(Assert (= (hash-table-count ht) (decf count))))))
(let ((iterations 5) (one 1.0) (two 2.0))
- (flet ((check-copy
- (ht)
- (let ((copy-of-ht (copy-hash-table ht)))
- (Assert (equal ht copy-of-ht))
- (Assert (not (eq ht copy-of-ht)))
- (Assert (eq (hash-table-count ht) (hash-table-count copy-of-ht)))
- (Assert (eq (hash-table-type ht) (hash-table-type copy-of-ht)))
- (Assert (eq (hash-table-size ht) (hash-table-size copy-of-ht)))
- (Assert (eql (hash-table-rehash-size ht) (hash-table-rehash-size copy-of-ht)))
- (Assert (eql (hash-table-rehash-threshold ht) (hash-table-rehash-threshold copy-of-ht))))))
+ (labels ((check-copy
+ (ht)
+ (let ((copy-of-ht (copy-hash-table ht)))
+ (Assert (equal ht copy-of-ht))
+ (Assert (not (eq ht copy-of-ht)))
+ (Assert (eq (hash-table-count ht)
+ (hash-table-count copy-of-ht)))
+ (Assert (eq (hash-table-type ht)
+ (hash-table-type copy-of-ht)))
+ (Assert (eq (hash-table-size ht)
+ (hash-table-size copy-of-ht)))
+ (Assert (eql (hash-table-rehash-size ht)
+ (hash-table-rehash-size copy-of-ht)))
+ (Assert (eql (hash-table-rehash-threshold ht)
+ (hash-table-rehash-threshold copy-of-ht))))))
(let ((ht (make-hash-table :size 100 :rehash-threshold .6 :test 'eq)))
(dotimes (j iterations)
diff -r 89cb6a66a61f -r 071b810ceb18 tests/automated/lisp-tests.el
--- a/tests/automated/lisp-tests.el Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/automated/lisp-tests.el Mon Oct 03 20:16:14 2011 +0100
@@ -570,11 +570,11 @@
(Check-Error wrong-type-argument (% 10.0 2))
(Check-Error wrong-type-argument (% 10 2.0))
-(flet ((test1 (x) (Assert (eql x (+ (% x 17) (* (/ x 17) 17))) x))
- (test2 (x) (Assert (eql (- x) (+ (% (- x) 17) (* (/ (- x) 17) 17))) x))
- (test3 (x) (Assert (eql x (+ (% (- x) 17) (* (/ (- x) 17) 17))) x))
- (test4 (x) (Assert (eql (% x -17) (- (% (- x) 17))) x))
- (test5 (x) (Assert (eql (% x -17) (% (- x) 17))) x))
+(labels ((test1 (x) (Assert (eql x (+ (% x 17) (* (/ x 17) 17))) x))
+ (test2 (x) (Assert (eql (- x) (+ (% (- x) 17) (* (/ (- x) 17) 17))) x))
+ (test3 (x) (Assert (eql x (+ (% (- x) 17) (* (/ (- x) 17) 17))) x))
+ (test4 (x) (Assert (eql (% x -17) (- (% (- x) 17))) x))
+ (test5 (x) (Assert (eql (% x -17) (% (- x) 17))) x))
(test1 most-negative-fixnum)
(if (featurep 'bignum)
(progn
@@ -859,7 +859,7 @@
(Assert (eq (rassoc "6" x) nil))
(Assert (eq (rassq "6" x) nil)))
-(flet ((a () (list '(1 . 2) 3 '(4 . 5))))
+(labels ((a () (list '(1 . 2) 3 '(4 . 5))))
(Assert (let* ((x (a)) (y (remassoc 1 x))) (and (not (eq x y)) (equal y '(3 (4 . 5))))))
(Assert (let* ((x (a)) (y (remassq 1 x))) (and (not (eq x y)) (equal y '(3 (4 . 5))))))
(Assert (let* ((x (a)) (y (remrassoc 1 x))) (and (eq x y) (equal y (a)))))
@@ -899,7 +899,7 @@
(Assert (let* ((x (a)) (y (old-delete 3 x))) (and (eq x y) (equal y '((1 . 2) (4 . 5))))))
(Assert (let* ((x (a)) (y (old-delq 3 x))) (and (eq x y) (equal y '((1 . 2) (4 . 5))))))))
-(flet ((a () (list '("1" . "2") "3" '("4" . "5"))))
+(labels ((a () (list '("1" . "2") "3" '("4" . "5"))))
(Assert (let* ((x (a)) (y (remassoc "1" x))) (and (not (eq x y)) (equal y '("3" ("4" . "5"))))))
(Assert (let* ((x (a)) (y (remassq "1" x))) (and (eq x y) (equal y (a)))))
(Assert (let* ((x (a)) (y (remrassoc "1" x))) (and (eq x y) (equal y (a)))))
@@ -1528,31 +1528,31 @@
(load test-file-name nil t nil)
(delete-file test-file-name))
-(flet ((cl-floor (x &optional y)
- (let ((q (floor x y)))
- (list q (- x (if y (* y q) q)))))
- (cl-ceiling (x &optional y)
- (let ((res (cl-floor x y)))
- (if (= (car (cdr res)) 0) res
- (list (1+ (car res)) (- (car (cdr res)) (or y 1))))))
- (cl-truncate (x &optional y)
- (if (eq (>= x 0) (or (null y) (>= y 0)))
- (cl-floor x y) (cl-ceiling x y)))
- (cl-round (x &optional y)
- (if y
- (if (and (integerp x) (integerp y))
- (let* ((hy (/ y 2))
- (res (cl-floor (+ x hy) y)))
- (if (and (= (car (cdr res)) 0)
- (= (+ hy hy) y)
- (/= (% (car res) 2) 0))
- (list (1- (car res)) hy)
- (list (car res) (- (car (cdr res)) hy))))
- (let ((q (round (/ x y))))
- (list q (- x (* q y)))))
- (if (integerp x) (list x 0)
- (let ((q (round x)))
- (list q (- x q))))))
+(labels ((cl-floor (x &optional y)
+ (let ((q (floor x y)))
+ (list q (- x (if y (* y q) q)))))
+ (cl-ceiling (x &optional y)
+ (let ((res (cl-floor x y)))
+ (if (= (car (cdr res)) 0) res
+ (list (1+ (car res)) (- (car (cdr res)) (or y 1))))))
+ (cl-truncate (x &optional y)
+ (if (eq (>= x 0) (or (null y) (>= y 0)))
+ (cl-floor x y) (cl-ceiling x y)))
+ (cl-round (x &optional y)
+ (if y
+ (if (and (integerp x) (integerp y))
+ (let* ((hy (/ y 2))
+ (res (cl-floor (+ x hy) y)))
+ (if (and (= (car (cdr res)) 0)
+ (= (+ hy hy) y)
+ (/= (% (car res) 2) 0))
+ (list (1- (car res)) hy)
+ (list (car res) (- (car (cdr res)) hy))))
+ (let ((q (round (/ x y))))
+ (list q (- x (* q y)))))
+ (if (integerp x) (list x 0)
+ (let ((q (round x)))
+ (list q (- x q))))))
(Assert-rounding (first second &key
one-floor-result two-floor-result
one-ffloor-result two-ffloor-result
@@ -2099,24 +2099,24 @@
;; Multiple value tests.
-(flet ((foo (x y)
- (floor (+ x y) y))
- (foo-zero (x y)
- (values (floor (+ x y) y)))
- (multiple-value-function-returning-t ()
- (values t pi e degrees-to-radians radians-to-degrees))
- (multiple-value-function-returning-nil ()
- (values nil pi e radians-to-degrees degrees-to-radians))
- (function-throwing-multiple-values ()
- (let* ((listing '(0 3 4 nil "string" symbol))
- (tail listing)
- elt)
- (while t
- (setq tail (cdr listing)
- elt (car listing)
- listing tail)
- (when (null elt)
- (throw 'VoN61Lo4Y (multiple-value-function-returning-t)))))))
+(labels ((foo (x y)
+ (floor (+ x y) y))
+ (foo-zero (x y)
+ (values (floor (+ x y) y)))
+ (multiple-value-function-returning-t ()
+ (values t pi e degrees-to-radians radians-to-degrees))
+ (multiple-value-function-returning-nil ()
+ (values nil pi e radians-to-degrees degrees-to-radians))
+ (function-throwing-multiple-values ()
+ (let* ((listing '(0 3 4 nil "string" symbol))
+ (tail listing)
+ elt)
+ (while t
+ (setq tail (cdr listing)
+ elt (car listing)
+ listing tail)
+ (when (null elt)
+ (throw 'VoN61Lo4Y (multiple-value-function-returning-t)))))))
(Assert
(= (+ (floor 5 3) (floor 19 4)) (+ 1 4) 5)
"Checking that multiple values are discarded correctly as func args")
@@ -2509,10 +2509,10 @@
(Assert (equal expected (merge 'list list '(1) #'<))
"checking merge's circularity checks are sane"))
-(flet ((list-nreverse (list)
- (do ((list1 list (cdr list1))
- (list2 nil (prog1 list1 (setcdr list1 list2))))
- ((atom list1) list2))))
+(labels ((list-nreverse (list)
+ (do ((list1 list (cdr list1))
+ (list2 nil (prog1 list1 (setcdr list1 list2))))
+ ((atom list1) list2))))
(let* ((integers (loop for i from 0 to 6000 collect i))
(characters (mapcan #'(lambda (integer)
(if (char-int-p integer)
@@ -2898,16 +2898,17 @@
;; behave incorrectly when compiled for the contorted-example function of
;; CLTL2, whence the following test:
-(flet ((needs-lexical-context (first second third)
- (if (eql 0 first)
- (funcall second)
- (block awkward
- (+ 5 (needs-lexical-context
- (1- first)
- third
- #'(lambda () (return-from awkward 0)))
- first)))))
- (if (compiled-function-p (symbol-function 'needs-lexical-context))
+(labels ((needs-lexical-context (first second third)
+ (if (eql 0 first)
+ (funcall second)
+ (block awkward
+ (+ 5 (needs-lexical-context
+ (1- first)
+ third
+ #'(lambda () (return-from awkward 0)))
+ first)))))
+ (if (compiled-function-p
+ (ignore-errors (indirect-function #'needs-lexical-context)))
(Known-Bug-Expect-Failure
(Assert (eql 0 (needs-lexical-context 2 nil nil))
"the function special operator doesn't create a lexical context."))
diff -r 89cb6a66a61f -r 071b810ceb18 tests/automated/mule-tests.el
--- a/tests/automated/mule-tests.el Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/automated/mule-tests.el Mon Oct 03 20:16:14 2011 +0100
@@ -647,7 +647,7 @@
finally (set-language-environment original-language-environment))
(with-temp-buffer
- (flet
+ (labels
((Assert-elc-is-escape-quoted ()
"Assert the current buffer has an escape-quoted cookie if compiled."
(save-excursion
diff -r 89cb6a66a61f -r 071b810ceb18 tests/automated/os-tests.el
--- a/tests/automated/os-tests.el Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/automated/os-tests.el Mon Oct 03 20:16:14 2011 +0100
@@ -62,13 +62,13 @@
(while cases
(setq case (car cases)
cases (cdr cases))
- (flet ((do-test (pos result)
- (erase-buffer)
- (insert original-string)
- (goto-char pos)
- (call-process-region 3 7 "tac" t t)
- (goto-char (point-min))
- (Assert (looking-at result))))
+ (labels ((do-test (pos result)
+ (erase-buffer)
+ (insert original-string)
+ (goto-char pos)
+ (call-process-region 3 7 "tac" t t)
+ (goto-char (point-min))
+ (Assert (looking-at result))))
(do-test (car case) (cdr case)))))
;; if you're in that much of a hurry you can blow cat off
;; if you've done tac, but I'm not going to bother
@@ -80,13 +80,13 @@
(while cases
(setq case (car cases)
cases (cdr cases))
- (flet ((do-test (pos result)
- (erase-buffer)
- (insert original-string)
- (goto-char pos)
- (call-process-region 3 7 "cat" t t)
- (goto-char (point-min))
- (Assert (looking-at result))))
+ (labels ((do-test (pos result)
+ (erase-buffer)
+ (insert original-string)
+ (goto-char pos)
+ (call-process-region 3 7 "cat" t t)
+ (goto-char (point-min))
+ (Assert (looking-at result))))
(do-test (car case) (cdr case)))))))
(loop
diff -r 89cb6a66a61f -r 071b810ceb18 tests/automated/symbol-tests.el
--- a/tests/automated/symbol-tests.el Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/automated/symbol-tests.el Mon Oct 03 20:16:14 2011 +0100
@@ -66,20 +66,20 @@
(Assert (not (eq interned uninterned)))
(Assert (not (equal interned uninterned)))))
-(flet ((check-weak-list-unique (weak-list &optional reversep)
- "Check that elements of WEAK-LIST are referenced only there."
- (let ((len (length (weak-list-list weak-list))))
- (if (string-match "Using the new GC algorithms."
- Installation-string)
- (Implementation-Incomplete-Expect-Failure
- (Assert (not (zerop len)))
- (garbage-collect)
- (Assert (eq (length (weak-list-list weak-list))
- (if (not reversep) 0 len))))
- (Assert (not (zerop len)))
- (garbage-collect)
- (Assert (eq (length (weak-list-list weak-list))
- (if (not reversep) 0 len)))))))
+(labels ((check-weak-list-unique (weak-list &optional reversep)
+ "Check that elements of WEAK-LIST are referenced only there."
+ (let ((len (length (weak-list-list weak-list))))
+ (if (string-match "Using the new GC algorithms."
+ Installation-string)
+ (Implementation-Incomplete-Expect-Failure
+ (Assert (not (zerop len)))
+ (garbage-collect)
+ (Assert (eq (length (weak-list-list weak-list))
+ (if (not reversep) 0 len))))
+ (Assert (not (zerop len)))
+ (garbage-collect)
+ (Assert (eq (length (weak-list-list weak-list))
+ (if (not reversep) 0 len)))))))
(let ((weak-list (make-weak-list))
(gc-cons-threshold most-positive-fixnum))
;; Symbols created with `make-symbol' and `gensym' should be fresh
diff -r 89cb6a66a61f -r 071b810ceb18 tests/automated/syntax-tests.el
--- a/tests/automated/syntax-tests.el Mon Oct 03 19:39:01 2011 +0100
+++ b/tests/automated/syntax-tests.el Mon Oct 03 20:16:14 2011 +0100
@@ -179,10 +179,10 @@
(insert "a ( \"b (c\" (\"defg\") \")\") h\n")
;; #### This test should check *every* position.
- (flet ((backward-up-list-moves-point-from-to (start expected-end)
- (goto-char start)
- (backward-up-list 1)
- (= (point) expected-end)))
+ (labels ((backward-up-list-moves-point-from-to (start expected-end)
+ (goto-char start)
+ (backward-up-list 1)
+ (= (point) expected-end)))
(Known-Bug-Expect-Failure
;; Evgeny's case
(Assert (backward-up-list-moves-point-from-to 16 12)))
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
commit: Force unfolding of (funcall #'(lambda () ...) if optimising, bytecomp.el.
13 years, 2 months
Aidan Kehoe
changeset: 5575:89cb6a66a61f
tag: tip
user: Aidan Kehoe <kehoea(a)parhasard.net>
date: Mon Oct 03 19:39:01 2011 +0100
files: lisp/ChangeLog lisp/bytecomp.el
description:
Force unfolding of (funcall #'(lambda () ...) if optimising, bytecomp.el.
lisp/ChangeLog addition:
2011-10-03 Aidan Kehoe <kehoea(a)parhasard.net>
* bytecomp.el (byte-compile-funcall):
Sometimes the optimizer shirks its responsibility and doesn't
unfold a lambda when it should. Do this here, if optimization is
turned on; this makes inlining labels more consistent and
trustworthy.
diff -r d4f334808463 -r 89cb6a66a61f lisp/ChangeLog
--- a/lisp/ChangeLog Sun Oct 02 15:32:16 2011 +0100
+++ b/lisp/ChangeLog Mon Oct 03 19:39:01 2011 +0100
@@ -1,3 +1,11 @@
+2011-10-03 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * bytecomp.el (byte-compile-funcall):
+ Sometimes the optimizer shirks its responsibility and doesn't
+ unfold a lambda when it should. Do this here, if optimization is
+ turned on; this makes inlining labels more consistent and
+ trustworthy.
+
2011-10-02 Aidan Kehoe <kehoea(a)parhasard.net>
* bytecomp.el (byte-compile-initial-macro-environment):
diff -r d4f334808463 -r 89cb6a66a61f lisp/bytecomp.el
--- a/lisp/bytecomp.el Sun Oct 02 15:32:16 2011 +0100
+++ b/lisp/bytecomp.el Mon Oct 03 19:39:01 2011 +0100
@@ -4157,8 +4157,19 @@
(byte-compile-constp (second form)))
(byte-compile-callargs-warn (cons (cl-const-expr-val (second form))
(nthcdr 2 form))))
- (mapc 'byte-compile-form (cdr form))
- (byte-compile-out 'byte-call (length (cdr (cdr form)))))
+ (if (and byte-optimize
+ (eq 'function (car-safe (cadr form)))
+ (eq 'lambda (car-safe (cadadr form)))
+ (or
+ (not (eq (setq form (cons (cadadr form) (cddr form)))
+ (setq form (byte-compile-unfold-lambda form))))
+ (prog1 nil (setq form `(funcall #',(car form) ,@(cdr form))))))
+ ;; Sometimes the optimizer fails to unfold well-formed calls of the
+ ;; form (funcall #'(lambda ...)); since we need it to do this for
+ ;; (declare (inline ...)) to work properly with labels, force that here.
+ (byte-compile-form form)
+ (mapc 'byte-compile-form (cdr form))
+ (byte-compile-out 'byte-call (length (cdr (cdr form))))))
(defun byte-compile-let (form)
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
[COMMIT] Support inlining labels, bytecomp.el.
13 years, 2 months
Aidan Kehoe
APPROVE COMMIT
NOTE: This patch has been committed.
# HG changeset patch
# User Aidan Kehoe <kehoea(a)parhasard.net>
# Date 1317565936 -3600
# Node ID d4f334808463b4785db56315e79b893d7a42b5e9
# Parent f0f1fd0d8486dc10d88245ca1f1f83f672557da5
Support inlining labels, bytecomp.el.
lisp/ChangeLog addition:
2011-10-02 Aidan Kehoe <kehoea(a)parhasard.net>
* bytecomp.el (byte-compile-initial-macro-environment):
Add #'declare to this, so it doesn't need to rely on
#'cl-compiling file to determine when we're byte-compiling.
Update #'labels to support declaring labels inline, as Common Lisp
requires.
* bytecomp.el (byte-compile-function-form):
Don't error if FUNCTION is quoting a non-lambda, non-symbol, just
return it.
* cl-extra.el (cl-macroexpand-all):
If a label name has been quoted, expand to the label placeholder
quoted with 'function. This allows the byte compiler to
distinguish between uses of the placeholder as data and uses in
contexts where it should be inlined.
* cl-macs.el:
* cl-macs.el (cl-do-proclaim):
When proclaming something as inline, if it is bound as a label,
don't modify the symbol's plist; instead, treat the first element
of its placeholder constant vector as a place to store compile
information.
* cl-macs.el (declare):
Leave processing declarations while compiling to the
implementation of #'declare in
byte-compile-initial-macro-environment.
tests/ChangeLog addition:
2011-10-02 Aidan Kehoe <kehoea(a)parhasard.net>
* automated/lisp-tests.el:
* automated/lisp-tests.el (+):
Test #'labels and inlining.
diff -r f0f1fd0d8486 -r d4f334808463 lisp/ChangeLog
--- a/lisp/ChangeLog Sun Sep 25 16:12:07 2011 +0100
+++ b/lisp/ChangeLog Sun Oct 02 15:32:16 2011 +0100
@@ -1,3 +1,29 @@
+2011-10-02 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * bytecomp.el (byte-compile-initial-macro-environment):
+ Add #'declare to this, so it doesn't need to rely on
+ #'cl-compiling file to determine when we're byte-compiling.
+ Update #'labels to support declaring labels inline, as Common Lisp
+ requires.
+ * bytecomp.el (byte-compile-function-form):
+ Don't error if FUNCTION is quoting a non-lambda, non-symbol, just
+ return it.
+ * cl-extra.el (cl-macroexpand-all):
+ If a label name has been quoted, expand to the label placeholder
+ quoted with 'function. This allows the byte compiler to
+ distinguish between uses of the placeholder as data and uses in
+ contexts where it should be inlined.
+ * cl-macs.el:
+ * cl-macs.el (cl-do-proclaim):
+ When proclaming something as inline, if it is bound as a label,
+ don't modify the symbol's plist; instead, treat the first element
+ of its placeholder constant vector as a place to store compile
+ information.
+ * cl-macs.el (declare):
+ Leave processing declarations while compiling to the
+ implementation of #'declare in
+ byte-compile-initial-macro-environment.
+
2011-09-25 Aidan Kehoe <kehoea(a)parhasard.net>
* files.el (binary-file-regexps):
diff -r f0f1fd0d8486 -r d4f334808463 lisp/bytecomp.el
--- a/lisp/bytecomp.el Sun Sep 25 16:12:07 2011 +0100
+++ b/lisp/bytecomp.el Sun Oct 02 15:32:16 2011 +0100
@@ -494,6 +494,11 @@
(if byte-compile-delete-errors
form
(funcall (cdr (symbol-function 'the)) type form))))
+ (declare
+ . ,#'(lambda (&rest specs)
+ (while specs
+ (if (listp cl-declare-stack) (push (car specs) cl-declare-stack))
+ (cl-do-proclaim (pop specs) nil))))
(load-time-value
. ,#'(lambda (form &optional read-only)
(let* ((gensym (gensym))
@@ -517,37 +522,116 @@
(placeholders
(mapcar #'(lambda (lambda)
(make-byte-code (second lambda) "\xc0\x87"
- [42] 1))
+ ;; This list is used for
+ ;; the byte-optimize
+ ;; property, if the
+ ;; function is to be
+ ;; inlined. See
+ ;; cl-do-proclaim.
+ (vector nil) 1))
lambdas))
(byte-compile-macro-environment
(pairlis names (mapcar
#'(lambda (placeholder)
`(lambda (&rest cl-labels-args)
+ ;; Be careful not to quote
+ ;; PLACEHOLDER, otherwise
+ ;; byte-optimize-funcall inlines
+ ;; it.
(list* 'funcall ,placeholder
cl-labels-args)))
placeholders)
byte-compile-macro-environment))
(gensym (gensym)))
- (put gensym 'byte-compile-label-alist
- (pairlis placeholders
- (mapcar 'second (mapcar 'cl-macroexpand-all
- lambdas))))
- (put gensym 'byte-compile
- #'(lambda (form)
- (let* ((byte-compile-label-alist
- (get (car form) 'byte-compile-label-alist)))
- (dolist (acons byte-compile-label-alist)
- (setf (cdr acons)
- (byte-compile-lambda (cdr acons))))
- (byte-compile-body-do-effect
- (sublis byte-compile-label-alist (cdr form)
-:test #'eq))
- (dolist (acons byte-compile-label-alist)
- (nsubst (cdr acons) (car acons)
- byte-compile-label-alist :test #'eq
-:descend-structures t)))))
- (cl-macroexpand-all (cons gensym body)
- byte-compile-macro-environment))))
+ (labels
+ ((byte-compile-transform-labels (form names lambdas
+ placeholders)
+ (let* ((inline
+ (mapcan
+ #'(lambda (name placeholder lambda)
+ (and
+ (eq
+ (getf (aref
+ (compiled-function-constants
+ placeholder) 0)
+ 'byte-optimizer)
+ 'byte-compile-inline-expand)
+ `(((function ,placeholder)
+ ,(byte-compile-lambda lambda)
+ (function ,lambda)))))
+ names placeholders lambdas))
+ (compiled
+ (mapcar #'byte-compile-lambda
+ (if (not inline)
+ lambdas
+ ;; See further down for the
+ ;; rationale of the sublis calls.
+ (sublis (pairlis
+ (mapcar #'cadar inline)
+ (mapcar #'third inline))
+ (sublis
+ (pairlis
+ (mapcar #'car inline)
+ (mapcar #'second inline))
+ lambdas :test #'equal)
+:test #'eq))))
+ elt)
+ (mapc #'(lambda (placeholder function)
+ (nsubst function placeholder compiled
+:test #'eq
+:descend-structures t))
+ placeholders compiled)
+ (when inline
+ (dolist (triad inline)
+ (nsubst (setq elt (elt compiled
+ (position (cadar triad)
+ placeholders)))
+ (second triad) compiled :test #'eq
+:descend-structures t)
+ (setf (second triad) elt))
+ ;; For inlined labels: first, replace uses of
+ ;; the placeholder in places where it's not an
+ ;; evident, explicit funcall (that is, where
+ ;; it is not to be inlined) with the compiled
+ ;; function:
+ (setq form (sublis
+ (pairlis (mapcar #'car inline)
+ (mapcar #'second inline))
+ form :test #'equal)
+ ;; Now replace uses of the placeholder
+ ;; where it is an evident funcall with the
+ ;; lambda, quoted as a function, to allow
+ ;; byte-optimize-funcall to do its
+ ;; thing. Note that the lambdas still have
+ ;; the placeholders, so there's no risk
+ ;; of recursive inlining.
+ form (sublis (pairlis
+ (mapcar #'cadar inline)
+ (mapcar #'third inline))
+ form :test #'eq)))
+ (sublis (pairlis placeholders compiled) form
+:test #'eq))))
+ (put gensym 'byte-compile
+ #'(lambda (form)
+ (let* ((names (cadr (cl-pop2 form)))
+ (lambdas (mapcar #'cadr (cdr (pop form))))
+ (placeholders (cadr (pop form))))
+ (byte-compile-body-do-effect
+ (byte-compile-transform-labels form names
+ lambdas
+ placeholders)))))
+ (put gensym 'byte-hunk-handler
+ #'(lambda (form)
+ (let* ((names (cadr (cl-pop2 form)))
+ (lambdas (mapcar #'cadr (cdr (pop form))))
+ (placeholders (cadr (pop form))))
+ (byte-compile-file-form
+ (cons 'progn
+ (byte-compile-transform-labels
+ form names lambdas placeholders))))))
+ (cl-macroexpand-all `(,gensym ',names (list ,@lambdas)
+ ',placeholders ,@body)
+ byte-compile-macro-environment)))))
(flet .
,#'(lambda (bindings &rest body)
(let* ((names (mapcar 'car bindings))
@@ -3699,10 +3783,9 @@
(if (cddr form)
(byte-compile-normal-call
`(signal 'wrong-number-of-arguments '(function ,(length (cdr form)))))
- (byte-compile-constant
- (cond ((symbolp (nth 1 form))
- (nth 1 form))
- ((byte-compile-lambda (nth 1 form)))))))
+ (byte-compile-constant (if (eq 'lambda (car-safe (nth 1 form)))
+ (byte-compile-lambda (nth 1 form))
+ (nth 1 form)))))
(defun byte-compile-insert (form)
(cond ((null (cdr form))
diff -r f0f1fd0d8486 -r d4f334808463 lisp/cl-extra.el
--- a/lisp/cl-extra.el Sun Sep 25 16:12:07 2011 +0100
+++ b/lisp/cl-extra.el Sun Oct 02 15:32:16 2011 +0100
@@ -619,8 +619,11 @@
(cl-macroexpand-all (nth 1 (nth 2 (nth 2 found))) env)
;; It's an atom, almost certainly a compiled function;
;; we're using the implementation of labels in
- ;; bytecomp.el.
- (nth 2 (nth 2 found)))
+ ;; bytecomp.el. Quote it with FUNCTION so that code can
+ ;; tell uses as data apart from the uses with funcall,
+ ;; where it's unquoted. #### We should warn if (car form)
+ ;; above is quote, rather than function.
+ (list 'function (nth 2 (nth 2 found))))
form))))
((memq (car form) '(defun defmacro))
(list* (car form) (nth 1 form) (cl-macroexpand-body (cddr form) env)))
diff -r f0f1fd0d8486 -r d4f334808463 lisp/cl-macs.el
--- a/lisp/cl-macs.el Sun Sep 25 16:12:07 2011 +0100
+++ b/lisp/cl-macs.el Sun Oct 02 15:32:16 2011 +0100
@@ -1969,18 +1969,38 @@
((eq (car-safe spec) 'inline)
(while (setq spec (cdr spec))
- (or (memq (get (car spec) 'byte-optimizer)
- '(nil byte-compile-inline-expand))
- (error "%s already has a byte-optimizer, can't make it inline"
- (car spec)))
- (put (car spec) 'byte-optimizer 'byte-compile-inline-expand)))
-
+ (let ((assq (cdr (assq (car spec) byte-compile-macro-environment))))
+ (if (and (consp assq) (eq (nth 1 (nth 1 assq)) 'cl-labels-args)
+ (atom (setq assq (nth 2 (nth 2 assq)))))
+ ;; It's a label, and we're using the labels
+ ;; implementation in bytecomp.el. Tell the compiler
+ ;; to inline it, don't mark the symbol to be inlined
+ ;; globally.
+ (setf (getf (aref (compiled-function-constants assq) 0)
+ 'byte-optimizer)
+ 'byte-compile-inline-expand)
+ (or (memq (get (car spec) 'byte-optimizer)
+ '(nil byte-compile-inline-expand))
+ (error
+ "%s already has a byte-optimizer, can't make it inline"
+ (car spec)))
+ (put (car spec) 'byte-optimizer 'byte-compile-inline-expand)))))
((eq (car-safe spec) 'notinline)
(while (setq spec (cdr spec))
- (if (eq (get (car spec) 'byte-optimizer)
- 'byte-compile-inline-expand)
- (put (car spec) 'byte-optimizer nil))))
-
+ (let ((assq (cdr (assq (car spec) byte-compile-macro-environment))))
+ (if (and (consp assq) (eq (nth 1 (nth 1 assq)) 'cl-labels-args)
+ (atom (setq assq (nth 2 (nth 2 assq)))))
+ ;; It's a label, and we're using the labels
+ ;; implementation in bytecomp.el. Tell the compiler
+ ;; not to inline it.
+ (if (eq 'byte-compile-inline-expand
+ (getf (aref (compiled-function-constants assq) 0)
+ 'byte-optimizer))
+ (remf (aref (compiled-function-constants assq) 0)
+ 'byte-optimizer))
+ (if (eq (get (car spec) 'byte-optimizer)
+ 'byte-compile-inline-expand)
+ (put (car spec) 'byte-optimizer nil))))))
((eq (car-safe spec) 'optimize)
(let ((speed (assq (nth 1 (assq 'speed (cdr spec)))
'((0 . nil) (1 . t) (2 . t) (3 . t))))
@@ -2014,14 +2034,8 @@
;;;###autoload
(defmacro declare (&rest specs)
- (if (cl-compiling-file)
- (while specs
- (if (listp cl-declare-stack) (push (car specs) cl-declare-stack))
- (cl-do-proclaim (pop specs) nil)))
nil)
-
-
;;; Generalized variables.
;;;###autoload
diff -r f0f1fd0d8486 -r d4f334808463 tests/ChangeLog
--- a/tests/ChangeLog Sun Sep 25 16:12:07 2011 +0100
+++ b/tests/ChangeLog Sun Oct 02 15:32:16 2011 +0100
@@ -1,3 +1,9 @@
+2011-10-02 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * automated/lisp-tests.el:
+ * automated/lisp-tests.el (+):
+ Test #'labels and inlining.
+
2011-09-04 Aidan Kehoe <kehoea(a)parhasard.net>
* automated/lisp-reader-tests.el:
diff -r f0f1fd0d8486 -r d4f334808463 tests/automated/lisp-tests.el
--- a/tests/automated/lisp-tests.el Sun Sep 25 16:12:07 2011 +0100
+++ b/tests/automated/lisp-tests.el Sun Oct 02 15:32:16 2011 +0100
@@ -2939,4 +2939,50 @@
(Check-Error wrong-number-of-arguments (apply-partially))
(Assert (equal (funcall construct-list) '(5 6 7))))
+;; Test labels and inlining.
+(labels
+ ((+ (&rest arguments)
+ ;; Shades of Java, hah.
+ (mapconcat #'prin1-to-string arguments ", "))
+ (print-with-commas (stream one two three four five)
+ (princ (+ one two three four five) stream))
+ (bookend (open close &rest arguments)
+ (refer-to-bookend (concat open (apply #'+ arguments) close)))
+ (refer-to-bookend (string)
+ (bookend "[" "]" string "hello" "there")))
+ (declare (inline + print-with-commas bookend refer-to-bookend))
+ (macrolet
+ ((with-first-arguments (&optional form)
+ (append form (list 1 [hi there] 40 "this is a string" pi)))
+ (with-second-arguments (&optional form)
+ (append form (list pi e ''hello ''there [40 50 60])))
+ (with-both-arguments (&optional form)
+ (append form
+ (macroexpand '(with-first-arguments))
+ (macroexpand '(with-second-arguments)))))
+
+ (with-temp-buffer
+ (Assert
+ (equal
+ (mapconcat #'prin1-to-string (with-first-arguments (list)) ", ")
+ (with-first-arguments (print-with-commas (current-buffer))))
+ "checking print-with-commas gives the expected result")
+ (Assert
+ (or
+ (not (compiled-function-p (indirect-function #'print-with-commas)))
+ (notany #'compiled-function-p
+ (compiled-function-constants
+ (indirect-function #'print-with-commas))))
+ "checking the label + was inlined correctly")
+ (insert ", ")
+ ;; This call to + will be inline in compiled code, but there's
+ ;; no easy way for us to check that:
+ (Assert (null (insert (with-second-arguments (+)))))
+ (Assert (equal
+ (mapconcat #'prin1-to-string (with-both-arguments (list)) ", ")
+ (buffer-string))
+ "checking the buffer contents are as expected at the end.")
+ (Assert (not (funcall (intern "eq") #'bookend #'refer-to-bookend))
+ "checking two mutually recursive functions compiled OK"))))
+
;;; end of lisp-tests.el
--
‘Iodine deficiency was endemic in parts of the UK until, through what has been
described as “an unplanned and accidental public health triumph”, iodine was
added to cattle feed to improve milk production in the 1930s.’
(EN Pearce, Lancet, June 2011)
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches
commit: Support inlining labels, bytecomp.el.
13 years, 2 months
Aidan Kehoe
changeset: 5574:d4f334808463
tag: tip
user: Aidan Kehoe <kehoea(a)parhasard.net>
date: Sun Oct 02 15:32:16 2011 +0100
files: lisp/ChangeLog lisp/bytecomp.el lisp/cl-extra.el lisp/cl-macs.el tests/ChangeLog tests/automated/lisp-tests.el
description:
Support inlining labels, bytecomp.el.
lisp/ChangeLog addition:
2011-10-02 Aidan Kehoe <kehoea(a)parhasard.net>
* bytecomp.el (byte-compile-initial-macro-environment):
Add #'declare to this, so it doesn't need to rely on
#'cl-compiling file to determine when we're byte-compiling.
Update #'labels to support declaring labels inline, as Common Lisp
requires.
* bytecomp.el (byte-compile-function-form):
Don't error if FUNCTION is quoting a non-lambda, non-symbol, just
return it.
* cl-extra.el (cl-macroexpand-all):
If a label name has been quoted, expand to the label placeholder
quoted with 'function. This allows the byte compiler to
distinguish between uses of the placeholder as data and uses in
contexts where it should be inlined.
* cl-macs.el:
* cl-macs.el (cl-do-proclaim):
When proclaming something as inline, if it is bound as a label,
don't modify the symbol's plist; instead, treat the first element
of its placeholder constant vector as a place to store compile
information.
* cl-macs.el (declare):
Leave processing declarations while compiling to the
implementation of #'declare in
byte-compile-initial-macro-environment.
tests/ChangeLog addition:
2011-10-02 Aidan Kehoe <kehoea(a)parhasard.net>
* automated/lisp-tests.el:
* automated/lisp-tests.el (+):
Test #'labels and inlining.
diff -r f0f1fd0d8486 -r d4f334808463 lisp/ChangeLog
--- a/lisp/ChangeLog Sun Sep 25 16:12:07 2011 +0100
+++ b/lisp/ChangeLog Sun Oct 02 15:32:16 2011 +0100
@@ -1,3 +1,29 @@
+2011-10-02 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * bytecomp.el (byte-compile-initial-macro-environment):
+ Add #'declare to this, so it doesn't need to rely on
+ #'cl-compiling file to determine when we're byte-compiling.
+ Update #'labels to support declaring labels inline, as Common Lisp
+ requires.
+ * bytecomp.el (byte-compile-function-form):
+ Don't error if FUNCTION is quoting a non-lambda, non-symbol, just
+ return it.
+ * cl-extra.el (cl-macroexpand-all):
+ If a label name has been quoted, expand to the label placeholder
+ quoted with 'function. This allows the byte compiler to
+ distinguish between uses of the placeholder as data and uses in
+ contexts where it should be inlined.
+ * cl-macs.el:
+ * cl-macs.el (cl-do-proclaim):
+ When proclaming something as inline, if it is bound as a label,
+ don't modify the symbol's plist; instead, treat the first element
+ of its placeholder constant vector as a place to store compile
+ information.
+ * cl-macs.el (declare):
+ Leave processing declarations while compiling to the
+ implementation of #'declare in
+ byte-compile-initial-macro-environment.
+
2011-09-25 Aidan Kehoe <kehoea(a)parhasard.net>
* files.el (binary-file-regexps):
diff -r f0f1fd0d8486 -r d4f334808463 lisp/bytecomp.el
--- a/lisp/bytecomp.el Sun Sep 25 16:12:07 2011 +0100
+++ b/lisp/bytecomp.el Sun Oct 02 15:32:16 2011 +0100
@@ -494,6 +494,11 @@
(if byte-compile-delete-errors
form
(funcall (cdr (symbol-function 'the)) type form))))
+ (declare
+ . ,#'(lambda (&rest specs)
+ (while specs
+ (if (listp cl-declare-stack) (push (car specs) cl-declare-stack))
+ (cl-do-proclaim (pop specs) nil))))
(load-time-value
. ,#'(lambda (form &optional read-only)
(let* ((gensym (gensym))
@@ -517,37 +522,116 @@
(placeholders
(mapcar #'(lambda (lambda)
(make-byte-code (second lambda) "\xc0\x87"
- [42] 1))
+ ;; This list is used for
+ ;; the byte-optimize
+ ;; property, if the
+ ;; function is to be
+ ;; inlined. See
+ ;; cl-do-proclaim.
+ (vector nil) 1))
lambdas))
(byte-compile-macro-environment
(pairlis names (mapcar
#'(lambda (placeholder)
`(lambda (&rest cl-labels-args)
+ ;; Be careful not to quote
+ ;; PLACEHOLDER, otherwise
+ ;; byte-optimize-funcall inlines
+ ;; it.
(list* 'funcall ,placeholder
cl-labels-args)))
placeholders)
byte-compile-macro-environment))
(gensym (gensym)))
- (put gensym 'byte-compile-label-alist
- (pairlis placeholders
- (mapcar 'second (mapcar 'cl-macroexpand-all
- lambdas))))
- (put gensym 'byte-compile
- #'(lambda (form)
- (let* ((byte-compile-label-alist
- (get (car form) 'byte-compile-label-alist)))
- (dolist (acons byte-compile-label-alist)
- (setf (cdr acons)
- (byte-compile-lambda (cdr acons))))
- (byte-compile-body-do-effect
- (sublis byte-compile-label-alist (cdr form)
-:test #'eq))
- (dolist (acons byte-compile-label-alist)
- (nsubst (cdr acons) (car acons)
- byte-compile-label-alist :test #'eq
-:descend-structures t)))))
- (cl-macroexpand-all (cons gensym body)
- byte-compile-macro-environment))))
+ (labels
+ ((byte-compile-transform-labels (form names lambdas
+ placeholders)
+ (let* ((inline
+ (mapcan
+ #'(lambda (name placeholder lambda)
+ (and
+ (eq
+ (getf (aref
+ (compiled-function-constants
+ placeholder) 0)
+ 'byte-optimizer)
+ 'byte-compile-inline-expand)
+ `(((function ,placeholder)
+ ,(byte-compile-lambda lambda)
+ (function ,lambda)))))
+ names placeholders lambdas))
+ (compiled
+ (mapcar #'byte-compile-lambda
+ (if (not inline)
+ lambdas
+ ;; See further down for the
+ ;; rationale of the sublis calls.
+ (sublis (pairlis
+ (mapcar #'cadar inline)
+ (mapcar #'third inline))
+ (sublis
+ (pairlis
+ (mapcar #'car inline)
+ (mapcar #'second inline))
+ lambdas :test #'equal)
+:test #'eq))))
+ elt)
+ (mapc #'(lambda (placeholder function)
+ (nsubst function placeholder compiled
+:test #'eq
+:descend-structures t))
+ placeholders compiled)
+ (when inline
+ (dolist (triad inline)
+ (nsubst (setq elt (elt compiled
+ (position (cadar triad)
+ placeholders)))
+ (second triad) compiled :test #'eq
+:descend-structures t)
+ (setf (second triad) elt))
+ ;; For inlined labels: first, replace uses of
+ ;; the placeholder in places where it's not an
+ ;; evident, explicit funcall (that is, where
+ ;; it is not to be inlined) with the compiled
+ ;; function:
+ (setq form (sublis
+ (pairlis (mapcar #'car inline)
+ (mapcar #'second inline))
+ form :test #'equal)
+ ;; Now replace uses of the placeholder
+ ;; where it is an evident funcall with the
+ ;; lambda, quoted as a function, to allow
+ ;; byte-optimize-funcall to do its
+ ;; thing. Note that the lambdas still have
+ ;; the placeholders, so there's no risk
+ ;; of recursive inlining.
+ form (sublis (pairlis
+ (mapcar #'cadar inline)
+ (mapcar #'third inline))
+ form :test #'eq)))
+ (sublis (pairlis placeholders compiled) form
+:test #'eq))))
+ (put gensym 'byte-compile
+ #'(lambda (form)
+ (let* ((names (cadr (cl-pop2 form)))
+ (lambdas (mapcar #'cadr (cdr (pop form))))
+ (placeholders (cadr (pop form))))
+ (byte-compile-body-do-effect
+ (byte-compile-transform-labels form names
+ lambdas
+ placeholders)))))
+ (put gensym 'byte-hunk-handler
+ #'(lambda (form)
+ (let* ((names (cadr (cl-pop2 form)))
+ (lambdas (mapcar #'cadr (cdr (pop form))))
+ (placeholders (cadr (pop form))))
+ (byte-compile-file-form
+ (cons 'progn
+ (byte-compile-transform-labels
+ form names lambdas placeholders))))))
+ (cl-macroexpand-all `(,gensym ',names (list ,@lambdas)
+ ',placeholders ,@body)
+ byte-compile-macro-environment)))))
(flet .
,#'(lambda (bindings &rest body)
(let* ((names (mapcar 'car bindings))
@@ -3699,10 +3783,9 @@
(if (cddr form)
(byte-compile-normal-call
`(signal 'wrong-number-of-arguments '(function ,(length (cdr form)))))
- (byte-compile-constant
- (cond ((symbolp (nth 1 form))
- (nth 1 form))
- ((byte-compile-lambda (nth 1 form)))))))
+ (byte-compile-constant (if (eq 'lambda (car-safe (nth 1 form)))
+ (byte-compile-lambda (nth 1 form))
+ (nth 1 form)))))
(defun byte-compile-insert (form)
(cond ((null (cdr form))
diff -r f0f1fd0d8486 -r d4f334808463 lisp/cl-extra.el
--- a/lisp/cl-extra.el Sun Sep 25 16:12:07 2011 +0100
+++ b/lisp/cl-extra.el Sun Oct 02 15:32:16 2011 +0100
@@ -619,8 +619,11 @@
(cl-macroexpand-all (nth 1 (nth 2 (nth 2 found))) env)
;; It's an atom, almost certainly a compiled function;
;; we're using the implementation of labels in
- ;; bytecomp.el.
- (nth 2 (nth 2 found)))
+ ;; bytecomp.el. Quote it with FUNCTION so that code can
+ ;; tell uses as data apart from the uses with funcall,
+ ;; where it's unquoted. #### We should warn if (car form)
+ ;; above is quote, rather than function.
+ (list 'function (nth 2 (nth 2 found))))
form))))
((memq (car form) '(defun defmacro))
(list* (car form) (nth 1 form) (cl-macroexpand-body (cddr form) env)))
diff -r f0f1fd0d8486 -r d4f334808463 lisp/cl-macs.el
--- a/lisp/cl-macs.el Sun Sep 25 16:12:07 2011 +0100
+++ b/lisp/cl-macs.el Sun Oct 02 15:32:16 2011 +0100
@@ -1969,18 +1969,38 @@
((eq (car-safe spec) 'inline)
(while (setq spec (cdr spec))
- (or (memq (get (car spec) 'byte-optimizer)
- '(nil byte-compile-inline-expand))
- (error "%s already has a byte-optimizer, can't make it inline"
- (car spec)))
- (put (car spec) 'byte-optimizer 'byte-compile-inline-expand)))
-
+ (let ((assq (cdr (assq (car spec) byte-compile-macro-environment))))
+ (if (and (consp assq) (eq (nth 1 (nth 1 assq)) 'cl-labels-args)
+ (atom (setq assq (nth 2 (nth 2 assq)))))
+ ;; It's a label, and we're using the labels
+ ;; implementation in bytecomp.el. Tell the compiler
+ ;; to inline it, don't mark the symbol to be inlined
+ ;; globally.
+ (setf (getf (aref (compiled-function-constants assq) 0)
+ 'byte-optimizer)
+ 'byte-compile-inline-expand)
+ (or (memq (get (car spec) 'byte-optimizer)
+ '(nil byte-compile-inline-expand))
+ (error
+ "%s already has a byte-optimizer, can't make it inline"
+ (car spec)))
+ (put (car spec) 'byte-optimizer 'byte-compile-inline-expand)))))
((eq (car-safe spec) 'notinline)
(while (setq spec (cdr spec))
- (if (eq (get (car spec) 'byte-optimizer)
- 'byte-compile-inline-expand)
- (put (car spec) 'byte-optimizer nil))))
-
+ (let ((assq (cdr (assq (car spec) byte-compile-macro-environment))))
+ (if (and (consp assq) (eq (nth 1 (nth 1 assq)) 'cl-labels-args)
+ (atom (setq assq (nth 2 (nth 2 assq)))))
+ ;; It's a label, and we're using the labels
+ ;; implementation in bytecomp.el. Tell the compiler
+ ;; not to inline it.
+ (if (eq 'byte-compile-inline-expand
+ (getf (aref (compiled-function-constants assq) 0)
+ 'byte-optimizer))
+ (remf (aref (compiled-function-constants assq) 0)
+ 'byte-optimizer))
+ (if (eq (get (car spec) 'byte-optimizer)
+ 'byte-compile-inline-expand)
+ (put (car spec) 'byte-optimizer nil))))))
((eq (car-safe spec) 'optimize)
(let ((speed (assq (nth 1 (assq 'speed (cdr spec)))
'((0 . nil) (1 . t) (2 . t) (3 . t))))
@@ -2014,14 +2034,8 @@
;;;###autoload
(defmacro declare (&rest specs)
- (if (cl-compiling-file)
- (while specs
- (if (listp cl-declare-stack) (push (car specs) cl-declare-stack))
- (cl-do-proclaim (pop specs) nil)))
nil)
-
-
;;; Generalized variables.
;;;###autoload
diff -r f0f1fd0d8486 -r d4f334808463 tests/ChangeLog
--- a/tests/ChangeLog Sun Sep 25 16:12:07 2011 +0100
+++ b/tests/ChangeLog Sun Oct 02 15:32:16 2011 +0100
@@ -1,3 +1,9 @@
+2011-10-02 Aidan Kehoe <kehoea(a)parhasard.net>
+
+ * automated/lisp-tests.el:
+ * automated/lisp-tests.el (+):
+ Test #'labels and inlining.
+
2011-09-04 Aidan Kehoe <kehoea(a)parhasard.net>
* automated/lisp-reader-tests.el:
diff -r f0f1fd0d8486 -r d4f334808463 tests/automated/lisp-tests.el
--- a/tests/automated/lisp-tests.el Sun Sep 25 16:12:07 2011 +0100
+++ b/tests/automated/lisp-tests.el Sun Oct 02 15:32:16 2011 +0100
@@ -2939,4 +2939,50 @@
(Check-Error wrong-number-of-arguments (apply-partially))
(Assert (equal (funcall construct-list) '(5 6 7))))
+;; Test labels and inlining.
+(labels
+ ((+ (&rest arguments)
+ ;; Shades of Java, hah.
+ (mapconcat #'prin1-to-string arguments ", "))
+ (print-with-commas (stream one two three four five)
+ (princ (+ one two three four five) stream))
+ (bookend (open close &rest arguments)
+ (refer-to-bookend (concat open (apply #'+ arguments) close)))
+ (refer-to-bookend (string)
+ (bookend "[" "]" string "hello" "there")))
+ (declare (inline + print-with-commas bookend refer-to-bookend))
+ (macrolet
+ ((with-first-arguments (&optional form)
+ (append form (list 1 [hi there] 40 "this is a string" pi)))
+ (with-second-arguments (&optional form)
+ (append form (list pi e ''hello ''there [40 50 60])))
+ (with-both-arguments (&optional form)
+ (append form
+ (macroexpand '(with-first-arguments))
+ (macroexpand '(with-second-arguments)))))
+
+ (with-temp-buffer
+ (Assert
+ (equal
+ (mapconcat #'prin1-to-string (with-first-arguments (list)) ", ")
+ (with-first-arguments (print-with-commas (current-buffer))))
+ "checking print-with-commas gives the expected result")
+ (Assert
+ (or
+ (not (compiled-function-p (indirect-function #'print-with-commas)))
+ (notany #'compiled-function-p
+ (compiled-function-constants
+ (indirect-function #'print-with-commas))))
+ "checking the label + was inlined correctly")
+ (insert ", ")
+ ;; This call to + will be inline in compiled code, but there's
+ ;; no easy way for us to check that:
+ (Assert (null (insert (with-second-arguments (+)))))
+ (Assert (equal
+ (mapconcat #'prin1-to-string (with-both-arguments (list)) ", ")
+ (buffer-string))
+ "checking the buffer contents are as expected at the end.")
+ (Assert (not (funcall (intern "eq") #'bookend #'refer-to-bookend))
+ "checking two mutually recursive functions compiled OK"))))
+
;;; end of lisp-tests.el
_______________________________________________
XEmacs-Patches mailing list
XEmacs-Patches(a)xemacs.org
http://lists.xemacs.org/mailman/listinfo/xemacs-patches