py: Change first arg of type.make_new from mp_obj_t to mp_obj_type_t*.

The first argument to the type.make_new method is naturally a uPy type,
and all uses of this argument cast it directly to a pointer to a type
structure.  So it makes sense to just have it a pointer to a type from
the very beginning (and a const pointer at that).  This patch makes
such a change, and removes all unnecessary casting to/from mp_obj_t.
diff --git a/cc3200/mods/modnetwork.c b/cc3200/mods/modnetwork.c
index b11b036..44d3169 100644
--- a/cc3200/mods/modnetwork.c
+++ b/cc3200/mods/modnetwork.c
@@ -91,7 +91,7 @@
     { MP_QSTR_login,        MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
     { MP_QSTR_timeout,      MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
 };
-STATIC mp_obj_t network_server_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
+STATIC mp_obj_t network_server_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
     // parse args
     mp_map_t kw_args;
     mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
diff --git a/cc3200/mods/modusocket.c b/cc3200/mods/modusocket.c
index 622a026..e5b043d 100644
--- a/cc3200/mods/modusocket.c
+++ b/cc3200/mods/modusocket.c
@@ -125,7 +125,7 @@
 // socket class
 
 // constructor socket(family=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP, fileno=None)
-STATIC mp_obj_t socket_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     mp_arg_check_num(n_args, n_kw, 0, 4, false);
 
     // create socket object
diff --git a/cc3200/mods/modwlan.c b/cc3200/mods/modwlan.c
index a7ee592..0e249d2 100644
--- a/cc3200/mods/modwlan.c
+++ b/cc3200/mods/modwlan.c
@@ -821,7 +821,7 @@
     { MP_QSTR_channel,      MP_ARG_KW_ONLY  | MP_ARG_INT,  {.u_int = 1} },
     { MP_QSTR_antenna,      MP_ARG_KW_ONLY  | MP_ARG_INT,  {.u_int = ANTENNA_TYPE_INTERNAL} },
 };
-STATIC mp_obj_t wlan_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
+STATIC mp_obj_t wlan_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
     // parse args
     mp_map_t kw_args;
     mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
diff --git a/cc3200/mods/pybadc.c b/cc3200/mods/pybadc.c
index 005c365..22a90ed 100644
--- a/cc3200/mods/pybadc.c
+++ b/cc3200/mods/pybadc.c
@@ -140,7 +140,7 @@
     { MP_QSTR_id,                          MP_ARG_INT, {.u_int = 0} },
     { MP_QSTR_bits,       MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 12} },
 };
-STATIC mp_obj_t adc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
+STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
     // parse args
     mp_map_t kw_args;
     mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
diff --git a/cc3200/mods/pybi2c.c b/cc3200/mods/pybi2c.c
index 52a0851..6c64c3d 100644
--- a/cc3200/mods/pybi2c.c
+++ b/cc3200/mods/pybi2c.c
@@ -319,7 +319,7 @@
     { MP_QSTR_baudrate,  MP_ARG_KW_ONLY  | MP_ARG_INT, {.u_int = 100000} },
     { MP_QSTR_pins,      MP_ARG_KW_ONLY  | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
 };
-STATIC mp_obj_t pyb_i2c_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
+STATIC mp_obj_t pyb_i2c_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
     // parse args
     mp_map_t kw_args;
     mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
diff --git a/cc3200/mods/pybpin.c b/cc3200/mods/pybpin.c
index ce0e386..a8a19a1 100644
--- a/cc3200/mods/pybpin.c
+++ b/cc3200/mods/pybpin.c
@@ -648,7 +648,7 @@
     mp_printf(print, ", alt=%d)", alt);
 }
 
