mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
bpo-47120: make POP_JUMP_IF_TRUE/FALSE/NONE/NOT_NONE relative (GH-32400)
This commit is contained in:
parent
98ff4a6877
commit
dd207a6ac5
14 changed files with 357 additions and 135 deletions
179
Python/ceval.c
179
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 if (jump >= 8) {
|
||||
assert(opcode == POP_JUMP_BACKWARD_IF_TRUE ||
|
||||
opcode == POP_JUMP_BACKWARD_IF_FALSE);
|
||||
JUMPBY(1 - oparg);
|
||||
CHECK_EVAL_BREAKER();
|
||||
}
|
||||
else {
|
||||
JUMPTO(oparg);
|
||||
CHECK_EVAL_BREAKER();
|
||||
NOTRACE_DISPATCH();
|
||||
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 if (jump >= 8) {
|
||||
assert(opcode == POP_JUMP_BACKWARD_IF_TRUE ||
|
||||
opcode == POP_JUMP_BACKWARD_IF_FALSE);
|
||||
JUMPBY(1 - oparg);
|
||||
CHECK_EVAL_BREAKER();
|
||||
}
|
||||
else {
|
||||
JUMPTO(oparg);
|
||||
CHECK_EVAL_BREAKER();
|
||||
NOTRACE_DISPATCH();
|
||||
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 if (jump >= 8) {
|
||||
assert(opcode == POP_JUMP_BACKWARD_IF_TRUE ||
|
||||
opcode == POP_JUMP_BACKWARD_IF_FALSE);
|
||||
JUMPBY(1 - oparg);
|
||||
CHECK_EVAL_BREAKER();
|
||||
}
|
||||
else {
|
||||
JUMPTO(oparg);
|
||||
CHECK_EVAL_BREAKER();
|
||||
NOTRACE_DISPATCH();
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue