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

This commit is contained in:
Mark Shannon 2022-05-19 17:49:29 +01:00 committed by GitHub
parent 70aa1b9b91
commit 3fd8610002
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 35 additions and 26 deletions

View File

@ -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

View File

@ -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",

14
Include/opcode.h generated
View File

@ -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

View File

@ -405,6 +405,7 @@ _code_type = type(_write_atomic.__code__)
# 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 @@ _code_type = type(_write_atomic.__code__)
# 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

View File

@ -98,7 +98,7 @@ def_op('LIST_TO_TUPLE', 82)
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_op('MAP_ADD', 147)
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)

View File

@ -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.

View File

@ -2698,6 +2698,7 @@ handle_eval_breaker:
}
TARGET(YIELD_VALUE) {
assert(oparg == STACK_LEVEL());
assert(frame->is_entry);
PyObject *retval = POP();
_PyFrame_GetGenerator(frame)->gi_frame_state = FRAME_SUSPENDED;

View File

@ -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);

View File

@ -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,