-STATIC mp_obj_t pin_make_new(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pin_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
 
     // Run an argument through the mapper and return the result.
diff --git a/cc3200/mods/pybrtc.c b/cc3200/mods/pybrtc.c
index 8d6b9b1..ea99411 100644
--- a/cc3200/mods/pybrtc.c
+++ b/cc3200/mods/pybrtc.c
@@ -285,7 +285,7 @@
     { MP_QSTR_id,                             MP_ARG_INT, {.u_int = 0} },
     { MP_QSTR_datetime,                       MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
 };
-STATIC mp_obj_t pyb_rtc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
+STATIC mp_obj_t pyb_rtc_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
     // parse args
     mp_map_t kw_args;
     mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
diff --git a/cc3200/mods/pybsd.c b/cc3200/mods/pybsd.c
index ea81f30..55b797d 100644
--- a/cc3200/mods/pybsd.c
+++ b/cc3200/mods/pybsd.c
@@ -64,7 +64,7 @@
  DECLARE PRIVATE FUNCTIONS
  ******************************************************************************/
 STATIC void pyb_sd_hw_init (pybsd_obj_t *self);
-STATIC mp_obj_t pyb_sd_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args);
+STATIC mp_obj_t pyb_sd_make_new (const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args);
 STATIC mp_obj_t pyb_sd_deinit (mp_obj_t self_in);
 
 /******************************************************************************
@@ -123,7 +123,7 @@
     { MP_QSTR_id,                          MP_ARG_INT, {.u_int = 0} },
     { MP_QSTR_pins,                        MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
 };
-STATIC mp_obj_t pyb_sd_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
+STATIC mp_obj_t pyb_sd_make_new (const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
     // parse args
     mp_map_t kw_args;
     mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
diff --git a/cc3200/mods/pybspi.c b/cc3200/mods/pybspi.c
index b7e4310..d4fcbe9 100644
--- a/cc3200/mods/pybspi.c
+++ b/cc3200/mods/pybspi.c
@@ -231,7 +231,7 @@
     { MP_QSTR_firstbit,     MP_ARG_KW_ONLY  | MP_ARG_INT,  {.u_int = PYBSPI_FIRST_BIT_MSB} },
     { MP_QSTR_pins,         MP_ARG_KW_ONLY  | MP_ARG_OBJ,  {.u_obj = MP_OBJ_NULL} },
 };
-STATIC mp_obj_t pyb_spi_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
+STATIC mp_obj_t pyb_spi_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
     // parse args
     mp_map_t kw_args;
     mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
diff --git a/cc3200/mods/pybtimer.c b/cc3200/mods/pybtimer.c
index 95eeb08..6a74f5a 100644
--- a/cc3200/mods/pybtimer.c
+++ b/cc3200/mods/pybtimer.c
@@ -356,7 +356,7 @@
 /// Construct a new timer object of the given id.  If additional
 /// arguments are given, then the timer is initialised by `init(...)`.
 /// `id` can be 1 to 4
-STATIC mp_obj_t pyb_timer_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_timer_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
 
diff --git a/cc3200/mods/pybuart.c b/cc3200/mods/pybuart.c
index 660453b..87d89f0 100644
--- a/cc3200/mods/pybuart.c
+++ b/cc3200/mods/pybuart.c
@@ -443,7 +443,7 @@
     { MP_QSTR_stop,                           MP_ARG_INT,  {.u_int = 1} },
     { MP_QSTR_pins,         MP_ARG_KW_ONLY  | MP_ARG_OBJ,  {.u_obj = MP_OBJ_NULL} },
 };
-STATIC mp_obj_t pyb_uart_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
+STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
     // parse args
     mp_map_t kw_args;
     mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
diff --git a/cc3200/mods/pybwdt.c b/cc3200/mods/pybwdt.c
index 8448054..6e5fe47 100644
--- a/cc3200/mods/pybwdt.c
+++ b/cc3200/mods/pybwdt.c
@@ -92,7 +92,7 @@
     { MP_QSTR_id,                             MP_ARG_OBJ,  {.u_obj = mp_const_none} },
     { MP_QSTR_timeout,                        MP_ARG_INT,  {.u_int = 5000} },   // 5 s
 };
-STATIC mp_obj_t pyb_wdt_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
+STATIC mp_obj_t pyb_wdt_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
     // check the arguments
     mp_map_t kw_args;
     mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
diff --git a/esp8266/modesp.c b/esp8266/modesp.c
index f6f6016..c408cec 100644
--- a/esp8266/modesp.c
+++ b/esp8266/modesp.c
@@ -82,7 +82,7 @@
 
 // constructor esp_socket(family=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP, fileno=None)
 // Arguments ignored as we do not support UDP (yet)
-STATIC mp_obj_t esp_socket_make_new(mp_obj_t type_in, mp_uint_t n_args,
+STATIC mp_obj_t esp_socket_make_new(const mp_obj_type_t *type_in, mp_uint_t n_args,
     mp_uint_t n_kw, const mp_obj_t *args) {
     mp_arg_check_num(n_args, n_kw, 0, 4, false);
 
diff --git a/esp8266/modpybadc.c b/esp8266/modpybadc.c
index ade63df..26b28c5 100644
--- a/esp8266/modpybadc.c
+++ b/esp8266/modpybadc.c
@@ -42,7 +42,7 @@
 STATIC pyb_adc_obj_t pyb_adc_vdd3 = {{&pyb_adc_type}, true};
 STATIC pyb_adc_obj_t pyb_adc_adc = {{&pyb_adc_type}, false};
 
-STATIC mp_obj_t pyb_adc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw,
+STATIC mp_obj_t pyb_adc_make_new(const mp_obj_type_t *type_in, mp_uint_t n_args, mp_uint_t n_kw,
     const mp_obj_t *args) {
     mp_arg_check_num(n_args, n_kw, 1, 1, false);
 
diff --git a/esp8266/modpybpin.c b/esp8266/modpybpin.c
index a2ab985..3c3aebe 100644
--- a/esp8266/modpybpin.c
+++ b/esp8266/modpybpin.c
@@ -119,7 +119,7 @@
 }
 
 // constructor(id, ...)
-STATIC mp_obj_t pyb_pin_make_new(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_pin_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
 
     // Run an argument through the mapper and return the result.
diff --git a/esp8266/modpybrtc.c b/esp8266/modpybrtc.c
index 1156216..6c2dde6 100644
--- a/esp8266/modpybrtc.c
+++ b/esp8266/modpybrtc.c
@@ -49,7 +49,7 @@
 // singleton RTC object
 STATIC const pyb_rtc_obj_t pyb_rtc_obj = {{&pyb_rtc_type}};
 
-STATIC mp_obj_t pyb_rtc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_rtc_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 0, 0, false);
 
diff --git a/extmod/moductypes.c b/extmod/moductypes.c
index cd7e9d1..9b07838 100644
--- a/extmod/moductypes.c
+++ b/extmod/moductypes.c
@@ -121,10 +121,10 @@
     nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "syntax error in uctypes descriptor"));
 }
 
-STATIC mp_obj_t uctypes_struct_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t uctypes_struct_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     mp_arg_check_num(n_args, n_kw, 2, 3, false);
     mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
-    o->base.type = MP_OBJ_TO_PTR(type_in);
+    o->base.type = type;
     o->addr = (void*)(uintptr_t)mp_obj_get_int(args[0]);
     o->desc = args[1];
     o->flags = LAYOUT_NATIVE;
diff --git a/extmod/moduhashlib.c b/extmod/moduhashlib.c
index 6ddfa61..8694357 100644
--- a/extmod/moduhashlib.c
+++ b/extmod/moduhashlib.c
@@ -41,10 +41,10 @@
 
 STATIC mp_obj_t hash_update(mp_obj_t self_in, mp_obj_t arg);
 
-STATIC mp_obj_t hash_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t hash_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     mp_arg_check_num(n_args, n_kw, 0, 1, false);
     mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX));
-    o->base.type = MP_OBJ_TO_PTR(type_in);
+    o->base.type = type;
     sha256_init((CRYAL_SHA256_CTX*)o->state);
     if (n_args == 1) {
         hash_update(MP_OBJ_FROM_PTR(o), args[0]);
diff --git a/py/modbuiltins.c b/py/modbuiltins.c
index 5377411..05bdbfe 100644
--- a/py/modbuiltins.c
+++ b/py/modbuiltins.c
@@ -512,7 +512,7 @@
         nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
                                           "must use keyword argument for key function"));
     }
-    mp_obj_t self = mp_type_list.make_new(MP_OBJ_FROM_PTR(&mp_type_list), 1, 0, args);
+    mp_obj_t self = mp_type_list.make_new(&mp_type_list, 1, 0, args);
     mp_obj_list_sort(1, &self, kwargs);
 
     return self;
diff --git a/py/obj.h b/py/obj.h
index 52b8b4f..14c3a81 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -42,12 +42,14 @@
 typedef machine_const_ptr_t mp_const_obj_t;
 #endif
 
-// Anything that wants to be a Micro Python object must have
-// mp_obj_base_t as its first member (except small ints and qstrs)
+// This mp_obj_type_t struct is a concrete MicroPython object which holds info
+// about a type.  See below for actual definition of the struct.
+typedef struct _mp_obj_type_t mp_obj_type_t;
 
-struct _mp_obj_type_t;
+// Anything that wants to be a concrete MicroPython object must have mp_obj_base_t
+// as its first member (small ints, qstr objs and inline floats are not concrete).
 struct _mp_obj_base_t {
-    const struct _mp_obj_type_t *type MICROPY_OBJ_BASE_ALIGNMENT;
+    const mp_obj_type_t *type MICROPY_OBJ_BASE_ALIGNMENT;
 };
 typedef struct _mp_obj_base_t mp_obj_base_t;
 
@@ -259,8 +261,8 @@
 //static inline bool MP_OBJ_IS_TYPE(mp_const_obj_t o, const mp_obj_type_t *t) { return (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t*)(o))->type == (t))); } // this does not work for checking a string, use below macro for that
 //static inline bool MP_OBJ_IS_INT(mp_const_obj_t o) { return (MP_OBJ_IS_SMALL_INT(o) || MP_OBJ_IS_TYPE(o, &mp_type_int)); } // returns true if o is a small int or long int
 // Need to forward declare these for the inline function to compile.
-extern const struct _mp_obj_type_t mp_type_int;
-extern const struct _mp_obj_type_t mp_type_bool;
+extern const mp_obj_type_t mp_type_int;
+extern const mp_obj_type_t mp_type_bool;
 static inline bool mp_obj_is_integer(mp_const_obj_t o) { return MP_OBJ_IS_INT(o) || MP_OBJ_IS_TYPE(o, &mp_type_bool); } // returns true if o is bool, small int or long int
 //static inline bool MP_OBJ_IS_STR(mp_const_obj_t o) { return (MP_OBJ_IS_QSTR(o) || MP_OBJ_IS_TYPE(o, &mp_type_str)); }
 
@@ -408,7 +410,7 @@
 } mp_print_kind_t;
 
 typedef void (*mp_print_fun_t)(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind);
-typedef mp_obj_t (*mp_make_new_fun_t)(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args);
+typedef mp_obj_t (*mp_make_new_fun_t)(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args);
 typedef mp_obj_t (*mp_call_fun_t)(mp_obj_t fun, size_t n_args, size_t n_kw, const mp_obj_t *args);
 typedef mp_obj_t (*mp_unary_op_fun_t)(mp_uint_t op, mp_obj_t);
 typedef mp_obj_t (*mp_binary_op_fun_t)(mp_uint_t op, mp_obj_t, mp_obj_t);
@@ -510,8 +512,6 @@
     */
 };
 
