Reported by Dan Corkill on sbcl-devel.
* Use WRITE-STRING on SYMBOL-NAME instead of FORMAT %A to ironclad
the specialized function name generation.
* Tests.
;;;; -*- coding: utf-8; -*-
+changes in sbcl-1.0.9 relative to sbcl-1.0.8:
+ * bug fix: new compiler transforms for MEMBER and ASSOC were affected
+ by printer control variables. (reported by Dan Corkill)
+
changes in sbcl-1.0.8 relative to sbcl-1.0.7:
* enhancement: experimental macro SB-EXT:COMPARE-AND-SWAP provides
atomic compare-and-swap operations on threaded platforms.
(or end length)
(sb!impl::signal-bounding-indices-bad-error vector start end)))))
+(defun specialized-list-seek-function-name (function-name key-functions)
+ (or (find-symbol (with-output-to-string (s)
+ ;; Write "%NAME-FUN1-FUN2-FUN3", etc. Not only is
+ ;; this ever so slightly faster then FORMAT, this
+ ;; way we are also proof against *PRINT-CASE*
+ ;; frobbing and such.
+ (write-char #\% s)
+ (write-string (symbol-name function-name) s)
+ (dolist (f key-functions)
+ (write-char #\- s)
+ (write-string (symbol-name f) s)))
+ (load-time-value (find-package "SB!KERNEL")))
+ (bug "Unknown list item seek transform: name=~S, key-functions=~S"
+ function-name key-functions)))
+
(defun transform-list-item-seek (name list key test test-not node)
;; Key can legally be NIL, but if it's NIL for sure we pretend it's
;; not there at all. If it might be NIL, make up a form to that
(values key '(%coerce-callable-to-fun key))))))
(let* ((funs (remove nil (list (and key 'key) (cond (test 'test)
(test-not 'test-not)))))
- (out-of-line (or (find-symbol (format nil "%~A~{-~A~}" name funs)
- (load-time-value (find-package "SB!KERNEL")))
- (bug "Unknown list item seek transform: name=~S, funs=~S"
- name funs)))
(target-expr (if key '(%funcall key target) 'target))
(test-expr (cond (test `(%funcall test item ,target-expr))
(test-not `(not (%funcall test-not item ,target-expr)))
;; constant nil list -- nothing to find!
nil)
(t
- `(,out-of-line item list ,@(mapcar #'ensure-fun funs)))))))))
+ ;; specialized out-of-line version
+ `(,(specialized-list-seek-function-name name funs)
+ item list ,@(mapcar #'ensure-fun funs)))))))))
(deftransform member ((item list &key key test test-not) * * :node node)
(transform-list-item-seek 'member list key test test-not node))
(assert (equal ',expected (let ((numbers ',numbers)
(tricky ',tricky))
(funcall fun ,@(cdr form)))))
- (assert (equal ',expected (funcall (lambda ()
- (declare (optimize speed))
- (let ((numbers ',numbers)
- (tricky ',tricky))
- ,form)))))
- (assert (equal ',expected (funcall (lambda ()
- (declare (optimize space))
- (let ((numbers ',numbers)
- (tricky ',tricky))
+ (assert (equal ',expected (funcall (lambda ()
+ (declare (optimize speed))
+ (let ((numbers ',numbers)
+ (tricky ',tricky))
+ ,form)))))
+ (assert (equal ',expected (funcall (lambda ()
+ (declare (optimize space))
+ (let ((numbers ',numbers)
+ (tricky ',tricky))
,form)))))))))
(let ((fun (car (list 'assoc))))
(test (1 a) (assoc 1 numbers))
;; Bug reported by Paul Dietz: ASSOC should ignore NIL elements in a
;; alist
(test (nil . c) (assoc nil tricky :test #'eq))))
+
+;;; bug reported by Dan Corkill: *PRINT-CASE* affected the compiler transforms
+;;; for ASSOC & MEMBER
+(let ((*print-case* :downcase))
+ (assert (eql 2 (cdr (funcall (compile nil '(lambda (i l) (assoc i l)))
+ :b '((:a . 1) (:b . 2))))))
+ (assert (equal '(3 4 5) (funcall (compile nil '(lambda (i l) (member i l)))
+ 3 '(1 2 3 4 5)))))
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.8.6"
+"1.0.8.7"