diff options
author | Mark Shannon <mark@hotpy.org> | 2024-04-30 10:33:13 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-30 10:33:13 (GMT) |
commit | 5b05d452cd20d9f0cfecdeec90adad3af5e4dfff (patch) | |
tree | 98991696903decd44fc348f6ac10f09b4c4785a5 /Python/executor_cases.c.h | |
parent | 0f797402bc77192c76a952410ca8e17359feab3c (diff) | |
download | cpython-5b05d452cd20d9f0cfecdeec90adad3af5e4dfff.zip cpython-5b05d452cd20d9f0cfecdeec90adad3af5e4dfff.tar.gz cpython-5b05d452cd20d9f0cfecdeec90adad3af5e4dfff.tar.bz2 |
GH-118095: Add tier 2 support for YIELD_VALUE (GH-118380)
Diffstat (limited to 'Python/executor_cases.c.h')
-rw-r--r-- | Python/executor_cases.c.h | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 2d9acfe..b17f376 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -1110,6 +1110,47 @@ /* _INSTRUMENTED_YIELD_VALUE is not a viable micro-op for tier 2 because it is instrumented */ + case _YIELD_VALUE: { + PyObject *retval; + PyObject *value; + oparg = CURRENT_OPARG(); + retval = stack_pointer[-1]; + // NOTE: It's important that YIELD_VALUE never raises an exception! + // The compiler treats any exception raised here as a failed close() + // or throw() call. + #if TIER_ONE + assert(frame != &entry_frame); + #endif + frame->instr_ptr++; + PyGenObject *gen = _PyFrame_GetGenerator(frame); + assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); + assert(oparg == 0 || oparg == 1); + gen->gi_frame_state = FRAME_SUSPENDED + oparg; + stack_pointer += -1; + _PyFrame_SetStackPointer(frame, stack_pointer); + tstate->exc_info = gen->gi_exc_state.previous_item; + gen->gi_exc_state.previous_item = NULL; + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *gen_frame = frame; + frame = tstate->current_frame = frame->previous; + gen_frame->previous = NULL; + /* We don't know which of these is relevant here, so keep them equal */ + assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); + #if TIER_ONE + assert(_PyOpcode_Deopt[frame->instr_ptr->op.code] == SEND || + _PyOpcode_Deopt[frame->instr_ptr->op.code] == FOR_ITER || + _PyOpcode_Deopt[frame->instr_ptr->op.code] == INTERPRETER_EXIT || + _PyOpcode_Deopt[frame->instr_ptr->op.code] == ENTER_EXECUTOR); + #endif + LOAD_IP(1 + INLINE_CACHE_ENTRIES_SEND); + LOAD_SP(); + value = retval; + LLTRACE_RESUME_FRAME(); + stack_pointer[0] = value; + stack_pointer += 1; + break; + } + case _POP_EXCEPT: { PyObject *exc_value; exc_value = stack_pointer[-1]; |