-typedef struct _mp_obj_type_t mp_obj_type_t;
-
 // Constant types, globally accessible
 extern const mp_obj_type_t mp_type_type;
 extern const mp_obj_type_t mp_type_object;
@@ -691,7 +691,7 @@
 void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qstr block);
 void mp_obj_exception_get_traceback(mp_obj_t self_in, size_t *n, size_t **values);
 mp_obj_t mp_obj_exception_get_value(mp_obj_t self_in);
-mp_obj_t mp_obj_exception_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args);
+mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args);
 mp_obj_t mp_alloc_emergency_exception_buf(mp_obj_t size_in);
 void mp_init_emergency_exception_buf(void);
 
diff --git a/py/objarray.c b/py/objarray.c
index 2c4813f..a17ae27 100644
--- a/py/objarray.c
+++ b/py/objarray.c
@@ -168,7 +168,7 @@
 #endif
 
 #if MICROPY_PY_ARRAY
-STATIC mp_obj_t array_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t array_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     (void)type_in;
     mp_arg_check_num(n_args, n_kw, 1, 2, false);
 
@@ -187,7 +187,7 @@
 #endif
 
 #if MICROPY_PY_BUILTINS_BYTEARRAY
-STATIC mp_obj_t bytearray_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t bytearray_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     (void)type_in;
     mp_arg_check_num(n_args, n_kw, 0, 1, false);
 
@@ -219,7 +219,7 @@
     return MP_OBJ_FROM_PTR(self);
 }
 
-STATIC mp_obj_t memoryview_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t memoryview_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     (void)type_in;
 
     // TODO possibly allow memoryview constructor to take start/stop so that one
diff --git a/py/objbool.c b/py/objbool.c
index 09878a7..8882a83 100644
--- a/py/objbool.c
+++ b/py/objbool.c
@@ -52,7 +52,7 @@
     }
 }
 
-STATIC mp_obj_t bool_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t bool_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     (void)type_in;
     mp_arg_check_num(n_args, n_kw, 0, 1, false);
 
diff --git a/py/objcomplex.c b/py/objcomplex.c
index df0467e..5da655e 100644
--- a/py/objcomplex.c
+++ b/py/objcomplex.c
@@ -69,7 +69,7 @@
     }
 }
 
-STATIC mp_obj_t complex_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t complex_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     (void)type_in;
     mp_arg_check_num(n_args, n_kw, 0, 2, false);
 
diff --git a/py/objdict.c b/py/objdict.c
index cb4c602..cc1f502 100644
--- a/py/objdict.c
+++ b/py/objdict.c
@@ -82,12 +82,12 @@
     }
 }
 
-STATIC mp_obj_t dict_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t dict_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     mp_obj_t dict_out = mp_obj_new_dict(0);
     mp_obj_dict_t *dict = MP_OBJ_TO_PTR(dict_out);
-    dict->base.type = MP_OBJ_TO_PTR(type_in);
+    dict->base.type = type;
     #if MICROPY_PY_COLLECTIONS_ORDEREDDICT
-    if (MP_OBJ_TO_PTR(type_in) == &mp_type_ordereddict) {
+    if (type == &mp_type_ordereddict) {
         dict->map.is_ordered = 1;
     }
     #endif
diff --git a/py/objenumerate.c b/py/objenumerate.c
index 46c3e80..26a5740 100644
--- a/py/objenumerate.c
+++ b/py/objenumerate.c
@@ -45,7 +45,7 @@
 };
 #define ENUMERATE_MAKE_NEW_NUM_ARGS MP_ARRAY_SIZE(enumerate_make_new_args)
 
-STATIC mp_obj_t enumerate_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
 #if MICROPY_CPYTHON_COMPAT
     // parse args
     mp_arg_val_t vals[ENUMERATE_MAKE_NEW_NUM_ARGS];
@@ -53,13 +53,13 @@
 
     // create enumerate object
     mp_obj_enumerate_t *o = m_new_obj(mp_obj_enumerate_t);
-    o->base.type = MP_OBJ_TO_PTR(type_in);
+    o->base.type = type;
     o->iter = mp_getiter(vals[0].u_obj);
     o->cur = vals[1].u_int;
 #else
     (void)n_kw;
     mp_obj_enumerate_t *o = m_new_obj(mp_obj_enumerate_t);
-    o->base.type = type_in;
+    o->base.type = type;
     o->iter = mp_getiter(args[0]);
     o->cur = n_args > 1 ? mp_obj_get_int(args[1]) : 0;
 #endif
diff --git a/py/objexcept.c b/py/objexcept.c
index 83aa528..d8aecb8 100644
--- a/py/objexcept.c
+++ b/py/objexcept.c
@@ -114,7 +114,7 @@
     mp_obj_tuple_print(print, MP_OBJ_FROM_PTR(o->args), kind);
 }
 
-mp_obj_t mp_obj_exception_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, false);
     mp_obj_exception_t *o = m_new_obj_var_maybe(mp_obj_exception_t, mp_obj_t, 0);
     if (o == NULL) {
@@ -125,7 +125,7 @@
     } else {
         o->args = MP_OBJ_TO_PTR(mp_obj_new_tuple(n_args, args));
     }
-    o->base.type = MP_OBJ_TO_PTR(type_in);
+    o->base.type = type;
     o->traceback_data = NULL;
     return MP_OBJ_FROM_PTR(o);
 }
@@ -290,7 +290,7 @@
 
 mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, mp_uint_t n_args, const mp_obj_t *args) {
     assert(exc_type->make_new == mp_obj_exception_make_new);
-    return exc_type->make_new(MP_OBJ_FROM_PTR(exc_type), n_args, 0, args);
+    return exc_type->make_new(exc_type, n_args, 0, args);
 }
 
 mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg) {
diff --git a/py/objfilter.c b/py/objfilter.c
index 168f0e7..e288102 100644
--- a/py/objfilter.c
+++ b/py/objfilter.c
@@ -34,10 +34,10 @@
     mp_obj_t iter;
 } mp_obj_filter_t;
 
-STATIC mp_obj_t filter_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t filter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     mp_arg_check_num(n_args, n_kw, 2, 2, false);
     mp_obj_filter_t *o = m_new_obj(mp_obj_filter_t);
