gh-96461: Improve docs for bytecode instructions (GH-96462)

* Clarify the meaning of the oparg for CACHE and COPY opcode in dis doc

* Use STACK to describe stack operation in analogy with a Python list

* Remove (delta) from BEFORE_WITH since BEFORE_WITH does not take an argument

* Fix the description of the stack impact of multiple opcodes
This commit is contained in:
Matthieu Dartiailh 2023-01-12 19:23:50 +01:00 committed by GitHub
parent c549fcccbb
commit eecd422d1b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -402,6 +402,10 @@ The Python compiler currently generates the following bytecode instructions.
**General instructions** **General instructions**
In the following, We will refer to the interpreter stack as STACK and describe
operations on it as if it was a Python list. The top of the stack corresponds to
``STACK[-1]`` in this language.
.. opcode:: NOP .. opcode:: NOP
Do nothing code. Used as a placeholder by the bytecode optimizer, and to Do nothing code. Used as a placeholder by the bytecode optimizer, and to
@ -410,7 +414,9 @@ The Python compiler currently generates the following bytecode instructions.
.. opcode:: POP_TOP .. opcode:: POP_TOP
Removes the top-of-stack (TOS) item. Removes the top-of-stack item.::
STACK.pop()
.. opcode:: END_FOR .. opcode:: END_FOR
@ -424,15 +430,20 @@ The Python compiler currently generates the following bytecode instructions.
.. opcode:: COPY (i) .. opcode:: COPY (i)
Push the *i*-th item to the top of the stack. The item is not removed from its Push the i-th item to the top of the stack without removing it from its original
original location. location.::
assert i > 0
STACK.append(STACK[-i])
.. versionadded:: 3.11 .. versionadded:: 3.11
.. opcode:: SWAP (i) .. opcode:: SWAP (i)
Swap TOS with the item at position *i*. Swap the top of the stack with the i-th element.::
STACK[-i], STACK[-1] = stack[-1], STACK[-i]
.. versionadded:: 3.11 .. versionadded:: 3.11
@ -463,79 +474,102 @@ result back on the stack.
.. opcode:: UNARY_NEGATIVE .. opcode:: UNARY_NEGATIVE
Implements ``TOS = -TOS``. Implements ``STACK[-1] = -STACK[-1]``.
.. opcode:: UNARY_NOT .. opcode:: UNARY_NOT
Implements ``TOS = not TOS``. Implements ``STACK[-1] = not STACK[-1]``.
.. opcode:: UNARY_INVERT .. opcode:: UNARY_INVERT
Implements ``TOS = ~TOS``. Implements ``STACK[-1] = ~STACK[-1]``.
.. opcode:: GET_ITER .. opcode:: GET_ITER
Implements ``TOS = iter(TOS)``. Implements ``STACK[-1] = iter(STACK[-1])``.
.. opcode:: GET_YIELD_FROM_ITER .. opcode:: GET_YIELD_FROM_ITER
If ``TOS`` is a :term:`generator iterator` or :term:`coroutine` object If ``STACK[-1]`` is a :term:`generator iterator` or :term:`coroutine` object
it is left as is. Otherwise, implements ``TOS = iter(TOS)``. it is left as is. Otherwise, implements ``STACK[-1] = iter(STACK[-1])``.
.. versionadded:: 3.5 .. versionadded:: 3.5
**Binary and in-place operations** **Binary and in-place operations**
In the following, TOS is the top-of-stack. Binary operations remove the top two items from the stack (``STACK[-1]`` and
TOS1, TOS2, TOS3 are the second, third and fourth items on the stack, respectively. ``STACK[-2]``). They perform the operation, then put the result back on the stack.
Binary operations remove the top two items from the stack (TOS and TOS1).
They perform the operation, then put the result back on the stack.
In-place operations are like binary operations, but the operation is done in-place In-place operations are like binary operations, but the operation is done in-place
when TOS1 supports it, and the resulting TOS may be (but does not have to be) when ``STACK[-2]`` supports it, and the resulting ``STACK[-1]`` may be (but does
the original TOS1. not have to be) the original ``STACK[-2]``.
.. opcode:: BINARY_OP (op) .. opcode:: BINARY_OP (op)
Implements the binary and in-place operators (depending on the value of Implements the binary and in-place operators (depending on the value of
*op*). *op*).::
``TOS = TOS1 op TOS``.
rhs = STACK.pop()
lhs = STACK.pop()
STACK.append(lhs op rhs)
.. versionadded:: 3.11 .. versionadded:: 3.11
.. opcode:: BINARY_SUBSCR .. opcode:: BINARY_SUBSCR
Implements ``TOS = TOS1[TOS]``. Implements::
key = STACK.pop()
container = STACK.pop()
STACK.append(container[index])
.. opcode:: STORE_SUBSCR .. opcode:: STORE_SUBSCR
Implements ``TOS1[TOS] = TOS2``. Implements::
key = STACK.pop()
container = STACK.pop()
value = STACK.pop()
container[key] = value
.. opcode:: DELETE_SUBSCR .. opcode:: DELETE_SUBSCR
Implements ``del TOS1[TOS]``. Implements::
key = STACK.pop()
container = STACK.pop()
del container[key]
.. opcode:: BINARY_SLICE .. opcode:: BINARY_SLICE
Implements ``TOS = TOS2[TOS1:TOS]``. Implements::
end = STACK.pop()
start = STACK.pop()
container = STACK.pop()
STACK.append(container[start:end])
.. versionadded:: 3.12 .. versionadded:: 3.12
.. opcode:: STORE_SLICE .. opcode:: STORE_SLICE
Implements ``TOS2[TOS1:TOS] = TOS3``. Implements::
end = STACK.pop()
start = STACK.pop()
container = STACK.pop()
values = STACK.pop()
container[start:end] = value
.. versionadded:: 3.12 .. versionadded:: 3.12
@ -544,7 +578,7 @@ the original TOS1.
.. opcode:: GET_AWAITABLE (where) .. opcode:: GET_AWAITABLE (where)
Implements ``TOS = get_awaitable(TOS)``, where ``get_awaitable(o)`` Implements ``STACK[-1] = get_awaitable(STACK[-1])``, where ``get_awaitable(o)``
returns ``o`` if ``o`` is a coroutine object or a generator object with returns ``o`` if ``o`` is a coroutine object or a generator object with
the CO_ITERABLE_COROUTINE flag, or resolves the CO_ITERABLE_COROUTINE flag, or resolves
``o.__await__``. ``o.__await__``.
@ -563,7 +597,7 @@ the original TOS1.
.. opcode:: GET_AITER .. opcode:: GET_AITER
Implements ``TOS = TOS.__aiter__()``. Implements ``STACK[-1] = STACK[-1].__aiter__()``.
.. versionadded:: 3.5 .. versionadded:: 3.5
.. versionchanged:: 3.7 .. versionchanged:: 3.7
@ -573,8 +607,8 @@ the original TOS1.
.. opcode:: GET_ANEXT .. opcode:: GET_ANEXT
Pushes ``get_awaitable(TOS.__anext__())`` to the stack. See Implement ``STACK.append(get_awaitable(STACK[-1].__anext__()))`` to the stack.
``GET_AWAITABLE`` for details about ``get_awaitable``. See ``GET_AWAITABLE`` for details about ``get_awaitable``.
.. versionadded:: 3.5 .. versionadded:: 3.5
@ -582,7 +616,7 @@ the original TOS1.
.. opcode:: END_ASYNC_FOR .. opcode:: END_ASYNC_FOR
Terminates an :keyword:`async for` loop. Handles an exception raised Terminates an :keyword:`async for` loop. Handles an exception raised
when awaiting a next item. If TOS is :exc:`StopAsyncIteration` pop 3 when awaiting a next item. If ``STACK[-1]`` is :exc:`StopAsyncIteration` pop 3
values from the stack and restore the exception state using the second values from the stack and restore the exception state using the second
of them. Otherwise re-raise the exception using the value of them. Otherwise re-raise the exception using the value
from the stack. An exception handler block is removed from the block stack. from the stack. An exception handler block is removed from the block stack.
@ -596,17 +630,19 @@ the original TOS1.
.. opcode:: CLEANUP_THROW .. opcode:: CLEANUP_THROW
Handles an exception raised during a :meth:`~generator.throw` or Handles an exception raised during a :meth:`~generator.throw` or
:meth:`~generator.close` call through the current frame. If TOS is an :meth:`~generator.close` call through the current frame. If ``STACK[-1]`` is an
instance of :exc:`StopIteration`, pop three values from the stack and push instance of :exc:`StopIteration`, pop three values from the stack and push
its ``value`` member. Otherwise, re-raise TOS. its ``value`` member. Otherwise, re-raise ``STACK[-1]``.
.. versionadded:: 3.12 .. versionadded:: 3.12
.. opcode:: BEFORE_ASYNC_WITH .. opcode:: BEFORE_ASYNC_WITH
Resolves ``__aenter__`` and ``__aexit__`` from the object on top of the Resolves ``__aenter__`` and ``__aexit__`` from ``STACK[-1]``.
stack. Pushes ``__aexit__`` and result of ``__aenter__()`` to the stack. Pushes ``__aexit__`` and result of ``__aenter__()`` to the stack::
STACK.extend((__aexit__, __aenter__())
.. versionadded:: 3.5 .. versionadded:: 3.5
@ -616,22 +652,37 @@ the original TOS1.
.. opcode:: SET_ADD (i) .. opcode:: SET_ADD (i)
Calls ``set.add(TOS1[-i], TOS)``. Used to implement set comprehensions. Implements::
item = STACK.pop()
set.add(STACK[-i], item)
Used to implement set comprehensions.
.. opcode:: LIST_APPEND (i) .. opcode:: LIST_APPEND (i)
Calls ``list.append(TOS1[-i], TOS)``. Used to implement list comprehensions. Implements::
item = STACK.pop()
list.append(STACK[-i], item)
Used to implement list comprehensions.
.. opcode:: MAP_ADD (i) .. opcode:: MAP_ADD (i)
Calls ``dict.__setitem__(TOS1[-i], TOS1, TOS)``. Used to implement dict Implements::
comprehensions.
value = STACK.pop()
key = STACK.pop()
dict.__setitem__(STACK[-i], key, value)
Used to implement dict comprehensions.
.. versionadded:: 3.1 .. versionadded:: 3.1
.. versionchanged:: 3.8 .. versionchanged:: 3.8
Map value is TOS and map key is TOS1. Before, those were reversed. Map value is ``STACK[-1]`` and map key is ``STACK[-2]``. Before, those
were reversed.
For all of the :opcode:`SET_ADD`, :opcode:`LIST_APPEND` and :opcode:`MAP_ADD` For all of the :opcode:`SET_ADD`, :opcode:`LIST_APPEND` and :opcode:`MAP_ADD`
instructions, while the added value or key/value pair is popped off, the instructions, while the added value or key/value pair is popped off, the
@ -641,12 +692,12 @@ iterations of the loop.
.. opcode:: RETURN_VALUE .. opcode:: RETURN_VALUE
Returns with TOS to the caller of the function. Returns with ``STACK[-1]`` to the caller of the function.
.. opcode:: YIELD_VALUE .. opcode:: YIELD_VALUE
Pops TOS and yields it from a :term:`generator`. Yields ``STACK.pop()`` from a :term:`generator`.
.. versionchanged:: 3.11 .. versionchanged:: 3.11
oparg set to be the stack depth, for efficient handling on frames. oparg set to be the stack depth, for efficient handling on frames.
@ -690,15 +741,16 @@ iterations of the loop.
.. opcode:: CHECK_EXC_MATCH .. opcode:: CHECK_EXC_MATCH
Performs exception matching for ``except``. Tests whether the TOS1 is an exception Performs exception matching for ``except``. Tests whether the ``STACK[-2]``
matching TOS. Pops TOS and pushes the boolean result of the test. is an exception matching ``STACK[-1]``. Pops STACK[-1] and pushes the boolean
result of the test.
.. versionadded:: 3.11 .. versionadded:: 3.11
.. opcode:: CHECK_EG_MATCH .. opcode:: CHECK_EG_MATCH
Performs exception matching for ``except*``. Applies ``split(TOS)`` on Performs exception matching for ``except*``. Applies ``split(STACK[-1])`` on
the exception group representing TOS1. the exception group representing ``STACK[-2]``.
In case of a match, pops two items from the stack and pushes the In case of a match, pops two items from the stack and pushes the
non-matching subgroup (``None`` in case of full match) followed by the non-matching subgroup (``None`` in case of full match) followed by the
@ -709,9 +761,9 @@ iterations of the loop.
.. opcode:: PREP_RERAISE_STAR .. opcode:: PREP_RERAISE_STAR
Combines the raised and reraised exceptions list from TOS, into an exception Combines the raised and reraised exceptions list from ``STACK[-1]``, into an
group to propagate from a try-except* block. Uses the original exception exception group to propagate from a try-except* block. Uses the original exception
group from TOS1 to reconstruct the structure of reraised exceptions. Pops group from ``STACK[-2]`` to reconstruct the structure of reraised exceptions. Pops
two items from the stack and pushes the exception to reraise or ``None`` two items from the stack and pushes the exception to reraise or ``None``
if there isn't one. if there isn't one.
@ -745,7 +797,7 @@ iterations of the loop.
to construct a class. to construct a class.
.. opcode:: BEFORE_WITH (delta) .. opcode:: BEFORE_WITH
This opcode performs several operations before a with block starts. First, This opcode performs several operations before a with block starts. First,
it loads :meth:`~object.__exit__` from the context manager and pushes it onto it loads :meth:`~object.__exit__` from the context manager and pushes it onto
@ -758,24 +810,24 @@ iterations of the loop.
.. opcode:: GET_LEN .. opcode:: GET_LEN
Push ``len(TOS)`` onto the stack. Perform ``STACK.append(len(STACK[-1]))``.
.. versionadded:: 3.10 .. versionadded:: 3.10
.. opcode:: MATCH_MAPPING .. opcode:: MATCH_MAPPING
If TOS is an instance of :class:`collections.abc.Mapping` (or, more technically: if If ``STACK[-1]`` is an instance of :class:`collections.abc.Mapping` (or, more
it has the :const:`Py_TPFLAGS_MAPPING` flag set in its technically: if it has the :const:`Py_TPFLAGS_MAPPING` flag set in its
:c:member:`~PyTypeObject.tp_flags`), push ``True`` onto the stack. Otherwise, push :c:member:`~PyTypeObject.tp_flags`), push ``True`` onto the stack. Otherwise,
``False``. push ``False``.
.. versionadded:: 3.10 .. versionadded:: 3.10
.. opcode:: MATCH_SEQUENCE .. opcode:: MATCH_SEQUENCE
If TOS is an instance of :class:`collections.abc.Sequence` and is *not* an instance If ``STACK[-1]`` is an instance of :class:`collections.abc.Sequence` and is *not* an instance
of :class:`str`/:class:`bytes`/:class:`bytearray` (or, more technically: if it has of :class:`str`/:class:`bytes`/:class:`bytearray` (or, more technically: if it has
the :const:`Py_TPFLAGS_SEQUENCE` flag set in its :c:member:`~PyTypeObject.tp_flags`), the :const:`Py_TPFLAGS_SEQUENCE` flag set in its :c:member:`~PyTypeObject.tp_flags`),
push ``True`` onto the stack. Otherwise, push ``False``. push ``True`` onto the stack. Otherwise, push ``False``.
@ -785,9 +837,9 @@ iterations of the loop.
.. opcode:: MATCH_KEYS .. opcode:: MATCH_KEYS
TOS is a tuple of mapping keys, and TOS1 is the match subject. If TOS1 ``STACK[-1]`` is a tuple of mapping keys, and ``STACK[-2]`` is the match subject.
contains all of the keys in TOS, push a :class:`tuple` containing the If ``STACK[-2]`` contains all of the keys in ``STACK[-1]``, push a :class:`tuple`
corresponding values. Otherwise, push ``None``. containing the corresponding values. Otherwise, push ``None``.
.. versionadded:: 3.10 .. versionadded:: 3.10
@ -798,7 +850,7 @@ iterations of the loop.
.. opcode:: STORE_NAME (namei) .. opcode:: STORE_NAME (namei)
Implements ``name = TOS``. *namei* is the index of *name* in the attribute Implements ``name = STACK.pop()``. *namei* is the index of *name* in the attribute
:attr:`co_names` of the code object. The compiler tries to use :attr:`co_names` of the code object. The compiler tries to use
:opcode:`STORE_FAST` or :opcode:`STORE_GLOBAL` if possible. :opcode:`STORE_FAST` or :opcode:`STORE_GLOBAL` if possible.
@ -811,31 +863,49 @@ iterations of the loop.
.. opcode:: UNPACK_SEQUENCE (count) .. opcode:: UNPACK_SEQUENCE (count)
Unpacks TOS into *count* individual values, which are put onto the stack Unpacks ``STACK[-1]`` into *count* individual values, which are put onto the stack
right-to-left. right-to-left.::
STACK.extend(STACK.pop()[:count:-1])
.. opcode:: UNPACK_EX (counts) .. opcode:: UNPACK_EX (counts)
Implements assignment with a starred target: Unpacks an iterable in TOS into Implements assignment with a starred target: Unpacks an iterable in ``STACK[-1]``
individual values, where the total number of values can be smaller than the into individual values, where the total number of values can be smaller than the
number of items in the iterable: one of the new values will be a list of all number of items in the iterable: one of the new values will be a list of all
leftover items. leftover items.
The low byte of *counts* is the number of values before the list value, the The number of values before and after the list value is limited to 255.
high byte of *counts* the number of values after it. The resulting values
are put onto the stack right-to-left. The number of values before the list value is encoded in the argument of the
opcode. The number of values after the list if any is encoded using an
``EXTENDED_ARG``. As a consequence, the argument can be seen as a two bytes values
where the low byte of *counts* is the number of values before the list value, the
high byte of *counts* the number of values after it.
The extracted values are put onto the stack right-to-left, i.e. ``a, *b, c = d``
will be stored after execution as ``STACK.extend((a, b, c))``.
.. opcode:: STORE_ATTR (namei) .. opcode:: STORE_ATTR (namei)
Implements ``TOS.name = TOS1``, where *namei* is the index of name in Implements::
:attr:`co_names`.
obj = STACK.pop()
value = STACK.pop()
obj.name = value
where *namei* is the index of name in :attr:`co_names`.
.. opcode:: DELETE_ATTR (namei) .. opcode:: DELETE_ATTR (namei)
Implements ``del TOS.name``, using *namei* as index into :attr:`co_names`. Implements::
obj = STACK.pop()
del obj.name
where *namei* is the index of name into :attr:`co_names`.
.. opcode:: STORE_GLOBAL (namei) .. opcode:: STORE_GLOBAL (namei)
@ -861,7 +931,11 @@ iterations of the loop.
.. opcode:: BUILD_TUPLE (count) .. opcode:: BUILD_TUPLE (count)
Creates a tuple consuming *count* items from the stack, and pushes the Creates a tuple consuming *count* items from the stack, and pushes the
resulting tuple onto the stack. resulting tuple onto the stack.::
assert count > 0
STACK, values = STACK[:-count], STACK[-count:]
STACK.append(tuple(values))
.. opcode:: BUILD_LIST (count) .. opcode:: BUILD_LIST (count)
@ -878,7 +952,7 @@ iterations of the loop.
Pushes a new dictionary object onto the stack. Pops ``2 * count`` items Pushes a new dictionary object onto the stack. Pops ``2 * count`` items
so that the dictionary holds *count* entries: so that the dictionary holds *count* entries:
``{..., TOS3: TOS2, TOS1: TOS}``. ``{..., STACK[-4]: STACK[-3], STACK[-2]: STACK[-1]}``.
.. versionchanged:: 3.5 .. versionchanged:: 3.5
The dictionary is created from stack items instead of creating an The dictionary is created from stack items instead of creating an
@ -889,7 +963,7 @@ iterations of the loop.
The version of :opcode:`BUILD_MAP` specialized for constant keys. Pops the The version of :opcode:`BUILD_MAP` specialized for constant keys. Pops the
top element on the stack which contains a tuple of keys, then starting from top element on the stack which contains a tuple of keys, then starting from
``TOS1``, pops *count* values to form values in the built dictionary. ``STACK[-2]``, pops *count* values to form values in the built dictionary.
.. versionadded:: 3.6 .. versionadded:: 3.6
@ -904,21 +978,36 @@ iterations of the loop.
.. opcode:: LIST_EXTEND (i) .. opcode:: LIST_EXTEND (i)
Calls ``list.extend(TOS1[-i], TOS)``. Used to build lists. Implements::
seq = STACK.pop()
list.extend(STACK[-i], seq)
Used to build lists.
.. versionadded:: 3.9 .. versionadded:: 3.9
.. opcode:: SET_UPDATE (i) .. opcode:: SET_UPDATE (i)
Calls ``set.update(TOS1[-i], TOS)``. Used to build sets. Implements::
seq = STACK.pop()
set.update(STACK[-i], seq)
Used to build sets.
.. versionadded:: 3.9 .. versionadded:: 3.9
.. opcode:: DICT_UPDATE (i) .. opcode:: DICT_UPDATE (i)
Calls ``dict.update(TOS1[-i], TOS)``. Used to build dicts. Implements::
map = STACK.pop()
dict.update(STACK[-i], map)
Used to build dicts.
.. versionadded:: 3.9 .. versionadded:: 3.9
@ -932,16 +1021,16 @@ iterations of the loop.
.. opcode:: LOAD_ATTR (namei) .. opcode:: LOAD_ATTR (namei)
If the low bit of ``namei`` is not set, this replaces TOS with If the low bit of ``namei`` is not set, this replaces ``STACK[-1]`` with
``getattr(TOS, co_names[namei>>1])``. ``getattr(STACK[-1], co_names[namei>>1])``.
If the low bit of ``namei`` is set, this will attempt to load a method named If the low bit of ``namei`` is set, this will attempt to load a method named
``co_names[namei>>1]`` from the TOS object. TOS is popped. ``co_names[namei>>1]`` from the ``STACK[-1]`` object. ``STACK[-1]`` is popped.
This bytecode distinguishes two cases: if TOS has a method with the correct This bytecode distinguishes two cases: if ``STACK[-1]`` has a method with the
name, the bytecode pushes the unbound method and TOS. TOS will be used as correct name, the bytecode pushes the unbound method and ``STACK[-1]``.
the first argument (``self``) by :opcode:`CALL` when calling the ``STACK[-1]`` will be used as the first argument (``self``) by :opcode:`CALL`
unbound method. Otherwise, ``NULL`` and the object return by the attribute when calling the unbound method. Otherwise, ``NULL`` and the object return by
lookup are pushed. the attribute lookup are pushed.
.. versionchanged:: 3.12 .. versionchanged:: 3.12
If the low bit of ``namei`` is set, then a ``NULL`` or ``self`` is If the low bit of ``namei`` is set, then a ``NULL`` or ``self`` is
@ -970,17 +1059,16 @@ iterations of the loop.
.. opcode:: IMPORT_NAME (namei) .. opcode:: IMPORT_NAME (namei)
Imports the module ``co_names[namei]``. TOS and TOS1 are popped and provide Imports the module ``co_names[namei]``. ``STACK[-1]`` and ``STACK[-2]`` are
the *fromlist* and *level* arguments of :func:`__import__`. The module popped and provide the *fromlist* and *level* arguments of :func:`__import__`.
object is pushed onto the stack. The current namespace is not affected: for The module object is pushed onto the stack. The current namespace is not affected: for a proper import statement, a subsequent :opcode:`STORE_FAST` instruction
a proper import statement, a subsequent :opcode:`STORE_FAST` instruction
modifies the namespace. modifies the namespace.
.. opcode:: IMPORT_FROM (namei) .. opcode:: IMPORT_FROM (namei)
Loads the attribute ``co_names[namei]`` from the module found in TOS. The Loads the attribute ``co_names[namei]`` from the module found in ``STACK[-1]``.
resulting object is pushed onto the stack, to be subsequently stored by a The resulting object is pushed onto the stack, to be subsequently stored by a
:opcode:`STORE_FAST` instruction. :opcode:`STORE_FAST` instruction.
@ -1005,7 +1093,8 @@ iterations of the loop.
.. opcode:: POP_JUMP_IF_TRUE (delta) .. opcode:: POP_JUMP_IF_TRUE (delta)
If TOS is true, increments the bytecode counter by *delta*. TOS is popped. If ``STACK[-1]`` is true, increments the bytecode counter by *delta*.
``STACK[-1]`` is popped.
.. versionchanged:: 3.11 .. versionchanged:: 3.11
The oparg is now a relative delta rather than an absolute target. The oparg is now a relative delta rather than an absolute target.
@ -1017,7 +1106,8 @@ iterations of the loop.
.. opcode:: POP_JUMP_IF_FALSE (delta) .. opcode:: POP_JUMP_IF_FALSE (delta)
If TOS is false, increments the bytecode counter by *delta*. TOS is popped. If ``STACK[-1]`` is false, increments the bytecode counter by *delta*.
``STACK[-1]`` is popped.
.. versionchanged:: 3.11 .. versionchanged:: 3.11
The oparg is now a relative delta rather than an absolute target. The oparg is now a relative delta rather than an absolute target.
@ -1029,7 +1119,11 @@ iterations of the loop.
.. opcode:: POP_JUMP_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. If ``STACK[-1]`` is not ``None``, increments the bytecode counter by *delta*.
``STACK[-1]`` is popped.
This opcode is a pseudo-instruction, replaced in final bytecode by
the directed versions (forward/backward).
.. versionadded:: 3.11 .. versionadded:: 3.11
@ -1039,7 +1133,11 @@ iterations of the loop.
.. opcode:: POP_JUMP_IF_NONE (delta) .. opcode:: POP_JUMP_IF_NONE (delta)
If TOS is ``None``, increments the bytecode counter by *delta*. TOS is popped. If ``STACK[-1]`` is ``None``, increments the bytecode counter by *delta*.
``STACK[-1]`` is popped.
This opcode is a pseudo-instruction, replaced in final bytecode by
the directed versions (forward/backward).
.. versionadded:: 3.11 .. versionadded:: 3.11
@ -1049,8 +1147,9 @@ iterations of the loop.
.. opcode:: JUMP_IF_TRUE_OR_POP (delta) .. opcode:: JUMP_IF_TRUE_OR_POP (delta)
If TOS is true, increments the bytecode counter by *delta* and leaves TOS on the If ``STACK[-1]`` is true, increments the bytecode counter by *delta* and leaves
stack. Otherwise (TOS is false), TOS is popped. ``STACK[-1]`` on the stack. Otherwise (``STACK[-1]`` is false), ``STACK[-1]``
is popped.
.. versionadded:: 3.1 .. versionadded:: 3.1
@ -1059,8 +1158,9 @@ iterations of the loop.
.. opcode:: JUMP_IF_FALSE_OR_POP (delta) .. opcode:: JUMP_IF_FALSE_OR_POP (delta)
If TOS is false, increments the bytecode counter by *delta* and leaves TOS on the If ``STACK[-1]`` is false, increments the bytecode counter by *delta* and leaves
stack. Otherwise (TOS is true), TOS is popped. ``STACK[-1]`` on the stack. Otherwise (``STACK[-1]`` is true), ``STACK[-1]`` is
popped.
.. versionadded:: 3.1 .. versionadded:: 3.1
@ -1070,10 +1170,10 @@ iterations of the loop.
.. opcode:: FOR_ITER (delta) .. opcode:: FOR_ITER (delta)
TOS is an :term:`iterator`. Call its :meth:`~iterator.__next__` method. If ``STACK[-1]`` is an :term:`iterator`. Call its :meth:`~iterator.__next__` method.
this yields a new value, push it on the stack (leaving the iterator below If this yields a new value, push it on the stack (leaving the iterator below
it). If the iterator indicates it is exhausted then the byte it). If the iterator indicates it is exhausted then the byte code counter is
code counter is incremented by *delta*. incremented by *delta*.
.. versionchanged:: 3.12 .. versionchanged:: 3.12
Up until 3.11 the iterator was popped when it was exhausted. Up until 3.11 the iterator was popped when it was exhausted.
@ -1104,7 +1204,7 @@ iterations of the loop.
.. opcode:: STORE_FAST (var_num) .. opcode:: STORE_FAST (var_num)
Stores TOS into the local ``co_varnames[var_num]``. Stores ``STACK.pop()`` into the local ``co_varnames[var_num]``.
.. opcode:: DELETE_FAST (var_num) .. opcode:: DELETE_FAST (var_num)
@ -1155,7 +1255,7 @@ iterations of the loop.
.. opcode:: STORE_DEREF (i) .. opcode:: STORE_DEREF (i)
Stores TOS into the cell contained in slot ``i`` of the "fast locals" Stores ``STACK.pop()`` into the cell contained in slot ``i`` of the "fast locals"
storage. storage.
.. versionchanged:: 3.11 .. versionchanged:: 3.11
@ -1188,9 +1288,9 @@ iterations of the loop.
depending on the value of *argc*: depending on the value of *argc*:
* 0: ``raise`` (re-raise previous exception) * 0: ``raise`` (re-raise previous exception)
* 1: ``raise TOS`` (raise exception instance or type at ``TOS``) * 1: ``raise STACK[-1]`` (raise exception instance or type at ``STACK[-1]``)
* 2: ``raise TOS1 from TOS`` (raise exception instance or type at ``TOS1`` * 2: ``raise STACK[-2] from STACK[-1]`` (raise exception instance or type at
with ``__cause__`` set to ``TOS``) ``STACK[-2]`` with ``__cause__`` set to ``STACK[-1]``)
.. opcode:: CALL (argc) .. opcode:: CALL (argc)
@ -1246,7 +1346,7 @@ iterations of the loop.
.. versionadded:: 3.11 .. versionadded:: 3.11
.. opcode:: KW_NAMES (i) .. opcode:: KW_NAMES (consti)
Prefixes :opcode:`CALL`. Prefixes :opcode:`CALL`.
Stores a reference to ``co_consts[consti]`` into an internal variable Stores a reference to ``co_consts[consti]`` into an internal variable
@ -1265,8 +1365,8 @@ iterations of the loop.
* ``0x02`` a dictionary of keyword-only parameters' default values * ``0x02`` a dictionary of keyword-only parameters' default values
* ``0x04`` a tuple of strings containing parameters' annotations * ``0x04`` a tuple of strings containing parameters' annotations
* ``0x08`` a tuple containing cells for free variables, making a closure * ``0x08`` a tuple containing cells for free variables, making a closure
* the code associated with the function (at TOS1) * the code associated with the function (at ``STACK[-2]``)
* the :term:`qualified name` of the function (at TOS) * the :term:`qualified name` of the function (at ``STACK[-1]``)
.. versionchanged:: 3.10 .. versionchanged:: 3.10
Flag value ``0x04`` is a tuple of strings instead of dictionary Flag value ``0x04`` is a tuple of strings instead of dictionary
@ -1275,9 +1375,20 @@ iterations of the loop.
.. index:: builtin: slice .. index:: builtin: slice
Pushes a slice object on the stack. *argc* must be 2 or 3. If it is 2, Pushes a slice object on the stack. *argc* must be 2 or 3. If it is 2, implements::
``slice(TOS1, TOS)`` is pushed; if it is 3, ``slice(TOS2, TOS1, TOS)`` is
pushed. See the :func:`slice` built-in function for more information. end = STACK.pop()
start = STACK.pop()
STACK.append(slice(start, stop))
if it is 3, implements::
step = STACK.pop()
end = STACK.pop()
start = STACK.pop()
STACK.append(slice(start, end, step))
See the :func:`slice` built-in function for more information.
.. opcode:: EXTENDED_ARG (ext) .. opcode:: EXTENDED_ARG (ext)
@ -1312,13 +1423,14 @@ iterations of the loop.
.. opcode:: MATCH_CLASS (count) .. opcode:: MATCH_CLASS (count)
TOS is a tuple of keyword attribute names, TOS1 is the class being matched ``STACK[-1]`` is a tuple of keyword attribute names, ``STACK[-2]`` is the class
against, and TOS2 is the match subject. *count* is the number of positional being matched against, and ``STACK[-3]`` is the match subject. *count* is the
sub-patterns. number of positional sub-patterns.
Pop TOS, TOS1, and TOS2. If TOS2 is an instance of TOS1 and has the Pop ``STACK[-1]``, ``STACK[-2]``, and ``STACK[-3]``. If ``STACK[-3]`` is an
positional and keyword attributes required by *count* and TOS, push a tuple instance of ``STACK[-2]`` and has the positional and keyword attributes
of extracted attributes. Otherwise, push ``None``. required by *count* and ``STACK[-1]``, push a tuple of extracted attributes.
Otherwise, push ``None``.
.. versionadded:: 3.10 .. versionadded:: 3.10
@ -1333,7 +1445,8 @@ iterations of the loop.
The ``where`` operand marks where the ``RESUME`` occurs: The ``where`` operand marks where the ``RESUME`` occurs:
* ``0`` The start of a function * ``0`` The start of a function, which is neither a generator, coroutine
nor an async generator
* ``1`` After a ``yield`` expression * ``1`` After a ``yield`` expression
* ``2`` After a ``yield from`` expression * ``2`` After a ``yield from`` expression
* ``3`` After an ``await`` expression * ``3`` After an ``await`` expression
@ -1344,6 +1457,7 @@ iterations of the loop.
.. opcode:: RETURN_GENERATOR .. opcode:: RETURN_GENERATOR
Create a generator, coroutine, or async generator from the current frame. Create a generator, coroutine, or async generator from the current frame.
Used as first opcode of in code object for the above mentioned callables.
Clear the current frame and return the newly created generator. Clear the current frame and return the newly created generator.
.. versionadded:: 3.11 .. versionadded:: 3.11
@ -1351,8 +1465,8 @@ iterations of the loop.
.. opcode:: SEND (delta) .. opcode:: SEND (delta)
Equivalent to ``TOS = TOS1.send(TOS)``. Used in ``yield from`` and ``await`` Equivalent to ``STACK[-1] = STACK[-2].send(STACK[-1])``. Used in ``yield from``
statements. and ``await`` statements.
If the call raises :exc:`StopIteration`, pop both items, push the If the call raises :exc:`StopIteration`, pop both items, push the
exception's ``value`` attribute, and increment the bytecode counter by exception's ``value`` attribute, and increment the bytecode counter by
@ -1382,9 +1496,8 @@ iterations of the loop.
.. opcode:: CALL_INTRINSIC_1 .. opcode:: CALL_INTRINSIC_1
Calls an intrinsic function with one argument. Passes the TOS as the argument Calls an intrinsic function with one argument. Passes ``STACK[-1]`` as the
and sets TOS to the result. Used to implement functionality that is necessary argument and sets ``STACK[-1]`` to the result. Used to implement functionality that is necessary but not performance critical.
but not performance critical.
The operand determines which intrinsic function is called: The operand determines which intrinsic function is called: