diff --git a/py/bc0.h b/py/bc0.h index e6a0e21241..7d6e52b72c 100644 --- a/py/bc0.h +++ b/py/bc0.h @@ -17,7 +17,6 @@ #define MP_BC_LOAD_FAST_1 (0x21) #define MP_BC_LOAD_FAST_2 (0x22) #define MP_BC_LOAD_FAST_N (0x23) // uint -#define MP_BC_LOAD_FAST_CHECKED (0x24) // uint #define MP_BC_LOAD_DEREF (0x25) // uint #define MP_BC_LOAD_NAME (0x26) // qstr #define MP_BC_LOAD_GLOBAL (0x27) // qstr diff --git a/py/emitbc.c b/py/emitbc.c index a1179a6954..d1d59ef4a5 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -413,17 +413,11 @@ STATIC void emit_bc_load_null(emit_t *emit) { STATIC void emit_bc_load_fast(emit_t *emit, qstr qstr, uint id_flags, int local_num) { assert(local_num >= 0); emit_bc_pre(emit, 1); - if (id_flags & ID_FLAG_IS_DELETED) { - // This local may be deleted, so need to do a checked load. - emit_write_byte_code_byte_uint(emit, MP_BC_LOAD_FAST_CHECKED, local_num); - } else { - // This local is never deleted, so can do a fast, uncheched load. - switch (local_num) { - case 0: emit_write_byte_code_byte(emit, MP_BC_LOAD_FAST_0); break; - case 1: emit_write_byte_code_byte(emit, MP_BC_LOAD_FAST_1); break; - case 2: emit_write_byte_code_byte(emit, MP_BC_LOAD_FAST_2); break; - default: emit_write_byte_code_byte_uint(emit, MP_BC_LOAD_FAST_N, local_num); break; - } + switch (local_num) { + case 0: emit_write_byte_code_byte(emit, MP_BC_LOAD_FAST_0); break; + case 1: emit_write_byte_code_byte(emit, MP_BC_LOAD_FAST_1); break; + case 2: emit_write_byte_code_byte(emit, MP_BC_LOAD_FAST_2); break; + default: emit_write_byte_code_byte_uint(emit, MP_BC_LOAD_FAST_N, local_num); break; } } diff --git a/py/emitpass1.c b/py/emitpass1.c index 301c04ebea..ad86588e20 100644 --- a/py/emitpass1.c +++ b/py/emitpass1.c @@ -96,7 +96,9 @@ STATIC void emit_pass1_store_id(emit_t *emit, qstr qstr) { STATIC void emit_pass1_delete_id(emit_t *emit, qstr qstr) { id_info_t *id = get_id_for_modification(emit->scope, qstr); - id->flags |= ID_FLAG_IS_DELETED; + // this flag is unused + //id->flags |= ID_FLAG_IS_DELETED; + (void)id; // suppress compiler warning } const emit_method_table_t emit_pass1_method_table = { diff --git a/py/showbc.c b/py/showbc.c index c3342ca841..615d1fe0de 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -132,11 +132,6 @@ void mp_byte_code_print(const byte *ip, int len) { printf("LOAD_FAST_N " UINT_FMT, unum); break; - case MP_BC_LOAD_FAST_CHECKED: - DECODE_UINT; - printf("LOAD_FAST_CHECKED " UINT_FMT, unum); - break; - case MP_BC_LOAD_DEREF: DECODE_UINT; printf("LOAD_DEREF " UINT_FMT, unum); diff --git a/py/vm.c b/py/vm.c index 1ea0c5eaa1..f62cb2d7b1 100644 --- a/py/vm.c +++ b/py/vm.c @@ -252,25 +252,21 @@ dispatch_loop: break; case MP_BC_LOAD_FAST_0: - PUSH(fastn[0]); - break; + obj1 = fastn[0]; + goto load_check; case MP_BC_LOAD_FAST_1: - PUSH(fastn[-1]); - break; + obj1 = fastn[-1]; + goto load_check; case MP_BC_LOAD_FAST_2: - PUSH(fastn[-2]); - break; + obj1 = fastn[-2]; + goto load_check; case MP_BC_LOAD_FAST_N: - DECODE_UINT; - PUSH(fastn[-unum]); - break; - - case MP_BC_LOAD_FAST_CHECKED: DECODE_UINT; obj1 = fastn[-unum]; + load_check: if (obj1 == MP_OBJ_NULL) { local_name_error: nlr_raise(mp_obj_new_exception_msg(&mp_type_NameError, "local variable referenced before assignment")); @@ -281,11 +277,7 @@ dispatch_loop: case MP_BC_LOAD_DEREF: DECODE_UINT; obj1 = mp_obj_cell_get(fastn[-unum]); - if (obj1 == MP_OBJ_NULL) { - goto local_name_error; - } - PUSH(obj1); - break; + goto load_check; case MP_BC_LOAD_NAME: DECODE_QSTR; diff --git a/tests/basics/unboundlocal.py b/tests/basics/unboundlocal.py new file mode 100644 index 0000000000..5573da1665 --- /dev/null +++ b/tests/basics/unboundlocal.py @@ -0,0 +1,19 @@ +# locals referenced before assignment + +def f1(): + print(x) + x = 1 + +def f2(): + for i in range(0): + print(i) + print(i) + +def check(f): + try: + f() + except NameError: + print("NameError") + +check(f1) +check(f2)