diff --git a/py/compile.c b/py/compile.c
index d2fa03f01e617343ff6dba4a091a9ff1c6084c71..4fde278d0fda345b04bfa6efda77d6771c18e938 100644
--- a/py/compile.c
+++ b/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);
 
diff --git a/py/emitbc.c b/py/emitbc.c
index 3e0c0b39723869dad91c1c518beb1d774107487b..0d7e6519b38a3fc553b5bf8640cc71c2946bbec2 100644
--- a/py/emitbc.c
+++ b/py/emitbc.c
@@ -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) {
diff --git a/py/vm.c b/py/vm.c
index 848a77a453a4450af3bf7be7501b2806dc77e478..f9eb2692dc743ff8bce7578b5be90730a82ef4be 100644
--- a/py/vm.c
+++ b/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