diff options
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 179 |
1 files changed, 132 insertions, 47 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index f3d1c10..b46b1ef 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3646,8 +3646,6 @@ handle_eval_breaker: goto error; } JUMPBY(INLINE_CACHE_ENTRIES_COMPARE_OP); - PREDICT(POP_JUMP_IF_FALSE); - PREDICT(POP_JUMP_IF_TRUE); DISPATCH(); } @@ -3670,7 +3668,7 @@ handle_eval_breaker: TARGET(COMPARE_OP_FLOAT_JUMP) { assert(cframe.use_tracing == 0); - // Combined: COMPARE_OP (float ? float) + POP_JUMP_IF_(true/false) + // Combined: COMPARE_OP (float ? float) + POP_JUMP_(direction)_IF_(true/false) _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; int when_to_jump_mask = cache->mask; PyObject *right = TOP(); @@ -3688,22 +3686,31 @@ handle_eval_breaker: STACK_SHRINK(2); Py_DECREF(left); Py_DECREF(right); - assert(opcode == POP_JUMP_IF_TRUE || opcode == POP_JUMP_IF_FALSE); - int jump = (1 << (sign + 1)) & when_to_jump_mask; + assert(opcode == POP_JUMP_FORWARD_IF_FALSE || + opcode == POP_JUMP_BACKWARD_IF_FALSE || + opcode == POP_JUMP_FORWARD_IF_TRUE || + opcode == POP_JUMP_BACKWARD_IF_TRUE); + int jump = (9 << (sign + 1)) & when_to_jump_mask; if (!jump) { next_instr++; - NOTRACE_DISPATCH(); } - else { - JUMPTO(oparg); + else if (jump >= 8) { + assert(opcode == POP_JUMP_BACKWARD_IF_TRUE || + opcode == POP_JUMP_BACKWARD_IF_FALSE); + JUMPBY(1 - oparg); CHECK_EVAL_BREAKER(); - NOTRACE_DISPATCH(); } + else { + assert(opcode == POP_JUMP_FORWARD_IF_TRUE || + opcode == POP_JUMP_FORWARD_IF_FALSE); + JUMPBY(1 + oparg); + } + NOTRACE_DISPATCH(); } TARGET(COMPARE_OP_INT_JUMP) { assert(cframe.use_tracing == 0); - // Combined: COMPARE_OP (int ? int) + POP_JUMP_IF_(true/false) + // Combined: COMPARE_OP (int ? int) + POP_JUMP_(direction)_IF_(true/false) _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; int when_to_jump_mask = cache->mask; PyObject *right = TOP(); @@ -3722,24 +3729,33 @@ handle_eval_breaker: STACK_SHRINK(2); Py_DECREF(left); Py_DECREF(right); - assert(opcode == POP_JUMP_IF_TRUE || opcode == POP_JUMP_IF_FALSE); - int jump = (1 << (sign + 1)) & when_to_jump_mask; + assert(opcode == POP_JUMP_FORWARD_IF_FALSE || + opcode == POP_JUMP_BACKWARD_IF_FALSE || + opcode == POP_JUMP_FORWARD_IF_TRUE || + opcode == POP_JUMP_BACKWARD_IF_TRUE); + int jump = (9 << (sign + 1)) & when_to_jump_mask; if (!jump) { next_instr++; - NOTRACE_DISPATCH(); } - else { - JUMPTO(oparg); + else if (jump >= 8) { + assert(opcode == POP_JUMP_BACKWARD_IF_TRUE || + opcode == POP_JUMP_BACKWARD_IF_FALSE); + JUMPBY(1 - oparg); CHECK_EVAL_BREAKER(); - NOTRACE_DISPATCH(); } + else { + assert(opcode == POP_JUMP_FORWARD_IF_TRUE || + opcode == POP_JUMP_FORWARD_IF_FALSE); + JUMPBY(1 + oparg); + } + NOTRACE_DISPATCH(); } TARGET(COMPARE_OP_STR_JUMP) { assert(cframe.use_tracing == 0); - // Combined: COMPARE_OP (str == str or str != str) + POP_JUMP_IF_(true/false) + // Combined: COMPARE_OP (str == str or str != str) + POP_JUMP_(direction)_IF_(true/false) _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; - int invert = cache->mask; + int when_to_jump_mask = cache->mask; PyObject *right = TOP(); PyObject *left = SECOND(); DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP); @@ -3752,22 +3768,31 @@ handle_eval_breaker: assert(oparg == Py_EQ || oparg == Py_NE); JUMPBY(INLINE_CACHE_ENTRIES_COMPARE_OP); NEXTOPARG(); - assert(opcode == POP_JUMP_IF_TRUE || opcode == POP_JUMP_IF_FALSE); + assert(opcode == POP_JUMP_FORWARD_IF_FALSE || + opcode == POP_JUMP_BACKWARD_IF_FALSE || + opcode == POP_JUMP_FORWARD_IF_TRUE || + opcode == POP_JUMP_BACKWARD_IF_TRUE); STACK_SHRINK(2); Py_DECREF(left); Py_DECREF(right); assert(res == 0 || res == 1); - assert(invert == 0 || invert == 1); - int jump = res ^ invert; + int sign = 1 - res; + int jump = (9 << (sign + 1)) & when_to_jump_mask; if (!jump) { next_instr++; - NOTRACE_DISPATCH(); } - else { - JUMPTO(oparg); + else if (jump >= 8) { + assert(opcode == POP_JUMP_BACKWARD_IF_TRUE || + opcode == POP_JUMP_BACKWARD_IF_FALSE); + JUMPBY(1 - oparg); CHECK_EVAL_BREAKER(); - NOTRACE_DISPATCH(); } + else { + assert(opcode == POP_JUMP_FORWARD_IF_TRUE || + opcode == POP_JUMP_FORWARD_IF_FALSE); + JUMPBY(1 + oparg); + } + NOTRACE_DISPATCH(); } TARGET(IS_OP) { @@ -3779,8 +3804,6 @@ handle_eval_breaker: SET_TOP(b); Py_DECREF(left); Py_DECREF(right); - PREDICT(POP_JUMP_IF_FALSE); - PREDICT(POP_JUMP_IF_TRUE); DISPATCH(); } @@ -3796,8 +3819,6 @@ handle_eval_breaker: PyObject *b = (res^oparg) ? Py_True : Py_False; Py_INCREF(b); PUSH(b); - PREDICT(POP_JUMP_IF_FALSE); - PREDICT(POP_JUMP_IF_TRUE); DISPATCH(); } @@ -3915,26 +3936,25 @@ handle_eval_breaker: JUMP_TO_INSTRUCTION(JUMP_BACKWARD_QUICK); } - TARGET(POP_JUMP_IF_FALSE) { - PREDICTED(POP_JUMP_IF_FALSE); + TARGET(POP_JUMP_BACKWARD_IF_FALSE) { + PREDICTED(POP_JUMP_BACKWARD_IF_FALSE); PyObject *cond = POP(); - int err; if (Py_IsTrue(cond)) { Py_DECREF(cond); DISPATCH(); } if (Py_IsFalse(cond)) { Py_DECREF(cond); - JUMPTO(oparg); + JUMPBY(-oparg); CHECK_EVAL_BREAKER(); DISPATCH(); } - err = PyObject_IsTrue(cond); + int err = PyObject_IsTrue(cond); Py_DECREF(cond); if (err > 0) ; else if (err == 0) { - JUMPTO(oparg); + JUMPBY(-oparg); CHECK_EVAL_BREAKER(); } else @@ -3942,24 +3962,46 @@ handle_eval_breaker: DISPATCH(); } - TARGET(POP_JUMP_IF_TRUE) { - PREDICTED(POP_JUMP_IF_TRUE); + TARGET(POP_JUMP_FORWARD_IF_FALSE) { + PREDICTED(POP_JUMP_FORWARD_IF_FALSE); + PyObject *cond = POP(); + if (Py_IsTrue(cond)) { + Py_DECREF(cond); + } + else if (Py_IsFalse(cond)) { + Py_DECREF(cond); + JUMPBY(oparg); + } + else { + int err = PyObject_IsTrue(cond); + Py_DECREF(cond); + if (err > 0) + ; + else if (err == 0) { + JUMPBY(oparg); + } + else + goto error; + } + DISPATCH(); + } + + TARGET(POP_JUMP_BACKWARD_IF_TRUE) { PyObject *cond = POP(); - int err; if (Py_IsFalse(cond)) { Py_DECREF(cond); DISPATCH(); } if (Py_IsTrue(cond)) { Py_DECREF(cond); - JUMPTO(oparg); + JUMPBY(-oparg); CHECK_EVAL_BREAKER(); DISPATCH(); } - err = PyObject_IsTrue(cond); + int err = PyObject_IsTrue(cond); Py_DECREF(cond); if (err > 0) { - JUMPTO(oparg); + JUMPBY(-oparg); CHECK_EVAL_BREAKER(); } else if (err == 0) @@ -3969,11 +4011,34 @@ handle_eval_breaker: DISPATCH(); } - TARGET(POP_JUMP_IF_NOT_NONE) { + TARGET(POP_JUMP_FORWARD_IF_TRUE) { + PyObject *cond = POP(); + if (Py_IsFalse(cond)) { + Py_DECREF(cond); + } + else if (Py_IsTrue(cond)) { + Py_DECREF(cond); + JUMPBY(oparg); + } + else { + int err = PyObject_IsTrue(cond); + Py_DECREF(cond); + if (err > 0) { + JUMPBY(oparg); + } + else if (err == 0) + ; + else + goto error; + } + DISPATCH(); + } + + TARGET(POP_JUMP_BACKWARD_IF_NOT_NONE) { PyObject *value = POP(); if (!Py_IsNone(value)) { Py_DECREF(value); - JUMPTO(oparg); + JUMPBY(-oparg); CHECK_EVAL_BREAKER(); DISPATCH(); } @@ -3981,11 +4046,20 @@ handle_eval_breaker: DISPATCH(); } - TARGET(POP_JUMP_IF_NONE) { + TARGET(POP_JUMP_FORWARD_IF_NOT_NONE) { + PyObject *value = POP(); + if (!Py_IsNone(value)) { + JUMPBY(oparg); + } + Py_DECREF(value); + DISPATCH(); + } + + TARGET(POP_JUMP_BACKWARD_IF_NONE) { PyObject *value = POP(); if (Py_IsNone(value)) { Py_DECREF(value); - JUMPTO(oparg); + JUMPBY(-oparg); CHECK_EVAL_BREAKER(); DISPATCH(); } @@ -3993,6 +4067,15 @@ handle_eval_breaker: DISPATCH(); } + TARGET(POP_JUMP_FORWARD_IF_NONE) { + PyObject *value = POP(); + if (Py_IsNone(value)) { + JUMPBY(oparg); + } + Py_DECREF(value); + DISPATCH(); + } + TARGET(JUMP_IF_FALSE_OR_POP) { PyObject *cond = TOP(); int err; @@ -4108,7 +4191,8 @@ handle_eval_breaker: PyObject *res = match ? Py_True : Py_False; Py_INCREF(res); PUSH(res); - PREDICT(POP_JUMP_IF_FALSE); + PREDICT(POP_JUMP_FORWARD_IF_FALSE); + PREDICT(POP_JUMP_BACKWARD_IF_FALSE); DISPATCH(); } @@ -4118,7 +4202,8 @@ handle_eval_breaker: PyObject *res = match ? Py_True : Py_False; Py_INCREF(res); PUSH(res); - PREDICT(POP_JUMP_IF_FALSE); + PREDICT(POP_JUMP_FORWARD_IF_FALSE); + PREDICT(POP_JUMP_BACKWARD_IF_FALSE); DISPATCH(); } |