diff options
author | penguin_wwy <940375606@qq.com> | 2022-01-06 11:38:35 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-06 11:38:35 (GMT) |
commit | 3db762db72cc0da938614b1e414abb1e12ca4094 (patch) | |
tree | eef08b55d931522d2f83ed7b6f2383d27d8a4ffe /Python | |
parent | 35d6540c904ef07b8602ff014e520603f84b5886 (diff) | |
download | cpython-3db762db72cc0da938614b1e414abb1e12ca4094.zip cpython-3db762db72cc0da938614b1e414abb1e12ca4094.tar.gz cpython-3db762db72cc0da938614b1e414abb1e12ca4094.tar.bz2 |
bpo-46031: add POP_JUMP_IF_NOT_NONE and POP_JUMP_IF_NONE (GH-30019)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 24 | ||||
-rw-r--r-- | Python/compile.c | 27 | ||||
-rw-r--r-- | Python/opcode_targets.h | 12 |
3 files changed, 57 insertions, 6 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index b4ac9ec..86d834c 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -4049,6 +4049,30 @@ check_eval_breaker: DISPATCH(); } + TARGET(POP_JUMP_IF_NOT_NONE) { + PyObject *value = POP(); + if (!Py_IsNone(value)) { + Py_DECREF(value); + JUMPTO(oparg); + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + Py_DECREF(value); + DISPATCH(); + } + + TARGET(POP_JUMP_IF_NONE) { + PyObject *value = POP(); + if (Py_IsNone(value)) { + Py_DECREF(value); + JUMPTO(oparg); + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + Py_DECREF(value); + DISPATCH(); + } + TARGET(JUMP_IF_FALSE_OR_POP) { PyObject *cond = TOP(); int err; diff --git a/Python/compile.c b/Python/compile.c index 3a39075..625a07b 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1110,6 +1110,8 @@ stack_effect(int opcode, int oparg, int jump) case POP_JUMP_IF_FALSE: case POP_JUMP_IF_TRUE: + case POP_JUMP_IF_NONE: + case POP_JUMP_IF_NOT_NONE: return -1; case LOAD_GLOBAL: @@ -8519,6 +8521,21 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) bb->b_instr[i+1].i_opcode = NOP; } break; + case IS_OP: + cnt = get_const_value(inst->i_opcode, oparg, consts); + if (cnt == NULL) { + goto error; + } + int jump_op = i+2 < bb->b_iused ? bb->b_instr[i+2].i_opcode : 0; + if (Py_IsNone(cnt) && (jump_op == POP_JUMP_IF_FALSE || jump_op == POP_JUMP_IF_TRUE)) { + unsigned char nextarg = bb->b_instr[i+1].i_oparg; + inst->i_opcode = NOP; + bb->b_instr[i+1].i_opcode = NOP; + bb->b_instr[i+2].i_opcode = nextarg ^ (jump_op == POP_JUMP_IF_FALSE) ? + POP_JUMP_IF_NOT_NONE : POP_JUMP_IF_NONE; + } + Py_DECREF(cnt); + break; } break; } @@ -8611,6 +8628,14 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) break; } break; + case POP_JUMP_IF_NOT_NONE: + case POP_JUMP_IF_NONE: + switch (target->i_opcode) { + case JUMP_ABSOLUTE: + case JUMP_FORWARD: + i -= jump_thread(inst, target, inst->i_opcode); + } + break; case POP_JUMP_IF_FALSE: switch (target->i_opcode) { case JUMP_ABSOLUTE: @@ -8766,6 +8791,8 @@ normalize_basic_block(basicblock *bb) { case JUMP_FORWARD: bb->b_nofallthrough = 1; /* fall through */ + case POP_JUMP_IF_NOT_NONE: + case POP_JUMP_IF_NONE: case POP_JUMP_IF_FALSE: case POP_JUMP_IF_TRUE: case JUMP_IF_FALSE_OR_POP: diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index e9f1a48..7ba4566 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -127,20 +127,20 @@ static void *opcode_targets[256] = { &&TARGET_STORE_FAST, &&TARGET_DELETE_FAST, &&TARGET_JUMP_IF_NOT_EG_MATCH, - &&TARGET_STORE_FAST__LOAD_FAST, - &&TARGET_LOAD_FAST__LOAD_CONST, + &&TARGET_POP_JUMP_IF_NOT_NONE, + &&TARGET_POP_JUMP_IF_NONE, &&TARGET_RAISE_VARARGS, - &&TARGET_LOAD_CONST__LOAD_FAST, + &&TARGET_STORE_FAST__LOAD_FAST, &&TARGET_MAKE_FUNCTION, &&TARGET_BUILD_SLICE, - &&TARGET_STORE_FAST__STORE_FAST, + &&TARGET_LOAD_FAST__LOAD_CONST, &&TARGET_MAKE_CELL, &&TARGET_LOAD_CLOSURE, &&TARGET_LOAD_DEREF, &&TARGET_STORE_DEREF, &&TARGET_DELETE_DEREF, - &&_unknown_opcode, - &&_unknown_opcode, + &&TARGET_LOAD_CONST__LOAD_FAST, + &&TARGET_STORE_FAST__STORE_FAST, &&TARGET_CALL_FUNCTION_EX, &&_unknown_opcode, &&TARGET_EXTENDED_ARG, |