[Python-checkins] GH-89914: Make the oparg of the YIELD_VALUE instruction equal the stack depth. (GH-92960)

markshannon webhook-mailer at python.org
Thu May 19 12:50:03 EDT 2022


https://github.com/python/cpython/commit/3fd86100022103f41ada043f5bb5a7201e80ac27
commit: 3fd86100022103f41ada043f5bb5a7201e80ac27
branch: main
author: Mark Shannon <mark at hotpy.org>
committer: markshannon <mark at hotpy.org>
date: 2022-05-19T17:49:29+01:00
summary:

GH-89914: Make the oparg of the YIELD_VALUE instruction equal the stack depth. (GH-92960)

files:
A Misc/NEWS.d/next/Core and Builtins/2022-05-19-15-29-53.gh-issue-89914.8bAffH.rst
M Doc/library/dis.rst
M Include/internal/pycore_opcode.h
M Include/opcode.h
M Lib/importlib/_bootstrap_external.py
M Lib/opcode.py
M Python/ceval.c
M Python/compile.c
M Python/opcode_targets.h

diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst
index 027db0153bea4..8bc3721109b1e 100644
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -575,6 +575,8 @@ iterations of the loop.
 
    Pops TOS and yields it from a :term:`generator`.
 
+    .. versionchanged:: 3.11
+       oparg set to be the stack depth, for efficient handling on frames.
 
 .. opcode:: YIELD_FROM
 
diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h
index 17a68f030b084..79926b62a365f 100644
--- a/Include/internal/pycore_opcode.h
+++ b/Include/internal/pycore_opcode.h
@@ -504,7 +504,7 @@ static const char *const _PyOpcode_OpName[256] = {
     [RETURN_VALUE] = "RETURN_VALUE",
     [IMPORT_STAR] = "IMPORT_STAR",
     [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS",
-    [YIELD_VALUE] = "YIELD_VALUE",
+    [LOAD_METHOD_NO_DICT] = "LOAD_METHOD_NO_DICT",
     [ASYNC_GEN_WRAP] = "ASYNC_GEN_WRAP",
     [PREP_RERAISE_STAR] = "PREP_RERAISE_STAR",
     [POP_EXCEPT] = "POP_EXCEPT",
@@ -531,7 +531,7 @@ static const char *const _PyOpcode_OpName[256] = {
     [JUMP_FORWARD] = "JUMP_FORWARD",
     [JUMP_IF_FALSE_OR_POP] = "JUMP_IF_FALSE_OR_POP",
     [JUMP_IF_TRUE_OR_POP] = "JUMP_IF_TRUE_OR_POP",
-    [LOAD_METHOD_NO_DICT] = "LOAD_METHOD_NO_DICT",
+    [LOAD_METHOD_WITH_DICT] = "LOAD_METHOD_WITH_DICT",
     [POP_JUMP_FORWARD_IF_FALSE] = "POP_JUMP_FORWARD_IF_FALSE",
     [POP_JUMP_FORWARD_IF_TRUE] = "POP_JUMP_FORWARD_IF_TRUE",
     [LOAD_GLOBAL] = "LOAD_GLOBAL",
@@ -539,13 +539,13 @@ static const char *const _PyOpcode_OpName[256] = {
     [CONTAINS_OP] = "CONTAINS_OP",
     [RERAISE] = "RERAISE",
     [COPY] = "COPY",
-    [LOAD_METHOD_WITH_DICT] = "LOAD_METHOD_WITH_DICT",
+    [LOAD_METHOD_WITH_VALUES] = "LOAD_METHOD_WITH_VALUES",
     [BINARY_OP] = "BINARY_OP",
     [SEND] = "SEND",
     [LOAD_FAST] = "LOAD_FAST",
     [STORE_FAST] = "STORE_FAST",
     [DELETE_FAST] = "DELETE_FAST",
-    [LOAD_METHOD_WITH_VALUES] = "LOAD_METHOD_WITH_VALUES",
+    [RESUME_QUICK] = "RESUME_QUICK",
     [POP_JUMP_FORWARD_IF_NOT_NONE] = "POP_JUMP_FORWARD_IF_NOT_NONE",
     [POP_JUMP_FORWARD_IF_NONE] = "POP_JUMP_FORWARD_IF_NONE",
     [RAISE_VARARGS] = "RAISE_VARARGS",
@@ -559,16 +559,16 @@ static const char *const _PyOpcode_OpName[256] = {
     [STORE_DEREF] = "STORE_DEREF",
     [DELETE_DEREF] = "DELETE_DEREF",
     [JUMP_BACKWARD] = "JUMP_BACKWARD",
-    [RESUME_QUICK] = "RESUME_QUICK",
-    [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX",
     [STORE_ATTR_ADAPTIVE] = "STORE_ATTR_ADAPTIVE",
+    [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX",
+    [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE",
     [EXTENDED_ARG] = "EXTENDED_ARG",
     [LIST_APPEND] = "LIST_APPEND",
     [SET_ADD] = "SET_ADD",
     [MAP_ADD] = "MAP_ADD",
     [LOAD_CLASSDEREF] = "LOAD_CLASSDEREF",
     [COPY_FREE_VARS] = "COPY_FREE_VARS",
-    [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE",
+    [YIELD_VALUE] = "YIELD_VALUE",
     [RESUME] = "RESUME",
     [MATCH_CLASS] = "MATCH_CLASS",
     [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT",
diff --git a/Include/opcode.h b/Include/opcode.h
index 9a076e01c6530..e04b5a6bfa7d4 100644
--- a/Include/opcode.h
+++ b/Include/opcode.h
@@ -42,7 +42,6 @@ extern "C" {
 #define RETURN_VALUE                            83
 #define IMPORT_STAR                             84
 #define SETUP_ANNOTATIONS                       85
-#define YIELD_VALUE                             86
 #define ASYNC_GEN_WRAP                          87
 #define PREP_RERAISE_STAR                       88
 #define POP_EXCEPT                              89
@@ -102,6 +101,7 @@ extern "C" {
 #define MAP_ADD                                147
 #define LOAD_CLASSDEREF                        148
 #define COPY_FREE_VARS                         149
+#define YIELD_VALUE                            150
 #define RESUME                                 151
 #define MATCH_CLASS                            152
 #define FORMAT_VALUE                           155
@@ -170,12 +170,12 @@ extern "C" {
 #define LOAD_METHOD_ADAPTIVE                    79
 #define LOAD_METHOD_CLASS                       80
 #define LOAD_METHOD_MODULE                      81
-#define LOAD_METHOD_NO_DICT                    113
-#define LOAD_METHOD_WITH_DICT                  121
-#define LOAD_METHOD_WITH_VALUES                127
-#define RESUME_QUICK                           141
-#define STORE_ATTR_ADAPTIVE                    143
-#define STORE_ATTR_INSTANCE_VALUE              150
+#define LOAD_METHOD_NO_DICT                     86
+#define LOAD_METHOD_WITH_DICT                  113
+#define LOAD_METHOD_WITH_VALUES                121
+#define RESUME_QUICK                           127
+#define STORE_ATTR_ADAPTIVE                    141
+#define STORE_ATTR_INSTANCE_VALUE              143
 #define STORE_ATTR_SLOT                        153
 #define STORE_ATTR_WITH_HINT                   154
 #define STORE_FAST__LOAD_FAST                  158
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
index e7941aeae059d..eac371fdefc78 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -405,6 +405,7 @@ def _write_atomic(path, data, mode=0o666):
 #     Python 3.11a7 3494 (New location info table)
 
 #     Python 3.12a1 3500 (Remove PRECALL opcode)
+#     Python 3.12a1 3501 (YIELD_VALUE oparg == stack_depth)
 
 #     Python 3.13 will start with 3550
 
@@ -418,7 +419,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 = (3500).to_bytes(2, 'little') + b'\r\n'
+MAGIC_NUMBER = (3501).to_bytes(2, 'little') + b'\r\n'
 
 _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little')  # For import.c
 
diff --git a/Lib/opcode.py b/Lib/opcode.py
index 27e9ab17969ba..410853a25cfec 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -98,7 +98,7 @@ def jabs_op(name, op):
 def_op('RETURN_VALUE', 83)
 def_op('IMPORT_STAR', 84)
 def_op('SETUP_ANNOTATIONS', 85)
-def_op('YIELD_VALUE', 86)
+
 def_op('ASYNC_GEN_WRAP', 87)
 def_op('PREP_RERAISE_STAR', 88)
 def_op('POP_EXCEPT', 89)
@@ -174,7 +174,7 @@ def jabs_op(name, op):
 def_op('LOAD_CLASSDEREF', 148)
 hasfree.append(148)
 def_op('COPY_FREE_VARS', 149)
-
+def_op('YIELD_VALUE', 150)
 def_op('RESUME', 151)
 def_op('MATCH_CLASS', 152)
 
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-19-15-29-53.gh-issue-89914.8bAffH.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-19-15-29-53.gh-issue-89914.8bAffH.rst
new file mode 100644
index 0000000000000..d2156f8bbf3d2
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-05-19-15-29-53.gh-issue-89914.8bAffH.rst	
@@ -0,0 +1,2 @@
+The operand of the ``YIELD_VALUE`` instruction is set to the stack depth.
+This is done to help frame handling on ``yield`` and may assist debuggers.
diff --git a/Python/ceval.c b/Python/ceval.c
index deb131813eb11..230198b41f6a5 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -2698,6 +2698,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
         }
 
         TARGET(YIELD_VALUE) {
+            assert(oparg == STACK_LEVEL());
             assert(frame->is_entry);
             PyObject *retval = POP();
             _PyFrame_GetGenerator(frame)->gi_frame_state = FRAME_SUSPENDED;
diff --git a/Python/compile.c b/Python/compile.c
index c42deb54ba3de..c862c10a83e53 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -1962,7 +1962,7 @@ compiler_add_yield_from(struct compiler *c, int await)
     compiler_use_next_block(c, start);
     ADDOP_JUMP(c, SEND, exit);
     compiler_use_next_block(c, resume);
-    ADDOP(c, YIELD_VALUE);
+    ADDOP_I(c, YIELD_VALUE, 0);
     ADDOP_I(c, RESUME, await ? 3 : 2);
     ADDOP_JUMP(c, JUMP_NO_INTERRUPT, start);
     compiler_use_next_block(c, exit);
@@ -4193,7 +4193,7 @@ addop_yield(struct compiler *c) {
     if (c->u->u_ste->ste_generator && c->u->u_ste->ste_coroutine) {
         ADDOP(c, ASYNC_GEN_WRAP);
     }
-    ADDOP(c, YIELD_VALUE);
+    ADDOP_I(c, YIELD_VALUE, 0);
     ADDOP_I(c, RESUME, 1);
     return 1;
 }
@@ -7152,6 +7152,9 @@ stackdepth(struct compiler *c, basicblock *entry)
                 next = NULL;
                 break;
             }
+            if (instr->i_opcode == YIELD_VALUE) {
+                instr->i_oparg = depth;
+            }
         }
         if (next != NULL) {
             assert(b->b_nofallthrough == 0);
diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h
index 3a6768bd228bd..0d8faf223112b 100644
--- a/Python/opcode_targets.h
+++ b/Python/opcode_targets.h
@@ -85,7 +85,7 @@ static void *opcode_targets[256] = {
     &&TARGET_RETURN_VALUE,
     &&TARGET_IMPORT_STAR,
     &&TARGET_SETUP_ANNOTATIONS,
-    &&TARGET_YIELD_VALUE,
+    &&TARGET_LOAD_METHOD_NO_DICT,
     &&TARGET_ASYNC_GEN_WRAP,
     &&TARGET_PREP_RERAISE_STAR,
     &&TARGET_POP_EXCEPT,
@@ -112,7 +112,7 @@ static void *opcode_targets[256] = {
     &&TARGET_JUMP_FORWARD,
     &&TARGET_JUMP_IF_FALSE_OR_POP,
     &&TARGET_JUMP_IF_TRUE_OR_POP,
-    &&TARGET_LOAD_METHOD_NO_DICT,
+    &&TARGET_LOAD_METHOD_WITH_DICT,
     &&TARGET_POP_JUMP_FORWARD_IF_FALSE,
     &&TARGET_POP_JUMP_FORWARD_IF_TRUE,
     &&TARGET_LOAD_GLOBAL,
@@ -120,13 +120,13 @@ static void *opcode_targets[256] = {
     &&TARGET_CONTAINS_OP,
     &&TARGET_RERAISE,
     &&TARGET_COPY,
-    &&TARGET_LOAD_METHOD_WITH_DICT,
+    &&TARGET_LOAD_METHOD_WITH_VALUES,
     &&TARGET_BINARY_OP,
     &&TARGET_SEND,
     &&TARGET_LOAD_FAST,
     &&TARGET_STORE_FAST,
     &&TARGET_DELETE_FAST,
-    &&TARGET_LOAD_METHOD_WITH_VALUES,
+    &&TARGET_RESUME_QUICK,
     &&TARGET_POP_JUMP_FORWARD_IF_NOT_NONE,
     &&TARGET_POP_JUMP_FORWARD_IF_NONE,
     &&TARGET_RAISE_VARARGS,
@@ -140,16 +140,16 @@ static void *opcode_targets[256] = {
     &&TARGET_STORE_DEREF,
     &&TARGET_DELETE_DEREF,
     &&TARGET_JUMP_BACKWARD,
-    &&TARGET_RESUME_QUICK,
-    &&TARGET_CALL_FUNCTION_EX,
     &&TARGET_STORE_ATTR_ADAPTIVE,
+    &&TARGET_CALL_FUNCTION_EX,
+    &&TARGET_STORE_ATTR_INSTANCE_VALUE,
     &&TARGET_EXTENDED_ARG,
     &&TARGET_LIST_APPEND,
     &&TARGET_SET_ADD,
     &&TARGET_MAP_ADD,
     &&TARGET_LOAD_CLASSDEREF,
     &&TARGET_COPY_FREE_VARS,
-    &&TARGET_STORE_ATTR_INSTANCE_VALUE,
+    &&TARGET_YIELD_VALUE,
     &&TARGET_RESUME,
     &&TARGET_MATCH_CLASS,
     &&TARGET_STORE_ATTR_SLOT,



More information about the Python-checkins mailing list