Move del to locals
diff --git a/py/gc.c b/py/gc.c
index 0d28828..e330e5c 100644
--- a/py/gc.c
+++ b/py/gc.c
@@ -8,6 +8,7 @@
 #include "misc.h"
 #include "qstr.h"
 #include "obj.h"
+#include "runtime.h"
 
 #if MICROPY_ENABLE_GC
 
@@ -175,12 +176,14 @@
         switch (ATB_GET_KIND(block)) {
             case AT_HEAD:
                 if (ATB_IS_MPOBJ(block)) {
-                    ATB_CLR_MPOBJ(block); // clear mpobj flag
-                    mp_obj_t *self = (mp_obj_t*)PTR_FROM_BLOCK(block);
-                    mp_obj_type_t *type= mp_obj_get_type(self);
-                    if (type->del != NULL) {
-                        type->del(self);
+                    mp_obj_t dest[2];
+                    mp_load_method((mp_obj_t*)PTR_FROM_BLOCK(block), MP_QSTR___del__, dest);
+                    // load_method returned a method
+                    if (dest[1] != MP_OBJ_NULL) {
+                        mp_call_method_n_kw(0, 0, dest);
                     }
+                    // clear mpobj flag
+                    ATB_CLR_MPOBJ(block);
                 }
                 free_tail = 1;
                 // fall through to free the head
@@ -305,16 +308,17 @@
     // mark first block as used head
     ATB_FREE_TO_HEAD(start_block);
 
-    if (is_mpobj) {
-        ATB_SET_MPOBJ(start_block);
-    }
-
     // mark rest of blocks as used tail
     // TODO for a run of many blocks can make this more efficient
     for (machine_uint_t bl = start_block + 1; bl <= end_block; bl++) {
         ATB_FREE_TO_TAIL(bl);
     }
 
+    if (is_mpobj) {
+        // set mp_obj flag only if it has del
+        ATB_SET_MPOBJ(start_block);
+    }
+
     // return pointer to first block
     return (void*)(gc_pool_start + start_block * WORDS_PER_BLOCK);
 }
diff --git a/py/obj.h b/py/obj.h
index 4178295..952187e 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -154,7 +154,6 @@
 typedef void (*mp_load_attr_fun_t)(mp_obj_t self_in, qstr attr, mp_obj_t *dest); // for fail, do nothing; for attr, dest[0] = value; for method, dest[0] = method, dest[1] = self
 typedef bool (*mp_store_attr_fun_t)(mp_obj_t self_in, qstr attr, mp_obj_t value); // return true if store succeeded
 typedef bool (*mp_store_item_fun_t)(mp_obj_t self_in, mp_obj_t index, mp_obj_t value); // return true if store succeeded
-typedef void (*mp_del_fun_t)(mp_obj_t self_in);
 
 typedef struct _mp_method_t {
     qstr name;
@@ -237,7 +236,6 @@
 
     unpack seq      list tuple
     */
-    mp_del_fun_t del;
 };
 
 typedef struct _mp_obj_type_t mp_obj_type_t;
diff --git a/py/qstrdefs.h b/py/qstrdefs.h
index 368b0fc..591c96a 100644
--- a/py/qstrdefs.h
+++ b/py/qstrdefs.h
@@ -27,6 +27,7 @@
 Q(__repr__)
 Q(__str__)
 Q(__getattr__)
+Q(__del__)
 
 Q(micropython)
 Q(byte_code)
diff --git a/stm/file.c b/stm/file.c
index fc6abfc..a8f66f4 100644
--- a/stm/file.c
+++ b/stm/file.c
@@ -13,12 +13,6 @@
     FIL fp;
 } pyb_file_obj_t;
 
-void file_obj_del(mp_obj_t self_in) {
-    pyb_file_obj_t *self = self_in;
-    f_close(&self->fp);
-    printf("<file del called>\n");
-}
-
 void file_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
     printf("<file %p>", self_in);
 }
@@ -62,6 +56,7 @@
     { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&file_obj_read_obj },
     { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&file_obj_write_obj },
     { MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&file_obj_close_obj },
+    { MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&file_obj_close_obj },
 };
 
 STATIC MP_DEFINE_CONST_DICT(file_locals_dict, file_locals_dict_table);
@@ -70,7 +65,6 @@
     { &mp_type_type },
     .name = MP_QSTR_File,
     .print = file_obj_print,
-    .del   = file_obj_del,
     .locals_dict = (mp_obj_t)&file_locals_dict,
 };