Skip to content

Commit 6e769da

Browse files
committed
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.
1 parent f4df3aa commit 6e769da

3 files changed

Lines changed: 12 additions & 11 deletions

File tree

py/compile.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2887,7 +2887,7 @@ STATIC void compile_scope_comp_iter(compiler_t *comp, mp_parse_node_struct_t *pn
28872887
EMIT(yield_value);
28882888
EMIT(pop_top);
28892889
} else {
2890-
EMIT_ARG(store_comp, comp->scope_cur->kind, for_depth + 2);
2890+
EMIT_ARG(store_comp, comp->scope_cur->kind, 5 * for_depth + 6);
28912891
}
28922892
} else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_if)) {
28932893
// if condition
@@ -2900,13 +2900,13 @@ STATIC void compile_scope_comp_iter(compiler_t *comp, mp_parse_node_struct_t *pn
29002900
// for loop
29012901
mp_parse_node_struct_t *pns_comp_for2 = (mp_parse_node_struct_t*)pn_iter;
29022902
compile_node(comp, pns_comp_for2->nodes[1]);
2903-
EMIT_ARG(get_iter, false);
2903+
EMIT_ARG(get_iter, true);
29042904
compile_scope_comp_iter(comp, pns_comp_for2, pn_inner_expr, for_depth + 1);
29052905
}
29062906

29072907
EMIT_ARG(jump, l_top);
29082908
EMIT_ARG(label_assign, l_end);
2909-
EMIT_ARG(for_iter_end, false);
2909+
EMIT_ARG(for_iter_end, true);
29102910
}
29112911

29122912
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) {
30703070
#endif
30713071
}
30723072

3073+
// dummy 4 objects
3074+
EMIT(load_null);
3075+
EMIT(load_null);
3076+
EMIT(load_null);
3077+
EMIT(load_null);
3078+
30733079
compile_load_id(comp, qstr_arg);
30743080
compile_scope_comp_iter(comp, pns_comp_for, pns->nodes[0], 0);
30753081

py/emitbc.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -788,12 +788,7 @@ void mp_emit_bc_for_iter(emit_t *emit, mp_uint_t label) {
788788
}
789789

790790
void mp_emit_bc_for_iter_end(emit_t *emit, bool use_stack) {
791-
emit_bc_pre(emit, -1);
792-
if (use_stack) {
793-
for (size_t i = 0; i < sizeof(mp_obj_iter_buf_t) / sizeof(mp_obj_t); ++i) {
794-
mp_emit_bc_pop_top(emit);
795-
}
796-
}
791+
emit_bc_pre(emit, use_stack ? -1 - sizeof(mp_obj_iter_buf_t) / sizeof(mp_obj_t) : -1);
797792
}
798793

799794
void mp_emit_bc_pop_block(emit_t *emit) {

py/vm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ unwind_jump:;
744744
assert(TOP());
745745
mp_obj_t value = mp_iternext_allow_raise(TOP());
746746
if (value == MP_OBJ_STOP_ITERATION) {
747-
--sp; // pop the exhausted iterator
747+
sp -= 5; // pop the exhausted iterator
748748
ip += ulab; // jump to after for-block
749749
} else {
750750
PUSH(value); // push the next iteration value
@@ -1294,7 +1294,7 @@ unwind_jump:;
12941294
const byte *ip = code_state->ip + 1;
12951295
DECODE_ULABEL; // the jump offset if iteration finishes; for labels are always forward
12961296
code_state->ip = ip + ulab; // jump to after for-block
1297-
code_state->sp -= 1; // pop the exhausted iterator
1297+
code_state->sp -= 5; // pop the exhausted iterator
12981298
goto outer_dispatch_loop; // continue with dispatch loop
12991299
} else if (*code_state->ip == MP_BC_YIELD_FROM) {
13001300
// StopIteration inside yield from call means return a value of

0 commit comments

Comments
 (0)