diff options
author | Mark Shannon <mark@hotpy.org> | 2020-01-14 10:12:45 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-14 10:12:45 (GMT) |
commit | 9af0e47b1705457bb6b327c197f2ec5737a1d8f6 (patch) | |
tree | 97378eee78d793d16bd19038d88371d776e720c3 /Python/compile.c | |
parent | 62e3973395fb9fab2eb8f651bcd0fea4e695e1cf (diff) | |
download | cpython-9af0e47b1705457bb6b327c197f2ec5737a1d8f6.zip cpython-9af0e47b1705457bb6b327c197f2ec5737a1d8f6.tar.gz cpython-9af0e47b1705457bb6b327c197f2ec5737a1d8f6.tar.bz2 |
bpo-39156: Break up COMPARE_OP into four logically distinct opcodes. (GH-17754)
Break up COMPARE_OP into four logically distinct opcodes:
* COMPARE_OP for rich comparisons
* IS_OP for 'is' and 'is not' tests
* CONTAINS_OP for 'in' and 'is not' tests
* JUMP_IF_NOT_EXC_MATCH for checking exceptions in 'try-except' statements.
Diffstat (limited to 'Python/compile.c')
-rw-r--r-- | Python/compile.c | 71 |
1 files changed, 44 insertions, 27 deletions
diff --git a/Python/compile.c b/Python/compile.c index ce6f18a..3138a3f 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1021,7 +1021,11 @@ stack_effect(int opcode, int oparg, int jump) case LOAD_ATTR: return 0; case COMPARE_OP: + case IS_OP: + case CONTAINS_OP: return -1; + case JUMP_IF_NOT_EXC_MATCH: + return -2; case IMPORT_NAME: return -1; case IMPORT_FROM: @@ -1502,6 +1506,12 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) return 0; \ } + +#define ADDOP_COMPARE(C, CMP) { \ + if (!compiler_addcompare((C), (cmpop_ty)(CMP))) \ + return 0; \ +} + /* VISIT and VISIT_SEQ takes an ASDL type as their second argument. They use the ASDL name to synthesize the name of the C type and the visit function. */ @@ -2433,35 +2443,49 @@ check_compare(struct compiler *c, expr_ty e) return 1; } -static int -cmpop(cmpop_ty op) +static int compiler_addcompare(struct compiler *c, cmpop_ty op) { + int cmp; switch (op) { case Eq: - return PyCmp_EQ; + cmp = Py_EQ; + break; case NotEq: - return PyCmp_NE; + cmp = Py_NE; + break; case Lt: - return PyCmp_LT; + cmp = Py_LT; + break; case LtE: - return PyCmp_LE; + cmp = Py_LE; + break; case Gt: - return PyCmp_GT; + cmp = Py_GT; + break; case GtE: - return PyCmp_GE; + cmp = Py_GE; + break; case Is: - return PyCmp_IS; + ADDOP_I(c, IS_OP, 0); + return 1; case IsNot: - return PyCmp_IS_NOT; + ADDOP_I(c, IS_OP, 1); + return 1; case In: - return PyCmp_IN; + ADDOP_I(c, CONTAINS_OP, 0); + return 1; case NotIn: - return PyCmp_NOT_IN; + ADDOP_I(c, CONTAINS_OP, 1); + return 1; default: - return PyCmp_BAD; + Py_UNREACHABLE(); } + ADDOP_I(c, COMPARE_OP, cmp); + return 1; } + + static int compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) { @@ -2526,14 +2550,12 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); ADDOP(c, DUP_TOP); ADDOP(c, ROT_THREE); - ADDOP_I(c, COMPARE_OP, - cmpop((cmpop_ty)(asdl_seq_GET(e->v.Compare.ops, i)))); + ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i)); ADDOP_JABS(c, POP_JUMP_IF_FALSE, cleanup); NEXT_BLOCK(c); } VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); - ADDOP_I(c, COMPARE_OP, - cmpop((cmpop_ty)(asdl_seq_GET(e->v.Compare.ops, n)))); + ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, n)); ADDOP_JABS(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); basicblock *end = compiler_new_block(c); if (end == NULL) @@ -2976,8 +2998,7 @@ compiler_try_finally(struct compiler *c, stmt_ty s) [tb, val, exc] L1: DUP ) [tb, val, exc, exc] <evaluate E1> ) - [tb, val, exc, exc, E1] COMPARE_OP EXC_MATCH ) only if E1 - [tb, val, exc, 1-or-0] POP_JUMP_IF_FALSE L2 ) + [tb, val, exc, exc, E1] JUMP_IF_NOT_EXC_MATCH L2 ) only if E1 [tb, val, exc] POP [tb, val] <assign to V1> (or POP if no V1) [tb] POP @@ -3029,8 +3050,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) if (handler->v.ExceptHandler.type) { ADDOP(c, DUP_TOP); VISIT(c, expr, handler->v.ExceptHandler.type); - ADDOP_I(c, COMPARE_OP, PyCmp_EXC_MATCH); - ADDOP_JABS(c, POP_JUMP_IF_FALSE, except); + ADDOP_JABS(c, JUMP_IF_NOT_EXC_MATCH, except); } ADDOP(c, POP_TOP); if (handler->v.ExceptHandler.name) { @@ -3873,8 +3893,7 @@ compiler_compare(struct compiler *c, expr_ty e) n = asdl_seq_LEN(e->v.Compare.ops) - 1; if (n == 0) { VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0)); - ADDOP_I(c, COMPARE_OP, - cmpop((cmpop_ty)(asdl_seq_GET(e->v.Compare.ops, 0)))); + ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, 0)); } else { basicblock *cleanup = compiler_new_block(c); @@ -3885,14 +3904,12 @@ compiler_compare(struct compiler *c, expr_ty e) (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); ADDOP(c, DUP_TOP); ADDOP(c, ROT_THREE); - ADDOP_I(c, COMPARE_OP, - cmpop((cmpop_ty)(asdl_seq_GET(e->v.Compare.ops, i)))); + ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i)); ADDOP_JABS(c, JUMP_IF_FALSE_OR_POP, cleanup); NEXT_BLOCK(c); } VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); - ADDOP_I(c, COMPARE_OP, - cmpop((cmpop_ty)(asdl_seq_GET(e->v.Compare.ops, n)))); + ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, n)); basicblock *end = compiler_new_block(c); if (end == NULL) return 0; |