-    o->base.type = MP_OBJ_TO_PTR(type_in);
+    o->base.type = type;
     o->fun = args[0];
     o->iter = mp_getiter(args[1]);
     return MP_OBJ_FROM_PTR(o);
diff --git a/py/objfloat.c b/py/objfloat.c
index f144bfd..aa37f9a 100644
--- a/py/objfloat.c
+++ b/py/objfloat.c
@@ -69,7 +69,7 @@
     }
 }
 
-STATIC mp_obj_t float_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t float_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     (void)type_in;
     mp_arg_check_num(n_args, n_kw, 0, 1, false);
 
diff --git a/py/objint.c b/py/objint.c
index e548eb8..46290a3 100644
--- a/py/objint.c
+++ b/py/objint.c
@@ -42,7 +42,7 @@
 #endif
 
 // This dispatcher function is expected to be independent of the implementation of long int
-STATIC mp_obj_t mp_obj_int_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t mp_obj_int_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     (void)type_in;
     mp_arg_check_num(n_args, n_kw, 0, 2, false);
 
diff --git a/py/objlist.c b/py/objlist.c
index 3fd38e8..62928af 100644
--- a/py/objlist.c
+++ b/py/objlist.c
@@ -68,7 +68,7 @@
     return list;
 }
 
-STATIC mp_obj_t list_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t list_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     (void)type_in;
     mp_arg_check_num(n_args, n_kw, 0, 1, false);
 
diff --git a/py/objmap.c b/py/objmap.c
index a0293c3..526bc05 100644
--- a/py/objmap.c
+++ b/py/objmap.c
@@ -36,10 +36,10 @@
     mp_obj_t iters[];
 } mp_obj_map_t;
 
-STATIC mp_obj_t map_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t map_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     mp_arg_check_num(n_args, n_kw, 2, MP_OBJ_FUN_ARGS_MAX, false);
     mp_obj_map_t *o = m_new_obj_var(mp_obj_map_t, mp_obj_t, n_args - 1);
-    o->base.type = MP_OBJ_TO_PTR(type_in);
+    o->base.type = type;
     o->n_iters = n_args - 1;
     o->fun = args[0];
     for (mp_uint_t i = 0; i < n_args - 1; i++) {
diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c
index 3e34603..62289f5 100644
--- a/py/objnamedtuple.c
+++ b/py/objnamedtuple.c
@@ -44,7 +44,7 @@
     mp_obj_tuple_t tuple;
 } mp_obj_namedtuple_t;
 
-STATIC mp_uint_t namedtuple_find_field(mp_obj_namedtuple_type_t *type, qstr name) {
+STATIC mp_uint_t namedtuple_find_field(const mp_obj_namedtuple_type_t *type, qstr name) {
     for (mp_uint_t i = 0; i < type->n_fields; i++) {
         if (type->fields[i] == name) {
             return i;
@@ -77,8 +77,8 @@
     }
 }
 
-STATIC mp_obj_t namedtuple_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
-    mp_obj_namedtuple_type_t *type = MP_OBJ_TO_PTR(type_in);
+STATIC mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+    const mp_obj_namedtuple_type_t *type = (const mp_obj_namedtuple_type_t*)type_in;
     mp_uint_t num_fields = type->n_fields;
     if (n_args + n_kw != num_fields) {
         if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
@@ -130,7 +130,7 @@
     }
 
     mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(num_fields, arg_objects));
-    tuple->base.type = MP_OBJ_TO_PTR(type_in);
+    tuple->base.type = type_in;
     return MP_OBJ_FROM_PTR(tuple);
 }
 
diff --git a/py/objobject.c b/py/objobject.c
index 5cd3773..bba6f05 100644
--- a/py/objobject.c
+++ b/py/objobject.c
@@ -33,11 +33,11 @@
     mp_obj_base_t base;
 } mp_obj_object_t;
 
-STATIC mp_obj_t object_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t object_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     (void)args;
     mp_arg_check_num(n_args, n_kw, 0, 0, false);
     mp_obj_object_t *o = m_new_obj(mp_obj_object_t);
-    o->base.type = MP_OBJ_TO_PTR(type_in);
+    o->base.type = type;
     return MP_OBJ_FROM_PTR(o);
 }
 
@@ -54,7 +54,7 @@
                     "__new__ arg must be a user-type"));
     }
     mp_obj_t o = MP_OBJ_SENTINEL;
-    mp_obj_t res = mp_obj_instance_make_new(cls, 1, 0, &o);
+    mp_obj_t res = mp_obj_instance_make_new(MP_OBJ_TO_PTR(cls), 1, 0, &o);
     return res;
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_1(object___new___fun_obj, object___new__);
diff --git a/py/objproperty.c b/py/objproperty.c
index 323696c..80e39e0 100644
--- a/py/objproperty.c
+++ b/py/objproperty.c
@@ -37,11 +37,11 @@
     mp_obj_t proxy[3]; // getter, setter, deleter
 } mp_obj_property_t;
 
-STATIC mp_obj_t property_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t property_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     mp_arg_check_num(n_args, n_kw, 0, 4, false);
 
     mp_obj_property_t *o = m_new_obj(mp_obj_property_t);
-    o->base.type = MP_OBJ_TO_PTR(type_in);
+    o->base.type = type;
     if (n_args >= 4) {
         // doc ignored
     }
diff --git a/py/objrange.c b/py/objrange.c
index bec026f..7945931 100644
--- a/py/objrange.c
+++ b/py/objrange.c
@@ -90,11 +90,11 @@
     }
 }
 
-STATIC mp_obj_t range_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t range_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     mp_arg_check_num(n_args, n_kw, 1, 3, false);
 
     mp_obj_range_t *o = m_new_obj(mp_obj_range_t);
-    o->base.type = MP_OBJ_TO_PTR(type_in);
+    o->base.type = type;
     o->start = 0;
     o->step = 1;
 
diff --git a/py/objreversed.c b/py/objreversed.c
index b0da00a..1e54bb5 100644
--- a/py/objreversed.c
+++ b/py/objreversed.c
@@ -38,7 +38,7 @@
     mp_uint_t cur_index;    // current index, plus 1; 0=no more, 1=last one (index 0)
 } mp_obj_reversed_t;
 
-STATIC mp_obj_t reversed_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t reversed_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     mp_arg_check_num(n_args, n_kw, 1, 1, false);
 
     // check if __reversed__ exists, and if so delegate to it
@@ -49,7 +49,7 @@
     }
 
     mp_obj_reversed_t *o = m_new_obj(mp_obj_reversed_t);
-    o->base.type = MP_OBJ_TO_PTR(type_in);
+    o->base.type = type;
     o->seq = args[0];
     o->cur_index = mp_obj_get_int(mp_obj_len(args[0])); // start at the end of the sequence
 
diff --git a/py/objset.c b/py/objset.c
index c83212c..8730918 100644
--- a/py/objset.c
+++ b/py/objset.c
@@ -119,7 +119,7 @@
     #endif
 }
 
