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