summaryrefslogtreecommitdiffstats
path: root/Python/compile.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2021-04-06 10:48:59 (GMT)
committerGitHub <noreply@github.com>2021-04-06 10:48:59 (GMT)
commitb37181e69209746adc2119c471599a1ea5faa6c8 (patch)
tree3605b5e9447fe18ed0c87b745daef1216301583f /Python/compile.c
parent489c36920e94bfb4988b6f965bd0aafdfaff0d4f (diff)
downloadcpython-b37181e69209746adc2119c471599a1ea5faa6c8.zip
cpython-b37181e69209746adc2119c471599a1ea5faa6c8.tar.gz
cpython-b37181e69209746adc2119c471599a1ea5faa6c8.tar.bz2
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.
Diffstat (limited to 'Python/compile.c')
-rw-r--r--Python/compile.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/Python/compile.c b/Python/compile.c
index 308d686..c2fa1c0 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -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)