mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
bpo-43683: Handle generator entry in bytecode (GH-25138)
* Handle check for sending None to starting generator and coroutine into bytecode. * Document new bytecode and make it fail gracefully if mis-compiled.
This commit is contained in:
parent
489c36920e
commit
b37181e692
10 changed files with 2680 additions and 2612 deletions
|
@ -1140,6 +1140,8 @@ stack_effect(int opcode, int oparg, int jump)
|
|||
return 1;
|
||||
case LIST_TO_TUPLE:
|
||||
return 0;
|
||||
case GEN_START:
|
||||
return -1;
|
||||
case LIST_EXTEND:
|
||||
case SET_UPDATE:
|
||||
case DICT_MERGE:
|
||||
|
@ -6169,7 +6171,11 @@ stackdepth(struct compiler *c)
|
|||
}
|
||||
|
||||
sp = stack;
|
||||
stackdepth_push(&sp, entryblock, 0);
|
||||
if (c->u->u_ste->ste_generator || c->u->u_ste->ste_coroutine) {
|
||||
stackdepth_push(&sp, entryblock, 1);
|
||||
} else {
|
||||
stackdepth_push(&sp, entryblock, 0);
|
||||
}
|
||||
while (sp != stack) {
|
||||
b = *--sp;
|
||||
int depth = b->b_startdepth;
|
||||
|
@ -6648,6 +6654,41 @@ optimize_cfg(struct assembler *a, PyObject *consts);
|
|||
static int
|
||||
ensure_exits_have_lineno(struct compiler *c);
|
||||
|
||||
static int
|
||||
insert_generator_prefix(struct compiler *c, basicblock *entryblock) {
|
||||
|
||||
int flags = compute_code_flags(c);
|
||||
if (flags < 0) {
|
||||
return -1;
|
||||
}
|
||||
int kind;
|
||||
if (flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) {
|
||||
if (flags & CO_COROUTINE) {
|
||||
kind = 1;
|
||||
}
|
||||
else if (flags & CO_ASYNC_GENERATOR) {
|
||||
kind = 2;
|
||||
}
|
||||
else {
|
||||
kind = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
if (compiler_next_instr(entryblock) < 0) {
|
||||
return -1;
|
||||
}
|
||||
for (int i = entryblock->b_iused-1; i > 0; i--) {
|
||||
entryblock->b_instr[i] = entryblock->b_instr[i-1];
|
||||
}
|
||||
entryblock->b_instr[0].i_opcode = GEN_START;
|
||||
entryblock->b_instr[0].i_oparg = kind;
|
||||
entryblock->b_instr[0].i_lineno = -1;
|
||||
entryblock->b_instr[0].i_target = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyCodeObject *
|
||||
assemble(struct compiler *c, int addNone)
|
||||
{
|
||||
|
@ -6685,6 +6726,10 @@ assemble(struct compiler *c, int addNone)
|
|||
entryblock = b;
|
||||
}
|
||||
|
||||
if (insert_generator_prefix(c, entryblock)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Set firstlineno if it wasn't explicitly set. */
|
||||
if (!c->u->u_firstlineno) {
|
||||
if (entryblock && entryblock->b_instr && entryblock->b_instr->i_lineno)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue