0.7.7.10:
[sbcl.git] / src / pcl / std-class.lisp
index 9697915..3a7da7b 100644 (file)
                   (nreverse collect)))))))
 
 (defun map-specializers (function)
-  (map-all-classes #'(lambda (class)
-                      (funcall function (class-eq-specializer class))
-                      (funcall function class)))
-  (maphash #'(lambda (object methods)
-              (declare (ignore methods))
-              (intern-eql-specializer object))
+  (map-all-classes (lambda (class)
+                    (funcall function (class-eq-specializer class))
+                    (funcall function class)))
+  (maphash (lambda (object methods)
+            (declare (ignore methods))
+            (intern-eql-specializer object))
           *eql-specializer-methods*)
-  (maphash #'(lambda (object specl)
-              (declare (ignore object))
-              (funcall function specl))
+  (maphash (lambda (object specl)
+            (declare (ignore object))
+            (funcall function specl))
           *eql-specializer-table*)
   nil)
 
 (defun map-all-generic-functions (function)
   (let ((all-generic-functions (make-hash-table :test 'eq)))
-    (map-specializers #'(lambda (specl)
-                         (dolist (gf (specializer-direct-generic-functions
-                                      specl))
-                           (unless (gethash gf all-generic-functions)
-                             (setf (gethash gf all-generic-functions) t)
-                             (funcall function gf))))))
+    (map-specializers (lambda (specl)
+                       (dolist (gf (specializer-direct-generic-functions
+                                    specl))
+                         (unless (gethash gf all-generic-functions)
+                           (setf (gethash gf all-generic-functions) t)
+                           (funcall function gf))))))
   nil)
 
 (defmethod shared-initialize :after ((specl class-eq-specializer)
       (ensure-class-values class args)
     (setf class (apply #'make-instance meta :name name initargs)
          (find-class name) class)
-    (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)
     class))
 
 (defmethod class-predicate-name ((class t))
                                         &rest initargs
                                         &key)
   (map-dependents class
-                 #'(lambda (dependent)
-                     (apply #'update-dependent class dependent initargs))))
+                 (lambda (dependent)
+                   (apply #'update-dependent class dependent initargs))))
 
 (defmethod shared-initialize :after ((slotd standard-slot-definition)
                                     slot-names &key)
 
 (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)))
+         (constructor (intern (format nil "~Aconstructor" conc-name)))
          (defstruct `(defstruct (,name
                                  ,@(when include
                                          `((:include ,(class-name include))))
-                                 (:print-function print-std-instance)
                                  (:predicate nil)
                                  (:conc-name ,conc-name)
                                  (:constructor ,constructor ())
     (if direct-slots-p
        (setf (slot-value class 'direct-slots)
              (setq direct-slots
-                   (mapcar #'(lambda (pl)
-                               (when defstruct-p
-                                 (let* ((slot-name (getf pl :name))
-                                        (acc-name
-                                         (format nil
-                                                 "~S structure class ~A"
-                                                 name slot-name))
-                                        (accessor (intern acc-name)))
-                                   (setq pl (list* :defstruct-accessor-symbol
-                                                   accessor pl))))
-                               (make-direct-slotd class pl))
+                   (mapcar (lambda (pl)
+                             (when defstruct-p
+                               (let* ((slot-name (getf pl :name))
+                                      (acc-name
+                                       (format nil
+                                               "~S structure class ~A"
+                                               name slot-name))
+                                      (accessor (intern acc-name)))
+                                 (setq pl (list* :defstruct-accessor-symbol
+                                                 accessor pl))))
+                             (make-direct-slotd class pl))
                            direct-slots)))
        (setq direct-slots (slot-value class 'direct-slots)))
     (when defstruct-p
         (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)))
+          (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))))
        (dolist (r (slot-definition-readers dslotd)) (fix r slot-name 'r))
        (dolist (w (slot-definition-writers dslotd)) (fix w slot-name 'w))))))
 \f
-(defun add-direct-subclasses (class new)
-  (dolist (n new)
+(defun add-direct-subclasses (class supers)
+  (dolist (super supers)
     (unless (memq class (class-direct-subclasses class))
-      (add-direct-subclass n class))))
+      (add-direct-subclass super class))))
 
-(defun remove-direct-subclasses (class new)
+(defun remove-direct-subclasses (class supers)
   (let ((old (class-direct-superclasses class)))
-    (dolist (o (set-difference old new))
+    (dolist (o (set-difference old supers))
       (remove-direct-subclass o class))))
 \f
 (defmethod finalize-inheritance ((class std-class))
                   (setf (gethash gf gf-table) t))
                 (mapc #'collect-gfs (class-direct-superclasses class))))
        (collect-gfs class)
-       (maphash #'(lambda (gf ignore)
-                    (declare (ignore ignore))
-                    (update-gf-dfun class gf))
+       (maphash (lambda (gf ignore)
+                  (declare (ignore ignore))
+                  (update-gf-dfun class gf))
                 gf-table)))))
 
 (defun update-inits (class inits)
            (if entry
                (push d (cdr entry))
                (push (list name d) name-dslotds-alist))))))
-    (mapcar #'(lambda (direct)
-               (compute-effective-slot-definition class
-                                                  (nreverse (cdr direct))))
+    (mapcar (lambda (direct)
+             (compute-effective-slot-definition class
+                                                (nreverse (cdr direct))))
            name-dslotds-alist)))
 
 (defmethod compute-slots :around ((class std-class))
     eslotds))
 
 (defmethod compute-slots ((class structure-class))
-  (mapcan #'(lambda (superclass)
-             (mapcar #'(lambda (dslotd)
-                         (compute-effective-slot-definition class
-                                                            (list dslotd)))
-                     (class-direct-slots superclass)))
+  (mapcan (lambda (superclass)
+           (mapcar (lambda (dslotd)
+                     (compute-effective-slot-definition class
+                                                        (list dslotd)))
+                   (class-direct-slots superclass)))
          (reverse (slot-value class 'class-precedence-list))))
 
 (defmethod compute-slots :around ((class structure-class))
   (let ((method (get-method generic-function () (list class) nil)))
     (when method (remove-method generic-function method))))
 \f
-;;; make-reader-method-function and make-write-method function are NOT part of
-;;; the standard protocol. They are however useful, PCL makes uses makes use
-;;; of them internally and documents them for PCL users.
+;;; MAKE-READER-METHOD-FUNCTION and MAKE-WRITE-METHOD function are NOT
+;;; part of the standard protocol. They are however useful, PCL makes
+;;; use of them internally and documents them for PCL users.
 ;;;
 ;;; *** This needs work to make type testing by the writer functions which
 ;;; *** do type testing faster. The idea would be to have one constructor
-;;; *** for each possible type test. In order to do this it would be nice
-;;; *** to have help from inform-type-system-about-class and friends.
+;;; *** for each possible type test.
 ;;;
 ;;; *** 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
+;;; *** have to give the OPTIMIZE-SLOT-VALUE method the user might have
 ;;; *** defined for this metaclass a chance to run.
 
 (defmethod make-reader-method-function ((class slot-class) slot-name)
 (defmethod make-boundp-method-function ((class slot-class) slot-name)
   (make-std-boundp-method-function (class-name class) slot-name))
 \f
-;;;; inform-type-system-about-class
-;;;
-;;; These are NOT part of the standard protocol. They are internal
-;;; mechanism which PCL uses to *try* and tell the type system about
-;;; class definitions. In a more fully integrated implementation of
-;;; CLOS, the type system would know about class objects and class
-;;; names in a more fundamental way and the mechanism used to inform
-;;; 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)))
 
        (eq (class-of class) new-super-meta-class))))
 \f
 (defun force-cache-flushes (class)
-  (let* ((owrapper (class-wrapper class))
-        (state (wrapper-state owrapper)))
+  (let* ((owrapper (class-wrapper class)))
     ;; We only need to do something if the state is still T. If the
     ;; state isn't T, it will be FLUSH or OBSOLETE, and both of those
     ;; will already be doing what we want. In particular, we must be
     ;; sure we never change an OBSOLETE into a FLUSH since OBSOLETE
     ;; means do what FLUSH does and then some.
-    (when (eq state t) ; FIXME: should be done through INVALID-WRAPPER-P
+    (unless (invalid-wrapper-p owrapper)
       (let ((nwrapper (make-wrapper (wrapper-no-of-instance-slots owrapper)
                                    class)))
        (setf (wrapper-instance-slots-layout nwrapper)
        (sb-sys:without-interrupts
          (update-lisp-class-layout class nwrapper)
          (setf (slot-value class 'wrapper) nwrapper)
-         (invalidate-wrapper owrapper ':flush nwrapper))))))
+         (invalidate-wrapper owrapper :flush nwrapper))))))
 
 (defun flush-cache-trap (owrapper nwrapper instance)
   (declare (ignore owrapper))
   (set-wrapper instance nwrapper))
 \f
-;;; make-instances-obsolete can be called by user code. It will cause the
-;;; next access to the instance (as defined in 88-002R) to trap through the
-;;; update-instance-for-redefined-class mechanism.
+;;; MAKE-INSTANCES-OBSOLETE can be called by user code. It will cause
+;;; the next access to the instance (as defined in 88-002R) to trap
+;;; through the UPDATE-INSTANCE-FOR-REDEFINED-CLASS mechanism.
 (defmethod make-instances-obsolete ((class std-class))
   (let* ((owrapper (class-wrapper class))
         (nwrapper (make-wrapper (wrapper-no-of-instance-slots owrapper)
       (sb-sys:without-interrupts
        (update-lisp-class-layout class nwrapper)
        (setf (slot-value class 'wrapper) nwrapper)
-       (invalidate-wrapper owrapper ':obsolete nwrapper)
+       (invalidate-wrapper owrapper :obsolete nwrapper)
        class)))
 
 (defmethod make-instances-obsolete ((class symbol))
   (make-instances-obsolete (find-class class)))
 
-;;; obsolete-instance-trap is the internal trap that is called when we see
-;;; an obsolete instance. The times when it is called are:
+;;; OBSOLETE-INSTANCE-TRAP is the internal trap that is called when we
+;;; see an obsolete instance. The times when it is called are:
 ;;;   - when the instance is involved in method lookup
 ;;;   - when attempting to access a slot of an instance
 ;;;
 ;;; sure that the traps are only happening when they should, and that
 ;;; the trap methods are computing appropriate new wrappers.
 
-;;; obsolete-instance-trap might be called on structure instances
-;;; after a structure is redefined. In most cases, obsolete-instance-trap
-;;; will not be able to fix the old instance, so it must signal an
-;;; error. The hard part of this is that the error system and debugger
-;;; might cause obsolete-instance-trap to be called again, so in that
-;;; case, we have to return some reasonable wrapper, instead.
+;;; OBSOLETE-INSTANCE-TRAP might be called on structure instances
+;;; after a structure is redefined. In most cases,
+;;; OBSOLETE-INSTANCE-TRAP will not be able to fix the old instance,
+;;; so it must signal an error. The hard part of this is that the
+;;; error system and debugger might cause OBSOLETE-INSTANCE-TRAP to be
+;;; called again, so in that case, we have to return some reasonable
+;;; wrapper, instead.
 
 (defvar *in-obsolete-instance-trap* nil)
 (defvar *the-wrapper-of-structure-object*
                                             plist)
        nwrapper)))
 \f
-(defmacro copy-instance-internal (instance)
-  `(progn
-     (let* ((class (class-of instance))
-           (copy (allocate-instance class)))
-       (if (std-instance-p ,instance)
-          (setf (std-instance-slots ,instance)
-                (std-instance-slots ,instance))
-        (setf (fsc-instance-slots ,instance)
-              (fsc-instance-slots ,instance)))
-       copy)))
-
-(defun change-class-internal (instance new-class)
+(defun change-class-internal (instance new-class initargs)
   (let* ((old-class (class-of instance))
         (copy (allocate-instance new-class))
         (new-wrapper (get-wrapper copy))
         (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))))))
+                  (clos-slots-ref old-slots old-position))))
+       (incf new-position)))
 
     ;; "The values of slots specified as shared in the class CFROM and
     ;; as local in the class CTO are retained."
     ;; old instance point to the new storage.
     (swap-wrappers-and-slots instance copy)
 
-    (update-instance-for-different-class copy instance)
+    (apply #'update-instance-for-different-class copy instance initargs)
     instance))
 
 (defmethod change-class ((instance standard-object)
-                        (new-class standard-class))
-  (change-class-internal instance new-class))
+                        (new-class standard-class)
+                        &rest initargs)
+  (change-class-internal instance new-class initargs))
 
 (defmethod change-class ((instance funcallable-standard-object)
-                        (new-class funcallable-standard-class))
-  (change-class-internal instance new-class))
+                        (new-class funcallable-standard-class)
+                        &rest initargs)
+  (change-class-internal instance new-class initargs))
 
 (defmethod change-class ((instance standard-object)
-                        (new-class funcallable-standard-class))
+                        (new-class funcallable-standard-class)
+                        &rest initargs)
+  (declare (ignore initargs))
   (error "You can't change the class of ~S to ~S~@
          because it isn't already an instance with metaclass ~S."
         instance new-class 'standard-class))
 
 (defmethod change-class ((instance funcallable-standard-object)
-                        (new-class standard-class))
+                        (new-class standard-class)
+                        &rest initargs)
+  (declare (ignore initargs))
   (error "You can't change the class of ~S to ~S~@
          because it isn't already an instance with metaclass ~S."
         instance new-class 'funcallable-standard-class))
 
-(defmethod change-class ((instance t) (new-class-name symbol))
-  (change-class instance (find-class new-class-name)))
+(defmethod change-class ((instance t) (new-class-name symbol) &rest initargs)
+  (apply #'change-class instance (find-class new-class-name) initargs))
 \f
 ;;;; The metaclass BUILT-IN-CLASS
 ;;;;