Mailing List Archive

GH-89914: Make the oparg of the YIELD_VALUE instruction equal the stack depth. (GH-92960)
https://github.com/python/cpython/commit/3fd86100022103f41ada043f5bb5a7201e80ac27
commit: 3fd86100022103f41ada043f5bb5a7201e80ac27
branch: main
author: Mark Shannon <mark@hotpy.org>
committer: markshannon <mark@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,

_______________________________________________
Python-checkins mailing list
Python-checkins@python.org
https://mail.python.org/mailman/listinfo/python-checkins