-STATIC mp_obj_t set_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t set_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     mp_arg_check_num(n_args, n_kw, 0, 1, false);
 
     switch (n_args) {
@@ -127,7 +127,7 @@
             // create a new, empty set
             mp_obj_set_t *set = MP_OBJ_TO_PTR(mp_obj_new_set(0, NULL));
             // set actual set/frozenset type
-            set->base.type = MP_OBJ_TO_PTR(type_in);
+            set->base.type = type;
             return MP_OBJ_FROM_PTR(set);
         }
 
@@ -141,7 +141,7 @@
                 mp_obj_set_store(set, item);
             }
             // Set actual set/frozenset type
-            ((mp_obj_set_t*)MP_OBJ_TO_PTR(set))->base.type = MP_OBJ_TO_PTR(type_in);
+            ((mp_obj_set_t*)MP_OBJ_TO_PTR(set))->base.type = type;
             return set;
         }
     }
@@ -327,7 +327,7 @@
     if (is_set_or_frozenset(self_in)) {
         self = MP_OBJ_TO_PTR(self_in);
     } else {
-        self = MP_OBJ_TO_PTR(set_make_new(MP_OBJ_FROM_PTR(&mp_type_set), 1, 0, &self_in));
+        self = MP_OBJ_TO_PTR(set_make_new(&mp_type_set, 1, 0, &self_in));
         cleanup_self = true;
     }
 
@@ -336,7 +336,7 @@
     if (is_set_or_frozenset(other_in)) {
         other = MP_OBJ_TO_PTR(other_in);
     } else {
-        other = MP_OBJ_TO_PTR(set_make_new(MP_OBJ_FROM_PTR(&mp_type_set), 1, 0, &other_in));
+        other = MP_OBJ_TO_PTR(set_make_new(&mp_type_set, 1, 0, &other_in));
         cleanup_other = true;
     }
     bool out = true;
diff --git a/py/objstr.c b/py/objstr.c
index a76ff0d..8a0a19d 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -131,7 +131,7 @@
     }
 }
 
-mp_obj_t mp_obj_str_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
 #if MICROPY_CPYTHON_COMPAT
     if (n_kw != 0) {
         mp_arg_error_unimpl_kw();
@@ -149,7 +149,7 @@
             mp_print_t print;
             vstr_init_print(&vstr, 16, &print);
             mp_obj_print_helper(&print, args[0], PRINT_STR);
-            return mp_obj_new_str_from_vstr(MP_OBJ_TO_PTR(type_in), &vstr);
+            return mp_obj_new_str_from_vstr(type, &vstr);
         }
 
         default: // 2 or 3 args
@@ -157,7 +157,7 @@
             if (MP_OBJ_IS_TYPE(args[0], &mp_type_bytes)) {
                 GET_STR_DATA_LEN(args[0], str_data, str_len);
                 GET_STR_HASH(args[0], str_hash);
-                mp_obj_str_t *o = MP_OBJ_TO_PTR(mp_obj_new_str_of_type(MP_OBJ_TO_PTR(type_in), NULL, str_len));
+                mp_obj_str_t *o = MP_OBJ_TO_PTR(mp_obj_new_str_of_type(type, NULL, str_len));
                 o->data = str_data;
                 o->hash = str_hash;
                 return MP_OBJ_FROM_PTR(o);
@@ -169,7 +169,7 @@
     }
 }
 
-STATIC mp_obj_t bytes_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     (void)type_in;
 
     #if MICROPY_CPYTHON_COMPAT
@@ -426,7 +426,7 @@
         if (!MP_OBJ_IS_TYPE(arg, &mp_type_list)) {
             // arg is not a list, try to convert it to one
             // TODO: Try to optimize?
-            arg = mp_type_list.make_new(MP_OBJ_FROM_PTR(&mp_type_list), 1, 0, &arg);
+            arg = mp_type_list.make_new(&mp_type_list, 1, 0, &arg);
         }
         mp_obj_list_get(arg, &seq_len, &seq_items);
     }
@@ -1767,7 +1767,7 @@
         args = new_args;
         n_args++;
     }
-    return mp_obj_str_make_new(MP_OBJ_FROM_PTR(&mp_type_str), n_args, 0, args);
+    return mp_obj_str_make_new(&mp_type_str, n_args, 0, args);
 }
 
 // TODO: should accept kwargs too
@@ -1779,7 +1779,7 @@
         args = new_args;
         n_args++;
     }
-    return bytes_make_new(MP_OBJ_NULL, n_args, 0, args);
+    return bytes_make_new(NULL, n_args, 0, args);
 }
 #endif
 
diff --git a/py/objstr.h b/py/objstr.h
index 1cfb195..6179a74 100644
--- a/py/objstr.h
+++ b/py/objstr.h
@@ -60,7 +60,7 @@
     else { str_len = ((mp_obj_str_t*)MP_OBJ_TO_PTR(str_obj_in))->len; str_data = ((mp_obj_str_t*)MP_OBJ_TO_PTR(str_obj_in))->data; }
 #endif
 
-mp_obj_t mp_obj_str_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args);
+mp_obj_t mp_obj_str_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args);
 void mp_str_print_json(const mp_print_t *print, const byte *str_data, size_t str_len);
 mp_obj_t mp_obj_str_format(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs);
 mp_obj_t mp_obj_str_split(size_t n_args, const mp_obj_t *args);
diff --git a/py/objstringio.c b/py/objstringio.c
index 357320c..f50abfb 100644
--- a/py/objstringio.c
+++ b/py/objstringio.c
@@ -120,15 +120,15 @@
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stringio___exit___obj, 4, 4, stringio___exit__);
 
-STATIC mp_obj_stringio_t *stringio_new(mp_obj_t type_in) {
+STATIC mp_obj_stringio_t *stringio_new(const mp_obj_type_t *type) {
     mp_obj_stringio_t *o = m_new_obj(mp_obj_stringio_t);
-    o->base.type = MP_OBJ_TO_PTR(type_in);
+    o->base.type = type;
     o->vstr = vstr_new();
     o->pos = 0;
     return o;
 }
 
-STATIC mp_obj_t stringio_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t stringio_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     (void)n_kw; // TODO check n_kw==0
     mp_obj_stringio_t *o = stringio_new(type_in);
 
diff --git a/py/objtuple.c b/py/objtuple.c
index 86720ed..c21390a 100644
--- a/py/objtuple.c
+++ b/py/objtuple.c
@@ -61,7 +61,7 @@
     }
 }
 
-STATIC mp_obj_t mp_obj_tuple_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t mp_obj_tuple_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     (void)type_in;
 
     mp_arg_check_num(n_args, n_kw, 0, 1, false);
diff --git a/py/objtype.c b/py/objtype.c
index c9ab596..39998c5 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -43,14 +43,14 @@
 #define DEBUG_printf(...) (void)0
 #endif
 
-STATIC mp_obj_t static_class_method_make_new(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args);
+STATIC mp_obj_t static_class_method_make_new(const mp_obj_type_t *self_in, size_t n_args, size_t n_kw, const mp_obj_t *args);
 
 /******************************************************************************/
 // instance object
 
-STATIC mp_obj_t mp_obj_new_instance(mp_obj_t class, uint subobjs) {
+STATIC mp_obj_t mp_obj_new_instance(const mp_obj_type_t *class, uint subobjs) {
     mp_obj_instance_t *o = m_new_obj_var(mp_obj_instance_t, mp_obj_t, subobjs);
-    o->base.type = MP_OBJ_TO_PTR(class);
+    o->base.type = class;
     mp_map_init(&o->members, 0);
     mp_seq_clear(o->subobj, 0, subobjs, sizeof(*o->subobj));
     return MP_OBJ_FROM_PTR(o);
@@ -235,16 +235,14 @@
     mp_printf(print, "<%s object at %p>", mp_obj_get_type_str(self_in), self_in);
 }
 
-mp_obj_t mp_obj_instance_make_new(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
-    assert(MP_OBJ_IS_TYPE(self_in, &mp_type_type));
-    mp_obj_type_t *self = MP_OBJ_TO_PTR(self_in);
+mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     assert(mp_obj_is_instance_type(self));
 
     const mp_obj_type_t *native_base;
     uint num_native_bases = instance_count_native_bases(self, &native_base);
     assert(num_native_bases < 2);
 
-    mp_obj_instance_t *o = MP_OBJ_TO_PTR(mp_obj_new_instance(self_in, num_native_bases));
+    mp_obj_instance_t *o = MP_OBJ_TO_PTR(mp_obj_new_instance(self, num_native_bases));
 
     // This executes only "__new__" part of obejection creation.
     // TODO: This won't work will for classes with native bases.
@@ -269,14 +267,15 @@
     if (init_fn[0] == MP_OBJ_SENTINEL) {
         // Native type's constructor is what wins - it gets all our arguments,
         // and none Python classes are initialized at all.
-        o->subobj[0] = native_base->make_new(MP_OBJ_FROM_PTR(native_base), n_args, n_kw, args);
+        o->subobj[0] = native_base->make_new(native_base, n_args, n_kw, args);
     } else if (init_fn[0] != MP_OBJ_NULL) {
         // now call Python class __new__ function with all args
         if (n_args == 0 && n_kw == 0) {
-            new_ret = mp_call_function_n_kw(init_fn[0], 1, 0, (mp_obj_t*)(void*)&self_in);
+            mp_obj_t args2[1] = {MP_OBJ_FROM_PTR(self)};
+            new_ret = mp_call_function_n_kw(init_fn[0], 1, 0, args2);
         } else {
             mp_obj_t *args2 = m_new(mp_obj_t, 1 + n_args + 2 * n_kw);
-            args2[0] = self_in;
+            args2[0] = MP_OBJ_FROM_PTR(self);
             memcpy(args2 + 1, args, (n_args + 2 * n_kw) * sizeof(mp_obj_t));
             new_ret = mp_call_function_n_kw(init_fn[0], n_args + 1, n_kw, args2);
             m_del(mp_obj_t, args2, 1 + n_args + 2 * n_kw);
@@ -778,7 +777,7 @@
     mp_printf(print, "<class '%q'>", self->name);
 }
 
-STATIC mp_obj_t type_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t type_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     (void)type_in;
 
     mp_arg_check_num(n_args, n_kw, 1, 3, false);
@@ -813,7 +812,7 @@
     }
 
     // make new instance
-    mp_obj_t o = self->make_new(self_in, n_args, n_kw, args);
+    mp_obj_t o = self->make_new(self, n_args, n_kw, args);
 
     // return new instance
     return o;
@@ -931,7 +930,7 @@
         // __new__ slot exists; check if it is a function
         if (MP_OBJ_IS_FUN(elem->value)) {
             // __new__ is a function, wrap it in a staticmethod decorator
-            elem->value = static_class_method_make_new(MP_OBJ_FROM_PTR(&mp_type_staticmethod), 1, 0, &elem->value);
+            elem->value = static_class_method_make_new(&mp_type_staticmethod, 1, 0, &elem->value);
         }
     }
 
@@ -957,7 +956,7 @@
     mp_print_str(print, ">");
 }
 
-STATIC mp_obj_t super_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t super_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     (void)type_in;
     // 0 arguments are turned into 2 in the compiler
     // 1 argument is not yet implemented
@@ -1108,8 +1107,7 @@
 /******************************************************************************/
 // staticmethod and classmethod types (probably should go in a different file)
 
-STATIC mp_obj_t static_class_method_make_new(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
-    mp_obj_type_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC mp_obj_t static_class_method_make_new(const mp_obj_type_t *self, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     assert(self == &mp_type_staticmethod || self == &mp_type_classmethod);
 
     mp_arg_check_num(n_args, n_kw, 1, 1, false);
diff --git a/py/objtype.h b/py/objtype.h
index 06227cf..61efd00 100644
--- a/py/objtype.h
+++ b/py/objtype.h
@@ -47,6 +47,6 @@
 #define mp_obj_is_instance_type(type) ((type)->make_new == mp_obj_instance_make_new)
 #define mp_obj_is_native_type(type) ((type)->make_new != mp_obj_instance_make_new)
 // this needs to be exposed for the above macros to work correctly
-mp_obj_t mp_obj_instance_make_new(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args);
+mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self_in, size_t n_args, size_t n_kw, const mp_obj_t *args);
 
 #endif // __MICROPY_INCLUDED_PY_OBJTYPE_H__
diff --git a/py/objzip.c b/py/objzip.c
index 4b240fb..d4cd614 100644
--- a/py/objzip.c
+++ b/py/objzip.c
@@ -36,11 +36,11 @@
     mp_obj_t iters[];
 } mp_obj_zip_t;
 
-STATIC mp_obj_t zip_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t zip_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, false);
 
     mp_obj_zip_t *o = m_new_obj_var(mp_obj_zip_t, mp_obj_t, n_args);
-    o->base.type = MP_OBJ_TO_PTR(type_in);
+    o->base.type = type;
     o->n_iters = n_args;
     for (mp_uint_t i = 0; i < n_args; i++) {
         o->iters[i] = mp_getiter(args[i]);
diff --git a/stmhal/accel.c b/stmhal/accel.c
index 59d83bf..434a92a 100644
--- a/stmhal/accel.c
+++ b/stmhal/accel.c
@@ -130,7 +130,7 @@
 ///     accel = pyb.Accel()
 ///     pyb.delay(20)
 ///     print(accel.x())
-STATIC mp_obj_t pyb_accel_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_accel_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 0, 0, false);
 
diff --git a/stmhal/adc.c b/stmhal/adc.c
index d8ce90c..4e364c3 100644
--- a/stmhal/adc.c
+++ b/stmhal/adc.c
@@ -153,7 +153,7 @@
 /// \classmethod \constructor(pin)
 /// Create an ADC object associated with the given pin.
 /// This allows you to then read analog values on that pin.
-STATIC mp_obj_t adc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check number of arguments
     mp_arg_check_num(n_args, n_kw, 1, 1, false);
 
@@ -436,7 +436,7 @@
 /******************************************************************************/
 /* Micro Python bindings : adc_all object                                     */
 
-STATIC mp_obj_t adc_all_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t adc_all_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check number of arguments
     mp_arg_check_num(n_args, n_kw, 1, 1, false);
 
