gh-111354: simplify detection of RESUME after YIELD_VALUE at except-depth 1 (#111459)

This commit is contained in:
Irit Katriel 2023-11-02 10:18:43 +00:00 committed by GitHub
parent 970e719a7a
commit 52cc4af6ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 362 additions and 339 deletions

View file

@ -343,12 +343,6 @@ is_resume(_Py_CODEUNIT *instr)
);
}
static inline bool
is_yield(_Py_CODEUNIT *instr)
{
return instr->op.code == YIELD_VALUE || instr->op.code == INSTRUMENTED_YIELD_VALUE;
}
PyObject *
_PyGen_yf(PyGenObject *gen)
{
@ -364,7 +358,8 @@ _PyGen_yf(PyGenObject *gen)
assert(_PyCode_CODE(_PyGen_GetCode(gen))[0].op.code != SEND);
return NULL;
}
if (!is_resume(frame->instr_ptr) || frame->instr_ptr->op.arg < RESUME_AFTER_YIELD_FROM)
if (!is_resume(frame->instr_ptr) ||
(frame->instr_ptr->op.arg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM)
{
/* Not in a yield from */
return NULL;
@ -381,6 +376,7 @@ gen_close(PyGenObject *gen, PyObject *args)
PyObject *retval;
int err = 0;
if (gen->gi_frame_state == FRAME_CREATED) {
gen->gi_frame_state = FRAME_COMPLETED;
Py_RETURN_NONE;
@ -397,19 +393,14 @@ gen_close(PyGenObject *gen, PyObject *args)
Py_DECREF(yf);
}
_PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
/* It is possible for the previous instruction to not be a
* YIELD_VALUE if the debugger has changed the lineno. */
assert(_PyOpcode_Caches[YIELD_VALUE] == 0);
assert(_PyOpcode_Caches[INSTRUMENTED_YIELD_VALUE] == 0);
if (err == 0 && is_yield(frame->instr_ptr - 1)) {
_Py_CODEUNIT *yield_instr = frame->instr_ptr - 1;
assert(is_resume(frame->instr_ptr));
int exception_handler_depth = yield_instr->op.arg;
assert(exception_handler_depth > 0);
if (is_resume(frame->instr_ptr)) {
/* We can safely ignore the outermost try block
* as it automatically generated to handle
* as it is automatically generated to handle
* StopIteration. */
if (exception_handler_depth == 1) {
int oparg = frame->instr_ptr->op.arg;
if (oparg & RESUME_OPARG_DEPTH1_MASK) {
// RESUME after YIELD_VALUE and exception depth is 1
assert((oparg & RESUME_OPARG_LOCATION_MASK) != RESUME_AT_FUNC_START);
gen->gi_frame_state = FRAME_COMPLETED;
Py_RETURN_NONE;
}