summaryrefslogtreecommitdiffstatshomepage
path: root/py/emitbc.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/emitbc.c')
-rw-r--r--py/emitbc.c24
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) {