changeset: 105357:303cedfb9e7a branch: 3.6 parent: 105354:7059e68db068 user: Victor Stinner date: Thu Nov 24 22:33:01 2016 +0100 files: Misc/NEWS Objects/genobject.c Python/ceval.c description: 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. diff -r 7059e68db068 -r 303cedfb9e7a Misc/NEWS --- a/Misc/NEWS Thu Nov 24 11:56:40 2016 -0800 +++ b/Misc/NEWS Thu Nov 24 22:33:01 2016 +0100 @@ -10,6 +10,10 @@ 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 ------- diff -r 7059e68db068 -r 303cedfb9e7a Objects/genobject.c --- a/Objects/genobject.c Thu Nov 24 11:56:40 2016 -0800 +++ b/Objects/genobject.c Thu Nov 24 22:33:01 2016 +0100 @@ -355,6 +355,14 @@ PyObject *bytecode = f->f_code->co_code; 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) return NULL; yf = f->f_stacktop[-1]; @@ -463,6 +471,7 @@ assert(ret == yf); Py_DECREF(ret); /* Termination repetition of YIELD_FROM */ + assert(gen->gi_frame->f_lasti >= 0); gen->gi_frame->f_lasti += sizeof(_Py_CODEUNIT); if (_PyGen_FetchStopIterationValue(&val) == 0) { ret = gen_send_ex(gen, val, 0, 0); diff -r 7059e68db068 -r 303cedfb9e7a Python/ceval.c --- a/Python/ceval.c Thu Nov 24 11:56:40 2016 -0800 +++ b/Python/ceval.c Thu Nov 24 22:33:01 2016 +0100 @@ -2043,6 +2043,7 @@ f->f_stacktop = stack_pointer; why = WHY_YIELD; /* and repeat... */ + assert(f->f_lasti >= (int)sizeof(_Py_CODEUNIT)); f->f_lasti -= sizeof(_Py_CODEUNIT); goto fast_yield; }