3 This is fairly easy. The superclasses are partitioned into chains.
4 Each chain is named after its head class (i.e., the class with no
7 ** Things in instance layouts
9 An instance layout contains a chunk for each component chain.
11 struct CLASS__ilayout {
12 struct CLASS__ichain_CHAINn NICKn;
16 An ilayout is a C structure consisting of an ichain for each of the
17 class's chains, with the primary chain first. The others are in
18 direct-superclass order.
22 An islots structure is a C structure consisting of a class's instance
25 struct CLASS__islots {
30 If a class defines no slots then it has no islots structure.
34 struct CLASS__ichain_CHAIN {
35 const struct CLASS__vt_CHAIN *_vt;
36 struct SUPERn__islots NICKn;
40 A ichain is a C structure consisting of:
42 * A pointer `_vt' to the chain's vtable structure.
44 * An islots substructure, named after the class's nick for each class
45 on the chain, least-specific first.
47 Because of the chain invariant, all of a class's ichains are prefixes of
48 the corresponding ichains of any of its subclasses.
50 The type CLASS is an alias for the class's primary ichain
51 CLASS__ichain_CHAIN. One needs to do a cross-chain upcast to find slots
52 in non-primary chains.
56 This is more complicated. The vtable for a chain doesn't just contain
57 things directly relevant to the classes on the chain: because a vtable
58 is (assumed) immutable, we can have copies of values from other chains
59 where this is convenient.
61 Note that effective methods are customized for particular classes: they
62 can assume that their argument points to a specific ichain of a an
63 instance of a specific class. This makes conversions in effective
64 methods very cheap. By including apparently effective-method pointers
65 for messages defined in other chains, we can speed up dispatch.
67 ** Things in a vtable chain
69 There are three kinds of items to store in a vtable chain.
74 * Effective method pointers
76 struct CLASS__vt_CHAIN {
77 struct METACLASS__ichain_sod_object *_class;
79 struct METACLASS__ichain_METACHAINn *_cls_NICKn;
80 ptrdiff_t _off_CHAINn;
81 struct SUPERn__vtmsgs NICKn;
84 A class has a separate vtable chain for each of its chains.
88 There is a single member _base which is the offset of the chain's ichain
89 in the overall ilayout structure. This lets you find the bottom of the
90 ilayout given a pointer to any ichain as
92 (CLASS__ilayout *)((char *)p - p->_vt._base)
96 The class's metaclass may have multiple chains. For each chain of the
97 metaclass, there is a separate pointer to that metaclass's ichain, named
98 _cls_NICKn after the metaclass's chain head. Exception: _cls_cls is
99 called _class instead.
103 For each other chain, there is a member _off_NICKn named after the
104 chain's head giving the offset of that ichain from the current chain's
105 ichain. (There's a long way around, exploring the class's layout
106 information, but this provides a much easier way of doing cross-chain
109 ** Effective method pointers
111 For each class, there may be a structure
113 struct CLASS__vtmsgs {
114 TYPEn (*MSGn)(ARGnn *, ...);
118 of pointers to effective methods for the messages defined by the class.
119 If a class defines no messages then it won't have a vtmsgs structure.
123 The first two items are always _class and _base. After that:
125 * for each class in the chain, from least to most specific,
127 * for each of that class's superclasses, in reverse class-precedence-
128 list order, which has not yet been processed:
130 * if the class is in a chain which hasn't been seen before (it must be
131 the chain head!), emit a chain offset for it;
133 * if the class has a metaclass chain which hasn't been seen before,
134 emit a class pointer for it;
136 * if the class has a vtmsgs structure, emit it.
140 Are class-slot initializers inherited? No. We have instance
141 initializers on metaclasses for that.