Skip to content

Commit ea2ae02

Browse files
authored
gh-91276: Make JUMP_IF_TRUE_OR_POP/JUMP_IF_FALSE_OR_POP relative (GH-32215)
1 parent 5d421d7 commit ea2ae02

File tree

8 files changed

+38
-12
lines changed

8 files changed

+38
-12
lines changed

Doc/library/dis.rst

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -993,21 +993,26 @@ iterations of the loop.
993993
.. versionadded:: 3.11
994994

995995

996-
.. opcode:: JUMP_IF_TRUE_OR_POP (target)
996+
.. opcode:: JUMP_IF_TRUE_OR_POP (delta)
997997

998-
If TOS is true, sets the bytecode counter to *target* and leaves TOS on the
998+
If TOS is true, increments the bytecode counter by *delta* and leaves TOS on the
999999
stack. Otherwise (TOS is false), TOS is popped.
10001000

10011001
.. versionadded:: 3.1
10021002

1003+
.. versionchanged:: 3.11
1004+
The oparg is now a relative delta rather than an absolute target.
10031005

1004-
.. opcode:: JUMP_IF_FALSE_OR_POP (target)
1006+
.. opcode:: JUMP_IF_FALSE_OR_POP (delta)
10051007

1006-
If TOS is false, sets the bytecode counter to *target* and leaves TOS on the
1008+
If TOS is false, increments the bytecode counter by *delta* and leaves TOS on the
10071009
stack. Otherwise (TOS is true), TOS is popped.
10081010

10091011
.. versionadded:: 3.1
10101012

1013+
.. versionchanged:: 3.11
1014+
The oparg is now a relative delta rather than an absolute target.
1015+
10111016

10121017
.. opcode:: FOR_ITER (delta)
10131018

Doc/whatsnew/3.11.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,9 @@ CPython bytecode changes
787787
:opcode:`POP_JUMP_FORWARD_IF_NONE` and :opcode:`POP_JUMP_BACKWARD_IF_NONE`
788788
opcodes to speed up conditional jumps.
789789

790+
* :opcode:`JUMP_IF_TRUE_OR_POP` and :opcode:`JUMP_IF_FALSE_OR_POP` are now
791+
relative rather than absolute.
792+
790793

791794
Deprecated
792795
==========

Include/opcode.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/importlib/_bootstrap_external.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ def _write_atomic(path, data, mode=0o666):
401401
# Python 3.11a6 3491 (remove JUMP_IF_NOT_EG_MATCH, add CHECK_EG_MATCH,
402402
# add JUMP_BACKWARD_NO_INTERRUPT, make JUMP_NO_INTERRUPT virtual)
403403
# Python 3.11a7 3492 (make POP_JUMP_IF_NONE/NOT_NONE/TRUE/FALSE relative)
404+
# Python 3.11a7 3493 (Make JUMP_IF_TRUE_OR_POP/JUMP_IF_FALSE_OR_POP relative)
404405

405406
# Python 3.12 will start with magic number 3500
406407

@@ -415,7 +416,8 @@ def _write_atomic(path, data, mode=0o666):
415416
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
416417
# in PC/launcher.c must also be updated.
417418

418-
MAGIC_NUMBER = (3492).to_bytes(2, 'little') + b'\r\n'
419+
MAGIC_NUMBER = (3493).to_bytes(2, 'little') + b'\r\n'
420+
419421
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
420422

421423
_PYCACHE = '__pycache__'

Lib/opcode.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ def jabs_op(name, op, entries=0):
131131
name_op('IMPORT_NAME', 108) # Index in name list
132132
name_op('IMPORT_FROM', 109) # Index in name list
133133
jrel_op('JUMP_FORWARD', 110) # Number of words to skip
134-
jabs_op('JUMP_IF_FALSE_OR_POP', 111) # Target byte offset from beginning of code
135-
jabs_op('JUMP_IF_TRUE_OR_POP', 112) # ""
134+
jrel_op('JUMP_IF_FALSE_OR_POP', 111) # Number of words to skip
135+
jrel_op('JUMP_IF_TRUE_OR_POP', 112) # ""
136136
jrel_op('POP_JUMP_FORWARD_IF_FALSE', 114)
137137
jrel_op('POP_JUMP_FORWARD_IF_TRUE', 115)
138138
name_op('LOAD_GLOBAL', 116, 5) # Index in name list
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make opcodes :opcode:`JUMP_IF_TRUE_OR_POP` and :opcode:`JUMP_IF_FALSE_OR_POP` relative rather than absolute.

Python/ceval.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4081,7 +4081,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
40814081
DISPATCH();
40824082
}
40834083
if (Py_IsFalse(cond)) {
4084-
JUMPTO(oparg);
4084+
JUMPBY(oparg);
40854085
DISPATCH();
40864086
}
40874087
err = PyObject_IsTrue(cond);
@@ -4090,7 +4090,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
40904090
Py_DECREF(cond);
40914091
}
40924092
else if (err == 0)
4093-
JUMPTO(oparg);
4093+
JUMPBY(oparg);
40944094
else
40954095
goto error;
40964096
DISPATCH();
@@ -4105,12 +4105,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
41054105
DISPATCH();
41064106
}
41074107
if (Py_IsTrue(cond)) {
4108-
JUMPTO(oparg);
4108+
JUMPBY(oparg);
41094109
DISPATCH();
41104110
}
41114111
err = PyObject_IsTrue(cond);
41124112
if (err > 0) {
4113-
JUMPTO(oparg);
4113+
JUMPBY(oparg);
41144114
}
41154115
else if (err == 0) {
41164116
STACK_SHRINK(1);

Python/compile.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7672,6 +7672,21 @@ normalize_jumps(struct assembler *a)
76727672
last->i_opcode = is_forward ?
76737673
POP_JUMP_FORWARD_IF_TRUE : POP_JUMP_BACKWARD_IF_TRUE;
76747674
break;
7675+
case JUMP_IF_TRUE_OR_POP:
7676+
case JUMP_IF_FALSE_OR_POP:
7677+
if (!is_forward) {
7678+
/* As far as we can tell, the compiler never emits
7679+
* these jumps with a backwards target. If/when this
7680+
* exception is raised, we have found a use case for
7681+
* a backwards version of this jump (or to replace
7682+
* it with the sequence (COPY 1, POP_JUMP_IF_T/F, POP)
7683+
*/
7684+
PyErr_Format(PyExc_SystemError,
7685+
"unexpected %s jumping backwards",
7686+
last->i_opcode == JUMP_IF_TRUE_OR_POP ?
7687+
"JUMP_IF_TRUE_OR_POP" : "JUMP_IF_FALSE_OR_POP");
7688+
}
7689+
break;
76757690
}
76767691
}
76777692
}

0 commit comments

Comments
 (0)