diff --git a/py/compile.c b/py/compile.c
index 4b78b7f37c556049fd9545c9e51725da1a42ffd5..a41851c3a142a2575f38a5da6b5bd88b1ba7216a 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -3647,9 +3647,21 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
     module_scope->pn = fold_constants(comp, module_scope->pn, &consts);
     mp_map_deinit(&consts);
 
+    // create standard emitter; it's used at least for MP_PASS_SCOPE
+    #if MICROPY_EMIT_CPYTHON
+    emit_t *emit_cpython = emit_cpython_new();
+    #else
+    emit_t *emit_bc = emit_bc_new();
+    #endif
+
     // compile pass 1
-    comp->emit = NULL;
-    comp->emit_method_table = &emit_pass1_method_table;
+    #if MICROPY_EMIT_CPYTHON
+    comp->emit = emit_cpython;
+    comp->emit_method_table = &emit_cpython_method_table;
+    #else
+    comp->emit = emit_bc;
+    comp->emit_method_table = &emit_bc_method_table;
+    #endif
     #if MICROPY_EMIT_INLINE_THUMB
     comp->emit_inline_asm = NULL;
     comp->emit_inline_asm_method_table = NULL;
@@ -3676,9 +3688,15 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
         scope_compute_things(s);
     }
 
+    // set max number of labels now that it's calculated
+    #if MICROPY_EMIT_CPYTHON
+    emit_cpython_set_max_num_labels(emit_cpython, max_num_labels);
+    #else
+    emit_bc_set_max_num_labels(emit_bc, max_num_labels);
+    #endif
+
     // compile pass 2 and 3
 #if !MICROPY_EMIT_CPYTHON
-    emit_t *emit_bc = NULL;
 #if MICROPY_EMIT_NATIVE
     emit_t *emit_native = NULL;
 #endif
@@ -3711,7 +3729,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
             // choose the emit type
 
 #if MICROPY_EMIT_CPYTHON
-            comp->emit = emit_cpython_new(max_num_labels);
+            comp->emit = emit_cpython;
             comp->emit_method_table = &emit_cpython_method_table;
 #else
             switch (s->emit_options) {
@@ -3746,9 +3764,6 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
 #endif // MICROPY_EMIT_NATIVE
 
                 default:
-                    if (emit_bc == NULL) {
-                        emit_bc = emit_bc_new(max_num_labels);
-                    }
                     comp->emit = emit_bc;
                     comp->emit_method_table = &emit_bc_method_table;
                     break;
@@ -3771,10 +3786,11 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
     }
 
     // free the emitters
-#if !MICROPY_EMIT_CPYTHON
-    if (emit_bc != NULL) {
-        emit_bc_free(emit_bc);
-    }
+
+#if MICROPY_EMIT_CPYTHON
+    emit_cpython_free(emit_cpython);
+#else
+    emit_bc_free(emit_bc);
 #if MICROPY_EMIT_NATIVE
     if (emit_native != NULL) {
 #if MICROPY_EMIT_X64
@@ -3793,7 +3809,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
         emit_inline_thumb_free(emit_inline_thumb);
     }
 #endif
-#endif // !MICROPY_EMIT_CPYTHON
+#endif // MICROPY_EMIT_CPYTHON
 
     // free the parse tree
     mp_parse_node_free(module_scope->pn);
diff --git a/py/emit.h b/py/emit.h
index 47ef16256d8e6222d21893a58433920a570c2f2d..33eccda2c26f5ed53246ff5c613ebbd9bbe38d0e 100644
--- a/py/emit.h
+++ b/py/emit.h
@@ -159,7 +159,6 @@ void mp_emit_common_get_id_for_load(scope_t *scope, qstr qst);
 void mp_emit_common_get_id_for_modification(scope_t *scope, qstr qst);
 void mp_emit_common_id_op(emit_t *emit, const mp_emit_method_table_id_ops_t *emit_method_table, scope_t *scope, qstr qst);
 
-extern const emit_method_table_t emit_pass1_method_table;
 extern const emit_method_table_t emit_cpython_method_table;
 extern const emit_method_table_t emit_bc_method_table;
 extern const emit_method_table_t emit_native_x64_method_table;
