Skip to content

Commit 29a858b

Browse files
authored
gh-98831: rewrite GET_LEN, GET_ITER, BEFORE_WITH and a few simple opcodes in the instruction definition DSL (#101443)
1 parent 909a674 commit 29a858b

File tree

3 files changed

+59
-69
lines changed

3 files changed

+59
-69
lines changed

Python/bytecodes.c

+21-36
Original file line numberDiff line numberDiff line change
@@ -2053,8 +2053,7 @@ dummy_func(
20532053
}
20542054
}
20552055

2056-
// stack effect: ( -- )
2057-
inst(JUMP_BACKWARD_NO_INTERRUPT) {
2056+
inst(JUMP_BACKWARD_NO_INTERRUPT, (--)) {
20582057
/* This bytecode is used in the `yield from` or `await` loop.
20592058
* If there is an interrupt, we want it handled in the innermost
20602059
* generator or coroutine, so we deliberately do not check it here.
@@ -2063,18 +2062,12 @@ dummy_func(
20632062
JUMPBY(-oparg);
20642063
}
20652064

2066-
// stack effect: ( -- __0)
2067-
inst(GET_LEN) {
2065+
inst(GET_LEN, (obj -- obj, len_o)) {
20682066
// PUSH(len(TOS))
2069-
Py_ssize_t len_i = PyObject_Length(TOP());
2070-
if (len_i < 0) {
2071-
goto error;
2072-
}
2073-
PyObject *len_o = PyLong_FromSsize_t(len_i);
2074-
if (len_o == NULL) {
2075-
goto error;
2076-
}
2077-
PUSH(len_o);
2067+
Py_ssize_t len_i = PyObject_Length(obj);
2068+
ERROR_IF(len_i < 0, error);
2069+
len_o = PyLong_FromSsize_t(len_i);
2070+
ERROR_IF(len_o == NULL, error);
20782071
}
20792072

20802073
inst(MATCH_CLASS, (subject, type, names -- attrs)) {
@@ -2110,15 +2103,11 @@ dummy_func(
21102103
ERROR_IF(values_or_none == NULL, error);
21112104
}
21122105

2113-
// stack effect: ( -- )
2114-
inst(GET_ITER) {
2106+
inst(GET_ITER, (iterable -- iter)) {
21152107
/* before: [obj]; after [getiter(obj)] */
2116-
PyObject *iterable = TOP();
2117-
PyObject *iter = PyObject_GetIter(iterable);
2118-
Py_DECREF(iterable);
2119-
SET_TOP(iter);
2120-
if (iter == NULL)
2121-
goto error;
2108+
iter = PyObject_GetIter(iterable);
2109+
DECREF_INPUTS();
2110+
ERROR_IF(iter == NULL, error);
21222111
}
21232112

21242113
// stack effect: ( -- )
@@ -2313,10 +2302,10 @@ dummy_func(
23132302
PREDICT(GET_AWAITABLE);
23142303
}
23152304

2316-
// stack effect: ( -- __0)
2317-
inst(BEFORE_WITH) {
2318-
PyObject *mgr = TOP();
2319-
PyObject *res;
2305+
inst(BEFORE_WITH, (mgr -- exit, res)) {
2306+
/* pop the context manager, push its __exit__ and the
2307+
* value returned from calling its __enter__
2308+
*/
23202309
PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__enter__));
23212310
if (enter == NULL) {
23222311
if (!_PyErr_Occurred(tstate)) {
@@ -2327,7 +2316,7 @@ dummy_func(
23272316
}
23282317
goto error;
23292318
}
2330-
PyObject *exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__));
2319+
exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__));
23312320
if (exit == NULL) {
23322321
if (!_PyErr_Occurred(tstate)) {
23332322
_PyErr_Format(tstate, PyExc_TypeError,
@@ -2339,14 +2328,13 @@ dummy_func(
23392328
Py_DECREF(enter);
23402329
goto error;
23412330
}
2342-
SET_TOP(exit);
2343-
Py_DECREF(mgr);
2331+
DECREF_INPUTS();
23442332
res = _PyObject_CallNoArgs(enter);
23452333
Py_DECREF(enter);
23462334
if (res == NULL) {
2347-
goto error;
2335+
Py_DECREF(exit);
2336+
ERROR_IF(true, error);
23482337
}
2349-
PUSH(res);
23502338
}
23512339

23522340
inst(WITH_EXCEPT_START, (exit_func, lasti, unused, val -- exit_func, lasti, unused, val, res)) {
@@ -2469,8 +2457,7 @@ dummy_func(
24692457
GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS);
24702458
}
24712459

2472-
// stack effect: ( -- )
2473-
inst(KW_NAMES) {
2460+
inst(KW_NAMES, (--)) {
24742461
assert(kwnames == NULL);
24752462
assert(oparg < PyTuple_GET_SIZE(consts));
24762463
kwnames = GETITEM(consts, oparg);
@@ -3252,8 +3239,7 @@ dummy_func(
32523239
PEEK(oparg) = top;
32533240
}
32543241

3255-
// stack effect: ( -- )
3256-
inst(EXTENDED_ARG) {
3242+
inst(EXTENDED_ARG, (--)) {
32573243
assert(oparg);
32583244
assert(cframe.use_tracing == 0);
32593245
opcode = _Py_OPCODE(*next_instr);
@@ -3262,8 +3248,7 @@ dummy_func(
32623248
DISPATCH_GOTO();
32633249
}
32643250

3265-
// stack effect: ( -- )
3266-
inst(CACHE) {
3251+
inst(CACHE, (--)) {
32673252
Py_UNREACHABLE();
32683253
}
32693254

Python/generated_cases.c.h

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

Python/opcode_metadata.h

+14-14
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,9 @@ _PyOpcode_num_popped(int opcode, int oparg) {
245245
case JUMP_IF_TRUE_OR_POP:
246246
return -1;
247247
case JUMP_BACKWARD_NO_INTERRUPT:
248-
return -1;
248+
return 0;
249249
case GET_LEN:
250-
return -1;
250+
return 1;
251251
case MATCH_CLASS:
252252
return 3;
253253
case MATCH_MAPPING:
@@ -257,7 +257,7 @@ _PyOpcode_num_popped(int opcode, int oparg) {
257257
case MATCH_KEYS:
258258
return 2;
259259
case GET_ITER:
260-
return -1;
260+
return 1;
261261
case GET_YIELD_FROM_ITER:
262262
return -1;
263263
case FOR_ITER:
@@ -273,7 +273,7 @@ _PyOpcode_num_popped(int opcode, int oparg) {
273273
case BEFORE_ASYNC_WITH:
274274
return -1;
275275
case BEFORE_WITH:
276-
return -1;
276+
return 1;
277277
case WITH_EXCEPT_START:
278278
return 4;
279279
case PUSH_EXC_INFO:
@@ -287,7 +287,7 @@ _PyOpcode_num_popped(int opcode, int oparg) {
287287
case CALL_BOUND_METHOD_EXACT_ARGS:
288288
return -1;
289289
case KW_NAMES:
290-
return -1;
290+
return 0;
291291
case CALL:
292292
return -1;
293293
case CALL_PY_EXACT_ARGS:
@@ -339,9 +339,9 @@ _PyOpcode_num_popped(int opcode, int oparg) {
339339
case SWAP:
340340
return -1;
341341
case EXTENDED_ARG:
342-
return -1;
342+
return 0;
343343
case CACHE:
344-
return -1;
344+
return 0;
345345
default:
346346
Py_UNREACHABLE();
347347
}
@@ -591,9 +591,9 @@ _PyOpcode_num_pushed(int opcode, int oparg) {
591591
case JUMP_IF_TRUE_OR_POP:
592592
return -1;
593593
case JUMP_BACKWARD_NO_INTERRUPT:
594-
return -1;
594+
return 0;
595595
case GET_LEN:
596-
return -1;
596+
return 2;
597597
case MATCH_CLASS:
598598
return 1;
599599
case MATCH_MAPPING:
@@ -603,7 +603,7 @@ _PyOpcode_num_pushed(int opcode, int oparg) {
603603
case MATCH_KEYS:
604604
return 3;
605605
case GET_ITER:
606-
return -1;
606+
return 1;
607607
case GET_YIELD_FROM_ITER:
608608
return -1;
609609
case FOR_ITER:
@@ -619,7 +619,7 @@ _PyOpcode_num_pushed(int opcode, int oparg) {
619619
case BEFORE_ASYNC_WITH:
620620
return -1;
621621
case BEFORE_WITH:
622-
return -1;
622+
return 2;
623623
case WITH_EXCEPT_START:
624624
return 5;
625625
case PUSH_EXC_INFO:
@@ -633,7 +633,7 @@ _PyOpcode_num_pushed(int opcode, int oparg) {
633633
case CALL_BOUND_METHOD_EXACT_ARGS:
634634
return -1;
635635
case KW_NAMES:
636-
return -1;
636+
return 0;
637637
case CALL:
638638
return -1;
639639
case CALL_PY_EXACT_ARGS:
@@ -685,9 +685,9 @@ _PyOpcode_num_pushed(int opcode, int oparg) {
685685
case SWAP:
686686
return -1;
687687
case EXTENDED_ARG:
688-
return -1;
688+
return 0;
689689
case CACHE:
690-
return -1;
690+
return 0;
691691
default:
692692
Py_UNREACHABLE();
693693
}

0 commit comments

Comments
 (0)