diff options
author | Damien George <damien.p.george@gmail.com> | 2014-04-09 15:26:46 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-04-09 15:26:46 +0100 |
commit | 2bf7c092225645d8c5b15e536afdce39e3593e42 (patch) | |
tree | e257514a3008411367ea5e62eaea4b101ccac257 /py/emitbc.c | |
parent | 11d8cd54c992eee55f27d3779738626bdc095c03 (diff) | |
download | micropython-2bf7c092225645d8c5b15e536afdce39e3593e42.tar.gz micropython-2bf7c092225645d8c5b15e536afdce39e3593e42.zip |
py: Properly implement deletion of locals and derefs, and detect errors.
Needed to reinstate 2 delete opcodes, to specifically check that a local
is not deleted twice.
Diffstat (limited to 'py/emitbc.c')
-rw-r--r-- | py/emitbc.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/py/emitbc.c b/py/emitbc.c index f16ffced11..21d1a61863 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -408,14 +408,20 @@ STATIC void emit_bc_load_null(emit_t *emit) { emit_write_byte_code_byte(emit, MP_BC_LOAD_NULL); }; -STATIC void emit_bc_load_fast(emit_t *emit, qstr qstr, int local_num) { +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); - 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; + 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; + } } } @@ -491,13 +497,11 @@ STATIC void emit_bc_store_subscr(emit_t *emit) { } STATIC void emit_bc_delete_fast(emit_t *emit, qstr qstr, int local_num) { - emit_bc_load_null(emit); - emit_bc_store_fast(emit, qstr, local_num); + emit_write_byte_code_byte_uint(emit, MP_BC_DELETE_FAST, local_num); } STATIC void emit_bc_delete_deref(emit_t *emit, qstr qstr, int local_num) { - emit_bc_load_null(emit); - emit_bc_store_deref(emit, qstr, local_num); + emit_write_byte_code_byte_uint(emit, MP_BC_DELETE_DEREF, local_num); } STATIC void emit_bc_delete_name(emit_t *emit, qstr qstr) { |