mirror of https://github.com/python/cpython
Fix _PyGen_yf()
Issue #28782: Fix a bug in the implementation ``yield from`` when checking if the next instruction is YIELD_FROM. Regression introduced by WORDCODE (issue #26647). Reviewed by Serhiy Storchaka and Yury Selivanov.
This commit is contained in:
parent
b3c5dc912d
commit
f7d199ff32
|
@ -10,6 +10,10 @@ What's New in Python 3.6.0 release candidate 1
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #28782: Fix a bug in the implementation ``yield from`` when checking
|
||||||
|
if the next instruction is YIELD_FROM. Regression introduced by WORDCODE
|
||||||
|
(issue #26647).
|
||||||
|
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
|
@ -355,6 +355,14 @@ _PyGen_yf(PyGenObject *gen)
|
||||||
PyObject *bytecode = f->f_code->co_code;
|
PyObject *bytecode = f->f_code->co_code;
|
||||||
unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode);
|
unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode);
|
||||||
|
|
||||||
|
if (f->f_lasti < 0) {
|
||||||
|
/* Return immediately if the frame didn't start yet. YIELD_FROM
|
||||||
|
always come after LOAD_CONST: a code object should not start
|
||||||
|
with YIELD_FROM */
|
||||||
|
assert(code[0] != YIELD_FROM);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (code[f->f_lasti + sizeof(_Py_CODEUNIT)] != YIELD_FROM)
|
if (code[f->f_lasti + sizeof(_Py_CODEUNIT)] != YIELD_FROM)
|
||||||
return NULL;
|
return NULL;
|
||||||
yf = f->f_stacktop[-1];
|
yf = f->f_stacktop[-1];
|
||||||
|
@ -463,6 +471,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
|
||||||
assert(ret == yf);
|
assert(ret == yf);
|
||||||
Py_DECREF(ret);
|
Py_DECREF(ret);
|
||||||
/* Termination repetition of YIELD_FROM */
|
/* Termination repetition of YIELD_FROM */
|
||||||
|
assert(gen->gi_frame->f_lasti >= 0);
|
||||||
gen->gi_frame->f_lasti += sizeof(_Py_CODEUNIT);
|
gen->gi_frame->f_lasti += sizeof(_Py_CODEUNIT);
|
||||||
if (_PyGen_FetchStopIterationValue(&val) == 0) {
|
if (_PyGen_FetchStopIterationValue(&val) == 0) {
|
||||||
ret = gen_send_ex(gen, val, 0, 0);
|
ret = gen_send_ex(gen, val, 0, 0);
|
||||||
|
|
|
@ -2043,6 +2043,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
||||||
f->f_stacktop = stack_pointer;
|
f->f_stacktop = stack_pointer;
|
||||||
why = WHY_YIELD;
|
why = WHY_YIELD;
|
||||||
/* and repeat... */
|
/* and repeat... */
|
||||||
|
assert(f->f_lasti >= (int)sizeof(_Py_CODEUNIT));
|
||||||
f->f_lasti -= sizeof(_Py_CODEUNIT);
|
f->f_lasti -= sizeof(_Py_CODEUNIT);
|
||||||
goto fast_yield;
|
goto fast_yield;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue