@@ -1148,10 +1148,15 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
1148
1148
#endif
1149
1149
}
1150
1150
1151
- // Allocate a full-sized mp_obj_full_type_t instance (i.e. all slots / extended fields).
1152
- // Given that Python types use almost all the slots anyway, this doesn't cost anything
1153
- // extra.
1154
- mp_obj_type_t * o = (mp_obj_type_t * )m_new0 (mp_obj_full_type_t , 1 );
1151
+ const void * base_protocol = NULL ;
1152
+ if (bases_len > 0 ) {
1153
+ base_protocol = MP_OBJ_TYPE_GET_SLOT_OR_NULL (((mp_obj_type_t * )MP_OBJ_TO_PTR (bases_items [0 ])), protocol );
1154
+ }
1155
+
1156
+ // Allocate a variable-sized mp_obj_type_t with as many slots as we need
1157
+ // (currently 9, plus 1 for base, plus 1 for base-protocol).
1158
+ // Note: 11 slots pushes it from 4 to 5 GC blocks.
1159
+ mp_obj_type_t * o = m_new_obj_var0 (mp_obj_type_t , void * , 9 + (bases_len ? 1 : 0 ) + (base_protocol ? 1 : 0 ));
1155
1160
o -> base .type = & mp_type_type ;
1156
1161
o -> flags = base_flags ;
1157
1162
o -> name = name ;
@@ -1166,13 +1171,10 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
1166
1171
// MP_OBJ_TYPE_SET_SLOT(o, iternext, not implemented)
1167
1172
MP_OBJ_TYPE_SET_SLOT (o , buffer , instance_get_buffer , 7 );
1168
1173
1169
- if (bases_len > 0 ) {
1170
- // Inherit protocol from a base class. This allows to define an
1171
- // abstract base class which would translate C-level protocol to
1172
- // Python method calls, and any subclass inheriting from it will
1173
- // support this feature.
1174
- MP_OBJ_TYPE_SET_SLOT (o , protocol , MP_OBJ_TYPE_GET_SLOT_OR_NULL (((mp_obj_type_t * )MP_OBJ_TO_PTR (bases_items [0 ])), protocol ), 8 );
1174
+ mp_obj_dict_t * locals_ptr = MP_OBJ_TO_PTR (locals_dict );
1175
+ MP_OBJ_TYPE_SET_SLOT (o , locals_dict , locals_ptr , 8 );
1175
1176
1177
+ if (bases_len > 0 ) {
1176
1178
if (bases_len >= 2 ) {
1177
1179
#if MICROPY_MULTIPLE_INHERITANCE
1178
1180
MP_OBJ_TYPE_SET_SLOT (o , parent , MP_OBJ_TO_PTR (bases_tuple ), 9 );
@@ -1182,10 +1184,15 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
1182
1184
} else {
1183
1185
MP_OBJ_TYPE_SET_SLOT (o , parent , MP_OBJ_TO_PTR (bases_items [0 ]), 9 );
1184
1186
}
1185
- }
1186
1187
1187
- mp_obj_dict_t * locals_ptr = MP_OBJ_TO_PTR (locals_dict );
1188
- MP_OBJ_TYPE_SET_SLOT (o , locals_dict , locals_ptr , 10 );
1188
+ // Inherit protocol from a base class. This allows to define an
1189
+ // abstract base class which would translate C-level protocol to
1190
+ // Python method calls, and any subclass inheriting from it will
1191
+ // support this feature.
1192
+ if (base_protocol ) {
1193
+ MP_OBJ_TYPE_SET_SLOT (o , protocol , base_protocol , 10 );
1194
+ }
1195
+ }
1189
1196
1190
1197
#if ENABLE_SPECIAL_ACCESSORS
1191
1198
// Check if the class has any special accessor methods
0 commit comments