@@ -195,8 +195,9 @@ bool PLACE_IN_ITCM(mp_obj_is_true)(mp_obj_t arg) {
195195 }
196196 } else {
197197 const mp_obj_type_t * type = mp_obj_get_type (arg );
198- if (type -> unary_op != NULL ) {
199- mp_obj_t result = type -> unary_op (MP_UNARY_OP_BOOL , arg );
198+ mp_unary_op_fun_t unary_op = mp_type_unary_op (type );
199+ if (unary_op ) {
200+ mp_obj_t result = unary_op (MP_UNARY_OP_BOOL , arg );
200201 if (result != MP_OBJ_NULL ) {
201202 return result == mp_const_true ;
202203 }
@@ -214,7 +215,7 @@ bool PLACE_IN_ITCM(mp_obj_is_true)(mp_obj_t arg) {
214215}
215216
216217bool mp_obj_is_callable (mp_obj_t o_in ) {
217- const mp_call_fun_t call = mp_obj_get_type (o_in )-> call ;
218+ const mp_call_fun_t call = mp_type_call ( mp_obj_get_type (o_in )) ;
218219 if (call != mp_obj_instance_call ) {
219220 return call != NULL ;
220221 }
@@ -281,19 +282,20 @@ mp_obj_t mp_obj_equal_not_equal(mp_binary_op_t op, mp_obj_t o1, mp_obj_t o2) {
281282 const mp_obj_type_t * type = mp_obj_get_type (o1 );
282283 // If a full equality test is not needed and the other object is a different
283284 // type then we don't need to bother trying the comparison.
284- if (type -> binary_op != NULL &&
285+ mp_binary_op_fun_t binary_op = mp_type_binary_op (type );
286+ if (binary_op != NULL &&
285287 ((type -> flags & MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE ) || mp_obj_get_type (o2 ) == type )) {
286288 // CPython is asymmetric: it will try __eq__ if there's no __ne__ but not the
287289 // other way around. If the class doesn't need a full test we can skip __ne__.
288290 if (op == MP_BINARY_OP_NOT_EQUAL && (type -> flags & MP_TYPE_FLAG_EQ_HAS_NEQ_TEST )) {
289- mp_obj_t r = type -> binary_op (MP_BINARY_OP_NOT_EQUAL , o1 , o2 );
291+ mp_obj_t r = binary_op (MP_BINARY_OP_NOT_EQUAL , o1 , o2 );
290292 if (r != MP_OBJ_NULL ) {
291293 return r ;
292294 }
293295 }
294296
295297 // Try calling __eq__.
296- mp_obj_t r = type -> binary_op (MP_BINARY_OP_EQUAL , o1 , o2 );
298+ mp_obj_t r = binary_op (MP_BINARY_OP_EQUAL , o1 , o2 );
297299 if (r != MP_OBJ_NULL ) {
298300 if (op == MP_BINARY_OP_EQUAL ) {
299301 return r ;
@@ -556,8 +558,9 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) {
556558 return MP_OBJ_NEW_SMALL_INT (l );
557559 } else {
558560 const mp_obj_type_t * type = mp_obj_get_type (o_in );
559- if (type -> unary_op != NULL ) {
560- return type -> unary_op (MP_UNARY_OP_LEN , o_in );
561+ mp_unary_op_fun_t unary_op = mp_type_unary_op (type );
562+ if (unary_op != NULL ) {
563+ return unary_op (MP_UNARY_OP_LEN , o_in );
561564 } else {
562565 return MP_OBJ_NULL ;
563566 }
@@ -566,8 +569,9 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) {
566569
567570mp_obj_t mp_obj_subscr (mp_obj_t base , mp_obj_t index , mp_obj_t value ) {
568571 const mp_obj_type_t * type = mp_obj_get_type (base );
569- if (type -> subscr != NULL ) {
570- mp_obj_t ret = type -> subscr (base , index , value );
572+ mp_subscr_fun_t subscr = mp_type_subscr (type );
573+ if (subscr != NULL ) {
574+ mp_obj_t ret = subscr (base , index , value );
571575 // May have called port specific C code. Make sure it didn't mess up the heap.
572576 assert_heap_ok ();
573577 if (ret != MP_OBJ_NULL ) {
@@ -620,7 +624,7 @@ typedef struct {
620624STATIC mp_obj_t generic_it_iternext (mp_obj_t self_in ) {
621625 mp_obj_generic_it_t * self = MP_OBJ_TO_PTR (self_in );
622626 const mp_obj_type_t * type = mp_obj_get_type (self -> obj );
623- mp_obj_t current_length = type -> unary_op (MP_UNARY_OP_LEN , self -> obj );
627+ mp_obj_t current_length = mp_type_unary_op ( type ) (MP_UNARY_OP_LEN , self -> obj );
624628 if (self -> cur < MP_OBJ_SMALL_INT_VALUE (current_length )) {
625629 mp_obj_t o_out = type -> subscr (self -> obj , MP_OBJ_NEW_SMALL_INT (self -> cur ), MP_OBJ_SENTINEL );
626630 self -> cur += 1 ;
@@ -642,10 +646,11 @@ mp_obj_t mp_obj_new_generic_iterator(mp_obj_t obj, mp_obj_iter_buf_t *iter_buf)
642646
643647bool mp_get_buffer (mp_obj_t obj , mp_buffer_info_t * bufinfo , mp_uint_t flags ) {
644648 const mp_obj_type_t * type = mp_obj_get_type (obj );
645- if (type -> buffer_p .get_buffer == NULL ) {
649+ const mp_getbuffer_fun_t get_buffer = mp_type_getbuffer (type );
650+ if (get_buffer == NULL ) {
646651 return false;
647652 }
648- int ret = type -> buffer_p . get_buffer (obj , bufinfo , flags );
653+ int ret = get_buffer (obj , bufinfo , flags );
649654 if (ret != 0 ) {
650655 return false;
651656 }
@@ -666,3 +671,55 @@ mp_obj_t mp_generic_unary_op(mp_unary_op_t op, mp_obj_t o_in) {
666671 return MP_OBJ_NULL ; // op not supported
667672 }
668673}
674+
675+ mp_call_fun_t mp_type_call (const mp_obj_type_t * type ) {
676+ return type -> call ;
677+ }
678+
679+ mp_unary_op_fun_t mp_type_unary_op (const mp_obj_type_t * type ) {
680+ return type -> unary_op ;
681+ }
682+
683+
684+ mp_binary_op_fun_t mp_type_binary_op (const mp_obj_type_t * type ) {
685+ return type -> binary_op ;
686+ }
687+
688+
689+ mp_attr_fun_t mp_type_attr (const mp_obj_type_t * type ) {
690+ return type -> attr ;
691+ }
692+
693+
694+ mp_subscr_fun_t mp_type_subscr (const mp_obj_type_t * type ) {
695+ return type -> subscr ;
696+ }
697+
698+
699+ mp_getiter_fun_t mp_type_getiter (const mp_obj_type_t * type ) {
700+ return type -> getiter ;
701+ }
702+
703+
704+ mp_fun_1_t mp_type_iternext (const mp_obj_type_t * type ) {
705+ return type -> iternext ;
706+ }
707+
708+
709+ mp_getbuffer_fun_t mp_type_getbuffer (const mp_obj_type_t * type ) {
710+ return type -> buffer_p .get_buffer ;
711+ }
712+
713+
714+ const void * mp_type_protocol (const mp_obj_type_t * type ) {
715+ return type -> protocol ;
716+ }
717+
718+
719+ const void * mp_type_parent (const mp_obj_type_t * type ) {
720+ return type -> parent ;
721+ }
722+
723+ size_t mp_type_size (const mp_obj_type_t * type ) {
724+ return sizeof (mp_obj_type_t );
725+ }
0 commit comments