diff --git a/pcl/cmu-low.lisp b/pcl/cmu-low.lisp index d8e7618feed299e63c6854b9a6b2c421c75531ed..5b5b08368c14f9f978273b54eefb8509fe1d1af6 100644 --- a/pcl/cmu-low.lisp +++ b/pcl/cmu-low.lisp @@ -127,8 +127,32 @@ ;;; (defmacro std-instance-p (x) `(kernel:%instancep ,x)) -(defmacro pcl-instance-p (x) - `(typep (kernel:layout-of ,x) 'wrapper)) + +;;; PCL-INSTANCE-P is implemented via a compiler transform so that the +;;; test can be optimised away when the result is known, such as is +;;; typically the case during slot access within methods, see +;;; get-slots-or-nil below. + +(in-package "C") + +(defknown pcl::pcl-instance-p (t) boolean + (movable foldable flushable explicit-check)) + +(deftransform pcl::pcl-instance-p ((object)) + (let* ((otype (continuation-type object)) + (std-obj (specifier-type 'pcl::std-object))) + (cond + ;; Flush tests whose result is known at compile time. + ((csubtypep otype std-obj) 't) + ((not (types-intersect otype std-obj)) 'nil) + (t + `(typep (kernel:layout-of object) 'pcl::wrapper))))) + +(in-package "PCL") + +;;; Definition for interpreted code. +(defun pcl-instance-p (x) + (typep (kernel:layout-of x) 'wrapper)) ;;; We define this as STANDARD-INSTANCE, since we're going to clobber the