summaryrefslogtreecommitdiff
path: root/Python/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/compile.c')
-rw-r--r--Python/compile.c118
1 files changed, 22 insertions, 96 deletions
diff --git a/Python/compile.c b/Python/compile.c
index c3ffaae8ce..725bb9b213 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -1111,6 +1111,8 @@ stack_effect(int opcode, int oparg, int jump)
return 1;
case GET_YIELD_FROM_ITER:
return 0;
+ case END_ASYNC_FOR:
+ return -7;
case FORMAT_VALUE:
/* If there's a fmt_spec on the stack, we go from 2->1,
else 1->1. */
@@ -2434,78 +2436,40 @@ compiler_for(struct compiler *c, stmt_ty s)
static int
compiler_async_for(struct compiler *c, stmt_ty s)
{
- _Py_IDENTIFIER(StopAsyncIteration);
-
- basicblock *try, *except, *end, *after_try, *try_cleanup,
- *after_loop_else;
-
- PyObject *stop_aiter_error = _PyUnicode_FromId(&PyId_StopAsyncIteration);
- if (stop_aiter_error == NULL) {
- return 0;
- }
-
- try = compiler_new_block(c);
+ basicblock *start, *except, *end;
+ start = compiler_new_block(c);
except = compiler_new_block(c);
end = compiler_new_block(c);
- after_try = compiler_new_block(c);
- try_cleanup = compiler_new_block(c);
- after_loop_else = compiler_new_block(c);
-
- if (try == NULL || except == NULL || end == NULL
- || after_try == NULL || try_cleanup == NULL
- || after_loop_else == NULL)
- return 0;
- if (!compiler_push_fblock(c, FOR_LOOP, try, end))
+ if (start == NULL || except == NULL || end == NULL)
return 0;
VISIT(c, expr, s->v.AsyncFor.iter);
ADDOP(c, GET_AITER);
- compiler_use_next_block(c, try);
-
+ compiler_use_next_block(c, start);
+ if (!compiler_push_fblock(c, FOR_LOOP, start, end))
+ return 0;
/* SETUP_FINALLY to guard the __anext__ call */
ADDOP_JREL(c, SETUP_FINALLY, except);
- if (!compiler_push_fblock(c, EXCEPT, try, NULL))
- return 0;
-
ADDOP(c, GET_ANEXT);
ADDOP_O(c, LOAD_CONST, Py_None, consts);
ADDOP(c, YIELD_FROM);
ADDOP(c, POP_BLOCK); /* for SETUP_FINALLY */
+
+ /* Success block for __anext__ */
VISIT(c, expr, s->v.AsyncFor.target);
- compiler_pop_fblock(c, EXCEPT, try);
- ADDOP_JREL(c, JUMP_FORWARD, after_try);
+ VISIT_SEQ(c, stmt, s->v.AsyncFor.body);
+ ADDOP_JABS(c, JUMP_ABSOLUTE, start);
+ compiler_pop_fblock(c, FOR_LOOP, start);
/* Except block for __anext__ */
compiler_use_next_block(c, except);
- ADDOP(c, DUP_TOP);
- ADDOP_O(c, LOAD_GLOBAL, stop_aiter_error, names);
- ADDOP_I(c, COMPARE_OP, PyCmp_EXC_MATCH);
- ADDOP_JABS(c, POP_JUMP_IF_FALSE, try_cleanup);
-
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_EXCEPT); /* for SETUP_FINALLY */
- ADDOP(c, POP_TOP); /* pop iterator from stack */
- ADDOP_JABS(c, JUMP_ABSOLUTE, after_loop_else);
-
-
- compiler_use_next_block(c, try_cleanup);
- ADDOP(c, END_FINALLY);
-
- /* Success block for __anext__ */
- compiler_use_next_block(c, after_try);
- VISIT_SEQ(c, stmt, s->v.AsyncFor.body);
- ADDOP_JABS(c, JUMP_ABSOLUTE, try);
-
- compiler_pop_fblock(c, FOR_LOOP, try);
+ ADDOP(c, END_ASYNC_FOR);
/* `else` block */
- compiler_use_next_block(c, after_loop_else);
VISIT_SEQ(c, stmt, s->v.For.orelse);
compiler_use_next_block(c, end);
@@ -4003,28 +3967,14 @@ compiler_async_comprehension_generator(struct compiler *c,
asdl_seq *generators, int gen_index,
expr_ty elt, expr_ty val, int type)
{
- _Py_IDENTIFIER(StopAsyncIteration);
-
comprehension_ty gen;
- basicblock *anchor, *if_cleanup, *try,
- *after_try, *except, *try_cleanup;
+ basicblock *start, *if_cleanup, *except;
Py_ssize_t i, n;
-
- PyObject *stop_aiter_error = _PyUnicode_FromId(&PyId_StopAsyncIteration);
- if (stop_aiter_error == NULL) {
- return 0;
- }
-
- try = compiler_new_block(c);
- after_try = compiler_new_block(c);
- try_cleanup = compiler_new_block(c);
+ start = compiler_new_block(c);
except = compiler_new_block(c);
if_cleanup = compiler_new_block(c);
- anchor = compiler_new_block(c);
- if (if_cleanup == NULL || anchor == NULL ||
- try == NULL || after_try == NULL ||
- except == NULL || try_cleanup == NULL) {
+ if (start == NULL || if_cleanup == NULL || except == NULL) {
return 0;
}
@@ -4041,39 +3991,14 @@ compiler_async_comprehension_generator(struct compiler *c,
ADDOP(c, GET_AITER);
}
- compiler_use_next_block(c, try);
-
+ compiler_use_next_block(c, start);
ADDOP_JREL(c, SETUP_FINALLY, except);
- if (!compiler_push_fblock(c, EXCEPT, try, NULL))
- return 0;
-
ADDOP(c, GET_ANEXT);
ADDOP_O(c, LOAD_CONST, Py_None, consts);
ADDOP(c, YIELD_FROM);
ADDOP(c, POP_BLOCK);
VISIT(c, expr, gen->target);
- compiler_pop_fblock(c, EXCEPT, try);
- ADDOP_JREL(c, JUMP_FORWARD, after_try);
-
-
- compiler_use_next_block(c, except);
- ADDOP(c, DUP_TOP);
- ADDOP_O(c, LOAD_GLOBAL, stop_aiter_error, names);
- ADDOP_I(c, COMPARE_OP, PyCmp_EXC_MATCH);
- ADDOP_JABS(c, POP_JUMP_IF_FALSE, try_cleanup);
-
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_EXCEPT); /* for SETUP_FINALLY */
- ADDOP_JABS(c, JUMP_ABSOLUTE, anchor);
-
-
- compiler_use_next_block(c, try_cleanup);
- ADDOP(c, END_FINALLY);
-
- compiler_use_next_block(c, after_try);
n = asdl_seq_LEN(gen->ifs);
for (i = 0; i < n; i++) {
@@ -4118,9 +4043,10 @@ compiler_async_comprehension_generator(struct compiler *c,
}
}
compiler_use_next_block(c, if_cleanup);
- ADDOP_JABS(c, JUMP_ABSOLUTE, try);
- compiler_use_next_block(c, anchor);
- ADDOP(c, POP_TOP);
+ ADDOP_JABS(c, JUMP_ABSOLUTE, start);
+
+ compiler_use_next_block(c, except);
+ ADDOP(c, END_ASYNC_FOR);
return 1;
}