0.9.14.25:
[sbcl.git] / src / code / class.lisp
index c19e3fb..dc0b524 100644 (file)
   ;; during cold-load.
   (translation nil :type (or ctype (member nil :initializing))))
 
-;;; FIXME: In CMU CL, this was a class with a print function, but not
-;;; necessarily a structure class (e.g. CONDITIONs). In SBCL,
-;;; we let CLOS handle our print functions, so that is no longer needed.
-;;; Is there any need for this class any more?
-(def!struct (slot-classoid (:include classoid)
-                           (:constructor nil)))
-
 ;;; STRUCTURE-CLASS represents what we need to know about structure
 ;;; classes. Non-structure "typed" defstructs are a special case, and
 ;;; don't have a corresponding class.
-(def!struct (basic-structure-classoid (:include slot-classoid)
-                                      (:constructor nil)))
-
-(def!struct (structure-classoid (:include basic-structure-classoid)
+(def!struct (structure-classoid (:include classoid)
                                 (:constructor make-structure-classoid))
   ;; If true, a default keyword constructor for this structure.
   (constructor nil :type (or function null)))
-
-;;; FUNCALLABLE-STRUCTURE-CLASS is used to represent funcallable
-;;; structures, which are used to implement generic functions.
-(def!struct (funcallable-structure-classoid
-             (:include basic-structure-classoid)
-             (:constructor make-funcallable-structure-classoid)))
 \f
 ;;;; classoid namespace
 
@@ -788,7 +772,18 @@ NIL is returned when no such class exists."
 
      (remhash name *forward-referenced-layouts*)
      (%note-type-defined name)
-     (setf (info :type :kind name) :instance)
+     ;; we need to handle things like
+     ;;   (setf (find-class 'foo) (find-class 'integer))
+     ;; and
+     ;;   (setf (find-class 'integer) (find-class 'integer))
+     (cond
+       ((built-in-classoid-p new-value)
+        (setf (info :type :kind name) (or (info :type :kind name) :defined))
+        (let ((translation (built-in-classoid-translation new-value)))
+          (when translation
+            (setf (info :type :translator name)
+                  (lambda (c) (declare (ignore c)) translation)))))
+       (t (setf (info :type :kind name) :instance)))
      (setf (classoid-cell-classoid (find-classoid-cell name)) new-value)
      (unless (eq (info :type :compiler-layout name)
                  (classoid-layout new-value))
@@ -825,6 +820,33 @@ NIL is returned when no such class exists."
 
 (!define-type-class classoid)
 
+;;; We might be passed classoids with invalid layouts; in any pairwise
+;;; class comparison, we must ensure that both are valid before
+;;; proceeding.
+(defun ensure-classoid-valid (classoid layout)
+  (aver (eq classoid (layout-classoid layout)))
+  (when (layout-invalid layout)
+    (if (typep classoid 'standard-classoid)
+        (let ((class (classoid-pcl-class classoid)))
+          (cond
+            ((sb!pcl:class-finalized-p class)
+             (sb!pcl::force-cache-flushes class))
+            ((sb!pcl::class-has-a-forward-referenced-superclass-p class)
+             (error "Invalid, unfinalizeable class ~S (classoid ~S)."
+                    class classoid))
+            (t (sb!pcl:finalize-inheritance class))))
+        (error "Don't know how to ensure validity of ~S (not ~
+                a STANDARD-CLASSOID)." classoid))))
+
+(defun ensure-both-classoids-valid (class1 class2)
+  (do ((layout1 (classoid-layout class1) (classoid-layout class1))
+       (layout2 (classoid-layout class2) (classoid-layout class2))
+       (i 0 (+ i 1)))
+      ((and (not (layout-invalid layout1)) (not (layout-invalid layout2))))
+    (aver (< i 2))
+    (ensure-classoid-valid class1 layout1)
+    (ensure-classoid-valid class2 layout2)))
+
 ;;; Simple methods for TYPE= and SUBTYPEP should never be called when
 ;;; the two classes are equal, since there are EQ checks in those
 ;;; operations.
@@ -834,6 +856,7 @@ NIL is returned when no such class exists."
 
 (!define-type-method (classoid :simple-subtypep) (class1 class2)
   (aver (not (eq class1 class2)))
+  (ensure-both-classoids-valid class1 class2)
   (let ((subclasses (classoid-subclasses class2)))
     (if (and subclasses (gethash class1 subclasses))
         (values t t)
@@ -857,6 +880,7 @@ NIL is returned when no such class exists."
 
 (!define-type-method (classoid :simple-intersection2) (class1 class2)
   (declare (type classoid class1 class2))
+  (ensure-both-classoids-valid class1 class2)
   (cond ((eq class1 class2)
          class1)
         ;; If one is a subclass of the other, then that is the
@@ -870,8 +894,8 @@ NIL is returned when no such class exists."
         ;; Otherwise, we can't in general be sure that the
         ;; intersection is empty, since a subclass of both might be
         ;; defined. But we can eliminate it for some special cases.
-        ((or (basic-structure-classoid-p class1)
-             (basic-structure-classoid-p class2))
+        ((or (structure-classoid-p class1)
+             (structure-classoid-p class2))
          ;; No subclass of both can be defined.
          *empty-type*)
         ((eq (classoid-state class1) :sealed)
@@ -915,11 +939,15 @@ NIL is returned when no such class exists."
 \f
 ;;;; PCL stuff
 
-(def!struct (std-classoid (:include classoid)
-                          (:constructor nil)))
-(def!struct (standard-classoid (:include std-classoid)
+;;; the CLASSOID that we use to represent type information for
+;;; STANDARD-CLASS and FUNCALLABLE-STANDARD-CLASS.  The type system
+;;; side does not need to distinguish between STANDARD-CLASS and
+;;; FUNCALLABLE-STANDARD-CLASS.
+(def!struct (standard-classoid (:include classoid)
                                (:constructor make-standard-classoid)))
-(def!struct (random-pcl-classoid (:include std-classoid)
+;;; a metaclass for miscellaneous PCL structure-like objects (at the
+;;; moment, only CTOR objects).
+(def!struct (random-pcl-classoid (:include classoid)
                                  (:constructor make-random-pcl-classoid)))
 \f
 ;;;; built-in classes
@@ -1489,6 +1517,13 @@ NIL is returned when no such class exists."
               (let ((layout (classoid-layout (find-classoid name))))
                 (dolist (code codes)
                   (setf (svref res code) layout)))))))
+  (setq *null-classoid-layout*
+        ;; KLUDGE: we use (LET () ...) instead of a LOCALLY here to
+        ;; work around a bug in the LOCALLY handling in the fopcompiler
+        ;; (present in 0.9.13-0.9.14.18). -- JES, 2006-07-16
+        (let ()
+          (declare (notinline find-classoid))
+          (classoid-layout (find-classoid 'null))))
   #-sb-xc-host (/show0 "done setting *BUILT-IN-CLASS-CODES*"))
 \f
 (!defun-from-collected-cold-init-forms !classes-cold-init)