diff --git a/stmhal/can.c b/stmhal/can.c
index 005bd9e..b2330cd 100644
--- a/stmhal/can.c
+++ b/stmhal/can.c
@@ -339,7 +339,7 @@
 ///
 ///   - `CAN(1)` is on `YA`: `(RX, TX) = (Y3, Y4) = (PB8, PB9)`
 ///   - `CAN(2)` is on `YB`: `(RX, TX) = (Y5, Y6) = (PB12, PB13)`
-STATIC mp_obj_t pyb_can_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_can_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
 
diff --git a/stmhal/dac.c b/stmhal/dac.c
index 8573dcc..6d7491c 100644
--- a/stmhal/dac.c
+++ b/stmhal/dac.c
@@ -192,7 +192,7 @@
 ///
 /// `port` can be a pin object, or an integer (1 or 2).
 /// DAC(1) is on pin X5 and DAC(2) is on pin X6.
-STATIC mp_obj_t pyb_dac_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_dac_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
 
diff --git a/stmhal/extint.c b/stmhal/extint.c
index 57116dc..ebc4a46 100644
--- a/stmhal/extint.c
+++ b/stmhal/extint.c
@@ -307,7 +307,7 @@
 };
 #define PYB_EXTINT_MAKE_NEW_NUM_ARGS MP_ARRAY_SIZE(pyb_extint_make_new_args)
 
-STATIC mp_obj_t extint_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t extint_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // type_in == extint_obj_type
 
     // parse args
@@ -315,7 +315,7 @@
     mp_arg_parse_all_kw_array(n_args, n_kw, args, PYB_EXTINT_MAKE_NEW_NUM_ARGS, pyb_extint_make_new_args, vals);
 
     extint_obj_t *self = m_new_obj(extint_obj_t);
-    self->base.type = type_in;
+    self->base.type = type;
     self->line = extint_register(vals[0].u_obj, vals[1].u_int, vals[2].u_int, vals[3].u_obj, false);
 
     return self;
diff --git a/stmhal/file.c b/stmhal/file.c
index d7d8009..a61fa05 100644
--- a/stmhal/file.c
+++ b/stmhal/file.c
@@ -157,7 +157,7 @@
 };
 #define FILE_OPEN_NUM_ARGS MP_ARRAY_SIZE(file_open_args)
 
-STATIC mp_obj_t file_open(mp_obj_t type, mp_arg_val_t *args) {
+STATIC mp_obj_t file_open(const mp_obj_type_t *type, mp_arg_val_t *args) {
     int mode = 0;
     const char *mode_s = mp_obj_str_get_str(args[1].u_obj);
     // TODO make sure only one of r, w, x, a, and b, t are specified
@@ -180,11 +180,11 @@
                 break;
             #if MICROPY_PY_IO_FILEIO
             case 'b':
-                type = (mp_obj_t)&mp_type_fileio;
+                type = &mp_type_fileio;
                 break;
             #endif
             case 't':
-                type = (mp_obj_t)&mp_type_textio;
+                type = &mp_type_textio;
                 break;
         }
     }
@@ -207,10 +207,10 @@
     return o;
 }
 
-STATIC mp_obj_t file_obj_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t file_obj_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS];
     mp_arg_parse_all_kw_array(n_args, n_kw, args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals);
-    return file_open(type_in, arg_vals);
+    return file_open(type, arg_vals);
 }
 
 // TODO gc hook to close the file if not already closed
@@ -275,6 +275,6 @@
     // TODO: analyze buffering args and instantiate appropriate type
     mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS];
     mp_arg_parse_all(n_args, args, kwargs, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals);
-    return file_open((mp_obj_t)&mp_type_textio, arg_vals);
+    return file_open(&mp_type_textio, arg_vals);
 }
 MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
diff --git a/stmhal/i2c.c b/stmhal/i2c.c
index c97629f..263ac9a 100644
--- a/stmhal/i2c.c
+++ b/stmhal/i2c.c
@@ -395,7 +395,7 @@
 ///
 ///   - `I2C(1)` is on the X position: `(SCL, SDA) = (X9, X10) = (PB6, PB7)`
 ///   - `I2C(2)` is on the Y position: `(SCL, SDA) = (Y9, Y10) = (PB10, PB11)`
-STATIC mp_obj_t pyb_i2c_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_i2c_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
 
diff --git a/stmhal/lcd.c b/stmhal/lcd.c
index 12d96e6..143ef9b 100644
--- a/stmhal/lcd.c
+++ b/stmhal/lcd.c
@@ -192,7 +192,7 @@
 ///
 /// Construct an LCD object in the given skin position.  `skin_position` can be 'X' or 'Y', and
 /// should match the position where the LCD pyskin is plugged in.
-STATIC mp_obj_t pyb_lcd_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_lcd_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 1, 1, false);
 
diff --git a/stmhal/led.c b/stmhal/led.c
index ca52931..990d204 100644
--- a/stmhal/led.c
+++ b/stmhal/led.c
@@ -217,7 +217,7 @@
 /// Create an LED object associated with the given LED:
 ///
 ///   - `id` is the LED number, 1-4.
-STATIC mp_obj_t led_obj_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t led_obj_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 1, 1, false);
 
diff --git a/stmhal/modnwcc3k.c b/stmhal/modnwcc3k.c
index 20e7035..85dc058 100644
--- a/stmhal/modnwcc3k.c
+++ b/stmhal/modnwcc3k.c
@@ -428,7 +428,7 @@
 //        [SPI on Y position; Y6=B13=SCK, Y7=B14=MISO, Y8=B15=MOSI]
 //
 //      STM32F4DISC: init(pyb.SPI(2), pyb.Pin.cpu.A15, pyb.Pin.cpu.B10, pyb.Pin.cpu.B11)
-STATIC mp_obj_t cc3k_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t cc3k_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 4, 4, false);
 
diff --git a/stmhal/modnwwiznet5k.c b/stmhal/modnwwiznet5k.c
index 2feb9b9..b6f1835 100644
--- a/stmhal/modnwwiznet5k.c
+++ b/stmhal/modnwwiznet5k.c
@@ -318,7 +318,7 @@
 
 /// \classmethod \constructor(spi, pin_cs, pin_rst)
 /// Create and return a WIZNET5K object.
-STATIC mp_obj_t wiznet5k_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 3, 3, false);
 
diff --git a/stmhal/modusocket.c b/stmhal/modusocket.c
index 402378a..8e461fe 100644
--- a/stmhal/modusocket.c
+++ b/stmhal/modusocket.c
@@ -41,7 +41,7 @@
 STATIC const mp_obj_type_t socket_type;
 
 // constructor socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
-STATIC mp_obj_t socket_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     mp_arg_check_num(n_args, n_kw, 0, 4, false);
 
     // create socket object (not bound to any NIC yet)
diff --git a/stmhal/pin.c b/stmhal/pin.c
index a0f3994..e3ae0be 100644
--- a/stmhal/pin.c
+++ b/stmhal/pin.c
@@ -244,7 +244,7 @@
 /// \classmethod \constructor(id, ...)
 /// Create a new Pin object associated with the id.  If additional arguments are given,
 /// they are used to initialise the pin.  See `init`.
