Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
use except depth of the yield, not of the resume
  • Loading branch information
iritkatriel committed Nov 1, 2023
commit c385597e8569c21924d95e50885c12f8a4ff01ed
3 changes: 1 addition & 2 deletions Include/internal/pycore_opcode_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ extern "C" {
#define RESUME_AFTER_AWAIT 3

#define RESUME_OPARG_LOCATION_MASK 0x3
#define RESUME_OPARG_DEPTH1_SHIFT 2
#define RESUME_OPARG_DEPTH1_MASK (1 << RESUME_OPARG_DEPTH1_SHIFT)
#define RESUME_OPARG_DEPTH1_MASK 0x4

#ifdef __cplusplus
}
Expand Down
8 changes: 4 additions & 4 deletions Lib/test/test_dis.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,15 +525,15 @@ async def _asyncwith(c):
dis_asyncwith = """\
%4d RETURN_GENERATOR
POP_TOP
RESUME 4
RESUME 0

%4d LOAD_FAST 0 (c)
BEFORE_ASYNC_WITH
GET_AWAITABLE 1
LOAD_CONST 0 (None)
>> SEND 3 (to 24)
YIELD_VALUE
RESUME 7
RESUME 3
JUMP_BACKWARD_NO_INTERRUPT 5 (to 14)
>> END_SEND
POP_TOP
Expand All @@ -549,7 +549,7 @@ async def _asyncwith(c):
LOAD_CONST 0 (None)
>> SEND 3 (to 60)
YIELD_VALUE
RESUME 7
RESUME 3
JUMP_BACKWARD_NO_INTERRUPT 5 (to 50)
>> END_SEND
POP_TOP
Expand Down Expand Up @@ -755,7 +755,7 @@ def foo(x):

%4d RETURN_GENERATOR
POP_TOP
RESUME 4
RESUME 0
LOAD_FAST 0 (.0)
>> FOR_ITER 10 (to 34)
STORE_FAST 1 (z)
Expand Down
4 changes: 2 additions & 2 deletions Objects/genobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,9 +398,9 @@ gen_close(PyGenObject *gen, PyObject *args)
* as it is automatically generated to handle
* StopIteration. */
int oparg = frame->instr_ptr->op.arg;
if (((oparg & RESUME_OPARG_LOCATION_MASK) > RESUME_AT_FUNC_START) &&
(oparg & RESUME_OPARG_DEPTH1_MASK)) {
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;
}
Expand Down
2 changes: 1 addition & 1 deletion Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,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 = (1 << RESUME_OPARG_DEPTH1_SHIFT) | 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;
Expand Down
13 changes: 12 additions & 1 deletion Python/flowgraph.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -878,9 +879,19 @@ label_exception_targets(basicblock *entryblock) {
todo++;
}
}
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;
instr->i_oparg |= ((except_stack->depth == 1) << RESUME_OPARG_DEPTH1_SHIFT);
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;
Expand Down