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