Skip to content

Commit 0359940

Browse files
committed
Simple input-output stack effects
No arrays; no conitionals; no types; no cache effects.
1 parent 12078e7 commit 0359940

File tree

4 files changed

+70
-85
lines changed

4 files changed

+70
-85
lines changed

Python/bytecodes.c

+29-58
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ do { \
6969
#define DISPATCH() ((void)0)
7070

7171
#define inst(name) case name:
72+
#define instr(name, arg) case name:
7273
#define family(name) static int family_##name
7374

7475
#define NAME_ERROR_MSG \
@@ -103,58 +104,46 @@ dummy_func(
103104
and that all operation that succeed call DISPATCH() ! */
104105

105106
// BEGIN BYTECODES //
106-
// stack effect: ( -- )
107-
inst(NOP) {
107+
instr(NOP, (--)) {
108108
}
109109

110-
// stack effect: ( -- )
111-
inst(RESUME) {
110+
instr(RESUME, (--)) {
112111
assert(tstate->cframe == &cframe);
113112
assert(frame == cframe.current_frame);
114113
if (_Py_atomic_load_relaxed_int32(eval_breaker) && oparg < 2) {
115114
goto handle_eval_breaker;
116115
}
117116
}
118117

119-
// stack effect: ( -- __0)
120-
inst(LOAD_CLOSURE) {
118+
instr(LOAD_CLOSURE, (-- value)) {
121119
/* We keep LOAD_CLOSURE so that the bytecode stays more readable. */
122-
PyObject *value = GETLOCAL(oparg);
120+
value = GETLOCAL(oparg);
123121
if (value == NULL) {
124122
goto unbound_local_error;
125123
}
126124
Py_INCREF(value);
127-
PUSH(value);
128125
}
129126

130-
// stack effect: ( -- __0)
131-
inst(LOAD_FAST_CHECK) {
132-
PyObject *value = GETLOCAL(oparg);
127+
instr(LOAD_FAST_CHECK, (-- value)) {
128+
value = GETLOCAL(oparg);
133129
if (value == NULL) {
134130
goto unbound_local_error;
135131
}
136132
Py_INCREF(value);
137-
PUSH(value);
138133
}
139134

140-
// stack effect: ( -- __0)
141-
inst(LOAD_FAST) {
142-
PyObject *value = GETLOCAL(oparg);
135+
instr(LOAD_FAST, (-- value)) {
136+
value = GETLOCAL(oparg);
143137
assert(value != NULL);
144138
Py_INCREF(value);
145-
PUSH(value);
146139
}
147140

148-
// stack effect: ( -- __0)
149-
inst(LOAD_CONST) {
150-
PyObject *value = GETITEM(consts, oparg);
141+
instr(LOAD_CONST, (-- value)) {
142+
value = GETITEM(consts, oparg);
151143
Py_INCREF(value);
152-
PUSH(value);
153144
}
154145

155-
// stack effect: (__0 -- )
156-
inst(STORE_FAST) {
157-
PyObject *value = POP();
146+
inst(STORE_FAST, (value --)) {
158147
SETLOCAL(oparg, value);
159148
}
160149

@@ -220,9 +209,7 @@ dummy_func(
220209
PUSH(value);
221210
}
222211

223-
// stack effect: (__0 -- )
224-
inst(POP_TOP) {
225-
PyObject *value = POP();
212+
instr(POP_TOP, (value --)) {
226213
Py_DECREF(value);
227214
}
228215

@@ -232,59 +219,43 @@ dummy_func(
232219
BASIC_PUSH(NULL);
233220
}
234221

235-
// stack effect: (__0, __1 -- )
236-
inst(END_FOR) {
237-
PyObject *value = POP();
238-
Py_DECREF(value);
239-
value = POP();
240-
Py_DECREF(value);
222+
instr(END_FOR, (value1, value2 --)) {
223+
Py_DECREF(value1);
224+
Py_DECREF(value2);
241225
}
242226

243-
// stack effect: ( -- )
244-
inst(UNARY_POSITIVE) {
245-
PyObject *value = TOP();
246-
PyObject *res = PyNumber_Positive(value);
227+
instr(UNARY_POSITIVE, (value -- res)) {
228+
res = PyNumber_Positive(value);
247229
Py_DECREF(value);
248-
SET_TOP(res);
249230
if (res == NULL)
250231
goto error;
251232
}
252233

253-
// stack effect: ( -- )
254-
inst(UNARY_NEGATIVE) {
255-
PyObject *value = TOP();
256-
PyObject *res = PyNumber_Negative(value);
234+
instr(UNARY_NEGATIVE, (value -- res)) {
235+
res = PyNumber_Negative(value);
257236
Py_DECREF(value);
258-
SET_TOP(res);
259237
if (res == NULL)
260238
goto error;
261239
}
262240

263-
// stack effect: ( -- )
264-
inst(UNARY_NOT) {
265-
PyObject *value = TOP();
241+
instr(UNARY_NOT, (value -- res)) {
266242
int err = PyObject_IsTrue(value);
267243
Py_DECREF(value);
268244
if (err == 0) {
269-
Py_INCREF(Py_True);
270-
SET_TOP(Py_True);
271-
DISPATCH();
245+
res = Py_True;
272246
}
273247
else if (err > 0) {
274-
Py_INCREF(Py_False);
275-
SET_TOP(Py_False);
276-
DISPATCH();
248+
res = Py_False;
277249
}
278-
STACK_SHRINK(1);
279-
goto error;
250+
else {
251+
goto error;
252+
}
253+
Py_INCREF(res);
280254
}
281255

282-
// stack effect: ( -- )
283-
inst(UNARY_INVERT) {
284-
PyObject *value = TOP();
285-
PyObject *res = PyNumber_Invert(value);
256+
inst(UNARY_INVERT, (value -- res)) {
257+
res = PyNumber_Invert(value);
286258
Py_DECREF(value);
287-
SET_TOP(res);
288259
if (res == NULL)
289260
goto error;
290261
}

Python/generated_cases.c.h

+34-26
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/cases_generator/generate_cases.py

+6
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ def write_cases(f: io.TextIOBase, instrs: list[InstDef]):
7373
for instr in instrs:
7474
assert isinstance(instr, InstDef)
7575
f.write(f"\n{indent}TARGET({instr.name}) {{\n")
76+
for input in instr.inputs or ():
77+
f.write(f"{indent} PyObject *{input} = POP();\n")
78+
for output in instr.outputs or ():
79+
f.write(f"{indent} PyObject *{output};\n")
7680
if instr.name in predictions:
7781
f.write(f"{indent} PREDICTED({instr.name});\n")
7882
# input = ", ".join(instr.inputs)
@@ -96,6 +100,8 @@ def write_cases(f: io.TextIOBase, instrs: list[InstDef]):
96100
# Write the body
97101
for line in blocklines:
98102
f.write(line)
103+
for output in instr.outputs or ():
104+
f.write(f"{indent} PUSH({output});\n")
99105
assert instr.block
100106
if not always_exits(instr.block):
101107
f.write(f"{indent} DISPATCH();\n")

Tools/cases_generator/parser.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def inst_header(self):
8383
# inst(NAME) | inst(NAME, (inputs -- outputs))
8484
# TODO: Error out when there is something unexpected.
8585
# TODO: Make INST a keyword in the lexer.
86-
if (tkn := self.expect(lx.IDENTIFIER)) and tkn.text == "inst":
86+
if (tkn := self.expect(lx.IDENTIFIER)) and tkn.text in ("inst", "instr"):
8787
if (self.expect(lx.LPAREN)
8888
and (tkn := self.expect(lx.IDENTIFIER))):
8989
name = tkn.text

0 commit comments

Comments
 (0)