chiark / gitweb /
It lives!
[sod] / layout.org
1 * Instance layout
2
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
5 successor).
6
7 ** Things in instance layouts
8
9 An instance layout contains a chunk for each component chain.
10
11         struct CLASS__ilayout {
12           struct CLASS__ichain_CHAINn NICKn;
13           /* ... */
14         };
15
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.
19
20 ** Instance slots
21
22 An islots structure is a C structure consisting of a class's instance
23 slots, in order.
24
25         struct CLASS__islots {
26           TYPEn SLOTn;
27           /* ... */
28         };
29
30 If a class defines no slots then it has no islots structure.
31
32 ** Instance chains
33
34         struct CLASS__ichain_CHAIN {
35           const struct CLASS__vt_CHAIN *_vt;
36           struct SUPERn__islots NICKn;
37           /* ... */
38         };
39
40 A ichain is a C structure consisting of:
41
42   * A pointer `_vt' to the chain's vtable structure.
43
44   * An islots substructure, named after the class's nick for each class
45     on the chain, least-specific first.
46
47 Because of the chain invariant, all of a class's ichains are prefixes of
48 the corresponding ichains of any of its subclasses.
49
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.
53
54 * Vtable layout
55
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.
60
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.
66
67 ** Things in a vtable chain
68
69 There are three kinds of items to store in a vtable chain.
70
71   * Class pointers
72   * The base offset
73   * Chain offsets
74   * Effective method pointers
75
76         struct CLASS__vt_CHAIN {
77           struct METACLASS__ichain_sod_object *_class;
78           size_t _base;
79           struct METACLASS__ichain_METACHAINn *_cls_NICKn;
80           ptrdiff_t _off_CHAINn;
81           struct SUPERn__vtmsgs NICKn;
82         };
83
84 A class has a separate vtable chain for each of its chains.
85
86 ** The base offset
87
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
91
92         (CLASS__ilayout *)((char *)p - p->_vt._base)
93
94 ** Class pointers
95
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.
100
101 ** Chain offsets
102
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
107 upcasts.)
108
109 ** Effective method pointers
110
111 For each class, there may be a structure
112
113         struct CLASS__vtmsgs {
114           TYPEn (*MSGn)(ARGnn *, ...);
115           /* ... */
116         };
117
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.
120
121 ** Layout order
122
123 The first two items are always _class and _base.  After that:
124
125   * for each class in the chain, from least to most specific,
126
127   * for each of that class's superclasses, in reverse class-precedence-
128     list order, which has not yet been processed:
129
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;
132
133   * if the class has a metaclass chain which hasn't been seen before,
134     emit a class pointer for it;
135
136   * if the class has a vtmsgs structure, emit it.
137
138 * Questions
139
140 Are class-slot initializers inherited?  No.  We have instance
141 initializers on metaclasses for that.