@@ -67,26 +67,24 @@ parts of instructions, we can reduce the potential for errors considerably.
67
67
68
68
## Specification
69
69
70
- This specification is at an early stage and is likely to change considerably.
70
+ This specification is a work in progress.
71
+ We update it as the need arises.
71
72
72
- Syntax
73
- ------
73
+ ### Syntax
74
74
75
75
Each op definition has a kind, a name, a stack and instruction stream effect,
76
76
and a piece of C code describing its semantics::
77
77
78
78
```
79
79
file:
80
- (definition | family)+
80
+ (definition | family | pseudo )+
81
81
82
82
definition:
83
83
"inst" "(" NAME ["," stack_effect] ")" "{" C-code "}"
84
84
|
85
85
"op" "(" NAME "," stack_effect ")" "{" C-code "}"
86
86
|
87
87
"macro" "(" NAME ")" "=" uop ("+" uop)* ";"
88
- |
89
- "super" "(" NAME ")" "=" NAME ("+" NAME)* ";"
90
88
91
89
stack_effect:
92
90
"(" [inputs] "--" [outputs] ")"
@@ -122,16 +120,17 @@ and a piece of C code describing its semantics::
122
120
object "[" C-expression "]"
123
121
124
122
family:
125
- "family" "(" NAME ")" = "{" NAME ("," NAME)+ "}" ";"
123
+ "family" "(" NAME ")" = "{" NAME ("," NAME)+ [","] "}" ";"
124
+
125
+ pseudo:
126
+ "pseudo" "(" NAME ")" = "{" NAME ("," NAME)+ [","] "}" ";"
126
127
```
127
128
128
129
The following definitions may occur:
129
130
130
131
* ` inst ` : A normal instruction, as previously defined by ` TARGET(NAME) ` in ` ceval.c ` .
131
132
* ` op ` : A part instruction from which macros can be constructed.
132
133
* ` macro ` : A bytecode instruction constructed from ops and cache effects.
133
- * ` super ` : A super-instruction, such as ` LOAD_FAST__LOAD_FAST ` , constructed from
134
- normal or macro instructions.
135
134
136
135
` NAME ` can be any ASCII identifier that is a C identifier and not a C or Python keyword.
137
136
` foo_1 ` is legal. ` $ ` is not legal, nor is ` struct ` or ` class ` .
@@ -159,15 +158,21 @@ By convention cache effects (`stream`) must precede the input effects.
159
158
160
159
The name ` oparg ` is pre-defined as a 32 bit value fetched from the instruction stream.
161
160
161
+ ### Special functions/macros
162
+
162
163
The C code may include special functions that are understood by the tools as
163
164
part of the DSL.
164
165
165
166
Those functions include:
166
167
167
168
* ` DEOPT_IF(cond, instruction) ` . Deoptimize if ` cond ` is met.
168
- * ` ERROR_IF(cond, label) ` . Jump to error handler if ` cond ` is true.
169
+ * ` ERROR_IF(cond, label) ` . Jump to error handler at ` label ` if ` cond ` is true.
169
170
* ` DECREF_INPUTS() ` . Generate ` Py_DECREF() ` calls for the input stack effects.
170
171
172
+ Note that the use of ` DECREF_INPUTS() ` is optional -- manual calls
173
+ to ` Py_DECREF() ` or other approaches are also acceptable
174
+ (e.g. calling an API that "steals" a reference).
175
+
171
176
Variables can either be defined in the input, output, or in the C code.
172
177
Variables defined in the input may not be assigned in the C code.
173
178
If an ` ERROR_IF ` occurs, all values will be removed from the stack;
@@ -187,17 +192,39 @@ These requirements result in the following constraints on the use of
187
192
intermediate results.)
188
193
3 . No ` DEOPT_IF ` may follow an ` ERROR_IF ` in the same block.
189
194
190
- Semantics
191
- ---------
195
+ (There is some wiggle room: these rules apply to dynamic code paths,
196
+ not to static occurrences in the source code.)
197
+
198
+ If code detects an error condition before the first ` DECREF ` of an input,
199
+ two idioms are valid:
200
+
201
+ - Use ` goto error ` .
202
+ - Use a block containing the appropriate ` DECREF ` calls ending in
203
+ ` ERROR_IF(true, error) ` .
204
+
205
+ An example of the latter would be:
206
+ ``` cc
207
+ res = PyObject_Add(left, right);
208
+ if (res == NULL ) {
209
+ DECREF_INPUTS ();
210
+ ERROR_IF(true, error);
211
+ }
212
+ ```
213
+
214
+ ### Semantics
192
215
193
216
The underlying execution model is a stack machine.
194
217
Operations pop values from the stack, and push values to the stack.
195
218
They also can look at, and consume, values from the instruction stream.
196
219
197
- All members of a family must have the same stack and instruction stream effect.
220
+ All members of a family
221
+ (which represents a specializable instruction and its specializations)
222
+ must have the same stack and instruction stream effect.
223
+
224
+ The same is true for all members of a pseudo instruction
225
+ (which is mapped by the bytecode compiler to one of its members).
198
226
199
- Examples
200
- --------
227
+ ## Examples
201
228
202
229
(Another source of examples can be found in the [tests](test_generator.py).)
203
230
@@ -237,27 +264,6 @@ This would generate:
237
264
}
238
265
```
239
266
240
- ### Super-instruction definition
241
-
242
- ``` C
243
- super ( LOAD_FAST__ LOAD_FAST ) = LOAD_FAST + LOAD_FAST ;
244
- ```
245
- This might get translated into the following:
246
- ```C
247
- TARGET(LOAD_FAST__LOAD_FAST) {
248
- PyObject *value;
249
- value = frame->f_localsplus[oparg];
250
- Py_INCREF(value);
251
- PUSH(value);
252
- NEXTOPARG();
253
- next_instr++;
254
- value = frame->f_localsplus[oparg];
255
- Py_INCREF(value);
256
- PUSH(value);
257
- DISPATCH();
258
- }
259
- ```
260
-
261
267
### Input stack effect and cache effect
262
268
```C
263
269
op ( CHECK_OBJECT_TYPE, (owner, type_version/2 -- owner) ) {
@@ -339,14 +345,26 @@ For explanations see "Generating the interpreter" below.)
339
345
}
340
346
```
341
347
342
- ### Define an instruction family
343
- These opcodes all share the same instruction format):
348
+ ### Defining an instruction family
349
+
350
+ A _ family_ represents a specializable instruction and its specializations.
351
+
352
+ Example: These opcodes all share the same instruction format):
353
+ ``` C
354
+ family (load_attr) = { LOAD_ATTR, LOAD_ATTR_INSTANCE_VALUE, LOAD_SLOT };
355
+ ```
356
+
357
+ ### Defining a pseudo instruction
358
+
359
+ A _pseudo instruction_ is used by the bytecode compiler to represent a set of possible concrete instructions.
360
+
361
+ Example: `JUMP` may expand to `JUMP_FORWARD` or `JUMP_BACKWARD`:
344
362
```C
345
- family(load_attr ) = { LOAD_ATTR, LOAD_ATTR_INSTANCE_VALUE, LOAD_SLOT } ;
363
+ pseudo(JUMP ) = { JUMP_FORWARD, JUMP_BACKWARD } ;
346
364
```
347
365
348
- Generating the interpreter
349
- ==========================
366
+
367
+ ## Generating the interpreter
350
368
351
369
The generated C code for a single instruction includes a preamble and dispatch at the end
352
370
which can be easily inserted. What is more complex is ensuring the correct stack effects
@@ -401,9 +419,7 @@ rather than popping and pushing, such that `LOAD_ATTR_SLOT` would look something
401
419
}
402
420
```
403
421
404
- Other tools
405
- ===========
422
+ ## Other tools
406
423
407
424
From the instruction definitions we can generate the stack marking code used in ` frame.set_lineno() ` ,
408
425
and the tables for use by disassemblers.
409
-
0 commit comments