mirror of
https://github.com/python/cpython.git
synced 2025-07-19 09:15:34 +00:00
gh-107901: synthetic jumps which are not at end of loop no longer check the eval breaker (#113721)
This commit is contained in:
parent
bb4c167060
commit
d36a365118
7 changed files with 108 additions and 53 deletions
|
@ -2897,7 +2897,7 @@ compiler_jump_if(struct compiler *c, location loc,
|
|||
compiler_jump_if(c, loc, e->v.IfExp.test, next2, 0));
|
||||
RETURN_IF_ERROR(
|
||||
compiler_jump_if(c, loc, e->v.IfExp.body, next, cond));
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
|
||||
|
||||
USE_LABEL(c, next2);
|
||||
RETURN_IF_ERROR(
|
||||
|
@ -2926,12 +2926,12 @@ compiler_jump_if(struct compiler *c, location loc,
|
|||
ADDOP(c, LOC(e), TO_BOOL);
|
||||
ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
|
||||
NEW_JUMP_TARGET_LABEL(c, end);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
|
||||
|
||||
USE_LABEL(c, cleanup);
|
||||
ADDOP(c, LOC(e), POP_TOP);
|
||||
if (!cond) {
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, next);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, next);
|
||||
}
|
||||
|
||||
USE_LABEL(c, end);
|
||||
|
@ -2963,7 +2963,7 @@ compiler_ifexp(struct compiler *c, expr_ty e)
|
|||
compiler_jump_if(c, LOC(e), e->v.IfExp.test, next, 0));
|
||||
|
||||
VISIT(c, expr, e->v.IfExp.body);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
|
||||
|
||||
USE_LABEL(c, next);
|
||||
VISIT(c, expr, e->v.IfExp.orelse);
|
||||
|
@ -3041,7 +3041,7 @@ compiler_if(struct compiler *c, stmt_ty s)
|
|||
|
||||
VISIT_SEQ(c, stmt, s->v.If.body);
|
||||
if (asdl_seq_LEN(s->v.If.orelse)) {
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
|
||||
|
||||
USE_LABEL(c, next);
|
||||
VISIT_SEQ(c, stmt, s->v.If.orelse);
|
||||
|
@ -3294,7 +3294,7 @@ compiler_try_finally(struct compiler *c, stmt_ty s)
|
|||
compiler_pop_fblock(c, FINALLY_TRY, body);
|
||||
VISIT_SEQ(c, stmt, s->v.Try.finalbody);
|
||||
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, exit);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, exit);
|
||||
/* `finally` block */
|
||||
|
||||
USE_LABEL(c, end);
|
||||
|
@ -3344,7 +3344,7 @@ compiler_try_star_finally(struct compiler *c, stmt_ty s)
|
|||
compiler_pop_fblock(c, FINALLY_TRY, body);
|
||||
VISIT_SEQ(c, stmt, s->v.TryStar.finalbody);
|
||||
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, exit);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, exit);
|
||||
|
||||
/* `finally` block */
|
||||
USE_LABEL(c, end);
|
||||
|
@ -3419,7 +3419,7 @@ compiler_try_except(struct compiler *c, stmt_ty s)
|
|||
if (s->v.Try.orelse && asdl_seq_LEN(s->v.Try.orelse)) {
|
||||
VISIT_SEQ(c, stmt, s->v.Try.orelse);
|
||||
}
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
|
||||
n = asdl_seq_LEN(s->v.Try.handlers);
|
||||
|
||||
USE_LABEL(c, except);
|
||||
|
@ -3483,7 +3483,7 @@ compiler_try_except(struct compiler *c, stmt_ty s)
|
|||
compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
|
||||
RETURN_IF_ERROR(
|
||||
compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
|
||||
|
||||
/* except: */
|
||||
USE_LABEL(c, cleanup_end);
|
||||
|
@ -3511,7 +3511,7 @@ compiler_try_except(struct compiler *c, stmt_ty s)
|
|||
compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body);
|
||||
ADDOP(c, NO_LOCATION, POP_BLOCK);
|
||||
ADDOP(c, NO_LOCATION, POP_EXCEPT);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
|
||||
}
|
||||
|
||||
USE_LABEL(c, except);
|
||||
|
@ -3599,7 +3599,7 @@ compiler_try_star_except(struct compiler *c, stmt_ty s)
|
|||
VISIT_SEQ(c, stmt, s->v.TryStar.body);
|
||||
compiler_pop_fblock(c, TRY_EXCEPT, body);
|
||||
ADDOP(c, NO_LOCATION, POP_BLOCK);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, orelse);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, orelse);
|
||||
Py_ssize_t n = asdl_seq_LEN(s->v.TryStar.handlers);
|
||||
|
||||
USE_LABEL(c, except);
|
||||
|
@ -3681,7 +3681,7 @@ compiler_try_star_except(struct compiler *c, stmt_ty s)
|
|||
RETURN_IF_ERROR(
|
||||
compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
|
||||
}
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, except);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, except);
|
||||
|
||||
/* except: */
|
||||
USE_LABEL(c, cleanup_end);
|
||||
|
@ -3698,11 +3698,11 @@ compiler_try_star_except(struct compiler *c, stmt_ty s)
|
|||
/* add exception raised to the res list */
|
||||
ADDOP_I(c, NO_LOCATION, LIST_APPEND, 3); // exc
|
||||
ADDOP(c, NO_LOCATION, POP_TOP); // lasti
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, except_with_error);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, except_with_error);
|
||||
|
||||
USE_LABEL(c, except);
|
||||
ADDOP(c, NO_LOCATION, NOP); // to hold a propagated location info
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, except_with_error);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, except_with_error);
|
||||
|
||||
USE_LABEL(c, no_match);
|
||||
ADDOP(c, loc, POP_TOP); // match (None)
|
||||
|
@ -3712,7 +3712,7 @@ compiler_try_star_except(struct compiler *c, stmt_ty s)
|
|||
if (i == n - 1) {
|
||||
/* Add exc to the list (if not None it's the unhandled part of the EG) */
|
||||
ADDOP_I(c, NO_LOCATION, LIST_APPEND, 1);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, reraise_star);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, reraise_star);
|
||||
}
|
||||
}
|
||||
/* artificial */
|
||||
|
@ -3728,7 +3728,7 @@ compiler_try_star_except(struct compiler *c, stmt_ty s)
|
|||
ADDOP(c, NO_LOCATION, POP_TOP);
|
||||
ADDOP(c, NO_LOCATION, POP_BLOCK);
|
||||
ADDOP(c, NO_LOCATION, POP_EXCEPT);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
|
||||
|
||||
USE_LABEL(c, reraise);
|
||||
ADDOP(c, NO_LOCATION, POP_BLOCK);
|
||||
|
@ -4626,7 +4626,7 @@ compiler_compare(struct compiler *c, expr_ty e)
|
|||
VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
|
||||
ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, n));
|
||||
NEW_JUMP_TARGET_LABEL(c, end);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
|
||||
|
||||
USE_LABEL(c, cleanup);
|
||||
ADDOP_I(c, loc, SWAP, 2);
|
||||
|
@ -5668,7 +5668,7 @@ pop_inlined_comprehension_state(struct compiler *c, location loc,
|
|||
}
|
||||
if (state.pushed_locals) {
|
||||
ADDOP(c, NO_LOCATION, POP_BLOCK);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, state.end);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, state.end);
|
||||
|
||||
// cleanup from an exception inside the comprehension
|
||||
USE_LABEL(c, state.cleanup);
|
||||
|
@ -5916,7 +5916,7 @@ compiler_with_except_finish(struct compiler *c, jump_target_label cleanup) {
|
|||
ADDOP(c, NO_LOCATION, POP_TOP);
|
||||
ADDOP(c, NO_LOCATION, POP_TOP);
|
||||
NEW_JUMP_TARGET_LABEL(c, exit);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, exit);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, exit);
|
||||
|
||||
USE_LABEL(c, cleanup);
|
||||
POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
|
||||
|
@ -7410,7 +7410,7 @@ compiler_match_inner(struct compiler *c, stmt_ty s, pattern_context *pc)
|
|||
ADDOP(c, LOC(m->pattern), POP_TOP);
|
||||
}
|
||||
VISIT_SEQ(c, stmt, m->body);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
|
||||
// If the pattern fails to match, we want the line number of the
|
||||
// cleanup to be associated with the failed pattern, not the last line
|
||||
// of the body
|
||||
|
|
|
@ -481,9 +481,12 @@ no_redundant_jumps(cfg_builder *g) {
|
|||
if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) {
|
||||
basicblock *next = next_nonempty_block(b->b_next);
|
||||
basicblock *jump_target = next_nonempty_block(last->i_target);
|
||||
assert(jump_target != next);
|
||||
if (jump_target == next) {
|
||||
return false;
|
||||
assert(next);
|
||||
if (last->i_loc.lineno == next->b_instr[0].i_loc.lineno) {
|
||||
assert(0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1097,6 +1100,7 @@ remove_redundant_jumps(cfg_builder *g) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1135,11 +1139,15 @@ jump_thread(cfg_instr *inst, cfg_instr *target, int opcode)
|
|||
assert(is_jump(target));
|
||||
// bpo-45773: If inst->i_target == target->i_target, then nothing actually
|
||||
// changes (and we fall into an infinite loop):
|
||||
if ((inst->i_loc.lineno == target->i_loc.lineno || target->i_loc.lineno == -1) &&
|
||||
if ((inst->i_loc.lineno == target->i_loc.lineno ||
|
||||
inst->i_loc.lineno == -1 || target->i_loc.lineno == -1) &&
|
||||
inst->i_target != target->i_target)
|
||||
{
|
||||
inst->i_target = target->i_target;
|
||||
inst->i_opcode = opcode;
|
||||
if (inst->i_loc.lineno == -1) {
|
||||
inst->i_loc = target->i_loc;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1602,9 +1610,14 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
|
|||
}
|
||||
break;
|
||||
case JUMP:
|
||||
case JUMP_NO_INTERRUPT:
|
||||
switch (target->i_opcode) {
|
||||
case JUMP:
|
||||
i -= jump_thread(inst, target, JUMP);
|
||||
continue;
|
||||
case JUMP_NO_INTERRUPT:
|
||||
i -= jump_thread(inst, target, opcode);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case FOR_ITER:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue