diff --git a/py/misc.h b/py/misc.h
index 153218ba2f8b6abf03eea3bb2b82d1d1a121cc1c..1bf4d8f29184d603c13b331f681a0597faecc11a 100644
--- a/py/misc.h
+++ b/py/misc.h
@@ -5,11 +5,7 @@
 
 /** types *******************************************************/
 
-typedef int bool;
-enum {
-    false = 0,
-    true = 1
-};
+#include <stdbool.h>
 
 typedef unsigned char byte;
 typedef unsigned int uint;
diff --git a/py/obj.h b/py/obj.h
index 1ba7427cbbb495e8c79e57923f82647975401c1e..49167bfccb6968c4ffd05e03514bd149eb4f502b 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -15,15 +15,14 @@ typedef machine_int_t mp_small_int_t;
 typedef machine_float_t mp_float_t;
 #endif
 
-// Anything that wants to be a Micro Python object must
-// have mp_obj_base_t as its first member (except NULL and small ints)
-
-typedef struct _mp_obj_base_t mp_obj_base_t;
-typedef struct _mp_obj_type_t mp_obj_type_t;
+// Anything that wants to be a Micro Python object must have
+// mp_obj_base_t as its first member (except NULL and small ints)
 
+struct _mp_obj_type_t;
 struct _mp_obj_base_t {
-    const mp_obj_type_t *type;
+    const struct _mp_obj_type_t *type;
 };
+typedef struct _mp_obj_base_t mp_obj_base_t;
 
 // The NULL object is used to indicate the absence of an object
 // It *cannot* be used when an mp_obj_t is expected, except where explicitly allowed
@@ -43,12 +42,13 @@ struct _mp_obj_base_t {
 
 #define MP_DECLARE_CONST_FUN_OBJ(obj_name) extern const mp_obj_fun_native_t obj_name
 
-#define MP_DEFINE_CONST_FUN_OBJ_0(obj_name, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, 0, 0, fun_name}
-#define MP_DEFINE_CONST_FUN_OBJ_1(obj_name, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, 1, 1, fun_name}
-#define MP_DEFINE_CONST_FUN_OBJ_2(obj_name, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, 2, 2, fun_name}
-#define MP_DEFINE_CONST_FUN_OBJ_3(obj_name, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, 3, 3, fun_name}
-#define MP_DEFINE_CONST_FUN_OBJ_VAR(obj_name, n_args_min, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, n_args_min, (~((machine_uint_t)0)), fun_name}
-#define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name, n_args_min, n_args_max, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, n_args_min, n_args_max, fun_name}
+#define MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, n_args_min, n_args_max, fun_name) const mp_obj_fun_native_t obj_name = {{&fun_native_type}, n_args_min, n_args_max, (void *)fun_name}
+#define MP_DEFINE_CONST_FUN_OBJ_0(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, 0, 0, (mp_fun_0_t)fun_name)
+#define MP_DEFINE_CONST_FUN_OBJ_1(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, 1, 1, (mp_fun_1_t)fun_name)
+#define MP_DEFINE_CONST_FUN_OBJ_2(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, 2, 2, (mp_fun_2_t)fun_name)
+#define MP_DEFINE_CONST_FUN_OBJ_3(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, 3, 3, (mp_fun_3_t)fun_name)
+#define MP_DEFINE_CONST_FUN_OBJ_VAR(obj_name, n_args_min, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, n_args_min, (~((machine_uint_t)0)), (mp_fun_var_t)fun_name)
+#define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name, n_args_min, n_args_max, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, n_args_min, n_args_max, (mp_fun_var_t)fun_name)
 
 // Type definitions for methods
 
@@ -83,7 +83,7 @@ struct _mp_obj_type_t {
     mp_fun_1_t getiter;
     mp_fun_1_t iternext;
 
-    const mp_method_t methods[];
+    const mp_method_t *methods;
 
     /*
     What we might need to add here:
@@ -108,6 +108,8 @@ struct _mp_obj_type_t {
     */
 };
 
+typedef struct _mp_obj_type_t mp_obj_type_t;
+
 // Constant objects, globally accessible
 
 extern const mp_obj_type_t mp_const_type;
@@ -241,6 +243,7 @@ typedef struct _mp_obj_fun_native_t { // need this so we can define const object
     // for const function objects, make an empty, const map
     // such functions won't be able to access the global scope, but that's probably okay
 } mp_obj_fun_native_t;
+
 extern const mp_obj_type_t fun_native_type;
 extern const mp_obj_type_t fun_bc_type;
 void mp_obj_fun_bc_get(mp_obj_t self_in, int *n_args, uint *n_state, const byte **code);
diff --git a/py/objbool.c b/py/objbool.c
index 77394dab991468e4225a02b660eecba3024f5ef4..cfab7db068e5a295841a611a94c747fa20601ef3 100644
--- a/py/objbool.c
+++ b/py/objbool.c
@@ -34,14 +34,8 @@ static mp_obj_t bool_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args
 const mp_obj_type_t bool_type = {
     { &mp_const_type },
     "bool",
-    bool_print, // print
-    bool_make_new, // make_new
-    NULL, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    NULL, // getiter
-    NULL, // iternext
-    .methods = {{NULL, NULL},},
+    .print = bool_print,
+    .make_new = bool_make_new,
 };
 
 static const mp_obj_bool_t false_obj = {{&bool_type}, false};
diff --git a/py/objboundmeth.c b/py/objboundmeth.c
index 4e6d2e01037d0298cc23dd8a954aff62ab40e45c..78e5c6249461b25eb52edd9a6d76cc705a944f78 100644
--- a/py/objboundmeth.c
+++ b/py/objboundmeth.c
@@ -36,14 +36,7 @@ mp_obj_t bound_meth_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
 const mp_obj_type_t bound_meth_type = {
     { &mp_const_type },
     "bound_method",
-    NULL, // print
-    NULL, // make_new
-    bound_meth_call_n, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    NULL, // getiter
-    NULL, // iternext
-    .methods = {{NULL, NULL},},
+    .call_n = bound_meth_call_n,
 };
 
 mp_obj_t mp_obj_new_bound_meth(mp_obj_t self, mp_obj_t meth) {
diff --git a/py/objcell.c b/py/objcell.c
index 3465f991981823c4633940bf56ee9afe95454615..264125bf3a0faae5397732fa767233e3d6101523 100644
--- a/py/objcell.c
+++ b/py/objcell.c
@@ -26,14 +26,6 @@ void mp_obj_cell_set(mp_obj_t self_in, mp_obj_t obj) {
 const mp_obj_type_t cell_type = {
     { &mp_const_type },
     "cell",
-    NULL, // print
-    NULL, // make_new
-    NULL, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    NULL, // getiter
-    NULL, // iternext
-    .methods = {{NULL, NULL},},
 };
 
 mp_obj_t mp_obj_new_cell(mp_obj_t obj) {
diff --git a/py/objclass.c b/py/objclass.c
index 536abdf7e3f0fa70fb345e12b93d9adc23efa304..d13d1775a496a65fb5c07bee865201258695ffe7 100644
--- a/py/objclass.c
+++ b/py/objclass.c
@@ -63,14 +63,7 @@ mp_map_t *mp_obj_class_get_locals(mp_obj_t self_in) {
 const mp_obj_type_t class_type = {
     { &mp_const_type },
     "class",
-    NULL, // print
-    NULL, // make_new
-    class_call_n, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    NULL, // getiter
-    NULL, // iternext
-    .methods = {{NULL, NULL},},
+    .call_n = class_call_n,
 };
 
 mp_obj_t mp_obj_new_class(mp_map_t *class_locals) {
diff --git a/py/objclosure.c b/py/objclosure.c
index 3317eb86f485b62c2237e075ce2f0cb0e740e12e..b372ee6fe74569b9b36c6c9a92956340dcb00a8e 100644
--- a/py/objclosure.c
+++ b/py/objclosure.c
@@ -35,14 +35,7 @@ mp_obj_t closure_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
 const mp_obj_type_t closure_type = {
     { &mp_const_type },
     "closure",
-    NULL, // print
-    NULL, // make_new
-    closure_call_n, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    NULL, // getiter
-    NULL, // iternext
-    .methods = {{NULL, NULL},},
+    .call_n = closure_call_n,
 };
 
 mp_obj_t mp_obj_new_closure(mp_obj_t fun, mp_obj_t closure_tuple) {
diff --git a/py/objcomplex.c b/py/objcomplex.c
index 46f43b54b5ac4f5376278176e832b16759c3c53e..1036bae420b4aea0e1d80427606c4efbd25e300b 100644
--- a/py/objcomplex.c
+++ b/py/objcomplex.c
@@ -87,14 +87,10 @@ static mp_obj_t complex_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
 const mp_obj_type_t complex_type = {
     { &mp_const_type },
     "complex",
-    complex_print, // print
-    complex_make_new, // make_new
-    NULL, // call_n
-    complex_unary_op, // unary_op
-    complex_binary_op, // binary_op
-    NULL, // getiter
-    NULL, // iternext
-    .methods = { { NULL, NULL }, },
+    .print = complex_print,
+    .make_new = complex_make_new,
+    .unary_op = complex_unary_op,
+    .binary_op = complex_binary_op,
 };
 
 mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag) {
diff --git a/py/objdict.c b/py/objdict.c
index b3e21aedd29c63c73a52cc51575450b94efb01eb..66a442fbaad32b408e60b9ee601585eacf0a4d5b 100644
--- a/py/objdict.c
+++ b/py/objdict.c
@@ -66,8 +66,6 @@ const mp_obj_type_t dict_type = {
     .print = dict_print,
     .make_new = dict_make_new,
     .binary_op = dict_binary_op,
-    .getiter = NULL,
-    .methods = {{NULL, NULL},},
 };
 
 mp_obj_t mp_obj_new_dict(int n_args) {
diff --git a/py/objexcept.c b/py/objexcept.c
index 22b8c58126018e1f07ddb0f2977509b0ae40a9bd..829b147853070c83182cb97d13bb51b0196fdba6 100644
--- a/py/objexcept.c
+++ b/py/objexcept.c
@@ -38,14 +38,7 @@ void exception_print(void (*print)(void *env, const char *fmt, ...), void *env,
 const mp_obj_type_t exception_type = {
     { &mp_const_type },
     "exception",
-    exception_print, // print
-    NULL, // make_new
-    NULL, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    NULL, // getiter
-    NULL, // iternext
-    .methods = {{NULL, NULL},},
+    .print = exception_print,
 };
 
 mp_obj_t mp_obj_new_exception(qstr id) {
diff --git a/py/objfloat.c b/py/objfloat.c
index 336ae597fc5460a51928c7abbf99e21a7e09ebfa..d21472d5d65abd13dc506992a802ad0f5ffc639f 100644
--- a/py/objfloat.c
+++ b/py/objfloat.c
@@ -68,7 +68,6 @@ const mp_obj_type_t float_type = {
     .make_new = float_make_new,
     .unary_op = float_unary_op,
     .binary_op = float_binary_op,
-    .methods = { { NULL, NULL }, },
 };
 
 mp_obj_t mp_obj_new_float(mp_float_t value) {
diff --git a/py/objfun.c b/py/objfun.c
index 0db6459a393d6e48a7b24bc17388922884ea8365..51b4329c63488ac4a7af8b449c01859a150e0d4e 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -72,16 +72,7 @@ mp_obj_t fun_native_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
 const mp_obj_type_t fun_native_type = {
     { &mp_const_type },
     "function",
-    NULL, // print
-    NULL, // make_new
-    fun_native_call_n, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    NULL, // getiter
-    NULL, // iternext
-    .methods = {
-        {NULL, NULL}, // end-of-list sentinel
-    },
+    .call_n = fun_native_call_n,
 };
 
 mp_obj_t rt_make_function_0(mp_fun_0_t fun) {
@@ -174,16 +165,7 @@ mp_obj_t fun_bc_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
 const mp_obj_type_t fun_bc_type = {
     { &mp_const_type },
     "function",
-    NULL, // print
-    NULL, // make_new
-    fun_bc_call_n, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    NULL, // getiter
-    NULL, // iternext
-    .methods = {
-        {NULL, NULL}, // end-of-list sentinel
-    },
+    .call_n = fun_bc_call_n,
 };
 
 mp_obj_t mp_obj_new_fun_bc(int n_args, uint n_state, const byte *code) {
@@ -288,16 +270,7 @@ mp_obj_t fun_asm_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
 static const mp_obj_type_t fun_asm_type = {
     { &mp_const_type },
     "function",
-    NULL, // print
-    NULL, // make_new
-    fun_asm_call_n, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    NULL, // getiter
-    NULL, // iternext
-    .methods = {
-        {NULL, NULL}, // end-of-list sentinel
-    },
+    .call_n = fun_asm_call_n,
 };
 
 mp_obj_t mp_obj_new_fun_asm(uint n_args, void *fun) {
diff --git a/py/objgenerator.c b/py/objgenerator.c
index a91b0d6fc6b26188f5fea3826e4ecbd7168b0375..7eeb4ef80be790b71888f6c095257435f4d2c1a5 100644
--- a/py/objgenerator.c
+++ b/py/objgenerator.c
@@ -39,14 +39,7 @@ mp_obj_t gen_wrap_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
 const mp_obj_type_t gen_wrap_type = {
     { &mp_const_type },
     "generator",
-    NULL, // print
-    NULL, // make_new
-    gen_wrap_call_n, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    NULL, // getiter
-    NULL, // iternext
-    .methods = {{NULL, NULL},},
+    .call_n = gen_wrap_call_n,
 };
 
 mp_obj_t mp_obj_new_gen_wrap(uint n_locals, uint n_stack, mp_obj_t fun) {
@@ -94,14 +87,9 @@ mp_obj_t gen_instance_iternext(mp_obj_t self_in) {
 const mp_obj_type_t gen_instance_type = {
     { &mp_const_type },
     "generator",
-    gen_instance_print, // print
-    NULL, // make_new
-    NULL, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    gen_instance_getiter, // getiter
-    gen_instance_iternext, // iternext
-    .methods = {{NULL, NULL},},
+    .print = gen_instance_print,
+    .getiter = gen_instance_getiter,
+    .iternext = gen_instance_iternext,
 };
 
 // args are in reverse order in the array
diff --git a/py/objinstance.c b/py/objinstance.c
index 8ef2773fd944be8f235cbb5fc225139273733555..209643e2bfea637e2cc441f603983d36d075b245 100644
--- a/py/objinstance.c
+++ b/py/objinstance.c
@@ -92,14 +92,6 @@ void mp_obj_instance_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) {
 const mp_obj_type_t instance_type = {
     { &mp_const_type },
     "instance",
-    NULL, // print
-    NULL, // make_new
-    NULL, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    NULL, // getiter
-    NULL, // iternext
-    .methods = {{NULL, NULL},},
 };
 
 mp_obj_t mp_obj_new_instance(mp_obj_t class) {
diff --git a/py/objint.c b/py/objint.c
index 8d69c4e7a76ba2339774ab2aec949463cf6f71e3..9cd5ebae295a9156a30e47872e1d39a59b95b850 100644
--- a/py/objint.c
+++ b/py/objint.c
@@ -34,7 +34,6 @@ const mp_obj_type_t int_type = {
     { &mp_const_type },
     "int",
     .make_new = int_make_new,
-    .methods = { { NULL, NULL }, },
 };
 
 mp_obj_t mp_obj_new_int(machine_int_t value) {
diff --git a/py/objlist.c b/py/objlist.c
index 02a6b1525b1e1a0b6d5534e756ecfc524e700fd3..df9e1974f9dfa5bb49d714f0ca9fd1f28a2aa540 100644
--- a/py/objlist.c
+++ b/py/objlist.c
@@ -57,6 +57,7 @@ static mp_obj_t list_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args
         default:
             nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "list takes at most 1 argument, %d given", (void*)(machine_int_t)n_args));
     }
+    return NULL;
 }
 
 static mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
@@ -260,27 +261,28 @@ static MP_DEFINE_CONST_FUN_OBJ_2(list_remove_obj, list_remove);
 static MP_DEFINE_CONST_FUN_OBJ_1(list_reverse_obj, list_reverse);
 static MP_DEFINE_CONST_FUN_OBJ_2(list_sort_obj, list_sort);
 
+static const mp_method_t list_type_methods[] = {
+    { "append", &list_append_obj },
+    { "clear", &list_clear_obj },
+    { "copy", &list_copy_obj },
+    { "count", &list_count_obj },
+    { "index", &list_index_obj },
+    { "insert", &list_insert_obj },
+    { "pop", &list_pop_obj },
+    { "remove", &list_remove_obj },
+    { "reverse", &list_reverse_obj },
+    { "sort", &list_sort_obj },
+    { NULL, NULL }, // end-of-list sentinel
+};
+
 const mp_obj_type_t list_type = {
     { &mp_const_type },
     "list",
     .print = list_print,
     .make_new = list_make_new,
-    .unary_op = NULL,
     .binary_op = list_binary_op,
     .getiter = list_getiter,
-    .methods = {
-        { "append", &list_append_obj },
-        { "clear", &list_clear_obj },
-        { "copy", &list_copy_obj },
-        { "count", &list_count_obj },
-        { "index", &list_index_obj },
-        { "insert", &list_insert_obj },
-        { "pop", &list_pop_obj },
-        { "remove", &list_remove_obj },
-        { "reverse", &list_reverse_obj },
-        { "sort", &list_sort_obj },
-        { NULL, NULL }, // end-of-list sentinel
-    },
+    .methods = list_type_methods,
 };
 
 static mp_obj_list_t *list_new(uint n) {
@@ -344,7 +346,6 @@ static const mp_obj_type_t list_it_type = {
     { &mp_const_type },
     "list_iterator",
     .iternext = list_it_iternext,
-    .methods = { { NULL, NULL }, },
 };
 
 mp_obj_t mp_obj_new_list_iterator(mp_obj_list_t *list, int cur) {
diff --git a/py/objmodule.c b/py/objmodule.c
index 2d6f9555e8b783a2df480a1031f6f6efecf583be..3e7a0f7fc48fa06e4e758d71a7047b79005775b9 100644
--- a/py/objmodule.c
+++ b/py/objmodule.c
@@ -24,14 +24,7 @@ void module_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_
 const mp_obj_type_t module_type = {
     { &mp_const_type },
     "module",
-    module_print, // print
-    NULL, // make_new
-    NULL, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    NULL, // getiter
-    NULL, // iternext
-    .methods = {{NULL, NULL},},
+    .print = module_print,
 };
 
 mp_obj_t mp_obj_new_module(qstr module_name) {
diff --git a/py/objnone.c b/py/objnone.c
index 877e61fe5cc9818578a84167a8bc52f4b872d115..c0efe6c0f5914bf28b80b87b2c97540f031d09fe 100644
--- a/py/objnone.c
+++ b/py/objnone.c
@@ -18,7 +18,6 @@ const mp_obj_type_t none_type = {
     { &mp_const_type },
     "NoneType",
     .print = none_print,
-    .methods = {{NULL, NULL},},
 };
 
 static const mp_obj_none_t none_obj = {{&none_type}};
diff --git a/py/objrange.c b/py/objrange.c
index 1ef42673f48d1ee0e8500846a83144d88cd1c869..a2a0e67b00bc31a384b8580ff89658a0fc547106 100644
--- a/py/objrange.c
+++ b/py/objrange.c
@@ -25,14 +25,7 @@ mp_obj_t range_getiter(mp_obj_t o_in) {
 static const mp_obj_type_t range_type = {
     { &mp_const_type} ,
     "range",
-    NULL, // print
-    NULL, // make_new
-    NULL, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    range_getiter,
-    NULL, // iternext
-    .methods = {{NULL, NULL},},
+    .getiter = range_getiter,
 };
 
 // range is a class and instances are immutable sequence objects
@@ -70,14 +63,7 @@ mp_obj_t range_it_iternext(mp_obj_t o_in) {
 static const mp_obj_type_t range_it_type = {
     { &mp_const_type },
     "range_iterator",
-    NULL, // print
-    NULL, // make_new
-    NULL, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    NULL, // getiter
-    range_it_iternext,
-    .methods = {{NULL, NULL},},
+    .iternext = range_it_iternext,
 };
 
 mp_obj_t mp_obj_new_range_iterator(int cur, int stop, int step) {
diff --git a/py/objset.c b/py/objset.c
index dd9a4d1e1d9ea389bbbb16e55c3a188532973517..67dab11dfb6cad7955d09370a127439f3343ffea 100644
--- a/py/objset.c
+++ b/py/objset.c
@@ -57,14 +57,8 @@ static mp_obj_t set_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args)
 const mp_obj_type_t set_type = {
     { &mp_const_type },
     "set",
-    set_print, // print
-    set_make_new, // make_new
-    NULL, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    NULL, // getiter
-    NULL, // iternext
-    .methods = { { NULL, NULL }, },
+    .print = set_print,
+    .make_new = set_make_new,
 };
 
 mp_obj_t mp_obj_new_set(int n_args, mp_obj_t *items) {
diff --git a/py/objslice.c b/py/objslice.c
index da69b92af271afded155e9df6064c5ad881edd2d..d95ccef06fc06544da34a1b72df58cfb975eb6ad 100644
--- a/py/objslice.c
+++ b/py/objslice.c
@@ -23,14 +23,7 @@ void ellipsis_print(void (*print)(void *env, const char *fmt, ...), void *env, m
 const mp_obj_type_t ellipsis_type = {
     { &mp_const_type },
     "ellipsis",
-    ellipsis_print, // print
-    NULL, // make_new
-    NULL, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    NULL, // getiter
-    NULL, // iternext
-    .methods = {{NULL, NULL},},
+    .print = ellipsis_print,
 };
 
 static const mp_obj_ellipsis_t ellipsis_obj = {{&ellipsis_type}};
@@ -58,7 +51,6 @@ const mp_obj_type_t slice_type = {
     { &mp_const_type },
     "slice",
     .print = slice_print,
-    .methods = { { NULL, NULL }, },
 };
 
 // TODO: Make sure to handle "empty" values, which are signified by None in CPython
diff --git a/py/objstr.c b/py/objstr.c
index db3e0beca0a85051ad887ea4a97e9949c6b45324..cc9f7f85b49567b27461e0433665fc0ff2f8f0c1 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -184,17 +184,19 @@ mp_obj_t str_format(int n_args, const mp_obj_t *args) {
 static MP_DEFINE_CONST_FUN_OBJ_2(str_join_obj, str_join);
 static MP_DEFINE_CONST_FUN_OBJ_VAR(str_format_obj, 1, str_format);
 
+static const mp_method_t str_type_methods[] = {
+    { "join", &str_join_obj },
+    { "format", &str_format_obj },
+    { NULL, NULL }, // end-of-list sentinel
+};
+
 const mp_obj_type_t str_type = {
     { &mp_const_type },
     "str",
     .print = str_print,
     .binary_op = str_binary_op,
     .getiter = str_getiter,
-    .methods = {
-        { "join", &str_join_obj },
-        { "format", &str_format_obj },
-        { NULL, NULL }, // end-of-list sentinel
-    },
+    .methods = str_type_methods,
 };
 
 mp_obj_t mp_obj_new_str(qstr qstr) {
@@ -235,7 +237,6 @@ static const mp_obj_type_t str_it_type = {
     { &mp_const_type },
     "str_iterator",
     .iternext = str_it_iternext,
-    .methods = { { NULL, NULL }, },
 };
 
 mp_obj_t mp_obj_new_str_iterator(mp_obj_str_t *str, int cur) {
diff --git a/py/objtuple.c b/py/objtuple.c
index ceca4200e4ee7ddd6f90995ecc8437f6ffe6f996..593b14e9f553900627413f6afef0858c8e5c2049 100644
--- a/py/objtuple.c
+++ b/py/objtuple.c
@@ -103,7 +103,6 @@ const mp_obj_type_t tuple_type = {
     .make_new = tuple_make_new,
     .binary_op = tuple_binary_op,
     .getiter = tuple_getiter,
-    .methods = {{NULL, NULL},},
 };
 
 // the zero-length tuple
@@ -166,7 +165,6 @@ static const mp_obj_type_t tuple_it_type = {
     { &mp_const_type },
     "tuple_iterator",
     .iternext = tuple_it_iternext,
-    .methods = {{NULL, NULL},},
 };
 
 static mp_obj_t mp_obj_new_tuple_iterator(mp_obj_tuple_t *tuple, int cur) {
diff --git a/py/objtype.c b/py/objtype.c
index 37d40b38f4dabd1040d01358e1e3622ba5fcd16f..8778c180caf868c1855b2f707e2631389b782c4c 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -27,5 +27,4 @@ const mp_obj_type_t mp_const_type = {
     "type",
     .print = type_print,
     .call_n = type_call_n,
-    .methods = {{NULL, NULL},},
 };
diff --git a/py/runtime.c b/py/runtime.c
index 6bc71abff7ea742fa3199e1db6f7b02655785220..0457f0df41660bd79fa70eec3f6c57fb75542f6f 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -775,10 +775,12 @@ mp_obj_t rt_load_attr(mp_obj_t base, qstr attr) {
     } else if (MP_OBJ_IS_OBJ(base)) {
         // generic method lookup
         mp_obj_base_t *o = base;
-        const mp_method_t *meth = &o->type->methods[0];
-        for (; meth->name != NULL; meth++) {
-            if (strcmp(meth->name, qstr_str(attr)) == 0) {
-                return mp_obj_new_bound_meth(base, (mp_obj_t)meth->fun);
+        const mp_method_t *meth = o->type->methods;
+        if (meth != NULL) {
+            for (; meth->name != NULL; meth++) {
+                if (strcmp(meth->name, qstr_str(attr)) == 0) {
+                    return mp_obj_new_bound_meth(base, (mp_obj_t)meth->fun);
+                }
             }
         }
     }
@@ -799,12 +801,14 @@ void rt_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) {
     } else if (MP_OBJ_IS_OBJ(base)) {
         // generic method lookup
         mp_obj_base_t *o = base;
-        const mp_method_t *meth = &o->type->methods[0];
-        for (; meth->name != NULL; meth++) {
-            if (strcmp(meth->name, qstr_str(attr)) == 0) {
-                dest[1] = (mp_obj_t)meth->fun;
-                dest[0] = base;
-                return;
+        const mp_method_t *meth = o->type->methods;
+        if (meth != NULL) {
+            for (; meth->name != NULL; meth++) {
+                if (strcmp(meth->name, qstr_str(attr)) == 0) {
+                    dest[1] = (mp_obj_t)meth->fun;
+                    dest[0] = base;
+                    return;
+                }
             }
         }
     }
diff --git a/stm/i2c.c b/stm/i2c.c
index 9e25ff9839dcff7ad8c9ac41c2cd5bd5b7d430fb..22c908566d251c0b013b0b738858ef12b23b3be1 100644
--- a/stm/i2c.c
+++ b/stm/i2c.c
@@ -326,18 +326,20 @@ static MP_DEFINE_CONST_FUN_OBJ_1(i2c_obj_read_obj, i2c_obj_read);
 static MP_DEFINE_CONST_FUN_OBJ_1(i2c_obj_readAndStop_obj, i2c_obj_readAndStop);
 static MP_DEFINE_CONST_FUN_OBJ_1(i2c_obj_stop_obj, i2c_obj_stop);
 
+static const mp_method_t i2c_methods[] = {
+    { "start", &i2c_obj_start_obj },
+    { "write", &i2c_obj_write_obj },
+    { "read", &i2c_obj_read_obj },
+    { "readAndStop", &i2c_obj_readAndStop_obj },
+    { "stop", &i2c_obj_stop_obj },
+    { NULL, NULL },
+};
+
 static const mp_obj_type_t i2c_obj_type = {
     { &mp_const_type },
     "I2C",
     .print = i2c_obj_print,
-    .methods = {
-        { "start", &i2c_obj_start_obj },
-        { "write", &i2c_obj_write_obj },
-        { "read", &i2c_obj_read_obj },
-        { "readAndStop", &i2c_obj_readAndStop_obj },
-        { "stop", &i2c_obj_stop_obj },
-        { NULL, NULL },
-    }
+    .methods = i2c_methods,
 };
 
 // create the I2C object
diff --git a/stm/led.c b/stm/led.c
index d4bc0a0c8764270d0a05190d362e012da1c8394e..eb7c76ef1f0a6e7f47a7ffd27148101e435ce833 100644
--- a/stm/led.c
+++ b/stm/led.c
@@ -176,15 +176,17 @@ mp_obj_t led_obj_off(mp_obj_t self_in) {
 static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on);
 static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off);
 
+static const mp_method_t led_methods[] = {
+    { "on", &led_obj_on_obj },
+    { "off", &led_obj_off_obj },
+    { NULL, NULL },
+};
+
 static const mp_obj_type_t led_obj_type = {
     { &mp_const_type },
     "Led",
     .print = led_obj_print,
-    .methods = {
-        { "on", &led_obj_on_obj },
-        { "off", &led_obj_off_obj },
-        { NULL, NULL },
-    }
+    .methods = led_methods,
 };
 
 mp_obj_t pyb_Led(mp_obj_t led_id) {
diff --git a/stm/main.c b/stm/main.c
index 07c974eff82245c8a795e27ee73ac2d76e958895..a038c89b74a90ff18fd5c7fec85500ecb099c897 100644
--- a/stm/main.c
+++ b/stm/main.c
@@ -689,22 +689,18 @@ static MP_DEFINE_CONST_FUN_OBJ_1(file_obj_close_obj, file_obj_close);
 
 // TODO gc hook to close the file if not already closed
 
+static const mp_method_t file_methods[] = {
+    { "read", &file_obj_read_obj },
+    { "write", &file_obj_write_obj },
+    { "close", &file_obj_close_obj },
+    {NULL, NULL},
+};
+
 static const mp_obj_type_t file_obj_type = {
     { &mp_const_type },
     "File",
-    file_obj_print, // print
-    NULL, // make_new
-    NULL, // call_n
-    NULL, // unary_op
-    NULL, // binary_op
-    NULL, // getiter
-    NULL, // iternext
-    .methods = {
-        { "read", &file_obj_read_obj },
-        { "write", &file_obj_write_obj },
-        { "close", &file_obj_close_obj },
-        {NULL, NULL},
-    }
+    .print = file_obj_print,
+    .methods = file_methods,
 };
 
 mp_obj_t pyb_io_open(mp_obj_t o_filename, mp_obj_t o_mode) {
diff --git a/stm/servo.c b/stm/servo.c
index 31190ce795e82b834bee4ebde5aecf91965327ef..cc9633a99603e99c9bc77f9415e42f67880fad36 100644
--- a/stm/servo.c
+++ b/stm/servo.c
@@ -137,14 +137,16 @@ static mp_obj_t servo_obj_angle(mp_obj_t self_in, mp_obj_t angle) {
 
 static MP_DEFINE_CONST_FUN_OBJ_2(servo_obj_angle_obj, servo_obj_angle);
 
+static const mp_method_t servo_methods[] = {
+    { "angle", &servo_obj_angle_obj },
+    { NULL, NULL },
+};
+
 static const mp_obj_type_t servo_obj_type = {
     { &mp_const_type },
     "Servo",
     .print = servo_obj_print,
-    .methods = {
-        { "angle", &servo_obj_angle_obj },
-        { NULL, NULL },
-    }
+    .methods = servo_methods,
 };
 
 mp_obj_t pyb_Servo(mp_obj_t servo_id) {
diff --git a/unix/main.c b/unix/main.c
index f7277b960c4f90bab3efa58699c113e49e9460b3..920aed3444adfaf10c7872bdbf262f78c579f756 100644
--- a/unix/main.c
+++ b/unix/main.c
@@ -154,7 +154,7 @@ static void do_str(const char *str) {
 
 typedef struct _test_obj_t {
     mp_obj_base_t base;
-    bool value;
+    int value;
 } test_obj_t;
 
 static void test_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
@@ -176,15 +176,17 @@ static mp_obj_t test_set(mp_obj_t self_in, mp_obj_t arg) {
 static MP_DEFINE_CONST_FUN_OBJ_1(test_get_obj, test_get);
 static MP_DEFINE_CONST_FUN_OBJ_2(test_set_obj, test_set);
 
+static const mp_method_t test_methods[] = {
+    { "get", &test_get_obj },
+    { "set", &test_set_obj },
+    { NULL, NULL },
+};
+
 static const mp_obj_type_t test_type = {
     { &mp_const_type },
     "Test",
     .print = test_print,
-    .methods = {
-        { "get", &test_get_obj },
-        { "set", &test_set_obj },
-        { NULL, NULL },
-    }
+    .methods = test_methods,
 };
 
 mp_obj_t test_obj_new(int value) {