diff options
author | Mark Shannon <mark@hotpy.org> | 2021-12-15 10:30:09 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-15 10:30:09 (GMT) |
commit | 0b50a4f0cdee41a18fb4ba6e75569f9cfaceb39e (patch) | |
tree | 307cc32e8ca72f71eaa8250e976306adc939e9fd /Python/ceval.c | |
parent | 86de99588db3beff964137f4fe27dd1077a09b35 (diff) | |
download | cpython-0b50a4f0cdee41a18fb4ba6e75569f9cfaceb39e.zip cpython-0b50a4f0cdee41a18fb4ba6e75569f9cfaceb39e.tar.gz cpython-0b50a4f0cdee41a18fb4ba6e75569f9cfaceb39e.tar.bz2 |
bpo-46039: Split yield from in two (GH-30035)
* Split YIELD_FROM opcode into SEND and JUMP_ABSOLUTE.
* Remove YIELD_FROM opcode.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 6d27848..7932433 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1798,7 +1798,8 @@ check_eval_breaker: if (_Py_atomic_load_relaxed(eval_breaker)) { opcode = _Py_OPCODE(*next_instr); if (opcode != BEFORE_ASYNC_WITH && - opcode != YIELD_FROM) { + opcode != SEND && + _Py_OPCODE(next_instr[-1]) != SEND) { /* Few cases where we skip running signal handlers and other pending calls: - If we're about to enter the 'with:'. It will prevent @@ -2642,8 +2643,9 @@ check_eval_breaker: DISPATCH(); } - TARGET(YIELD_FROM) { + TARGET(SEND) { assert(frame->depth == 0); + assert(STACK_LEVEL() >= 2); PyObject *v = POP(); PyObject *receiver = TOP(); PySendResult gen_status; @@ -2680,17 +2682,13 @@ check_eval_breaker: } if (gen_status == PYGEN_RETURN) { assert (retval != NULL); - Py_DECREF(receiver); SET_TOP(retval); - retval = NULL; + JUMPBY(oparg); DISPATCH(); } assert (gen_status == PYGEN_NEXT); - /* receiver remains on stack, retval is value to be yielded */ - /* and repeat... */ - assert(frame->f_lasti > 0); - frame->f_lasti -= 1; + assert (retval != NULL); frame->f_state = FRAME_SUSPENDED; _PyFrame_SetStackPointer(frame, stack_pointer); TRACE_FUNCTION_EXIT(); @@ -6770,8 +6768,11 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj, return -1; } if (line != -1 && f->f_trace_lines) { - /* Trace backward edges or if line number has changed */ - if (frame->f_lasti < instr_prev || line != lastline) { + /* Trace backward edges (except in 'yield from') or if line number has changed */ + int trace = line != lastline || + (frame->f_lasti < instr_prev && + _Py_OPCODE(frame->f_code->co_firstinstr[frame->f_lasti]) != SEND); + if (trace) { result = call_trace(func, obj, tstate, frame, PyTrace_LINE, Py_None); } } |