* Instance layout This is fairly easy. The superclasses are partitioned into chains. Each chain is named after its head class (i.e., the class with no successor). ** Things in instance layouts An instance layout contains a chunk for each component chain. struct CLASS__ilayout { struct CLASS__ichain_CHAINn NICKn; /* ... */ }; An ilayout is a C structure consisting of an ichain for each of the class's chains, with the primary chain first. The others are in direct-superclass order. ** Instance slots An islots structure is a C structure consisting of a class's instance slots, in order. struct CLASS__islots { TYPEn SLOTn; /* ... */ }; If a class defines no slots then it has no islots structure. ** Instance chains struct CLASS__ichain_CHAIN { const struct CLASS__vt_CHAIN *_vt; struct SUPERn__islots NICKn; /* ... */ }; A ichain is a C structure consisting of: * A pointer `_vt' to the chain's vtable structure. * An islots substructure, named after the class's nick for each class on the chain, least-specific first. Because of the chain invariant, all of a class's ichains are prefixes of the corresponding ichains of any of its subclasses. The type CLASS is an alias for the class's primary ichain CLASS__ichain_CHAIN. One needs to do a cross-chain upcast to find slots in non-primary chains. * Vtable layout This is more complicated. The vtable for a chain doesn't just contain things directly relevant to the classes on the chain: because a vtable is (assumed) immutable, we can have copies of values from other chains where this is convenient. Note that effective methods are customized for particular classes: they can assume that their argument points to a specific ichain of a an instance of a specific class. This makes conversions in effective methods very cheap. By including apparently effective-method pointers for messages defined in other chains, we can speed up dispatch. ** Things in a vtable chain There are three kinds of items to store in a vtable chain. * Class pointers * The base offset * Chain offsets * Effective method pointers struct CLASS__vt_CHAIN { struct METACLASS__ichain_sod_object *_class; size_t _base; struct METACLASS__ichain_METACHAINn *_cls_NICKn; ptrdiff_t _off_CHAINn; struct SUPERn__vtmsgs NICKn; }; A class has a separate vtable chain for each of its chains. ** The base offset There is a single member _base which is the offset of the chain's ichain in the overall ilayout structure. This lets you find the bottom of the ilayout given a pointer to any ichain as (CLASS__ilayout *)((char *)p - p->_vt._base) ** Class pointers The class's metaclass may have multiple chains. For each chain of the metaclass, there is a separate pointer to that metaclass's ichain, named _cls_NICKn after the metaclass's chain head. Exception: _cls_cls is called _class instead. ** Chain offsets For each other chain, there is a member _off_NICKn named after the chain's head giving the offset of that ichain from the current chain's ichain. (There's a long way around, exploring the class's layout information, but this provides a much easier way of doing cross-chain upcasts.) ** Effective method pointers For each class, there may be a structure struct CLASS__vtmsgs { TYPEn (*MSGn)(ARGnn *, ...); /* ... */ }; of pointers to effective methods for the messages defined by the class. If a class defines no messages then it won't have a vtmsgs structure. ** Layout order The first two items are always _class and _base. After that: * for each class in the chain, from least to most specific, * for each of that class's superclasses, in reverse class-precedence- list order, which has not yet been processed: * if the class is in a chain which hasn't been seen before (it must be the chain head!), emit a chain offset for it; * if the class has a metaclass chain which hasn't been seen before, emit a class pointer for it; * if the class has a vtmsgs structure, emit it. * Questions Are class-slot initializers inherited? No. We have instance initializers on metaclasses for that.