Skip to content

Commit 533b9e8

Browse files
Anselm KruisAnselm Kruis
authored andcommitted
Stackless issue python#188: enable soft switching for sub-iterators and coroutines
Improve the finalisation of a soft switched YIELD_FROM instruction.
1 parent 362a9a0 commit 533b9e8

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

Python/ceval.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,27 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
11031103
}
11041104
else if (f->f_execute == slp_eval_frame_yield_from) {
11051105
/* finalise the YIELD_FROM operation */
1106-
goto stackless_yield_from_return;
1106+
PyObject *receiver = TOP();
1107+
if (retval == NULL) {
1108+
int err;
1109+
if (tstate->c_tracefunc != NULL
1110+
&& PyErr_ExceptionMatches(PyExc_StopIteration))
1111+
call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f);
1112+
err = _PyGen_FetchStopIterationValue(&retval);
1113+
if (err < 0)
1114+
goto error;
1115+
Py_DECREF(receiver);
1116+
SET_TOP(retval);
1117+
}
1118+
else {
1119+
/* receiver remains on stack, retval is value to be yielded */
1120+
f->f_stacktop = stack_pointer;
1121+
why = WHY_YIELD;
1122+
/* and repeat... */
1123+
assert(f->f_lasti >= (int)sizeof(_Py_CODEUNIT));
1124+
f->f_lasti -= sizeof(_Py_CODEUNIT);
1125+
goto fast_yield;
1126+
}
11071127
}
11081128
else
11091129
Py_FatalError("invalid frame function");
@@ -1997,7 +2017,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
19972017
#ifdef STACKLESS
19982018
if (STACKLESS_UNWINDING(retval)) {
19992019
HANDLE_UNWINDING(slp_eval_frame_yield_from, 0, retval);
2000-
stackless_yield_from_return:
20012020
receiver = TOP();
20022021
}
20032022
#endif

0 commit comments

Comments
 (0)