Skip to content

Commit

Permalink
pythongh-98831: rewrite SEND, GET_YIELD_FROM_ITER, RETURN_GENERATOR i…
Browse files Browse the repository at this point in the history
…n the instruction definition DSL (python#101516)
  • Loading branch information
iritkatriel committed Feb 3, 2023
1 parent fef6510 commit 77af074
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 42 deletions.
35 changes: 14 additions & 21 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -663,14 +663,10 @@ dummy_func(
PREDICT(LOAD_CONST);
}

// error: SEND stack effect depends on jump flag
inst(SEND) {
inst(SEND, (receiver, v -- receiver if (!jump), retval)) {
assert(frame != &entry_frame);
assert(STACK_LEVEL() >= 2);
PyObject *v = POP();
PyObject *receiver = TOP();
bool jump = false;
PySendResult gen_status;
PyObject *retval;
if (tstate->c_tracefunc == NULL) {
gen_status = PyIter_Send(receiver, v, &retval);
} else {
Expand All @@ -695,21 +691,20 @@ dummy_func(
gen_status = PYGEN_NEXT;
}
}
Py_DECREF(v);
if (gen_status == PYGEN_ERROR) {
assert(retval == NULL);
goto error;
}
Py_DECREF(v);
if (gen_status == PYGEN_RETURN) {
assert(retval != NULL);
Py_DECREF(receiver);
SET_TOP(retval);
JUMPBY(oparg);
jump = true;
}
else {
assert(gen_status == PYGEN_NEXT);
assert(retval != NULL);
PUSH(retval);
}
}

Expand Down Expand Up @@ -2043,31 +2038,30 @@ dummy_func(
ERROR_IF(iter == NULL, error);
}

// stack effect: ( -- )
inst(GET_YIELD_FROM_ITER) {
inst(GET_YIELD_FROM_ITER, (iterable -- iter)) {
/* before: [obj]; after [getiter(obj)] */
PyObject *iterable = TOP();
PyObject *iter;
if (PyCoro_CheckExact(iterable)) {
/* `iterable` is a coroutine */
if (!(frame->f_code->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) {
/* and it is used in a 'yield from' expression of a
regular generator. */
Py_DECREF(iterable);
SET_TOP(NULL);
_PyErr_SetString(tstate, PyExc_TypeError,
"cannot 'yield from' a coroutine object "
"in a non-coroutine generator");
goto error;
}
iter = iterable;
}
else if (PyGen_CheckExact(iterable)) {
iter = iterable;
}
else if (!PyGen_CheckExact(iterable)) {
else {
/* `iterable` is not a generator. */
iter = PyObject_GetIter(iterable);
Py_DECREF(iterable);
SET_TOP(iter);
if (iter == NULL)
if (iter == NULL) {
goto error;
}
Py_DECREF(iterable);
}
PREDICT(LOAD_CONST);
}
Expand Down Expand Up @@ -3013,8 +3007,7 @@ dummy_func(
func = (PyObject *)func_obj;
}

// stack effect: ( -- )
inst(RETURN_GENERATOR) {
inst(RETURN_GENERATOR, (--)) {
assert(PyFunction_Check(frame->f_funcobj));
PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj;
PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func);
Expand Down
35 changes: 20 additions & 15 deletions Python/generated_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions Python/opcode_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
case GET_AWAITABLE:
return 1;
case SEND:
return -1;
return 2;
case YIELD_VALUE:
return 1;
case POP_EXCEPT:
Expand Down Expand Up @@ -259,7 +259,7 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
case GET_ITER:
return 1;
case GET_YIELD_FROM_ITER:
return -1;
return 1;
case FOR_ITER:
return -1;
case FOR_ITER_LIST:
Expand Down Expand Up @@ -327,7 +327,7 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
case MAKE_FUNCTION:
return ((oparg & 0x01) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x08) ? 1 : 0) + 1;
case RETURN_GENERATOR:
return -1;
return 0;
case BUILD_SLICE:
return ((oparg == 3) ? 1 : 0) + 2;
case FORMAT_VALUE:
Expand Down Expand Up @@ -445,7 +445,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
case GET_AWAITABLE:
return 1;
case SEND:
return -1;
return ((!jump) ? 1 : 0) + 1;
case YIELD_VALUE:
return 1;
case POP_EXCEPT:
Expand Down Expand Up @@ -605,7 +605,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
case GET_ITER:
return 1;
case GET_YIELD_FROM_ITER:
return -1;
return 1;
case FOR_ITER:
return -1;
case FOR_ITER_LIST:
Expand Down Expand Up @@ -673,7 +673,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
case MAKE_FUNCTION:
return 1;
case RETURN_GENERATOR:
return -1;
return 0;
case BUILD_SLICE:
return 1;
case FORMAT_VALUE:
Expand Down

0 comments on commit 77af074

Please sign in to comment.