changes relative to sbcl-1.0.36:
* enhancement: Backtrace from THROW to uncaught tag on x86oids now shows
stack frame thrown from.
+ * optimization: SLOT-VALUE and (SETF SLOT-VALUE) take advantage of
+ constraint propgation, allowing better compilation eg. when used to
+ access structures with WITH-SLOTS. (lp#520366)
* bug fix: Fix compiler error involving MAKE-ARRAY and IF forms
in :INITIAL-CONTENTS. (lp#523612)
* bug fix: FUNCTION-LAMBDA-EXPRESSION lost declarations from interpreted
(defknown slot-value (t symbol) t (any))
(defknown sb-pcl::set-slot-value (t symbol t) t (any))
-(deftransform slot-value ((object slot-name) (t (constant-arg symbol)))
+(deftransform slot-value ((object slot-name) (t (constant-arg symbol)) *
+ :node node)
(let ((c-slot-name (lvar-value slot-name)))
(if (sb-pcl::interned-symbol-p c-slot-name)
(let* ((type (lvar-type object))
(sb-kernel::structure-classoid-name type))))
(dsd (when dd
(find c-slot-name (dd-slots dd) :key #'dsd-name))))
- (if dsd
- `(,(dsd-accessor-name dsd) object)
- `(sb-pcl::accessor-slot-value object ',c-slot-name)))
+ (cond (dsd
+ `(,(dsd-accessor-name dsd) object))
+ (t
+ (delay-ir1-transform node :constraint)
+ `(sb-pcl::accessor-slot-value object ',c-slot-name))))
(give-up-ir1-transform "slot name is not an interned symbol"))))
(deftransform sb-pcl::set-slot-value ((object slot-name new-value)
(sb-kernel::structure-classoid-name type))))
(dsd (when dd
(find c-slot-name (dd-slots dd) :key #'dsd-name))))
- (if dsd
- `(setf (,(dsd-accessor-name dsd) object) new-value)
- (if (policy node (= safety 3))
- ;; Safe code wants to check the type, and the global
- ;; accessor won't do that. Also see the comment in the
- ;; compiler-macro.
- (give-up-ir1-transform "cannot use optimized accessor in safe code")
- `(sb-pcl::accessor-set-slot-value object ',c-slot-name new-value))))
+ (cond (dsd
+ `(setf (,(dsd-accessor-name dsd) object) new-value))
+ ((policy node (= safety 3))
+ ;; Safe code wants to check the type, and the global
+ ;; accessor won't do that. Also see the comment in the
+ ;; compiler-macro.
+ (give-up-ir1-transform "cannot use optimized accessor in safe code"))
+ (t
+ (delay-ir1-transform node :constraint)
+ `(sb-pcl::accessor-set-slot-value object ',c-slot-name new-value))))
(give-up-ir1-transform "slot name is not an interned symbol"))))
;;;; absolutely no warranty. See the COPYING and CREDITS files for
;;;; more information.
+(load "compiler-test-util.lisp")
(defpackage "CLOS-IMPURE"
- (:use "CL" "ASSERTOID" "TEST-UTIL"))
+ (:use "CL" "ASSERTOID" "TEST-UTIL" "COMPILER-TEST-UTIL"))
(in-package "CLOS-IMPURE")
\f
;;; It should be possible to do DEFGENERIC and DEFMETHOD referring to
bug-485019)
(bug-485019 (make-instance 'bug-485019)))
+;;; The compiler didn't propagate the declarared type before applying
+;;; the transform for (SETF SLOT-VALUE), so the generic accessor was used.
+(defstruct foo-520366
+ slot)
+(defun quux-520366 (cont)
+ (funcall cont))
+(defun bar-520366 (foo-struct)
+ (declare (type foo-520366 foo-struct))
+ (with-slots (slot) foo-struct
+ (tagbody
+ (quux-520366 #'(lambda ()
+ (setf slot :value)
+ (go TAG)))
+ TAG)))
+(with-test (:name :bug-520366)
+ (let ((callees (find-named-callees #'bar-520366)))
+ (assert (equal (list #'quux) callees))))
+
;;;; success