@@ -167,13 +166,17 @@ extern const emit_method_table_t emit_native_x86_method_table;
 extern const emit_method_table_t emit_native_thumb_method_table;
 extern const emit_method_table_t emit_native_arm_method_table;
 
-emit_t *emit_cpython_new(mp_uint_t max_num_labels);
-emit_t *emit_bc_new(mp_uint_t max_num_labels);
+emit_t *emit_cpython_new(void);
+emit_t *emit_bc_new(void);
 emit_t *emit_native_x64_new(mp_uint_t max_num_labels);
 emit_t *emit_native_x86_new(mp_uint_t max_num_labels);
 emit_t *emit_native_thumb_new(mp_uint_t max_num_labels);
 emit_t *emit_native_arm_new(mp_uint_t max_num_labels);
 
+void emit_cpython_set_max_num_labels(emit_t* emit, mp_uint_t max_num_labels);
+void emit_bc_set_max_num_labels(emit_t* emit, mp_uint_t max_num_labels);
+
+void emit_cpython_free(emit_t *emit);
 void emit_bc_free(emit_t *emit);
 void emit_native_x64_free(emit_t *emit);
 void emit_native_x86_free(emit_t *emit);
diff --git a/py/emitbc.c b/py/emitbc.c
index 53437a8f86891d9a7bfb6ec7cdf9e2d5e94ded2c..52e10130c435e8bf17ece5ec44be599d4e4f2df1 100644
--- a/py/emitbc.c
+++ b/py/emitbc.c
@@ -65,11 +65,14 @@ struct _emit_t {
 STATIC void emit_bc_rot_two(emit_t *emit);
 STATIC void emit_bc_rot_three(emit_t *emit);
 
-emit_t *emit_bc_new(mp_uint_t max_num_labels) {
+emit_t *emit_bc_new(void) {
     emit_t *emit = m_new0(emit_t, 1);
+    return emit;
+}
+
+void emit_bc_set_max_num_labels(emit_t* emit, mp_uint_t max_num_labels) {
     emit->max_num_labels = max_num_labels;
     emit->label_offsets = m_new(mp_uint_t, emit->max_num_labels);
-    return emit;
 }
 
 void emit_bc_free(emit_t *emit) {
@@ -338,6 +341,10 @@ STATIC void emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
 }
 
 STATIC void emit_bc_end_pass(emit_t *emit) {
+    if (emit->pass == MP_PASS_SCOPE) {
+        return;
+    }
+
     // check stack is back to zero size
     if (emit->stack_size != 0) {
         printf("ERROR: stack size not back to zero; got %d\n", emit->stack_size);
@@ -403,6 +410,9 @@ STATIC void emit_bc_set_source_line(emit_t *emit, mp_uint_t source_line) {
 }
 
 STATIC void emit_bc_pre(emit_t *emit, mp_int_t stack_size_delta) {
+    if (emit->pass == MP_PASS_SCOPE) {
+        return;
+    }
     assert((mp_int_t)emit->stack_size + stack_size_delta >= 0);
     emit->stack_size += stack_size_delta;
     if (emit->stack_size > emit->scope->stack_size) {
@@ -413,6 +423,9 @@ STATIC void emit_bc_pre(emit_t *emit, mp_int_t stack_size_delta) {
 
 STATIC void emit_bc_label_assign(emit_t *emit, mp_uint_t l) {
     emit_bc_pre(emit, 0);
+    if (emit->pass == MP_PASS_SCOPE) {
+        return;
+    }
     assert(l < emit->max_num_labels);
     if (emit->pass < MP_PASS_EMIT) {
         // assign label offset
diff --git a/py/emitcpy.c b/py/emitcpy.c
index 0e040b0e9e78b8fc8117330357205875421a03e0..48c293091cd1b557e4b2f098fe2fc3352836fb72 100644
--- a/py/emitcpy.c
+++ b/py/emitcpy.c
@@ -47,11 +47,19 @@ struct _emit_t {
     mp_uint_t *label_offsets;
 };
 
-emit_t *emit_cpython_new(mp_uint_t max_num_labels) {
-    emit_t *emit = m_new(emit_t, 1);
+emit_t *emit_cpython_new(void) {
+    emit_t *emit = m_new0(emit_t, 1);
+    return emit;
+}
+
+void emit_cpython_set_max_num_labels(emit_t* emit, mp_uint_t max_num_labels) {
     emit->max_num_labels = max_num_labels;
     emit->label_offsets = m_new(mp_uint_t, max_num_labels);
-    return emit;
+}
+
+void emit_cpython_free(emit_t *emit) {
+    m_del(mp_uint_t, emit->label_offsets, emit->max_num_labels);
+    m_del_obj(emit_t, emit);
 }
 
 STATIC void emit_cpy_set_native_type(emit_t *emit, mp_uint_t op, mp_uint_t arg1, qstr arg2) {
@@ -69,6 +77,9 @@ STATIC void emit_cpy_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope)
 }
 
 STATIC void emit_cpy_end_pass(emit_t *emit) {
+    if (emit->pass == MP_PASS_SCOPE) {
+        return;
+    }
     // check stack is back to zero size
     if (emit->stack_size != 0) {
         printf("ERROR: stack size not back to zero; got %d\n", emit->stack_size);
@@ -88,6 +99,9 @@ STATIC void emit_cpy_set_source_line(emit_t *emit, mp_uint_t source_line) {
 
 // TODO: module-polymorphic function (read: name clash if made global)
 static void emit_pre(emit_t *emit, int stack_size_delta, int bytecode_size) {
+    if (emit->pass == MP_PASS_SCOPE) {
+        return;
+    }
     emit->stack_size += stack_size_delta;
     if (emit->stack_size > emit->scope->stack_size) {
         emit->scope->stack_size = emit->stack_size;
@@ -105,6 +119,9 @@ static void emit_pre(emit_t *emit, int stack_size_delta, int bytecode_size) {
 
 STATIC void emit_cpy_label_assign(emit_t *emit, mp_uint_t l) {
     emit_pre(emit, 0, 0);
+    if (emit->pass == MP_PASS_SCOPE) {
+        return;
+    }
     assert(l < emit->max_num_labels);
     if (emit->pass < MP_PASS_EMIT) {
         // assign label offset
diff --git a/py/emitpass1.c b/py/emitpass1.c
deleted file mode 100644
index 995aceddef2891e518b0dee6037f6cf6b31ee65b..0000000000000000000000000000000000000000
--- a/py/emitpass1.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * This file is part of the Micro Python project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2013, 2014 Damien P. George
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <assert.h>
-
-#include "py/emit.h"
-
-STATIC void emit_pass1_dummy(emit_t *emit) {
-    (void)emit;
-}
-
-STATIC void emit_pass1_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
-    assert(pass == MP_PASS_SCOPE);
-}
-
-STATIC bool emit_pass1_last_emit_was_return_value(emit_t *emit) {
-    (void)emit;
-    return false;
-}
-
-const emit_method_table_t emit_pass1_method_table = {
-    (void*)emit_pass1_dummy,
-    emit_pass1_start_pass,
-    emit_pass1_dummy,
-    emit_pass1_last_emit_was_return_value,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-
-    {
-        (void*)emit_pass1_dummy,
-        (void*)emit_pass1_dummy,
-        (void*)emit_pass1_dummy,
-        (void*)emit_pass1_dummy,
-    },
-    {
-        (void*)emit_pass1_dummy,
-        (void*)emit_pass1_dummy,
-        (void*)emit_pass1_dummy,
-        (void*)emit_pass1_dummy,
-    },
-    {
-        (void*)emit_pass1_dummy,
-        (void*)emit_pass1_dummy,
-        (void*)emit_pass1_dummy,
-        (void*)emit_pass1_dummy,
-    },
-
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    #if MICROPY_PY_BUILTINS_SET
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    #endif
-    #if MICROPY_PY_BUILTINS_SLICE
-    (void*)emit_pass1_dummy,
-    #endif
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-
-#if MICROPY_EMIT_CPYTHON
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-    (void*)emit_pass1_dummy,
-#endif
-};
diff --git a/py/py.mk b/py/py.mk
index 6227ad9eb4c84d4cc8c624579ed22c35bc191f95..e120f8be4a3759eec535677248b9060e4c9d475e 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -31,7 +31,6 @@ PY_O_BASENAME = \
 	scope.o \
 	compile.o \
 	emitcommon.o \
-	emitpass1.o \
 	emitcpy.o \
 	emitbc.o \
 	asmx64.o \