bpo-43683: Streamline YIELD_VALUE and SEND (GH-30723)

* Split YIELD_VALUE into ASYNC_GEN_WRAP; YIELD_VALUE for async generators.

* Split SEND into SEND; YIELD_VALUE.

* Document new opcodes.
This commit is contained in:
Mark Shannon 2022-01-24 11:08:53 +00:00 committed by GitHub
parent d75a51bea3
commit 0367a36fdc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 72 additions and 43 deletions

View file

@ -2650,32 +2650,25 @@ handle_eval_breaker:
}
assert (gen_status == PYGEN_NEXT);
assert (retval != NULL);
frame->f_state = FRAME_SUSPENDED;
_PyFrame_SetStackPointer(frame, stack_pointer);
TRACE_FUNCTION_EXIT();
DTRACE_FUNCTION_EXIT();
_Py_LeaveRecursiveCall(tstate);
/* Restore previous cframe and return. */
tstate->cframe = cframe.previous;
tstate->cframe->use_tracing = cframe.use_tracing;
assert(tstate->cframe->current_frame == frame->previous);
assert(!_PyErr_Occurred(tstate));
return retval;
PUSH(retval);
DISPATCH();
}
TARGET(ASYNC_GEN_WRAP) {
PyObject *v = TOP();
assert(frame->f_code->co_flags & CO_ASYNC_GENERATOR);
PyObject *w = _PyAsyncGenValueWrapperNew(v);
if (w == NULL) {
goto error;
}
SET_TOP(w);
Py_DECREF(v);
DISPATCH();
}
TARGET(YIELD_VALUE) {
assert(frame->is_entry);
PyObject *retval = POP();
if (frame->f_code->co_flags & CO_ASYNC_GENERATOR) {
PyObject *w = _PyAsyncGenValueWrapperNew(retval);
Py_DECREF(retval);
if (w == NULL) {
retval = NULL;
goto error;
}
retval = w;
}
frame->f_state = FRAME_SUSPENDED;
_PyFrame_SetStackPointer(frame, stack_pointer);
TRACE_FUNCTION_EXIT();

View file

@ -910,6 +910,7 @@ stack_effect(int opcode, int oparg, int jump)
return -1;
case SETUP_ANNOTATIONS:
return 0;
case ASYNC_GEN_WRAP:
case YIELD_VALUE:
return 0;
case POP_BLOCK:
@ -1541,6 +1542,9 @@ compiler_addop_j_noline(struct compiler *c, int opcode, basicblock *b)
#define POP_EXCEPT_AND_RERAISE(C) \
RETURN_IF_FALSE(compiler_pop_except_and_reraise((C)))
#define ADDOP_YIELD(C) \
RETURN_IF_FALSE(addop_yield(C))
#define VISIT(C, TYPE, V) {\
if (!compiler_visit_ ## TYPE((C), (V))) \
return 0; \
@ -1844,6 +1848,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, RESUME, await ? 3 : 2);
ADDOP_JUMP(c, JUMP_NO_INTERRUPT, start);
compiler_use_next_block(c, exit);
@ -4094,6 +4099,17 @@ addop_binary(struct compiler *c, operator_ty binop, bool inplace)
return 1;
}
static int
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, RESUME, 1);
return 1;
}
static int
compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
{
@ -5144,8 +5160,7 @@ compiler_sync_comprehension_generator(struct compiler *c,
switch (type) {
case COMP_GENEXP:
VISIT(c, expr, elt);
ADDOP(c, YIELD_VALUE);
ADDOP_I(c, RESUME, 1);
ADDOP_YIELD(c);
ADDOP(c, POP_TOP);
break;
case COMP_LISTCOMP:
@ -5243,8 +5258,7 @@ compiler_async_comprehension_generator(struct compiler *c,
switch (type) {
case COMP_GENEXP:
VISIT(c, expr, elt);
ADDOP(c, YIELD_VALUE);
ADDOP_I(c, RESUME, 1);
ADDOP_YIELD(c);
ADDOP(c, POP_TOP);
break;
case COMP_LISTCOMP:
@ -5714,8 +5728,7 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
else {
ADDOP_LOAD_CONST(c, Py_None);
}
ADDOP(c, YIELD_VALUE);
ADDOP_I(c, RESUME, 1);
ADDOP_YIELD(c);
break;
case YieldFrom_kind:
if (c->u->u_ste->ste_type != FunctionBlock)

View file

@ -86,7 +86,7 @@ static void *opcode_targets[256] = {
&&TARGET_IMPORT_STAR,
&&TARGET_SETUP_ANNOTATIONS,
&&TARGET_YIELD_VALUE,
&&TARGET_STORE_ATTR_WITH_HINT,
&&TARGET_ASYNC_GEN_WRAP,
&&TARGET_PREP_RERAISE_STAR,
&&TARGET_POP_EXCEPT,
&&TARGET_STORE_NAME,
@ -130,7 +130,7 @@ static void *opcode_targets[256] = {
&&TARGET_POP_JUMP_IF_NOT_NONE,
&&TARGET_POP_JUMP_IF_NONE,
&&TARGET_RAISE_VARARGS,
&&TARGET_LOAD_FAST__LOAD_FAST,
&&TARGET_STORE_ATTR_WITH_HINT,
&&TARGET_MAKE_FUNCTION,
&&TARGET_BUILD_SLICE,
&&TARGET_JUMP_NO_INTERRUPT,
@ -139,20 +139,20 @@ static void *opcode_targets[256] = {
&&TARGET_LOAD_DEREF,
&&TARGET_STORE_DEREF,
&&TARGET_DELETE_DEREF,
&&TARGET_LOAD_FAST__LOAD_FAST,
&&TARGET_STORE_FAST__LOAD_FAST,
&&TARGET_LOAD_FAST__LOAD_CONST,
&&TARGET_CALL_FUNCTION_EX,
&&TARGET_LOAD_CONST__LOAD_FAST,
&&TARGET_LOAD_FAST__LOAD_CONST,
&&TARGET_EXTENDED_ARG,
&&TARGET_LIST_APPEND,
&&TARGET_SET_ADD,
&&TARGET_MAP_ADD,
&&TARGET_LOAD_CLASSDEREF,
&&TARGET_COPY_FREE_VARS,
&&TARGET_STORE_FAST__STORE_FAST,
&&TARGET_LOAD_CONST__LOAD_FAST,
&&TARGET_RESUME,
&&TARGET_MATCH_CLASS,
&&_unknown_opcode,
&&TARGET_STORE_FAST__STORE_FAST,
&&_unknown_opcode,
&&TARGET_FORMAT_VALUE,
&&TARGET_BUILD_CONST_KEY_MAP,