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