1 Data Structures
2 ===============
3
4 The fundamental "value type" is a pair of references: one pointing to the
5 referenced object represented by the interchangeable value; one referring to
6 the context of the referenced object, typically the object through which the
7 referenced object was acquired as an attribute.
8
9 Value Layout
10 ------------
11
12 0 1
13 object context
14 reference reference
15
16 Such values are used as the stored representations of attributes (of classes,
17 instances, modules, and other objects supporting attribute-like entities) as
18 well as the stored values associated with names in functions and methods.
19
20 Stored Values and Contexts
21 --------------------------
22
23 See assignment.txt for information about contexts and transformations.
24
25 Acquiring Values
26 ----------------
27
28 There are two classes of instructions which provide values:
29
30 Instruction Purpose Context Operations
31 ----------- ------- ------------------
32
33 LoadConst Load class, function, Combine null context with
34 module, constant loaded object
35
36 LoadAddress Load attribute from Preserve or override stored
37 LoadAddressContext class, module, context (as described in
38 LoadAttr instance assignment.txt)
39 LoadAttrIndex
40
41 Storing Values
42 --------------
43
44 There is only one class of instruction for storing values:
45
46 Instruction Purpose Context Operations
47 ----------- ------- ------------------
48
49 StoreAddress Store attribute in a Preserve context; note that no
50 known object test for class attribute
51 assignment should be necessary
52 since this instruction should only
53 be generated for module globals
54
55 StoreAttr Store attribute in an Preserve context; note that no
56 instance test for class attribute
57 assignment should be necessary
58 since this instruction should only
59 be generated for self accesses
60
61 StoreAttrIndex Store attribute in an Preserve context; since the index
62 unknown object lookup could yield a class
63 attribute, a test of the nature of
64 the nature of the structure is
65 necessary in order to prevent
66 assignments to classes
67
68 Note that contexts are never changed in the stored value: they are preserved.
69 See assignment.txt for more information.
70
71 Objects
72 -------
73
74 Since classes, functions and instances are all "objects", each must support
75 certain features and operations in the same way.
76
77 The __class__ Attribute
78 -----------------------
79
80 All objects support the __class__ attribute:
81
82 Class: refers to the type class (type.__class__ also refers to the type class)
83 Function: refers to the function class
84 Instance: refers to the class instantiated to make the object
85
86 Invocation
87 ----------
88
89 The following actions need to be supported:
90
91 Class: create instance, call __init__ with instance, return object
92 Function: call function body, return result
93 Instance: call __call__ method, return result
94
95 Structure Layout
96 ----------------
97
98 A suitable structure layout might be something like this:
99
100 Identifier Identifier Address Details Type Object ...
101
102 0 1 2 3 4 5 6
103 classcode attrcode invocation invocation __class__ attribute ...
104 reference #args, reference reference
105 defaults
106 reference
107
108 Here, the classcode refers to the attribute lookup table for the object. Since
109 classes and instances share the same classcode, they might resemble the
110 following:
111
112 Class C:
113
114 0 1 2 3 4 5 6
115 code for C attrcode __new__ __new__ class type attribute ...
116 for C reference #args, reference reference
117 defaults
118 reference
119
120 Instance of C:
121
122 0 1 2 3 4 5 6
123 code for C attrcode C.__call__ C.__call__ class C attribute ...
124 for C reference #args, reference reference
125 (if exists) defaults
126 reference
127
128 The __new__ reference would lead to code consisting of the following
129 instructions:
130
131 create instance for C
132 call C.__init__(instance, ...)
133 return instance
134
135 If C has a __call__ attribute, the invocation "slot" of C instances would
136 refer to the same thing as C.__call__. This "slot" has to be prepared when
137 creating instances, either by modifying the sequence of instructions used in,
138 amongst other places, the instantiator function, or by generating a template
139 instance whose details are copied when new instances are created.
140
141 For functions, the same general layout applies:
142
143 Function f:
144
145 0 1 2 3 4 5 6
146 code for attrcode code code class attribute ...
147 function for reference #args, function (default)
148 function defaults reference reference
149 reference
150
151 Here, the code reference would lead to code for the function. Note that the
152 function locals are completely distinct from this structure and are not
153 comparable to attributes. Instead, attributes are reserved for default
154 parameter values.
155
156 For modules, there is no meaningful invocation reference:
157
158 Module m:
159
160 0 1 2 3 4 5 6
161 code for m attrcode (unused) (unused) module type attribute ...
162 for m reference (global)
163 reference
164
165 Both classes and modules have code in their definitions, but this would be
166 generated in order and not referenced externally.
167
168 Invocation Operation
169 --------------------
170
171 Consequently, regardless of the object an invocation is always done as
172 follows:
173
174 get invocation reference (at object+1)
175 jump to reference
176
177 Additional preparation is necessary before the above code: positional
178 arguments must be saved to the parameter stack, and keyword arguments must be
179 resolved and saved to the appropriate position in the parameter stack.
180
181 Attribute Operations
182 --------------------
183
184 Attribute access needs to go through the attribute lookup table. Some
185 optimisations are possible and are described in the appropriate section.
186
187 One important aspect of attribute access is the appropriate setting of the
188 context in the acquired attribute value. From the table describing the
189 acquisition of values, it is clear that the principal exception is that where
190 a class-originating attribute is accessed on an instance. Consequently, the
191 following algorithm could be employed once an attribute has been located:
192
193 1. If the attribute's context is a special value, indicating that it should
194 be replaced upon instance access, then proceed to the next step;
195 otherwise, acquire both the context and the object as they are.
196
197 2. If the accessor is an instance, use that as the value's context, acquiring
198 only the object from the attribute.
199
200 Where accesses can be determined ahead of time (as discussed in the
201 optimisations section), the above algorithm may not necessarily be employed in
202 the generated code for some accesses.
203
204 Instance/Class Compatibility
205 ----------------------------
206
207 Although it would be possible to have a data structure mapping classes to
208 compatible classes, which in the case of context (or self argument)
209 suitability in invocations would involve a mapping from a class to itself plus
210 its descendants, the need to retain the key to such a data structure for each
211 class might introduce a noticeable overhead. Such a structure would
212 effectively be a matrix with each dimension indexed using the same sequence of
213 codes for each of the classes in a program.
214
215 The current solution is to insert descendants as special attributes into the
216 object/attribute lookup table. This requires an extra key to be retained,
217 since each class must provide its own attribute code such that upon an
218 instance/class compatibility test, the code may be obtained and used in the
219 object table.