py: Make FOR_ITER opcode pop 1+4 slots from the stack when finished.
The extra 4 slots correspond to the iterator object stored on the stack.
This commit is contained in:
parent
f4df3aaa72
commit
6e769da0da
12
py/compile.c
12
py/compile.c
@ -2887,7 +2887,7 @@ STATIC void compile_scope_comp_iter(compiler_t *comp, mp_parse_node_struct_t *pn
|
||||
EMIT(yield_value);
|
||||
EMIT(pop_top);
|
||||
} else {
|
||||
EMIT_ARG(store_comp, comp->scope_cur->kind, for_depth + 2);
|
||||
EMIT_ARG(store_comp, comp->scope_cur->kind, 5 * for_depth + 6);
|
||||
}
|
||||
} else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_if)) {
|
||||
// if condition
|
||||
@ -2900,13 +2900,13 @@ STATIC void compile_scope_comp_iter(compiler_t *comp, mp_parse_node_struct_t *pn
|
||||
// for loop
|
||||
mp_parse_node_struct_t *pns_comp_for2 = (mp_parse_node_struct_t*)pn_iter;
|
||||
compile_node(comp, pns_comp_for2->nodes[1]);
|
||||
EMIT_ARG(get_iter, false);
|
||||
EMIT_ARG(get_iter, true);
|
||||
compile_scope_comp_iter(comp, pns_comp_for2, pn_inner_expr, for_depth + 1);
|
||||
}
|
||||
|
||||
EMIT_ARG(jump, l_top);
|
||||
EMIT_ARG(label_assign, l_end);
|
||||
EMIT_ARG(for_iter_end, false);
|
||||
EMIT_ARG(for_iter_end, true);
|
||||
}
|
||||
|
||||
STATIC void check_for_doc_string(compiler_t *comp, mp_parse_node_t pn) {
|
||||
@ -3070,6 +3070,12 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// dummy 4 objects
|
||||
EMIT(load_null);
|
||||
EMIT(load_null);
|
||||
EMIT(load_null);
|
||||
EMIT(load_null);
|
||||
|
||||
compile_load_id(comp, qstr_arg);
|
||||
compile_scope_comp_iter(comp, pns_comp_for, pns->nodes[0], 0);
|
||||
|
||||
|
@ -788,12 +788,7 @@ void mp_emit_bc_for_iter(emit_t *emit, mp_uint_t label) {
|
||||
}
|
||||
|
||||
void mp_emit_bc_for_iter_end(emit_t *emit, bool use_stack) {
|
||||
emit_bc_pre(emit, -1);
|
||||
if (use_stack) {
|
||||
for (size_t i = 0; i < sizeof(mp_obj_iter_buf_t) / sizeof(mp_obj_t); ++i) {
|
||||
mp_emit_bc_pop_top(emit);
|
||||
}
|
||||
}
|
||||
emit_bc_pre(emit, use_stack ? -1 - sizeof(mp_obj_iter_buf_t) / sizeof(mp_obj_t) : -1);
|
||||
}
|
||||
|
||||
void mp_emit_bc_pop_block(emit_t *emit) {
|
||||
|
4
py/vm.c
4
py/vm.c
@ -744,7 +744,7 @@ unwind_jump:;
|
||||
assert(TOP());
|
||||
mp_obj_t value = mp_iternext_allow_raise(TOP());
|
||||
if (value == MP_OBJ_STOP_ITERATION) {
|
||||
--sp; // pop the exhausted iterator
|
||||
sp -= 5; // pop the exhausted iterator
|
||||
ip += ulab; // jump to after for-block
|
||||
} else {
|
||||
PUSH(value); // push the next iteration value
|
||||
@ -1294,7 +1294,7 @@ exception_handler:
|
||||
const byte *ip = code_state->ip + 1;
|
||||
DECODE_ULABEL; // the jump offset if iteration finishes; for labels are always forward
|
||||
code_state->ip = ip + ulab; // jump to after for-block
|
||||
code_state->sp -= 1; // pop the exhausted iterator
|
||||
code_state->sp -= 5; // pop the exhausted iterator
|
||||
goto outer_dispatch_loop; // continue with dispatch loop
|
||||
} else if (*code_state->ip == MP_BC_YIELD_FROM) {
|
||||
// StopIteration inside yield from call means return a value of
|
||||
|
Loading…
Reference in New Issue
Block a user