summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2021-12-15 10:30:09 (GMT)
committerGitHub <noreply@github.com>2021-12-15 10:30:09 (GMT)
commit0b50a4f0cdee41a18fb4ba6e75569f9cfaceb39e (patch)
tree307cc32e8ca72f71eaa8250e976306adc939e9fd /Python/ceval.c
parent86de99588db3beff964137f4fe27dd1077a09b35 (diff)
downloadcpython-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.c21
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);
}
}