Skip to content

Commit 4c72517

Browse files
authored
gh-93554: Conditional jump opcodes only jump forward (GH-96318)
1 parent a91f255 commit 4c72517

File tree

13 files changed

+298
-448
lines changed

13 files changed

+298
-448
lines changed

Doc/library/dis.rst

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -999,60 +999,48 @@ iterations of the loop.
999999
.. versionadded:: 3.11
10001000

10011001

1002-
.. opcode:: POP_JUMP_FORWARD_IF_TRUE (delta)
1002+
.. opcode:: POP_JUMP_IF_TRUE (delta)
10031003

10041004
If TOS is true, increments the bytecode counter by *delta*. TOS is popped.
10051005

1006-
.. versionadded:: 3.11
1007-
1008-
1009-
.. opcode:: POP_JUMP_BACKWARD_IF_TRUE (delta)
1010-
1011-
If TOS is true, decrements the bytecode counter by *delta*. TOS is popped.
1012-
1013-
.. versionadded:: 3.11
1006+
.. versionchanged:: 3.11
1007+
The oparg is now a relative delta rather than an absolute target.
1008+
This opcode is a pseudo-instruction, replaced in final bytecode by
1009+
the directed versions (forward/backward).
10141010

1011+
.. versionchanged:: 3.12
1012+
This is no longer a pseudo-instruction.
10151013

1016-
.. opcode:: POP_JUMP_FORWARD_IF_FALSE (delta)
1014+
.. opcode:: POP_JUMP_IF_FALSE (delta)
10171015

10181016
If TOS is false, increments the bytecode counter by *delta*. TOS is popped.
10191017

1020-
.. versionadded:: 3.11
1021-
1022-
1023-
.. opcode:: POP_JUMP_BACKWARD_IF_FALSE (delta)
1024-
1025-
If TOS is false, decrements the bytecode counter by *delta*. TOS is popped.
1026-
1027-
.. versionadded:: 3.11
1018+
.. versionchanged:: 3.11
1019+
The oparg is now a relative delta rather than an absolute target.
1020+
This opcode is a pseudo-instruction, replaced in final bytecode by
1021+
the directed versions (forward/backward).
10281022

1023+
.. versionchanged:: 3.12
1024+
This is no longer a pseudo-instruction.
10291025

1030-
.. opcode:: POP_JUMP_FORWARD_IF_NOT_NONE (delta)
1026+
.. opcode:: POP_JUMP_IF_NOT_NONE (delta)
10311027

10321028
If TOS is not ``None``, increments the bytecode counter by *delta*. TOS is popped.
10331029

10341030
.. versionadded:: 3.11
10351031

1036-
1037-
.. opcode:: POP_JUMP_BACKWARD_IF_NOT_NONE (delta)
1038-
1039-
If TOS is not ``None``, decrements the bytecode counter by *delta*. TOS is popped.
1040-
1041-
.. versionadded:: 3.11
1032+
.. versionchanged:: 3.12
1033+
This is no longer a pseudo-instruction.
10421034

10431035

1044-
.. opcode:: POP_JUMP_FORWARD_IF_NONE (delta)
1036+
.. opcode:: POP_JUMP_IF_NONE (delta)
10451037

10461038
If TOS is ``None``, increments the bytecode counter by *delta*. TOS is popped.
10471039

10481040
.. versionadded:: 3.11
10491041

1050-
1051-
.. opcode:: POP_JUMP_BACKWARD_IF_NONE (delta)
1052-
1053-
If TOS is ``None``, decrements the bytecode counter by *delta*. TOS is popped.
1054-
1055-
.. versionadded:: 3.11
1042+
.. versionchanged:: 3.12
1043+
This is no longer a pseudo-instruction.
10561044

10571045

10581046
.. opcode:: JUMP_IF_TRUE_OR_POP (delta)
@@ -1433,10 +1421,6 @@ but are replaced by real opcodes or removed before bytecode is generated.
14331421

14341422
.. opcode:: JUMP
14351423
.. opcode:: JUMP_NO_INTERRUPT
1436-
.. opcode:: POP_JUMP_IF_FALSE
1437-
.. opcode:: POP_JUMP_IF_TRUE
1438-
.. opcode:: POP_JUMP_IF_NONE
1439-
.. opcode:: POP_JUMP_IF_NOT_NONE
14401424

14411425
Undirected relative jump instructions which are replaced by their
14421426
directed (forward/backward) counterparts by the assembler.

Include/internal/pycore_opcode.h

Lines changed: 21 additions & 25 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/opcode.h

Lines changed: 14 additions & 26 deletions
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: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ def _write_atomic(path, data, mode=0o666):
412412
# Python 3.12a1 3506 (Add BINARY_SLICE and STORE_SLICE instructions)
413413
# Python 3.12a1 3507 (Set lineno of module's RESUME to 0)
414414
# Python 3.12a1 3508 (Add CLEANUP_THROW)
415+
# Python 3.12a1 3509 (Conditional jumps only jump forward)
415416

416417
# Python 3.13 will start with 3550
417418

@@ -424,7 +425,7 @@ def _write_atomic(path, data, mode=0o666):
424425
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
425426
# in PC/launcher.c must also be updated.
426427

427-
MAGIC_NUMBER = (3508).to_bytes(2, 'little') + b'\r\n'
428+
MAGIC_NUMBER = (3509).to_bytes(2, 'little') + b'\r\n'
428429

429430
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
430431

Lib/opcode.py

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,8 @@ def pseudo_op(name, op, real_ops):
153153
jrel_op('JUMP_FORWARD', 110) # Number of words to skip
154154
jrel_op('JUMP_IF_FALSE_OR_POP', 111) # Number of words to skip
155155
jrel_op('JUMP_IF_TRUE_OR_POP', 112) # ""
156-
jrel_op('POP_JUMP_FORWARD_IF_FALSE', 114)
157-
jrel_op('POP_JUMP_FORWARD_IF_TRUE', 115)
156+
jrel_op('POP_JUMP_IF_FALSE', 114)
157+
jrel_op('POP_JUMP_IF_TRUE', 115)
158158
name_op('LOAD_GLOBAL', 116) # Index in name list
159159
def_op('IS_OP', 117)
160160
def_op('CONTAINS_OP', 118)
@@ -170,8 +170,8 @@ def pseudo_op(name, op, real_ops):
170170
haslocal.append(126)
171171
def_op('LOAD_FAST_CHECK', 127) # Local variable number
172172
haslocal.append(127)
173-
jrel_op('POP_JUMP_FORWARD_IF_NOT_NONE', 128)
174-
jrel_op('POP_JUMP_FORWARD_IF_NONE', 129)
173+
jrel_op('POP_JUMP_IF_NOT_NONE', 128)
174+
jrel_op('POP_JUMP_IF_NONE', 129)
175175
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
176176
def_op('GET_AWAITABLE', 131)
177177
def_op('MAKE_FUNCTION', 132) # Flags
@@ -216,10 +216,6 @@ def pseudo_op(name, op, real_ops):
216216
def_op('KW_NAMES', 172)
217217
hasconst.append(172)
218218

219-
jrel_op('POP_JUMP_BACKWARD_IF_NOT_NONE', 173)
220-
jrel_op('POP_JUMP_BACKWARD_IF_NONE', 174)
221-
jrel_op('POP_JUMP_BACKWARD_IF_FALSE', 175)
222-
jrel_op('POP_JUMP_BACKWARD_IF_TRUE', 176)
223219

224220
hasarg.extend([op for op in opmap.values() if op >= HAVE_ARGUMENT])
225221

@@ -235,11 +231,8 @@ def pseudo_op(name, op, real_ops):
235231

236232
pseudo_op('JUMP', 260, ['JUMP_FORWARD', 'JUMP_BACKWARD'])
237233
pseudo_op('JUMP_NO_INTERRUPT', 261, ['JUMP_FORWARD', 'JUMP_BACKWARD_NO_INTERRUPT'])
238-
pseudo_op('POP_JUMP_IF_FALSE', 262, ['POP_JUMP_FORWARD_IF_FALSE', 'POP_JUMP_BACKWARD_IF_FALSE'])
239-
pseudo_op('POP_JUMP_IF_TRUE', 263, ['POP_JUMP_FORWARD_IF_TRUE', 'POP_JUMP_BACKWARD_IF_TRUE'])
240-
pseudo_op('POP_JUMP_IF_NONE', 264, ['POP_JUMP_FORWARD_IF_NONE', 'POP_JUMP_BACKWARD_IF_NONE'])
241-
pseudo_op('POP_JUMP_IF_NOT_NONE', 265, ['POP_JUMP_FORWARD_IF_NOT_NONE', 'POP_JUMP_BACKWARD_IF_NOT_NONE'])
242-
pseudo_op('LOAD_METHOD', 266, ['LOAD_ATTR'])
234+
235+
pseudo_op('LOAD_METHOD', 262, ['LOAD_ATTR'])
243236

244237
MAX_PSEUDO_OPCODE = MIN_PSEUDO_OPCODE + len(_pseudo_ops) - 1
245238

0 commit comments

Comments
 (0)