mirror of
https://github.com/micropython/micropython.git
synced 2026-01-07 12:40:15 +01:00
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.
This commit is contained in:
24
py/emitbc.c
24
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) {
|
||||
|
||||
Reference in New Issue
Block a user