1 Namespace Definition
2 ====================
3
4 Module attributes are defined either at the module level or by global
5 statements.
6
7 Class attributes are defined only within class statements.
8
9 Instance attributes are defined only by assignments to attributes of self
10 within __init__ methods.
11
12 Data Structures
13 ===============
14
15 Since classes, functions and instances are all "objects", each must support
16 certain features and operations in the same way.
17
18 The __class__ Attribute
19 -----------------------
20
21 All objects support the __class__ attribute:
22
23 Class: refers to the type class (type.__class__ also refers to the type class)
24 Function: refers to the function class
25 Instance: refers to the class instantiated to make the object
26
27 Invocation
28 ----------
29
30 The following actions need to be supported:
31
32 Class: create instance, call __init__ with instance, return object
33 Function: call function body, return result
34 Instance: call __call__ method, return result
35
36 Structure Layout
37 ----------------
38
39 A suitable structure layout might be something like this:
40
41 0 1 2 3 4
42 classcode invocation __class__ attribute ...
43 reference reference reference
44
45 Here, the classcode refers to the attribute lookup table for the object. Since
46 classes and instances share the same classcode, they might resemble the
47 following:
48
49 Class C:
50
51 0 1 2 3 4
52 code for C __new__ class type attribute ...
53 reference reference reference
54
55 Instance of C:
56
57 0 1 2 3 4
58 code for C C.__call__ class C attribute ...
59 reference reference reference
60 (if exists)
61
62 The __new__ reference would lead to code consisting of the following
63 instructions:
64
65 create instance for C
66 call C.__init__(instance, ...)
67 return instance
68
69 If C has a __call__ attribute, the invocation "slot" of C instances would
70 refer to the same thing as C.__call__.
71
72 For functions, the same general layout applies:
73
74 Function f:
75
76 0 1 2 3 4
77 code for code class attribute ...
78 function reference function reference
79 reference
80
81 Here, the code reference would lead to code for the function. Note that the
82 function locals are completely distinct from this structure and are not
83 comparable to attributes.
84
85 For modules, the invocation reference would point to the start of the
86 module's code:
87
88 Module m:
89
90 0 1 2 3 4
91 code for m code module type attribute ...
92 reference reference (global)
93 reference
94
95 Invocation Operation
96 --------------------
97
98 Consequently, regardless of the object an invocation is always done as
99 follows:
100
101 get invocation reference (at object+1)
102 jump to reference
103
104 Additional preparation is necessary before the above code: positional
105 arguments must be saved to the parameter stack, and keyword arguments must be
106 resolved and saved to the appropriate position in the parameter stack.
107
108 Attribute Operations
109 --------------------
110
111 Attribute access needs to go through the attribute lookup table.
112
113 Instruction Evaluation Model
114 ============================
115
116 Programs use a value stack where evaluated instructions may save their
117 results. A value stack pointer indicates the top of this stack. In addition, a
118 separate stack is used to record the invocation frames. All stack pointers
119 refer to the next address to be used by the stack, not the address of the
120 uppermost element.
121
122 Frame Stack Value Stack
123 ----------- ----------- Address of Callable
124 -------------------
125 previous ...
126 current ------> callable -----> identifier
127 arg1 reference to code
128 arg2
129 arg3
130 local4
131 local5
132 ...
133
134 Loading local names is a matter of performing frame-relative accesses to the
135 value stack.
136
137 Invocations and Argument Evaluation
138 -----------------------------------
139
140 When preparing for an invocation, the caller first sets the invocation frame
141 pointer. Then, positional arguments are added to the stack such that the first
142 argument positions are filled. A number of stack locations for the remaining
143 arguments specified in the program are then reserved. The names of keyword
144 arguments are used (in the form of table index values) to consult the
145 parameter table and to find the location in which such arguments are to be
146 stored.
147
148 fn(a, b, d=1, e=2, c=3) -> fn(a, b, c, d, e)
149
150 Value Stack
151 -----------
152
153 ... ... ... ...
154 fn fn fn fn
155 a a a a
156 b b b b
157 ___ ___ ___ --> 3
158 ___ --> 1 1 | 1
159 ___ | ___ --> 2 | 2
160 1 ----------- 2 ----------- 3 -----------
161
162 Conceptually, the frame can be considered as a collection of attributes, as
163 seen in other kinds of structures:
164
165 Frame for invocation of fn:
166
167 0 1 2 3 4 5
168 code a b c d e
169 reference
170
171 However, where arguments are specified positionally, such "attributes" are not
172 set using a comparable approach to that employed with other structures.
173 Keyword arguments are set using an attribute-like mechanism, though, where the
174 position of each argument discovered using the parameter table.
175
176 Tuples, Frames and Allocation
177 -----------------------------
178
179 Using the approach where arguments are treated like attributes in some kind of
180 structure, we could choose to allocate frames in places other than a stack.
181 This would produce something somewhat similar to a plain tuple object.
182
183 Optimisations
184 =============
185
186 Some optimisations around constant objects might be possible; these depend on
187 the following:
188
189 * Reliable tracking of assignments: where assignment operations occur, the
190 target of the assignment should be determined if any hope of optimisation
191 is to be maintained. Where no guarantees can be made about the target of
192 an assignment, no assignment-related information should be written to
193 potential targets.
194
195 * Objects acting as "containers" of attributes must be regarded as "safe":
196 where assignments are recorded as occurring on an attribute, it must be
197 guaranteed that no other unforeseen ways exist to assign to such
198 attributes.
199
200 The discussion below presents certain rules which must be imposed to uphold
201 the above requirements.
202
203 Safe Containers
204 ---------------
205
206 Where attributes of modules, classes and instances are only set once and are
207 effectively constant, it should be possible to circumvent the attribute lookup
208 mechanism and to directly reference the attribute value. This technique may
209 only be considered applicable for the following "container" objects, subject
210 to the noted constraints:
211
212 1. For modules, "safety" is enforced by ensuring that assignments to module
213 attributes are only permitted within the module itself either at the
214 top-level or via names declared as globals. Thus, the following would not
215 be permitted:
216
217 another_module.this_module.attr = value
218
219 In the above, this_module is a reference to the current module.
220
221 2. For classes, "safety" is enforced by ensuring that assignments to class
222 attributes are only permitted within the class definition, outside
223 methods. This would mean that classes would be "sealed" at definition time
224 (like functions).
225
226 Unlike the property of function locals that they may only sensibly be accessed
227 within the function in which they reside, these cases demand additional
228 controls or assumptions on or about access to the stored data. Meanwhile, it
229 would be difficult to detect eligible attributes on arbitrary instances due to
230 the need for some kind of type inference or abstract execution.
231
232 Constant Attributes
233 -------------------
234
235 When accessed via "safe containers", as described above, any attribute with
236 only one recorded assignment on it can be considered a constant attribute and
237 this eligible for optimisation, the consequence of which would be the
238 replacement of a LoadAttrIndex instruction (which needs to look up an
239 attribute using the run-time details of the "container" and the compile-time
240 details of the attribute) with a LoadAttr instruction.
241
242 However, some restrictions exist on assignment operations which may be
243 regarded to cause only one assignment in the lifetime of a program:
244
245 1. For module attributes, only assignments at the top-level outside loop
246 statements can be reliably assumed to cause only a single assignment.
247
248 2. For class attributes, only assignments at the top-level within class
249 definitions and outside loop statements can be reliably assumed to cause
250 only a single assignment.
251
252 All assignments satisfying the "safe container" requirements, but not the
253 requirements immediately above, should each be recorded as causing at least
254 one assignment.
255
256 Additional Controls
257 -------------------
258
259 For the above cases for "container" objects, the following controls would need
260 to apply:
261
262 1. Modules would need to be immutable after initialisation. However, during
263 initialisation, there remains a possibility of another module attempting
264 to access the original module. For example, if ppp/__init__.py contained
265 the following...
266
267 x = 1
268 import ppp.qqq
269 print x
270
271 ...and if ppp/qqq.py contained the following...
272
273 import ppp
274 ppp.x = 2
275
276 ...then the value 2 would be printed. Since modules are objects which are
277 registered globally in a program, it would be possible to set attributes
278 in the above way.
279
280 2. Classes would need to be immutable after initialisation. However, since
281 classes are objects, any reference to a class after initialisation could
282 be used to set attributes on the class.
283
284 Solutions:
285
286 1. Insist on global scope for module attribute assignments.
287
288 2. Insist on local scope within classes.
289
290 Both of the above measures need to be enforced at run-time, since an arbitrary
291 attribute assignment could be attempted on any kind of object, yet to uphold
292 the properties of "safe containers", attempts to change attributes of such
293 objects should be denied. Since foreseen attribute assignment operations have
294 certain properties detectable at compile-time, it could be appropriate to
295 generate special instructions (or modified instructions) during the
296 initialisation of modules and classes for such foreseen assignments, whilst
297 employing normal attribute assignment operations in all other cases. Indeed,
298 the StoreAttr instruction, which is used to set attributes in "safe
299 containers" would be used exclusively for this purpose; the StoreAttrIndex
300 instruction would be used exclusively for all other attribute assignments.
301
302 Constant Attribute Values
303 -------------------------
304
305 Where an attribute value is itself regarded as constant, is a "safe container"
306 and is used in an operation accessing its own attributes, the value can be
307 directly inspected for optimisations or employed in the generated code. For
308 the attribute values themselves, only objects of a constant nature may be
309 considered suitable for this particular optimisation:
310
311 * Classes
312 * Modules
313 * Instances defined as constant literals
314
315 This is because arbitrary objects (such as most instances) have no
316 well-defined form before run-time and cannot be investigated further at
317 compile-time or have a representation inserted into the generated code.
318
319 Class Attributes and Access via Instances
320 -----------------------------------------
321
322 Unlike module attributes, class attributes can be accessed in a number of
323 different ways:
324
325 * Using the class itself:
326
327 C.x = 123
328 cls = C; cls.x = 234
329
330 * Using a subclass of the class (for reading attributes):
331
332 class D(C):
333 pass
334 D.x # setting D.x would populate D, not C
335
336 * Using instances of the class or a subclass of the class (for reading
337 attributes):
338
339 c = C()
340 c.x # setting c.x would populate c, not C
341
342 Since assignments are only achieved using direct references to the class, and
343 since class attributes should be defined only within the class initialisation
344 process, the properties of class attributes should be consistent with those
345 desired.
346
347 Method Access via Instances
348 ---------------------------
349
350 It is desirable to optimise method access, even though most method calls are
351 likely to occur via instances. It is possible, given the properties of methods
352 as class attributes to investigate the kind of instance that the self
353 parameter/local refers to within each method: it should be an instance either
354 of the class in which the method is defined or a compatible class, although
355 situations exist where this might not be the case:
356
357 * Explicit invocation of a method:
358
359 d = D() # D is not related to C
360 C.f(d) # calling f(self) in C
361
362 If blatant usage of incompatible instances were somehow disallowed, it would
363 still be necessary to investigate the properties of an instance's class and
364 its relationship with other classes. Consider the following example:
365
366 class A:
367 def f(self): ...
368
369 class B:
370 def f(self): ...
371 def g(self):
372 self.f()
373
374 class C(A, B):
375 pass
376
377 Here, instances of B passed into the method B.g could be assumed to provide
378 access to B.f when self.f is resolved at compile-time. However, instances of C
379 passed into B.g would instead provide access to A.f when self.f is resolved at
380 compile-time (since the method resolution order is C, A, B instead of just B).
381
382 One solution might be to specialise methods for each instance type, but this
383 could be costly. Another less ambitious solution might only involve the
384 optimisation of such internal method calls if an unambiguous target can be
385 resolved.
386
387 Optimising Function Invocations
388 -------------------------------
389
390 Where an attribute value is itself regarded as constant and is a function,
391 knowledge about the parameters of the function can be employed to optimise the
392 preparation of the invocation frame.