-STATIC mp_obj_t pin_make_new(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pin_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
 
     // Run an argument through the mapper and return the result.
diff --git a/stmhal/rtc.c b/stmhal/rtc.c
index ad595dd..bb16e48 100644
--- a/stmhal/rtc.c
+++ b/stmhal/rtc.c
@@ -418,7 +418,7 @@
 
 /// \classmethod \constructor()
 /// Create an RTC object.
-STATIC mp_obj_t pyb_rtc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_rtc_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 0, 0, false);
 
diff --git a/stmhal/servo.c b/stmhal/servo.c
index 7f5a09f..382b48f 100644
--- a/stmhal/servo.c
+++ b/stmhal/servo.c
@@ -185,7 +185,7 @@
 
 /// \classmethod \constructor(id)
 /// Create a servo object.  `id` is 1-4.
-STATIC mp_obj_t pyb_servo_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_servo_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 1, 1, false);
 
diff --git a/stmhal/spi.c b/stmhal/spi.c
index d9bc7ec..3a1737e 100644
--- a/stmhal/spi.c
+++ b/stmhal/spi.c
@@ -466,7 +466,7 @@
 ///
 /// At the moment, the NSS pin is not used by the SPI driver and is free
 /// for other use.
-STATIC mp_obj_t pyb_spi_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_spi_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
 
diff --git a/stmhal/timer.c b/stmhal/timer.c
index a97f1f2..e1d659c 100644
--- a/stmhal/timer.c
+++ b/stmhal/timer.c
@@ -637,7 +637,7 @@
 /// Construct a new timer object of the given id.  If additional
 /// arguments are given, then the timer is initialised by `init(...)`.
 /// `id` can be 1 to 14, excluding 3.
-STATIC mp_obj_t pyb_timer_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_timer_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
 
diff --git a/stmhal/uart.c b/stmhal/uart.c
index 024cc04..272b207 100644
--- a/stmhal/uart.c
+++ b/stmhal/uart.c
@@ -589,7 +589,7 @@
 ///   - `UART(6)` is on `YA`: `(TX, RX) = (Y1, Y2) = (PC6, PC7)`
 ///   - `UART(3)` is on `YB`: `(TX, RX) = (Y9, Y10) = (PB10, PB11)`
 ///   - `UART(2)` is on: `(TX, RX) = (X3, X4) = (PA2, PA3)`
-STATIC mp_obj_t pyb_uart_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
 
diff --git a/stmhal/usb.c b/stmhal/usb.c
index ca77415..1e1469c 100644
--- a/stmhal/usb.c
+++ b/stmhal/usb.c
@@ -354,7 +354,7 @@
 
 /// \classmethod \constructor()
 /// Create a new USB_VCP object.
-STATIC mp_obj_t pyb_usb_vcp_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_usb_vcp_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 0, 0, false);
 
@@ -543,7 +543,7 @@
 
 STATIC const pyb_usb_hid_obj_t pyb_usb_hid_obj = {{&pyb_usb_hid_type}};
 
-STATIC mp_obj_t pyb_usb_hid_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_usb_hid_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 0, 0, false);
 
diff --git a/stmhal/usrsw.c b/stmhal/usrsw.c
index 69b0ca9..c9b7690 100644
--- a/stmhal/usrsw.c
+++ b/stmhal/usrsw.c
@@ -83,7 +83,7 @@
 
 /// \classmethod \constructor()
 /// Create and return a switch object.
-STATIC mp_obj_t pyb_switch_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_switch_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 0, 0, false);
 
diff --git a/teensy/led.c b/teensy/led.c
index 5798f53..c7ac8be 100644
--- a/teensy/led.c
+++ b/teensy/led.c
@@ -89,7 +89,7 @@
     mp_printf(print, "<LED %lu>", self->led_id);
 }
 
-STATIC mp_obj_t led_obj_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t led_obj_make_new(const mp_obj_type_t *type, uint n_args, uint n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 1, 1, false);
 
diff --git a/teensy/timer.c b/teensy/timer.c
index 88583a0..af64ac7 100644
--- a/teensy/timer.c
+++ b/teensy/timer.c
@@ -304,7 +304,7 @@
 /// Construct a new timer object of the given id.  If additional
 /// arguments are given, then the timer is initialised by `init(...)`.
 /// `id` can be 1 to 14, excluding 3.
-STATIC mp_obj_t pyb_timer_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_timer_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
 
diff --git a/teensy/uart.c b/teensy/uart.c
index 8b73d73..b4c0a4d 100644
--- a/teensy/uart.c
+++ b/teensy/uart.c
@@ -306,7 +306,7 @@
 ///   - `UART(6)` is on `YA`: `(TX, RX) = (Y1, Y2) = (PC6, PC7)`
 ///   - `UART(3)` is on `YB`: `(TX, RX) = (Y9, Y10) = (PB10, PB11)`
 ///   - `UART(2)` is on: `(TX, RX) = (X3, X4) = (PA2, PA3)`
-STATIC mp_obj_t pyb_uart_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, uint n_args, uint n_kw, const mp_obj_t *args) {
     // check arguments
     mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
 
diff --git a/unix/file.c b/unix/file.c
index 2d3eb7b..9ce5b69 100644
--- a/unix/file.c
+++ b/unix/file.c
@@ -202,10 +202,10 @@
     return MP_OBJ_FROM_PTR(o);
 }
 
-STATIC mp_obj_t fdfile_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t fdfile_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS];
     mp_arg_parse_all_kw_array(n_args, n_kw, args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals);
-    return fdfile_open(MP_OBJ_TO_PTR(type_in), arg_vals);
+    return fdfile_open(type, arg_vals);
 }
 
 STATIC const mp_rom_map_elem_t rawfile_locals_dict_table[] = {
diff --git a/unix/modffi.c b/unix/modffi.c
index 337f7a7..86a0b44 100644
--- a/unix/modffi.c
+++ b/unix/modffi.c
@@ -301,7 +301,7 @@
 }
 MP_DEFINE_CONST_FUN_OBJ_2(ffimod_addr_obj, ffimod_addr);
 
-STATIC mp_obj_t ffimod_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t ffimod_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     (void)n_args;
     (void)n_kw;
 
@@ -315,7 +315,7 @@
         nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno)));
     }
     mp_obj_ffimod_t *o = m_new_obj(mp_obj_ffimod_t);
-    o->base.type = MP_OBJ_TO_PTR(type_in);
+    o->base.type = type;
     o->handle = mod;
     return MP_OBJ_FROM_PTR(o);
 }
@@ -478,7 +478,7 @@
 */
 
 STATIC mp_obj_t mod_ffi_open(size_t n_args, const mp_obj_t *args) {
-    return ffimod_make_new((mp_obj_t)&ffimod_type, n_args, 0, args);
+    return ffimod_make_new(&ffimod_type, n_args, 0, args);
 }
 MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_ffi_open_obj, 1, 2, mod_ffi_open);
 
diff --git a/unix/modsocket.c b/unix/modsocket.c
index a9bb2e0..8af229c 100644
--- a/unix/modsocket.c
+++ b/unix/modsocket.c
@@ -313,7 +313,7 @@
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_makefile_obj, 1, 3, socket_makefile);
 
-STATIC mp_obj_t socket_make_new(mp_obj_t type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
     (void)type_in;
     (void)n_kw;