-(flet ((check-class-is-finalized (class)
- (unless (eq (sod-class-state class) :finalized)
- (error "Class ~S is not finalized" class))))
- (macrolet ((define-layout-slot (slot (class) &body body)
- `(define-on-demand-slot sod-class ,slot (,class)
- (check-class-is-finalized ,class)
- ,@body)))
- (define-layout-slot %ilayout (class)
- (compute-ilayout class))
- (define-layout-slot effective-methods (class)
- (compute-effective-methods class))
- (define-layout-slot vtables (class)
- (compute-vtables class))))
+(defmethod finalize-sod-class ((class sod-class))
+
+ ;; CLONE-AND-HACK WARNING: Note that `bootstrap-classes' has a (very brief)
+ ;; clone of the CPL and chain establishment code. If the interface changes
+ ;; then `bootstrap-classes' will need to be changed too.
+
+ ;; Set up the metaclass if it's not been set already. This is delayed
+ ;; to give bootstrapping a chance to set up metaclass and superclass
+ ;; circularities.
+ (default-slot (class 'metaclass) (guess-metaclass class))
+
+ ;; Finalize all of the superclasses. There's some special pleading here to
+ ;; make bootstrapping work: we don't try to finalize the metaclass if we're
+ ;; a root class (no direct superclasses -- because in that case the
+ ;; metaclass will have to be a subclass of us!), or if it's equal to us.
+ ;; This is enough to tie the knot at the top of the class graph.
+ (with-slots (name direct-superclasses metaclass) class
+ (dolist (super direct-superclasses)
+ (finalize-sod-class super))
+ (unless (or (null direct-superclasses)
+ (eq class metaclass))
+ (finalize-sod-class metaclass)))
+
+ ;; Stash the class's type.
+ (setf (slot-value class '%type)
+ (make-class-type (sod-class-name class)))
+
+ ;; Clobber the lists of items if they've not been set.
+ (dolist (slot '(slots instance-initializers class-initializers
+ messages methods))
+ (unless (slot-boundp class slot)
+ (setf (slot-value class slot) nil)))
+
+ ;; If the CPL hasn't been done yet, compute it.
+ (with-slots (class-precedence-list) class
+ (unless (slot-boundp class 'class-precedence-list)
+ (setf class-precedence-list (compute-cpl class))))
+
+ ;; Check that the class is fairly sane.
+ (check-sod-class class)
+
+ ;; Determine the class's layout.
+ (setf (values (slot-value class 'chain-head)
+ (slot-value class 'chain)
+ (slot-value class 'chains))
+ (compute-chains class)))