diff options
Diffstat (limited to 'Python')
-rw-r--r-- | Python/bytecodes.c | 6 | ||||
-rw-r--r-- | Python/ceval.c | 2 | ||||
-rw-r--r-- | Python/compile.c | 4 | ||||
-rw-r--r-- | Python/flowgraph.c | 18 | ||||
-rw-r--r-- | Python/generated_cases.c.h | 6 | ||||
-rw-r--r-- | Python/opcode_targets.h | 2 |
6 files changed, 23 insertions, 15 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 9aca82a..9f1dfa3 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -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); diff --git a/Python/ceval.c b/Python/ceval.c index e07b282..cf48929 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -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; diff --git a/Python/compile.c b/Python/compile.c index 30005c3..1604e14 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -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; } diff --git a/Python/flowgraph.c b/Python/flowgraph.c index e89ad39..87401e1 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -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; } } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index dc62d79..38c368f 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -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); diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index bcd6ea7..d35da27 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -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, |