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 Acquiring Values
17 ----------------
18
19 Values are acquired through name lookups and attribute access, yielding
20 the appropriate object reference together with a context reference as
21 indicated in the following table:
22
23 Type of Access Context Notes
24 -------------- ------- -----
25
26 Local name Preserved Functions provide no context
27
28 Global name Preserved Modules provide no context
29
30 Class-originating Accessor Class accessor preserves the stored
31 attribute -or- context; instance accessor overrides
32 Preserved the stored context if it is null or
33 belongs to the instance's class
34 hierarchy
35
36 Instance-originating Preserved Methods retain their original context
37 attribute
38
39 There may be some scope for simplifying the above, to the detriment of Python
40 compatibility, since the unbound vs. bound methods situation can be confusing.
41
42 Manipulating Values
43 -------------------
44
45 According to the table describing value acquisition, different instructions
46 must implement different operations when acquiring values:
47
48 Instruction Purpose Context Operations
49 ----------- ------- ------------------
50
51 LoadConst Load class, function, Combine null context with loaded
52 module, constant object
53
54 LoadAddress Load attribute from Classes, functions and modules
55 known object stored as cause the loaded attribute to be
56 an attribute retrieved unchanged; whereas
57 constants (representing instances)
58 cause the constant to override the
59 attribute's own context (since all
60 attributes should belong to the
61 constant's class hierarchy)
62
63 LoadAttr Load attribute from Attributes with null contexts or
64 instance stored as an contexts compatible with the
65 attribute instance cause loaded attributes
66 to combine the instance as context
67 with the object from the
68 attribute; other attributes have
69 their context preserved
70
71 LoadAttrIndex Load attribute from Classes, functions and modules as
72 unknown object stored the unknown object accessor cause
73 as an attribute the loaded attribute to be
74 retrieved unchanged; whereas
75 instances cause the LoadAttr rules
76 to apply
77
78 Consequently, a certain amount of run-time testing is required for both
79 LoadAttr and LoadAttrIndex.
80
81 Objects
82 -------
83
84 Since classes, functions and instances are all "objects", each must support
85 certain features and operations in the same way.
86
87 The __class__ Attribute
88 -----------------------
89
90 All objects support the __class__ attribute:
91
92 Class: refers to the type class (type.__class__ also refers to the type class)
93 Function: refers to the function class
94 Instance: refers to the class instantiated to make the object
95
96 Invocation
97 ----------
98
99 The following actions need to be supported:
100
101 Class: create instance, call __init__ with instance, return object
102 Function: call function body, return result
103 Instance: call __call__ method, return result
104
105 Structure Layout
106 ----------------
107
108 A suitable structure layout might be something like this:
109
110 Identifier Address Details Type Object ...
111
112 0 1 2 3 4 5
113 classcode invocation invocation __class__ attribute ...
114 reference #args, reference reference
115 #defaults
116
117 Here, the classcode refers to the attribute lookup table for the object. Since
118 classes and instances share the same classcode, they might resemble the
119 following:
120
121 Class C:
122
123 0 1 2 3 4 5
124 code for C __new__ __new__ class type attribute ...
125 reference #args, reference reference
126 #defaults
127
128 Instance of C:
129
130 0 1 2 3 4 5
131 code for C C.__call__ C.__call__ class C attribute ...
132 reference #args, reference reference
133 (if exists) #defaults
134
135 The __new__ reference would lead to code consisting of the following
136 instructions:
137
138 create instance for C
139 call C.__init__(instance, ...)
140 return instance
141
142 If C has a __call__ attribute, the invocation "slot" of C instances would
143 refer to the same thing as C.__call__.
144
145 For functions, the same general layout applies:
146
147 Function f:
148
149 0 1 2 3 4 5
150 code for code code class attribute ...
151 function reference #args, function reference
152 #defaults reference
153
154 Here, the code reference would lead to code for the function. Note that the
155 function locals are completely distinct from this structure and are not
156 comparable to attributes. Instead, attributes are reserved for default
157 parameter values.
158
159 For modules, there is no meaningful invocation reference:
160
161 Module m:
162
163 0 1 2 3 4 5
164 code for m (unused) (unused) module type attribute ...
165 reference (global)
166 reference
167
168 Both classes and modules have code in their definitions, but this would be
169 generated in order and not referenced externally.
170
171 Invocation Operation
172 --------------------
173
174 Consequently, regardless of the object an invocation is always done as
175 follows:
176
177 get invocation reference (at object+1)
178 jump to reference
179
180 Additional preparation is necessary before the above code: positional
181 arguments must be saved to the parameter stack, and keyword arguments must be
182 resolved and saved to the appropriate position in the parameter stack.
183
184 Attribute Operations
185 --------------------
186
187 Attribute access needs to go through the attribute lookup table. Some
188 optimisations are possible and are described in the appropriate section.
189
190 One important aspect of attribute access is the appropriate setting of the
191 context in the acquired attribute value. From the table describing the
192 acquisition of values, it is clear that the principal exception is that where
193 a class-originating attribute is accessed on an instance. Consequently, the
194 following algorithm could be employed once an attribute has been located:
195
196 1. If the attribute's context is a special value, indicating that it should
197 be replaced upon instance access, then proceed to the next step;
198 otherwise, acquire both the context and the object as they are.
199
200 2. If the accessor is an instance, use that as the value's context, acquiring
201 only the object from the attribute.
202
203 Where accesses can be determined ahead of time (as discussed in the
204 optimisations section), the above algorithm may not necessarily be employed in
205 the generated code for some accesses.