Skip to content

gh-93554: Conditional jumps only jump forward #96318

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Sep 1, 2022
56 changes: 20 additions & 36 deletions Doc/library/dis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -999,60 +999,48 @@ iterations of the loop.
.. versionadded:: 3.11


.. opcode:: POP_JUMP_FORWARD_IF_TRUE (delta)
.. opcode:: POP_JUMP_IF_TRUE (delta)

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

.. versionadded:: 3.11


.. opcode:: POP_JUMP_BACKWARD_IF_TRUE (delta)

If TOS is true, decrements the bytecode counter by *delta*. TOS is popped.

.. versionadded:: 3.11
.. versionchanged:: 3.11
The oparg is now a relative delta rather than an absolute target.
This opcode is a pseudo-instruction, replaced in final bytecode by
the directed versions (forward/backward).

.. versionchanged:: 3.12
This is no longer a pseudo-instruction.

.. opcode:: POP_JUMP_FORWARD_IF_FALSE (delta)
.. opcode:: POP_JUMP_IF_FALSE (delta)

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

.. versionadded:: 3.11


.. opcode:: POP_JUMP_BACKWARD_IF_FALSE (delta)

If TOS is false, decrements the bytecode counter by *delta*. TOS is popped.

.. versionadded:: 3.11
.. versionchanged:: 3.11
The oparg is now a relative delta rather than an absolute target.
This opcode is a pseudo-instruction, replaced in final bytecode by
the directed versions (forward/backward).

.. versionchanged:: 3.12
This is no longer a pseudo-instruction.

.. opcode:: POP_JUMP_FORWARD_IF_NOT_NONE (delta)
.. opcode:: POP_JUMP_IF_NOT_NONE (delta)

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

.. versionadded:: 3.11


.. opcode:: POP_JUMP_BACKWARD_IF_NOT_NONE (delta)

If TOS is not ``None``, decrements the bytecode counter by *delta*. TOS is popped.

.. versionadded:: 3.11
.. versionchanged:: 3.12
This is no longer a pseudo-instruction.


.. opcode:: POP_JUMP_FORWARD_IF_NONE (delta)
.. opcode:: POP_JUMP_IF_NONE (delta)

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

.. versionadded:: 3.11


.. opcode:: POP_JUMP_BACKWARD_IF_NONE (delta)

If TOS is ``None``, decrements the bytecode counter by *delta*. TOS is popped.

.. versionadded:: 3.11
.. versionchanged:: 3.12
This is no longer a pseudo-instruction.


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

.. opcode:: JUMP
.. opcode:: JUMP_NO_INTERRUPT
.. opcode:: POP_JUMP_IF_FALSE
.. opcode:: POP_JUMP_IF_TRUE
.. opcode:: POP_JUMP_IF_NONE
.. opcode:: POP_JUMP_IF_NOT_NONE

Undirected relative jump instructions which are replaced by their
directed (forward/backward) counterparts by the assembler.
Expand Down
46 changes: 21 additions & 25 deletions Include/internal/pycore_opcode.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 14 additions & 26 deletions Include/opcode.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Lib/importlib/_bootstrap_external.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ def _write_atomic(path, data, mode=0o666):
# Python 3.12a1 3506 (Add BINARY_SLICE and STORE_SLICE instructions)
# Python 3.12a1 3507 (Set lineno of module's RESUME to 0)
# Python 3.12a1 3508 (Add CLEANUP_THROW)
# Python 3.12a1 3509 (Conditional jumps only jump forward)

# Python 3.13 will start with 3550

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

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

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

Expand Down
19 changes: 6 additions & 13 deletions Lib/opcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@ def pseudo_op(name, op, real_ops):
jrel_op('JUMP_FORWARD', 110) # Number of words to skip
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)
jrel_op('POP_JUMP_IF_FALSE', 114)
jrel_op('POP_JUMP_IF_TRUE', 115)
name_op('LOAD_GLOBAL', 116) # Index in name list
def_op('IS_OP', 117)
def_op('CONTAINS_OP', 118)
Expand All @@ -170,8 +170,8 @@ def pseudo_op(name, op, real_ops):
haslocal.append(126)
def_op('LOAD_FAST_CHECK', 127) # Local variable number
haslocal.append(127)
jrel_op('POP_JUMP_FORWARD_IF_NOT_NONE', 128)
jrel_op('POP_JUMP_FORWARD_IF_NONE', 129)
jrel_op('POP_JUMP_IF_NOT_NONE', 128)
jrel_op('POP_JUMP_IF_NONE', 129)
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
def_op('GET_AWAITABLE', 131)
def_op('MAKE_FUNCTION', 132) # Flags
Expand Down Expand Up @@ -216,10 +216,6 @@ def pseudo_op(name, op, real_ops):
def_op('KW_NAMES', 172)
hasconst.append(172)

jrel_op('POP_JUMP_BACKWARD_IF_NOT_NONE', 173)
jrel_op('POP_JUMP_BACKWARD_IF_NONE', 174)
jrel_op('POP_JUMP_BACKWARD_IF_FALSE', 175)
jrel_op('POP_JUMP_BACKWARD_IF_TRUE', 176)

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

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

pseudo_op('JUMP', 260, ['JUMP_FORWARD', 'JUMP_BACKWARD'])
pseudo_op('JUMP_NO_INTERRUPT', 261, ['JUMP_FORWARD', 'JUMP_BACKWARD_NO_INTERRUPT'])
pseudo_op('POP_JUMP_IF_FALSE', 262, ['POP_JUMP_FORWARD_IF_FALSE', 'POP_JUMP_BACKWARD_IF_FALSE'])
pseudo_op('POP_JUMP_IF_TRUE', 263, ['POP_JUMP_FORWARD_IF_TRUE', 'POP_JUMP_BACKWARD_IF_TRUE'])
pseudo_op('POP_JUMP_IF_NONE', 264, ['POP_JUMP_FORWARD_IF_NONE', 'POP_JUMP_BACKWARD_IF_NONE'])
pseudo_op('POP_JUMP_IF_NOT_NONE', 265, ['POP_JUMP_FORWARD_IF_NOT_NONE', 'POP_JUMP_BACKWARD_IF_NOT_NONE'])
pseudo_op('LOAD_METHOD', 266, ['LOAD_ATTR'])

pseudo_op('LOAD_METHOD', 262, ['LOAD_ATTR'])

MAX_PSEUDO_OPCODE = MIN_PSEUDO_OPCODE + len(_pseudo_ops) - 1

Expand Down
Loading