summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>2022-04-15 19:19:24 (GMT)
committerGitHub <noreply@github.com>2022-04-15 19:19:24 (GMT)
commitea2ae026078b328ddeab060940568a4d3bf1b417 (patch)
treefba97e66d949767124286ee10bfd64fc56e60a99
parent5d421d7342fc0d278c129c05bea7028430e94a4e (diff)
downloadcpython-ea2ae026078b328ddeab060940568a4d3bf1b417.zip
cpython-ea2ae026078b328ddeab060940568a4d3bf1b417.tar.gz
cpython-ea2ae026078b328ddeab060940568a4d3bf1b417.tar.bz2
gh-91276: Make JUMP_IF_TRUE_OR_POP/JUMP_IF_FALSE_OR_POP relative (GH-32215)
-rw-r--r--Doc/library/dis.rst13
-rw-r--r--Doc/whatsnew/3.11.rst3
-rw-r--r--Include/opcode.h2
-rw-r--r--Lib/importlib/_bootstrap_external.py4
-rw-r--r--Lib/opcode.py4
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2022-03-31-14-33-48.bpo-47120.6S_uoU.rst1
-rw-r--r--Python/ceval.c8
-rw-r--r--Python/compile.c15
8 files changed, 38 insertions, 12 deletions
diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst
index 657778c..08e6c73 100644
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -993,21 +993,26 @@ iterations of the loop.
.. versionadded:: 3.11
-.. opcode:: JUMP_IF_TRUE_OR_POP (target)
+.. opcode:: JUMP_IF_TRUE_OR_POP (delta)
- If TOS is true, sets the bytecode counter to *target* and leaves TOS on the
+ If TOS is true, increments the bytecode counter by *delta* and leaves TOS on the
stack. Otherwise (TOS is false), TOS is popped.
.. versionadded:: 3.1
+ .. versionchanged:: 3.11
+ The oparg is now a relative delta rather than an absolute target.
-.. opcode:: JUMP_IF_FALSE_OR_POP (target)
+.. opcode:: JUMP_IF_FALSE_OR_POP (delta)
- If TOS is false, sets the bytecode counter to *target* and leaves TOS on the
+ If TOS is false, increments the bytecode counter by *delta* and leaves TOS on the
stack. Otherwise (TOS is true), TOS is popped.
.. versionadded:: 3.1
+ .. versionchanged:: 3.11
+ The oparg is now a relative delta rather than an absolute target.
+
.. opcode:: FOR_ITER (delta)
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index b6f47f5..ca76efc 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -787,6 +787,9 @@ CPython bytecode changes
:opcode:`POP_JUMP_FORWARD_IF_NONE` and :opcode:`POP_JUMP_BACKWARD_IF_NONE`
opcodes to speed up conditional jumps.
+* :opcode:`JUMP_IF_TRUE_OR_POP` and :opcode:`JUMP_IF_FALSE_OR_POP` are now
+ relative rather than absolute.
+
Deprecated
==========
diff --git a/Include/opcode.h b/Include/opcode.h
index 0badf78..8db4238 100644
--- a/Include/opcode.h
+++ b/Include/opcode.h
@@ -199,7 +199,7 @@ static const uint32_t _PyOpcode_RelativeJump[8] = {
0U,
0U,
536870912U,
- 135020544U,
+ 135118848U,
4163U,
122880U,
0U,
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
index d580e54..4eece8d 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -401,6 +401,7 @@ _code_type = type(_write_atomic.__code__)
# Python 3.11a6 3491 (remove JUMP_IF_NOT_EG_MATCH, add CHECK_EG_MATCH,
# add JUMP_BACKWARD_NO_INTERRUPT, make JUMP_NO_INTERRUPT virtual)
# Python 3.11a7 3492 (make POP_JUMP_IF_NONE/NOT_NONE/TRUE/FALSE relative)
+# Python 3.11a7 3493 (Make JUMP_IF_TRUE_OR_POP/JUMP_IF_FALSE_OR_POP relative)
# Python 3.12 will start with magic number 3500
@@ -415,7 +416,8 @@ _code_type = type(_write_atomic.__code__)
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
# in PC/launcher.c must also be updated.
-MAGIC_NUMBER = (3492).to_bytes(2, 'little') + b'\r\n'
+MAGIC_NUMBER = (3493).to_bytes(2, 'little') + b'\r\n'
+
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
_PYCACHE = '__pycache__'
diff --git a/Lib/opcode.py b/Lib/opcode.py
index ee9effb..9ee0683 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -131,8 +131,8 @@ hascompare.append(107)
name_op('IMPORT_NAME', 108) # Index in name list
name_op('IMPORT_FROM', 109) # Index in name list
jrel_op('JUMP_FORWARD', 110) # Number of words to skip
-jabs_op('JUMP_IF_FALSE_OR_POP', 111) # Target byte offset from beginning of code
-jabs_op('JUMP_IF_TRUE_OR_POP', 112) # ""
+jrel_op('JUMP_IF_FALSE_OR_POP', 111) # Number of words to skip
+jrel_op('JUMP_IF_TRUE_OR_POP', 112) # ""
jrel_op('POP_JUMP_FORWARD_IF_FALSE', 114)
jrel_op('POP_JUMP_FORWARD_IF_TRUE', 115)
name_op('LOAD_GLOBAL', 116, 5) # Index in name list
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-31-14-33-48.bpo-47120.6S_uoU.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-31-14-33-48.bpo-47120.6S_uoU.rst
new file mode 100644
index 0000000..c87d984
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-31-14-33-48.bpo-47120.6S_uoU.rst
@@ -0,0 +1 @@
+Make opcodes :opcode:`JUMP_IF_TRUE_OR_POP` and :opcode:`JUMP_IF_FALSE_OR_POP` relative rather than absolute.
diff --git a/Python/ceval.c b/Python/ceval.c
index 7891547..66856e5 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -4081,7 +4081,7 @@ handle_eval_breaker:
DISPATCH();
}
if (Py_IsFalse(cond)) {
- JUMPTO(oparg);
+ JUMPBY(oparg);
DISPATCH();
}
err = PyObject_IsTrue(cond);
@@ -4090,7 +4090,7 @@ handle_eval_breaker:
Py_DECREF(cond);
}
else if (err == 0)
- JUMPTO(oparg);
+ JUMPBY(oparg);
else
goto error;
DISPATCH();
@@ -4105,12 +4105,12 @@ handle_eval_breaker:
DISPATCH();
}
if (Py_IsTrue(cond)) {
- JUMPTO(oparg);
+ JUMPBY(oparg);
DISPATCH();
}
err = PyObject_IsTrue(cond);
if (err > 0) {
- JUMPTO(oparg);
+ JUMPBY(oparg);
}
else if (err == 0) {
STACK_SHRINK(1);
diff --git a/Python/compile.c b/Python/compile.c
index 718b521..3b91566 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -7672,6 +7672,21 @@ normalize_jumps(struct assembler *a)
last->i_opcode = is_forward ?
POP_JUMP_FORWARD_IF_TRUE : POP_JUMP_BACKWARD_IF_TRUE;
break;
+ case JUMP_IF_TRUE_OR_POP:
+ case JUMP_IF_FALSE_OR_POP:
+ if (!is_forward) {
+ /* As far as we can tell, the compiler never emits
+ * these jumps with a backwards target. If/when this
+ * exception is raised, we have found a use case for
+ * a backwards version of this jump (or to replace
+ * it with the sequence (COPY 1, POP_JUMP_IF_T/F, POP)
+ */
+ PyErr_Format(PyExc_SystemError,
+ "unexpected %s jumping backwards",
+ last->i_opcode == JUMP_IF_TRUE_OR_POP ?
+ "JUMP_IF_TRUE_OR_POP" : "JUMP_IF_FALSE_OR_POP");
+ }
+ break;
}
}
}