From 34250f3b10e04fb23e6c476bab19ed0cdc2a75d4 Mon Sep 17 00:00:00 2001 From: MatthieuDartiailh Date: Mon, 4 Sep 2023 16:16:53 +0200 Subject: [PATCH 1/8] doc: describe how CACHE opcodes are taken into account in jumps --- Doc/library/dis.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 6cd5f181c8433a..13008900a07594 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -42,6 +42,16 @@ interpreter. bytecode to specialize it for different runtime conditions. The adaptive bytecode can be shown by passing ``adaptive=True``. + .. versionchanged:: 3.12 + For instruction leading to a jump, a jump by 0 instruction should always + lead to jumping to the instruction directly following the origin instruction. + Starting with 3.12, some instructions leading to a jump can be followed + by a :opcode:`CACHE` instruction in which case a jump with an argument of + 0 will jump to the first non-``CACHE`` instruction following the origin + instruction. + As a consequence, the presence of the :opcode:`CACHE` instructions is + transparent for forward jumps but need to be taken into account when + reasoning about backward jumps. Example: Given the function :func:`!myfunc`:: From e7d90219b38707badb9f87079b2d58187fef98cc Mon Sep 17 00:00:00 2001 From: MatthieuDartiailh Date: Mon, 4 Sep 2023 16:26:03 +0200 Subject: [PATCH 2/8] doc: document MIN_INSTRUMENTED_OPCODE in dis --- Doc/library/dis.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 13008900a07594..48e62c6aae3b7c 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -1784,8 +1784,9 @@ These collections are provided for automatic introspection of bytecode instructions: .. versionchanged:: 3.12 - The collections now contain pseudo instructions as well. These are - opcodes with values ``>= MIN_PSEUDO_OPCODE``. + The collections now contain pseudo instructions and instrumented + instructions as well. These are opcodes with values ``>= MIN_PSEUDO_OPCODE`` + and ``>= MIN_INSTRUMENTED_OPCODE``. .. data:: opname From 0586fecbdbc4ad0eacd79225b6f861c7a08620b1 Mon Sep 17 00:00:00 2001 From: MatthieuDartiailh Date: Mon, 4 Sep 2023 16:42:44 +0200 Subject: [PATCH 3/8] doc: document END_SEND and fix SEND documentation --- Doc/library/dis.rst | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 48e62c6aae3b7c..fcc1863c9d5112 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -497,6 +497,15 @@ operations on it as if it was a Python list. The top of the stack corresponds to .. versionadded:: 3.12 +.. opcode:: END_SEND + + Removes the top value from the stack. + Equivalent to ``POP_TOP``. + Used to clean up when a generator exit, hence the name. + + .. versionadded:: 3.12 + + .. opcode:: COPY (i) Push the i-th item to the top of the stack without removing it from its original @@ -1608,9 +1617,9 @@ iterations of the loop. Equivalent to ``STACK[-1] = STACK[-2].send(STACK[-1])``. Used in ``yield from`` and ``await`` statements. - If the call raises :exc:`StopIteration`, pop both items, push the - exception's ``value`` attribute, and increment the bytecode counter by - *delta*. + If the call raises :exc:`StopIteration`, pop the top value from the stack, + push the exception's ``value`` attribute, and increment the bytecode counter + by *delta*. .. versionadded:: 3.11 From 761745675ab7744da353605455bffc5cd606e567 Mon Sep 17 00:00:00 2001 From: MatthieuDartiailh Date: Tue, 5 Sep 2023 09:40:18 +0200 Subject: [PATCH 4/8] Doc: clarify CALL_INSTRINSIC_2 stack effect --- Doc/library/dis.rst | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index fcc1863c9d5112..798c7d361fc574 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -1695,9 +1695,13 @@ iterations of the loop. .. opcode:: CALL_INTRINSIC_2 - Calls an intrinsic function with two arguments. Passes ``STACK[-2]``, ``STACK[-1]`` as the - arguments and sets ``STACK[-1]`` to the result. Used to implement functionality that is - necessary but not performance critical. + Calls an intrinsic function with two arguments. Used to implement functionality + that is necessary but not performance critical:: + + arg2 = STACK.pop() + arg1 = STACK.pop() + result = intrinsic2(arg1, arg2) + STACK.push(result) The operand determines which intrinsic function is called: From 6ad38e3cdc4c591c5e9c2c669777315bdc88d77d Mon Sep 17 00:00:00 2001 From: MatthieuDartiailh Date: Tue, 5 Sep 2023 09:57:29 +0200 Subject: [PATCH 5/8] doc: clarify the stack manipulation of LOAD_SUPER_ATTR --- Doc/library/dis.rst | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 798c7d361fc574..3f38b63b9ff2f6 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -1151,15 +1151,21 @@ iterations of the loop. .. opcode:: LOAD_SUPER_ATTR (namei) - This opcode implements :func:`super` (e.g. ``super().method()`` and - ``super().attr``). It works the same as :opcode:`LOAD_ATTR`, except that - ``namei`` is shifted left by 2 bits instead of 1, and instead of expecting a - single receiver on the stack, it expects three objects (from top of stack - down): ``self`` (the first argument to the current method), ``cls`` (the - class within which the current method was defined), and the global ``super``. + This opcode implements :func:`super` both in its 0 argument form and in its + 2 arguments form (e.g. ``super().method()``, ``super().attr`` and + ``super(cls, self).method()``, ``super(cls, self).attr``). + + It pops three values from the stack (from top of stack down): + - ``self``: the first argument to the current method + - ``cls``: the class within which the current method was defined) + - the global ``super`` + + With respect to its argument, it works similarly to :opcode:`LOAD_ATTR`, + except that ``namei`` is shifted left by 2 bits instead of 1. The low bit of ``namei`` signals to attempt a method load, as with - :opcode:`LOAD_ATTR`. + :opcode:`LOAD_ATTR` which results in pushing ``None`` and the loaded method. + When it is unset a single value is pushed to the stack. The second-low bit of ``namei``, if set, means that this was a two-argument call to :func:`super` (unset means zero-argument). From 364420046e6bc79585db918409f24fc98cf1d6c5 Mon Sep 17 00:00:00 2001 From: Matthieu Dartiailh Date: Mon, 25 Sep 2023 19:18:41 +0200 Subject: [PATCH 6/8] Apply suggestions from code review Co-authored-by: Carl Meyer --- Doc/library/dis.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 3f38b63b9ff2f6..5825fcdf7cd4d6 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -501,7 +501,7 @@ operations on it as if it was a Python list. The top of the stack corresponds to Removes the top value from the stack. Equivalent to ``POP_TOP``. - Used to clean up when a generator exit, hence the name. + Used to clean up when a generator exits. .. versionadded:: 3.12 @@ -1151,20 +1151,20 @@ iterations of the loop. .. opcode:: LOAD_SUPER_ATTR (namei) - This opcode implements :func:`super` both in its 0 argument form and in its - 2 arguments form (e.g. ``super().method()``, ``super().attr`` and + This opcode implements :func:`super`, both in its zero-argument and + two-argument forms (e.g. ``super().method()``, ``super().attr`` and ``super(cls, self).method()``, ``super(cls, self).attr``). It pops three values from the stack (from top of stack down): - ``self``: the first argument to the current method - - ``cls``: the class within which the current method was defined) + - ``cls``: the class within which the current method was defined - the global ``super`` With respect to its argument, it works similarly to :opcode:`LOAD_ATTR`, except that ``namei`` is shifted left by 2 bits instead of 1. The low bit of ``namei`` signals to attempt a method load, as with - :opcode:`LOAD_ATTR` which results in pushing ``None`` and the loaded method. + :opcode:`LOAD_ATTR`, which results in pushing ``None`` and the loaded method. When it is unset a single value is pushed to the stack. The second-low bit of ``namei``, if set, means that this was a two-argument From 0a1dee27634989b3ad756d4db66071716c7cc00f Mon Sep 17 00:00:00 2001 From: Matthieu Dartiailh Date: Thu, 28 Sep 2023 09:41:40 +0200 Subject: [PATCH 7/8] Update dis.rst --- Doc/library/dis.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 5825fcdf7cd4d6..d7dd78e26c4c5e 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -499,8 +499,7 @@ operations on it as if it was a Python list. The top of the stack corresponds to .. opcode:: END_SEND - Removes the top value from the stack. - Equivalent to ``POP_TOP``. + Implements ``del STACK[-2]``. Used to clean up when a generator exits. .. versionadded:: 3.12 From 5a93f492971cfa3a81d40122db56d913d504578f Mon Sep 17 00:00:00 2001 From: MatthieuDartiailh Date: Tue, 17 Oct 2023 13:42:24 +0200 Subject: [PATCH 8/8] docs: address review comments --- Doc/library/dis.rst | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index d7dd78e26c4c5e..22818a61fcaedb 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -43,14 +43,12 @@ interpreter. adaptive bytecode can be shown by passing ``adaptive=True``. .. versionchanged:: 3.12 - For instruction leading to a jump, a jump by 0 instruction should always - lead to jumping to the instruction directly following the origin instruction. - Starting with 3.12, some instructions leading to a jump can be followed - by a :opcode:`CACHE` instruction in which case a jump with an argument of - 0 will jump to the first non-``CACHE`` instruction following the origin - instruction. + The argument of a jump is the offset of the target instruction relative + to the instruction that appears immediately after the jump instruction's + :opcode:`CACHE` entries. + As a consequence, the presence of the :opcode:`CACHE` instructions is - transparent for forward jumps but need to be taken into account when + transparent for forward jumps but needs to be taken into account when reasoning about backward jumps. Example: Given the function :func:`!myfunc`:: @@ -1652,7 +1650,7 @@ iterations of the loop. Calls an intrinsic function with one argument. Passes ``STACK[-1]`` as the argument and sets ``STACK[-1]`` to the result. Used to implement - functionality that is necessary but not performance critical. + functionality that is not performance critical. The operand determines which intrinsic function is called: @@ -1701,7 +1699,7 @@ iterations of the loop. .. opcode:: CALL_INTRINSIC_2 Calls an intrinsic function with two arguments. Used to implement functionality - that is necessary but not performance critical:: + that is not performance critical:: arg2 = STACK.pop() arg1 = STACK.pop()