Skip to content

Commit 04e06e2

Browse files
authored
gh-98831: rewrite SEND, GET_YIELD_FROM_ITER, RETURN_GENERATOR in the instruction definition DSL (#101516)
1 parent a52cc98 commit 04e06e2

File tree

3 files changed

+40
-42
lines changed

3 files changed

+40
-42
lines changed

Python/bytecodes.c

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -663,14 +663,10 @@ dummy_func(
663663
PREDICT(LOAD_CONST);
664664
}
665665

666-
// error: SEND stack effect depends on jump flag
667-
inst(SEND) {
666+
inst(SEND, (receiver, v -- receiver if (!jump), retval)) {
668667
assert(frame != &entry_frame);
669-
assert(STACK_LEVEL() >= 2);
670-
PyObject *v = POP();
671-
PyObject *receiver = TOP();
668+
bool jump = false;
672669
PySendResult gen_status;
673-
PyObject *retval;
674670
if (tstate->c_tracefunc == NULL) {
675671
gen_status = PyIter_Send(receiver, v, &retval);
676672
} else {
@@ -695,21 +691,20 @@ dummy_func(
695691
gen_status = PYGEN_NEXT;
696692
}
697693
}
698-
Py_DECREF(v);
699694
if (gen_status == PYGEN_ERROR) {
700695
assert(retval == NULL);
701696
goto error;
702697
}
698+
Py_DECREF(v);
703699
if (gen_status == PYGEN_RETURN) {
704700
assert(retval != NULL);
705701
Py_DECREF(receiver);
706-
SET_TOP(retval);
707702
JUMPBY(oparg);
703+
jump = true;
708704
}
709705
else {
710706
assert(gen_status == PYGEN_NEXT);
711707
assert(retval != NULL);
712-
PUSH(retval);
713708
}
714709
}
715710

@@ -2043,31 +2038,30 @@ dummy_func(
20432038
ERROR_IF(iter == NULL, error);
20442039
}
20452040

2046-
// stack effect: ( -- )
2047-
inst(GET_YIELD_FROM_ITER) {
2041+
inst(GET_YIELD_FROM_ITER, (iterable -- iter)) {
20482042
/* before: [obj]; after [getiter(obj)] */
2049-
PyObject *iterable = TOP();
2050-
PyObject *iter;
20512043
if (PyCoro_CheckExact(iterable)) {
20522044
/* `iterable` is a coroutine */
20532045
if (!(frame->f_code->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) {
20542046
/* and it is used in a 'yield from' expression of a
20552047
regular generator. */
2056-
Py_DECREF(iterable);
2057-
SET_TOP(NULL);
20582048
_PyErr_SetString(tstate, PyExc_TypeError,
20592049
"cannot 'yield from' a coroutine object "
20602050
"in a non-coroutine generator");
20612051
goto error;
20622052
}
2053+
iter = iterable;
2054+
}
2055+
else if (PyGen_CheckExact(iterable)) {
2056+
iter = iterable;
20632057
}
2064-
else if (!PyGen_CheckExact(iterable)) {
2058+
else {
20652059
/* `iterable` is not a generator. */
20662060
iter = PyObject_GetIter(iterable);
2067-
Py_DECREF(iterable);
2068-
SET_TOP(iter);
2069-
if (iter == NULL)
2061+
if (iter == NULL) {
20702062
goto error;
2063+
}
2064+
Py_DECREF(iterable);
20712065
}
20722066
PREDICT(LOAD_CONST);
20732067
}
@@ -3010,8 +3004,7 @@ dummy_func(
30103004
PUSH((PyObject *)func);
30113005
}
30123006

3013-
// stack effect: ( -- )
3014-
inst(RETURN_GENERATOR) {
3007+
inst(RETURN_GENERATOR, (--)) {
30153008
assert(PyFunction_Check(frame->f_funcobj));
30163009
PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj;
30173010
PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func);

Python/generated_cases.c.h

Lines changed: 20 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/opcode_metadata.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
9999
case GET_AWAITABLE:
100100
return 1;
101101
case SEND:
102-
return -1;
102+
return 2;
103103
case YIELD_VALUE:
104104
return 1;
105105
case POP_EXCEPT:
@@ -259,7 +259,7 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
259259
case GET_ITER:
260260
return 1;
261261
case GET_YIELD_FROM_ITER:
262-
return -1;
262+
return 1;
263263
case FOR_ITER:
264264
return -1;
265265
case FOR_ITER_LIST:
@@ -327,7 +327,7 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
327327
case MAKE_FUNCTION:
328328
return -1;
329329
case RETURN_GENERATOR:
330-
return -1;
330+
return 0;
331331
case BUILD_SLICE:
332332
return -1;
333333
case FORMAT_VALUE:
@@ -445,7 +445,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
445445
case GET_AWAITABLE:
446446
return 1;
447447
case SEND:
448-
return -1;
448+
return ((!jump) ? 1 : 0) + 1;
449449
case YIELD_VALUE:
450450
return 1;
451451
case POP_EXCEPT:
@@ -605,7 +605,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
605605
case GET_ITER:
606606
return 1;
607607
case GET_YIELD_FROM_ITER:
608-
return -1;
608+
return 1;
609609
case FOR_ITER:
610610
return -1;
611611
case FOR_ITER_LIST:
@@ -673,7 +673,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
673673
case MAKE_FUNCTION:
674674
return -1;
675675
case RETURN_GENERATOR:
676-
return -1;
676+
return 0;
677677
case BUILD_SLICE:
678678
return -1;
679679
case FORMAT_VALUE:

0 commit comments

Comments
 (0)