summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c179
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();
}