+;;;; PCL's view of funcallable instances
+
+(defstruct (pcl-funcallable-instance
+ (:alternate-metaclass sb-kernel:funcallable-instance
+ sb-kernel:random-pcl-class
+ sb-kernel:make-random-pcl-class)
+ (:type sb-kernel:funcallable-structure)
+ (:constructor allocate-funcallable-instance-1 ())
+ (:copier nil)
+ (:conc-name nil))
+ ;; Note: The PCL wrapper is in the layout slot.
+
+ ;; PCL data vector.
+ (pcl-funcallable-instance-slots nil)
+ ;; The debug-name for this function.
+ (funcallable-instance-name nil))
+
+(import 'sb-kernel:funcallable-instance-p)
+
+;;; This "works" on non-PCL FINs, which allows us to weaken
+;;; FUNCALLABLE-INSTANCE-P to return true for all FINs. This is also
+;;; necessary for bootstrapping to work, since the layouts for early
+;;; GFs are not initially initialized.
+(defmacro funcallable-instance-data-1 (fin slot)
+ (ecase (eval slot)
+ (wrapper `(sb-kernel:%funcallable-instance-layout ,fin))
+ (slots `(sb-kernel:%funcallable-instance-info ,fin 0))))
+
+;;; FIXME: Now that we no longer try to make our CLOS implementation
+;;; portable to other implementations of Common Lisp, all the
+;;; funcallable instance wrapper logic here can go away in favor
+;;; of direct calls to native SBCL funcallable instance operations.
+(defun set-funcallable-instance-function (fin new-value)
+ (declare (type function new-value))
+ (aver (funcallable-instance-p fin))
+ (setf (sb-kernel:funcallable-instance-function fin) new-value))
+(defmacro fsc-instance-p (fin)
+ `(funcallable-instance-p ,fin))
+(defmacro fsc-instance-class (fin)
+ `(wrapper-class (funcallable-instance-data-1 ,fin 'wrapper)))
+(defmacro fsc-instance-wrapper (fin)
+ `(funcallable-instance-data-1 ,fin 'wrapper))
+(defmacro fsc-instance-slots (fin)
+ `(funcallable-instance-data-1 ,fin 'slots))
+\f
+(declaim (inline clos-slots-ref (setf clos-slots-ref)))