Skip to content

Commit a34c7d6

Browse files
committed
gh-142250: Add hasjforward and hasjback collections to opcode.py and document in dis.rst
1 parent 53ec7c8 commit a34c7d6

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

Doc/library/dis.rst

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,18 +813,23 @@ not have to be) the original ``STACK[-2]``.
813813
.. versionadded:: 3.5
814814

815815

816-
.. opcode:: END_ASYNC_FOR
816+
.. opcode:: END_ASYNC_FOR (delta)
817817

818818
Terminates an :keyword:`async for` loop. Handles an exception raised
819819
when awaiting a next item. The stack contains the async iterable in
820820
``STACK[-2]`` and the raised exception in ``STACK[-1]``. Both are popped.
821821
If the exception is not :exc:`StopAsyncIteration`, it is re-raised.
822+
823+
Decrements the bytecode counter by *delta* to jump back to the loop start
824+
if continuing iteration.
822825

823826
.. versionadded:: 3.8
824827

825828
.. versionchanged:: 3.11
826829
Exception representation on the stack now consist of one, not three, items.
827830

831+
.. versionchanged:: 3.14
832+
Added the *delta* parameter. This opcode is now a backward jump instruction.
828833

829834
.. opcode:: CLEANUP_THROW
830835

@@ -2081,3 +2086,16 @@ instructions:
20812086

20822087
.. deprecated:: 3.13
20832088
All jumps are now relative. This list is empty.
2089+
2090+
.. data:: hasjforward
2091+
2092+
Sequence of bytecodes that perform forward jumps.
2093+
2094+
.. versionadded:: 3.14
2095+
2096+
.. data:: hasjback
2097+
2098+
Sequence of bytecodes that perform backward jumps, such as
2099+
:opcode:`JUMP_BACKWARD`, :opcode:`FOR_ITER`, and :opcode:`END_ASYNC_FOR`.
2100+
2101+
.. versionadded:: 3.14

Lib/opcode.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
__all__ = ["cmp_op", "stack_effect", "hascompare", "opname", "opmap",
99
"HAVE_ARGUMENT", "EXTENDED_ARG", "hasarg", "hasconst", "hasname",
10-
"hasjump", "hasjrel", "hasjabs", "hasfree", "haslocal", "hasexc"]
10+
"hasjump", "hasjrel", "hasjabs", "hasjforward", "hasjback", "hasfree", "haslocal", "hasexc"]
1111

1212
import builtins
1313
import _opcode
@@ -17,6 +17,18 @@
1717
HAVE_ARGUMENT, MIN_INSTRUMENTED_OPCODE) # noqa: F401
1818
EXTENDED_ARG = opmap['EXTENDED_ARG']
1919

20+
def _is_backward_jump_op(op):
21+
"""Helper function to identify backward jump opcodes."""
22+
# Get the opcode name from the op number
23+
op_name = opname[op] if op < len(opname) else None
24+
return op_name in (
25+
'JUMP_BACKWARD',
26+
'JUMP_BACKWARD_NO_INTERRUPT',
27+
'FOR_ITER',
28+
'END_ASYNC_FOR',
29+
)
30+
31+
2032
opname = ['<%r>' % (op,) for op in range(max(opmap.values()) + 1)]
2133
for m in (opmap, _specialized_opmap):
2234
for op, i in m.items():
@@ -35,6 +47,12 @@
3547
haslocal = [op for op in opmap.values() if _opcode.has_local(op)]
3648
hasexc = [op for op in opmap.values() if _opcode.has_exc(op)]
3749

50+
hasjforward = [op for op in hasjump if not _is_backward_jump_op(op)]
51+
hasjback = [op for op in hasjump if _is_backward_jump_op(op)]
52+
53+
54+
55+
_intrinsic_1_descs = _opcode.get_intrinsic1_descs()
3856

3957
_intrinsic_1_descs = _opcode.get_intrinsic1_descs()
4058
_intrinsic_2_descs = _opcode.get_intrinsic2_descs()

0 commit comments

Comments
 (0)