(defmethod class-default-initargs ((class slot-class))
(plist-value class 'default-initargs))
-(defmethod class-constructors ((class slot-class))
- (plist-value class 'constructors))
-
(defmethod class-slot-cells ((class std-class))
(plist-value class 'class-slot-cells))
\f
(with-slots (direct-methods) specializer
(or (cdr direct-methods)
(setf (cdr direct-methods)
- (gathering1 (collecting-once)
+ (let (collect)
(dolist (m (car direct-methods))
- (gather1 (method-generic-function m))))))))
+ ;; the old PCL code used COLLECTING-ONCE which used
+ ;; #'EQ to check for newness
+ (pushnew (method-generic-function m) collect :test #'eq))
+ (nreverse collect))))))
\f
;;; This hash table is used to store the direct methods and direct generic
;;; functions of EQL specializers. Each value in the table is the cons.
(when entry
(or (cdr entry)
(setf (cdr entry)
- (gathering1 (collecting-once)
+ (let (collect)
(dolist (m (car entry))
- (gather1 (method-generic-function m)))))))))
+ (pushnew (method-generic-function m) collect :test #'eq))
+ (nreverse collect)))))))
(defun map-specializers (function)
(map-all-classes #'(lambda (class)
(defmethod ensure-class-using-class (name (class null) &rest args &key)
(multiple-value-bind (meta initargs)
(ensure-class-values class args)
- (inform-type-system-about-class (class-prototype meta) name);***
(setf class (apply #'make-instance meta :name name initargs)
(find-class name) class)
- (inform-type-system-about-class class name) ;***
+ (inform-type-system-about-class class name)
class))
(defmethod ensure-class-using-class (name (class pcl-class) &rest args &key)
(unless (eq (class-of class) meta) (change-class class meta))
(apply #'reinitialize-instance class initargs)
(setf (find-class name) class)
- (inform-type-system-about-class class name) ;***
+ (inform-type-system-about-class class name)
class))
(defmethod class-predicate-name ((class t))
'constantly-nil)
+(defun fix-super (s)
+ (cond ((classp s) s)
+ ((not (legal-class-name-p s))
+ (error "~S is not a class or a legal class name." s))
+ (t
+ (or (find-class s nil)
+ (setf (find-class s)
+ (make-instance 'forward-referenced-class
+ :name s))))))
+
(defun ensure-class-values (class args)
(let* ((initargs (copy-list args))
(unsupplied (list 1))
*the-class-standard-class*)
(t
(class-of class)))))
- (flet ((fix-super (s)
- (cond ((classp s) s)
- ((not (legal-class-name-p s))
- (error "~S is not a class or a legal class name." s))
- (t
- (or (find-class s nil)
- (setf (find-class s)
- (make-instance 'forward-referenced-class
- :name s)))))))
- (loop (unless (remf initargs :metaclass) (return)))
- (loop (unless (remf initargs :direct-superclasses) (return)))
- (loop (unless (remf initargs :direct-slots) (return)))
- (values meta
- (list* :direct-superclasses
- (and (neq supplied-supers unsupplied)
- (mapcar #'fix-super supplied-supers))
- :direct-slots
- (and (neq supplied-slots unsupplied) supplied-slots)
- initargs)))))
+ (loop (unless (remf initargs :metaclass) (return)))
+ (loop (unless (remf initargs :direct-superclasses) (return)))
+ (loop (unless (remf initargs :direct-slots) (return)))
+ (values meta
+ (list* :direct-superclasses
+ (and (neq supplied-supers unsupplied)
+ (mapcar #'fix-super supplied-supers))
+ :direct-slots
+ (and (neq supplied-slots unsupplied) supplied-slots)
+ initargs))))
\f
-#|| ; since it doesn't do anything
-(defmethod shared-initialize :before ((class std-class)
- slot-names
- &key direct-superclasses)
- (declare (ignore slot-names))
- ;; *** error checking
- )
-||#
(defmethod shared-initialize :after
((class std-class)
(setq direct-default-initargs
(plist-value class 'direct-default-initargs)))
(setf (plist-value class 'class-slot-cells)
- (gathering1 (collecting)
+ (let (collect)
(dolist (dslotd direct-slots)
(when (eq (slot-definition-allocation dslotd) class)
(let ((initfunction (slot-definition-initfunction dslotd)))
- (gather1 (cons (slot-definition-name dslotd)
+ (push (cons (slot-definition-name dslotd)
(if initfunction
(funcall initfunction)
- +slot-unbound+))))))))
+ +slot-unbound+))
+ collect))))
+ (nreverse collect)))
(setq predicate-name (if predicate-name-p
(setf (slot-value class 'predicate-name)
(car predicate-name))
#'(lambda (dependent)
(apply #'update-dependent class dependent initargs))))
+(defmethod shared-initialize :after ((slotd standard-slot-definition)
+ slot-names &key)
+ (declare (ignore slot-names))
+ (with-slots (allocation class)
+ slotd
+ (setq allocation (if (eq allocation :class) class allocation))))
+
+(defmethod shared-initialize :after ((slotd structure-slot-definition)
+ slot-names
+ &key (allocation :instance))
+ (declare (ignore slot-names))
+ (unless (eq allocation :instance)
+ (error "Structure slots must have :INSTANCE allocation.")))
+
+(defun make-structure-class-defstruct-form (name direct-slots include)
+ (let* ((conc-name (intern (format nil "~S structure class " name)))
+ (constructor (intern (format nil "~A constructor" conc-name)))
+ (defstruct `(defstruct (,name
+ ,@(when include
+ `((:include ,(class-name include))))
+ (:print-function print-std-instance)
+ (:predicate nil)
+ (:conc-name ,conc-name)
+ (:constructor ,constructor ())
+ (:copier nil))
+ ,@(mapcar (lambda (slot)
+ `(,(slot-definition-name slot)
+ +slot-unbound+))
+ direct-slots)))
+ (reader-names (mapcar (lambda (slotd)
+ (intern (format nil
+ "~A~A reader"
+ conc-name
+ (slot-definition-name
+ slotd))))
+ direct-slots))
+ (writer-names (mapcar (lambda (slotd)
+ (intern (format nil
+ "~A~A writer"
+ conc-name
+ (slot-definition-name
+ slotd))))
+ direct-slots))
+ (readers-init
+ (mapcar (lambda (slotd reader-name)
+ (let ((accessor
+ (slot-definition-defstruct-accessor-symbol
+ slotd)))
+ `(defun ,reader-name (obj)
+ (declare (type ,name obj))
+ (,accessor obj))))
+ direct-slots reader-names))
+ (writers-init
+ (mapcar (lambda (slotd writer-name)
+ (let ((accessor
+ (slot-definition-defstruct-accessor-symbol
+ slotd)))
+ `(defun ,writer-name (nv obj)
+ (declare (type ,name obj))
+ (setf (,accessor obj) nv))))
+ direct-slots writer-names))
+ (defstruct-form
+ `(progn
+ ,defstruct
+ ,@readers-init ,@writers-init
+ (cons nil nil))))
+ (values defstruct-form constructor reader-names writer-names)))
+
(defmethod shared-initialize :after
((class structure-class)
slot-names
direct-slots)))
(setq direct-slots (slot-value class 'direct-slots)))
(when defstruct-p
- (let* ((include (car (slot-value class 'direct-superclasses)))
- (conc-name (intern (format nil "~S structure class " name)))
- (constructor (intern (format nil "~A constructor" conc-name)))
- (defstruct `(defstruct (,name
- ,@(when include
- `((:include ,(class-name include))))
- (:print-function print-std-instance)
- (:predicate nil)
- (:conc-name ,conc-name)
- (:constructor ,constructor ())
- (:copier nil))
- ,@(mapcar (lambda (slot)
- `(,(slot-definition-name slot)
- +slot-unbound+))
- direct-slots)))
- (reader-names (mapcar (lambda (slotd)
- (intern (format nil
- "~A~A reader"
- conc-name
- (slot-definition-name
- slotd))))
- direct-slots))
- (writer-names (mapcar (lambda (slotd)
- (intern (format nil
- "~A~A writer"
- conc-name
- (slot-definition-name
- slotd))))
- direct-slots))
- (readers-init
- (mapcar (lambda (slotd reader-name)
- (let ((accessor
- (slot-definition-defstruct-accessor-symbol
- slotd)))
- `(defun ,reader-name (obj)
- (declare (type ,name obj))
- (,accessor obj))))
- direct-slots reader-names))
- (writers-init
- (mapcar (lambda (slotd writer-name)
- (let ((accessor
- (slot-definition-defstruct-accessor-symbol
- slotd)))
- `(defun ,writer-name (nv obj)
- (declare (type ,name obj))
- (setf (,accessor obj) nv))))
- direct-slots writer-names))
- (defstruct-form
- `(progn
- ,defstruct
- ,@readers-init ,@writers-init
- (cons nil nil))))
- (unless (structure-type-p name) (eval defstruct-form))
- (mapc #'(lambda (dslotd reader-name writer-name)
- (let* ((reader (gdefinition reader-name))
- (writer (when (gboundp writer-name)
- (gdefinition writer-name))))
- (setf (slot-value dslotd 'internal-reader-function)
- reader)
- (setf (slot-value dslotd 'internal-writer-function)
- writer)))
- direct-slots reader-names writer-names)
- (setf (slot-value class 'defstruct-form) defstruct-form)
- (setf (slot-value class 'defstruct-constructor) constructor))))
- (add-direct-subclasses class direct-superclasses)
- (setf (slot-value class 'class-precedence-list)
- (compute-class-precedence-list class))
- (setf (slot-value class 'slots) (compute-slots class))
- (let ((lclass (cl:find-class (class-name class))))
- (setf (sb-kernel:class-pcl-class lclass) class)
- (setf (slot-value class 'wrapper) (sb-kernel:class-layout lclass)))
- (update-pv-table-cache-info class)
- (setq predicate-name (if predicate-name-p
+ (let ((include (car (slot-value class 'direct-superclasses))))
+ (multiple-value-bind (defstruct-form constructor reader-names writer-names)
+ (make-structure-class-defstruct-form name direct-slots include)
+ (unless (structure-type-p name) (eval defstruct-form))
+ (mapc #'(lambda (dslotd reader-name writer-name)
+ (let* ((reader (gdefinition reader-name))
+ (writer (when (gboundp writer-name)
+ (gdefinition writer-name))))
+ (setf (slot-value dslotd 'internal-reader-function)
+ reader)
+ (setf (slot-value dslotd 'internal-writer-function)
+ writer)))
+ direct-slots reader-names writer-names)
+ (setf (slot-value class 'defstruct-form) defstruct-form)
+ (setf (slot-value class 'defstruct-constructor) constructor))))
+ (add-direct-subclasses class direct-superclasses)
+ (setf (slot-value class 'class-precedence-list)
+ (compute-class-precedence-list class))
+ (setf (slot-value class 'slots) (compute-slots class))
+ (let ((lclass (cl:find-class (class-name class))))
+ (setf (sb-kernel:class-pcl-class lclass) class)
+ (setf (slot-value class 'wrapper) (sb-kernel:class-layout lclass)))
+ (update-pv-table-cache-info class)
+ (setq predicate-name (if predicate-name-p
(setf (slot-value class 'predicate-name)
- (car predicate-name))
+ (car predicate-name))
(or (slot-value class 'predicate-name)
(setf (slot-value class 'predicate-name)
- (make-class-predicate-name
- (class-name class))))))
- (make-class-predicate class predicate-name)
- (add-slot-accessors class direct-slots))
-
+ (make-class-predicate-name
+ (class-name class))))))
+ (make-class-predicate class predicate-name)
+ (add-slot-accessors class direct-slots)))
+
(defmethod direct-slot-definition-class ((class structure-class) initargs)
(declare (ignore initargs))
(find-class 'structure-direct-slot-definition))
(make-wrapper nslots class))
((and (equal nlayout olayout)
(not
- (iterate ((o (list-elements owrapper-class-slots))
- (n (list-elements nwrapper-class-slots)))
- (unless (eq (car o) (car n)) (return t)))))
+ (loop for o in owrapper-class-slots
+ for n in nwrapper-class-slots
+ do (unless (eq (car o) (car n)) (return t)))))
owrapper)
(t
- ;; This will initialize the new wrapper to have the same
- ;; state as the old wrapper. We will then have to change
- ;; that. This may seem like wasted work (it is), but the
- ;; spec requires that we call make-instances-obsolete.
+ ;; This will initialize the new wrapper to have the
+ ;; same state as the old wrapper. We will then have
+ ;; to change that. This may seem like wasted work
+ ;; (and it is), but the spec requires that we call
+ ;; MAKE-INSTANCES-OBSOLETE.
(make-instances-obsolete class)
(class-wrapper class)))))
(update-pv-table-cache-info class)))))
(defun compute-class-slots (eslotds)
- (gathering1 (collecting)
+ (let (collect)
(dolist (eslotd eslotds)
- (gather1
- (assoc (slot-definition-name eslotd)
- (class-slot-cells (slot-definition-allocation eslotd)))))))
+ (push (assoc (slot-definition-name eslotd)
+ (class-slot-cells (slot-definition-allocation eslotd)))
+ collect))
+ (nreverse collect)))
(defun compute-layout (cpl instance-eslotds)
(let* ((names
- (gathering1 (collecting)
+ (let (collect)
(dolist (eslotd instance-eslotds)
(when (eq (slot-definition-allocation eslotd) :instance)
- (gather1 (slot-definition-name eslotd))))))
+ (push (slot-definition-name eslotd) collect)))
+ (nreverse collect)))
(order ()))
(labels ((rwalk (tail)
(when tail
;;; *** There is a subtle bug here which is going to have to be fixed.
;;; *** Namely, the simplistic use of the template has to be fixed. We
;;; *** have to give the optimize-slot-value method the user might have
-;;; *** defined for this metclass a chance to run.
+;;; *** defined for this metaclass a chance to run.
(defmethod make-reader-method-function ((class slot-class) slot-name)
(make-std-reader-method-function (class-name class) slot-name))
(make-std-boundp-method-function (class-name class) slot-name))
\f
;;;; inform-type-system-about-class
-;;;; make-type-predicate
;;;
;;; These are NOT part of the standard protocol. They are internal
;;; mechanism which PCL uses to *try* and tell the type system about
;;; the type system about new classes would be different.
(defmethod inform-type-system-about-class ((class std-class) name)
(inform-type-system-about-std-class name))
+
+(defmethod inform-type-system-about-class ((class structure-class) (name t))
+ nil)
\f
(defmethod compatible-meta-class-change-p (class proto-new-class)
(eq (class-of class) (class-of proto-new-class)))
(lambda (condition stream)
;; Don't try to print the structure, since it probably won't work.
(format stream
- "obsolete structure error in ~S:~@
- for a structure of type: ~S"
- (sb-kernel::condition-function-name condition)
+ "~@<obsolete structure error for a structure of type ~2I~_~S~:>"
(type-of (obsolete-structure-datum condition))))))
(defun obsolete-instance-trap (owrapper nwrapper instance)
;; -- --> shared --
;; Go through all the old local slots.
- (iterate ((name (list-elements olayout))
- (opos (interval :from 0)))
- (let ((npos (posq name nlayout)))
- (if npos
- (setf (clos-slots-ref nslots npos)
- (clos-slots-ref oslots opos))
- (progn
- (push name discarded)
- (unless (eq (clos-slots-ref oslots opos) +slot-unbound+)
- (setf (getf plist name) (clos-slots-ref oslots opos)))))))
+ (let ((opos 0))
+ (dolist (name olayout)
+ (let ((npos (posq name nlayout)))
+ (if npos
+ (setf (clos-slots-ref nslots npos)
+ (clos-slots-ref oslots opos))
+ (progn
+ (push name discarded)
+ (unless (eq (clos-slots-ref oslots opos) +slot-unbound+)
+ (setf (getf plist name) (clos-slots-ref oslots opos))))))
+ (incf opos)))
;; Go through all the old shared slots.
- (iterate ((oclass-slot-and-val (list-elements oclass-slots)))
+ (dolist (oclass-slot-and-val oclass-slots)
(let ((name (car oclass-slot-and-val))
(val (cdr oclass-slot-and-val)))
(let ((npos (posq name nlayout)))
(old-class-slots (wrapper-class-slots old-wrapper)))
;; "The values of local slots specified by both the class CTO and
- ;; CFROM are retained. If such a local slot was unbound, it remains
- ;; unbound."
- (iterate ((new-slot (list-elements new-layout))
- (new-position (interval :from 0)))
- (let ((old-position (posq new-slot old-layout)))
- (when old-position
- (setf (clos-slots-ref new-slots new-position)
- (clos-slots-ref old-slots old-position)))))
+ ;; CFROM are retained. If such a local slot was unbound, it
+ ;; remains unbound."
+ (let ((new-position 0))
+ (dolist (new-slot new-layout)
+ (let ((old-position (posq new-slot old-layout)))
+ (when old-position
+ (setf (clos-slots-ref new-slots new-position)
+ (clos-slots-ref old-slots old-position))))))
;; "The values of slots specified as shared in the class CFROM and
;; as local in the class CTO are retained."
- (iterate ((slot-and-val (list-elements old-class-slots)))
+ (dolist (slot-and-val old-class-slots)
(let ((position (posq (car slot-and-val) new-layout)))
(when position
(setf (clos-slots-ref new-slots position) (cdr slot-and-val)))))