mirror of
https://github.com/python/cpython.git
synced 2025-07-15 23:35:23 +00:00
gh-111354: simplify detection of RESUME after YIELD_VALUE at except-depth 1 (#111459)
This commit is contained in:
parent
970e719a7a
commit
52cc4af6ae
18 changed files with 362 additions and 339 deletions
|
@ -149,7 +149,7 @@ dummy_func(
|
|||
next_instr = this_instr;
|
||||
}
|
||||
else {
|
||||
if (oparg < RESUME_AFTER_YIELD_FROM) {
|
||||
if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) {
|
||||
CHECK_EVAL_BREAKER();
|
||||
}
|
||||
this_instr->op.code = RESUME_CHECK;
|
||||
|
@ -177,7 +177,7 @@ dummy_func(
|
|||
next_instr = this_instr;
|
||||
}
|
||||
else {
|
||||
if (oparg < 2) {
|
||||
if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) {
|
||||
CHECK_EVAL_BREAKER();
|
||||
}
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
|
@ -1047,7 +1047,6 @@ dummy_func(
|
|||
|
||||
inst(INSTRUMENTED_YIELD_VALUE, (retval -- unused)) {
|
||||
assert(frame != &entry_frame);
|
||||
assert(oparg >= 0); /* make the generator identify this as HAS_ARG */
|
||||
frame->instr_ptr = next_instr;
|
||||
PyGenObject *gen = _PyFrame_GetGenerator(frame);
|
||||
gen->gi_frame_state = FRAME_SUSPENDED;
|
||||
|
@ -1073,7 +1072,6 @@ dummy_func(
|
|||
// 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.
|
||||
assert(oparg >= 0); /* make the generator identify this as HAS_ARG */
|
||||
assert(frame != &entry_frame);
|
||||
frame->instr_ptr = next_instr;
|
||||
PyGenObject *gen = _PyFrame_GetGenerator(frame);
|
||||
|
|
|
@ -642,7 +642,7 @@ static const _Py_CODEUNIT _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS[] = {
|
|||
{ .op.code = INTERPRETER_EXIT, .op.arg = 0 }, /* reached on return */
|
||||
{ .op.code = NOP, .op.arg = 0 },
|
||||
{ .op.code = INTERPRETER_EXIT, .op.arg = 0 }, /* reached on yield */
|
||||
{ .op.code = RESUME, .op.arg = RESUME_AT_FUNC_START }
|
||||
{ .op.code = RESUME, .op.arg = RESUME_OPARG_DEPTH1_MASK | RESUME_AT_FUNC_START }
|
||||
};
|
||||
|
||||
extern const struct _PyCode_DEF(8) _Py_InitCleanup;
|
||||
|
|
|
@ -1549,7 +1549,7 @@ compiler_add_yield_from(struct compiler *c, location loc, int await)
|
|||
// Set up a virtual try/except to handle when StopIteration is raised during
|
||||
// a close or throw call. The only way YIELD_VALUE raises if they do!
|
||||
ADDOP_JUMP(c, loc, SETUP_FINALLY, fail);
|
||||
ADDOP_I(c, loc, YIELD_VALUE, 0);
|
||||
ADDOP(c, loc, YIELD_VALUE);
|
||||
ADDOP(c, NO_LOCATION, POP_BLOCK);
|
||||
ADDOP_I(c, loc, RESUME, await ? RESUME_AFTER_AWAIT : RESUME_AFTER_YIELD_FROM);
|
||||
ADDOP_JUMP(c, loc, JUMP_NO_INTERRUPT, send);
|
||||
|
@ -4159,7 +4159,7 @@ addop_yield(struct compiler *c, location loc) {
|
|||
if (c->u->u_ste->ste_generator && c->u->u_ste->ste_coroutine) {
|
||||
ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_ASYNC_GEN_WRAP);
|
||||
}
|
||||
ADDOP_I(c, loc, YIELD_VALUE, 0);
|
||||
ADDOP(c, loc, YIELD_VALUE);
|
||||
ADDOP_I(c, loc, RESUME, RESUME_AFTER_YIELD);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
|
|
@ -840,6 +840,7 @@ label_exception_targets(basicblock *entryblock) {
|
|||
assert(except_stack != NULL);
|
||||
b->b_exceptstack = NULL;
|
||||
handler = except_stack_top(except_stack);
|
||||
int last_yield_except_depth = -1;
|
||||
for (int i = 0; i < b->b_iused; i++) {
|
||||
cfg_instr *instr = &b->b_instr[i];
|
||||
if (is_block_push(instr)) {
|
||||
|
@ -878,10 +879,21 @@ label_exception_targets(basicblock *entryblock) {
|
|||
todo++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (instr->i_opcode == YIELD_VALUE) {
|
||||
instr->i_oparg = except_stack->depth;
|
||||
else if (instr->i_opcode == YIELD_VALUE) {
|
||||
instr->i_except = handler;
|
||||
last_yield_except_depth = except_stack->depth;
|
||||
}
|
||||
else if (instr->i_opcode == RESUME) {
|
||||
instr->i_except = handler;
|
||||
if (instr->i_oparg != RESUME_AT_FUNC_START) {
|
||||
assert(last_yield_except_depth >= 0);
|
||||
if (last_yield_except_depth == 1) {
|
||||
instr->i_oparg |= RESUME_OPARG_DEPTH1_MASK;
|
||||
}
|
||||
last_yield_except_depth = -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
instr->i_except = handler;
|
||||
}
|
||||
}
|
||||
|
|
6
Python/generated_cases.c.h
generated
6
Python/generated_cases.c.h
generated
|
@ -35,7 +35,7 @@
|
|||
next_instr = this_instr;
|
||||
}
|
||||
else {
|
||||
if (oparg < RESUME_AFTER_YIELD_FROM) {
|
||||
if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) {
|
||||
CHECK_EVAL_BREAKER();
|
||||
}
|
||||
this_instr->op.code = RESUME_CHECK;
|
||||
|
@ -71,7 +71,7 @@
|
|||
next_instr = this_instr;
|
||||
}
|
||||
else {
|
||||
if (oparg < 2) {
|
||||
if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) {
|
||||
CHECK_EVAL_BREAKER();
|
||||
}
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
|
@ -1499,7 +1499,6 @@
|
|||
PyObject *retval;
|
||||
retval = stack_pointer[-1];
|
||||
assert(frame != &entry_frame);
|
||||
assert(oparg >= 0); /* make the generator identify this as HAS_ARG */
|
||||
frame->instr_ptr = next_instr;
|
||||
PyGenObject *gen = _PyFrame_GetGenerator(frame);
|
||||
gen->gi_frame_state = FRAME_SUSPENDED;
|
||||
|
@ -1530,7 +1529,6 @@
|
|||
// 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.
|
||||
assert(oparg >= 0); /* make the generator identify this as HAS_ARG */
|
||||
assert(frame != &entry_frame);
|
||||
frame->instr_ptr = next_instr;
|
||||
PyGenObject *gen = _PyFrame_GetGenerator(frame);
|
||||
|
|
2
Python/opcode_targets.h
generated
2
Python/opcode_targets.h
generated
|
@ -44,6 +44,7 @@ static void *opcode_targets[256] = {
|
|||
&&TARGET_UNARY_NEGATIVE,
|
||||
&&TARGET_UNARY_NOT,
|
||||
&&TARGET_WITH_EXCEPT_START,
|
||||
&&TARGET_YIELD_VALUE,
|
||||
&&TARGET_BINARY_OP,
|
||||
&&TARGET_BUILD_CONST_KEY_MAP,
|
||||
&&TARGET_BUILD_LIST,
|
||||
|
@ -117,7 +118,6 @@ static void *opcode_targets[256] = {
|
|||
&&TARGET_SWAP,
|
||||
&&TARGET_UNPACK_EX,
|
||||
&&TARGET_UNPACK_SEQUENCE,
|
||||
&&TARGET_YIELD_VALUE,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue