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/vm.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/vm.c')
-rw-r--r-- | py/vm.c | 32 |
1 files changed, 31 insertions, 1 deletions
@@ -241,9 +241,23 @@ dispatch_loop: PUSH(fastn[-unum]); break; + case MP_BC_LOAD_FAST_CHECKED: + DECODE_UINT; + obj1 = fastn[-unum]; + if (obj1 == MP_OBJ_NULL) { + local_name_error: + nlr_raise(mp_obj_new_exception_msg(&mp_type_NameError, "local variable referenced before assignment")); + } + PUSH(obj1); + break; + case MP_BC_LOAD_DEREF: DECODE_UINT; - PUSH(mp_obj_cell_get(fastn[-unum])); + obj1 = mp_obj_cell_get(fastn[-unum]); + if (obj1 == MP_OBJ_NULL) { + goto local_name_error; + } + PUSH(obj1); break; case MP_BC_LOAD_NAME: @@ -314,6 +328,22 @@ dispatch_loop: sp -= 3; break; + case MP_BC_DELETE_FAST: + DECODE_UINT; + if (fastn[-unum] == MP_OBJ_NULL) { + goto local_name_error; + } + fastn[-unum] = MP_OBJ_NULL; + break; + + case MP_BC_DELETE_DEREF: + DECODE_UINT; + if (mp_obj_cell_get(fastn[-unum]) == MP_OBJ_NULL) { + goto local_name_error; + } + mp_obj_cell_set(fastn[-unum], MP_OBJ_NULL); + break; + case MP_BC_DELETE_NAME: DECODE_QSTR; mp_delete_name(qst); |