mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
bpo-46039: Split yield from in two (GH-30035)
* Split YIELD_FROM opcode into SEND and JUMP_ABSOLUTE. * Remove YIELD_FROM opcode.
This commit is contained in:
parent
86de99588d
commit
0b50a4f0cd
10 changed files with 91 additions and 53 deletions
|
@ -249,7 +249,13 @@ mark_stacks(PyCodeObject *code_obj, int len)
|
|||
next_stack = pop_value(pop_value(pop_value(next_stack)));
|
||||
stacks[i+1] = next_stack;
|
||||
break;
|
||||
|
||||
case SEND:
|
||||
j = get_arg(code, i) + i + 1;
|
||||
assert(j < len);
|
||||
assert(stacks[j] == UNINITIALIZED || stacks[j] == pop_value(next_stack));
|
||||
stacks[j] = pop_value(next_stack);
|
||||
stacks[i+1] = next_stack;
|
||||
break;
|
||||
case JUMP_FORWARD:
|
||||
j = get_arg(code, i) + i + 1;
|
||||
assert(j < len);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "pycore_frame.h" // InterpreterFrame
|
||||
#include "frameobject.h" // PyFrameObject
|
||||
#include "structmember.h" // PyMemberDef
|
||||
#include "opcode.h" // YIELD_FROM
|
||||
#include "opcode.h" // SEND
|
||||
|
||||
static PyObject *gen_close(PyGenObject *, PyObject *);
|
||||
static PyObject *async_gen_asend_new(PyAsyncGenObject *, PyObject *);
|
||||
|
@ -356,14 +356,14 @@ _PyGen_yf(PyGenObject *gen)
|
|||
unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode);
|
||||
|
||||
if (frame->f_lasti < 0) {
|
||||
/* Return immediately if the frame didn't start yet. YIELD_FROM
|
||||
/* Return immediately if the frame didn't start yet. SEND
|
||||
always come after LOAD_CONST: a code object should not start
|
||||
with YIELD_FROM */
|
||||
assert(code[0] != YIELD_FROM);
|
||||
with SEND */
|
||||
assert(code[0] != SEND);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (code[(frame->f_lasti+1)*sizeof(_Py_CODEUNIT)] != YIELD_FROM)
|
||||
if (code[frame->f_lasti*sizeof(_Py_CODEUNIT)] != SEND || frame->stacktop < 0)
|
||||
return NULL;
|
||||
yf = _PyFrame_StackPeek(frame);
|
||||
Py_INCREF(yf);
|
||||
|
@ -486,9 +486,13 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
|
|||
ret = _PyFrame_StackPop((InterpreterFrame *)gen->gi_iframe);
|
||||
assert(ret == yf);
|
||||
Py_DECREF(ret);
|
||||
/* Termination repetition of YIELD_FROM */
|
||||
/* Termination repetition of SEND loop */
|
||||
assert(frame->f_lasti >= 0);
|
||||
frame->f_lasti += 1;
|
||||
PyObject *bytecode = gen->gi_code->co_code;
|
||||
unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode);
|
||||
assert(code[frame->f_lasti*sizeof(_Py_CODEUNIT)] == SEND);
|
||||
int jump = code[frame->f_lasti*sizeof(_Py_CODEUNIT)+1];
|
||||
frame->f_lasti += jump;
|
||||
if (_PyGen_FetchStopIterationValue(&val) == 0) {
|
||||
ret = gen_send(gen, val);
|
||||
Py_DECREF(val);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue