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.
82
83 Invocation Operation
84 --------------------
85
86 Consequently, regardless of the object an invocation is always done as
87 follows:
88
89 get invocation reference (at object+1)
90 jump to reference
91
92 Additional preparation is necessary before the above code: positional
93 arguments must be saved to the parameter stack, and keyword arguments must be
94 resolved and saved to the appropriate position in the parameter stack.
95
96 Attribute Operations
97 --------------------
98
99 Attribute access needs to go through the attribute lookup table.
100
101 Instruction Evaluation Model
102 ============================
103
104 Programs use a value stack where evaluated instructions may save their
105 results. A value stack pointer indicates the top of this stack. In addition, a
106 separate stack is used to record the invocation frames. All stack pointers
107 refer to the next address to be used by the stack, not the address of the
108 uppermost element.
109
110 Frame Stack Value Stack
111 ----------- ----------- Address of Callable
112 -------------------
113 previous ...
114 current ------> callable -----> identifier
115 arg1 reference to code
116 arg2
117 arg3
118 local4
119 local5
120 ...
121
122 Loading local names is a matter of performing frame-relative accesses to the
123 value stack.
124
125 Invocations and Argument Evaluation
126 -----------------------------------
127
128 When preparing for an invocation, the caller first sets the invocation frame
129 pointer. Then, positional arguments are added to the stack such that the first
130 argument positions are filled. A number of stack locations for the remaining
131 arguments specified in the program are then reserved. The names of keyword
132 arguments are used (in the form of table index values) to consult the
133 parameter table and to find the location in which such arguments are to be
134 stored.
135
136 fn(a, b, d=1, e=2, c=3) -> fn(a, b, c, d, e)
137
138 Value Stack
139 -----------
140
141 ... ... ... ...
142 fn fn fn fn
143 a a a a
144 b b b b
145 ___ ___ ___ --> 3
146 ___ --> 1 1 | 1
147 ___ | ___ --> 2 | 2
148 1 ----------- 2 ----------- 3 -----------
149
150 Conceptually, the frame can be considered as a collection of attributes, as
151 seen in other kinds of structures:
152
153 Frame for invocation of fn:
154
155 0 1 2 3 4 5
156 code a b c d e
157 reference
158
159 However, where arguments are specified positionally, such "attributes" are not
160 set using a comparable approach to that employed with other structures.
161 Keyword arguments are set using an attribute-like mechanism, though, where the
162 position of each argument discovered using the parameter table.
163
164 Tuples, Frames and Allocation
165 -----------------------------
166
167 Using the approach where arguments are treated like attributes in some kind of
168 structure, we could choose to allocate frames in places other than a stack.
169 This would produce something somewhat similar to a plain tuple object.
170
171 Optimisations
172 =============
173
174 Constant Attributes
175 -------------------
176
177 Where attributes of modules, classes and instances are only set once and are
178 effectively constant, it should be possible to circumvent the attribute lookup
179 mechanism and to directly reference the attribute value. This technique may
180 only be considered applicable in the following cases for "container" objects:
181
182 1. For modules, provided that assignments to module attributes are only
183 permitted within the module itself either at the top-level or via names
184 declared as globals. Thus, the following would not be permitted:
185
186 another_module.this_module.attr = value
187
188 (Where this_module is a reference to the current module.)
189
190 2. For classes, provided that assignments to class attributes are only
191 permitted within the class definition, outside methods. This would mean
192 that classes would be "sealed" at definition time (like functions).
193
194 Unlike the property of function locals that they may only sensibly be accessed
195 within the function in which they reside, these cases demand additional
196 controls or assumptions on or about access to the stored data. Meanwhile, it
197 would be difficult to detect eligible attributes on arbitrary instances due to
198 the need for some kind of type inference or abstract execution.
199
200 Where (1) and (2) apply, any attribute with only one recorded assignment on it
201 can be considered a constant attribute and this eligible for this
202 optimisation, the consequence of which would be the replacement of a
203 LoadAttrIndex instruction (which needs to look up an attribute using the
204 run-time details of the "container" and the compile-time details of the
205 attribute) with a LoadAttr instruction.
206
207 Constant Attribute Values
208 -------------------------
209
210 Where an attribute value is itself constant and be used either in an operation
211 accessing its own attributes, or in an invocation, the value can be directly
212 inspected for optimisations or employed in the generated code. For the
213 attribute values themselves, only objects of a constant nature may be
214 considered suitable for this particular optimisation:
215
216 * Functions
217 * Classes
218 * Modules
219 * Instances defined as constant literals
220
221 This is because arbitrary objects (such as most instances) have no
222 well-defined form before run-time and cannot be investigated further at
223 compile-time or have a representation inserted into the generated code.