@@ -575,12 +575,13 @@ struct _mp_obj_type_t {
575575 // The name of this type, a qstr.
576576 uint16_t name ;
577577
578- // Corresponds to __repr__ and __str__ special methods.
579- mp_print_fun_t print ;
580-
581578 // Corresponds to __new__ and __init__ special methods, to make an instance of the type.
582579 mp_make_new_fun_t make_new ;
583580
581+ #if MICROPY_OBJ_TYPE_REPR == MICROPY_OBJ_TYPE_REPR_FULL
582+ // Corresponds to __repr__ and __str__ special methods.
583+ mp_print_fun_t print ;
584+
584585 // Corresponds to __call__ special method, ie T(...).
585586 mp_call_fun_t call ;
586587
@@ -633,17 +634,87 @@ struct _mp_obj_type_t {
633634
634635 // A dict mapping qstrs to objects local methods/constants/etc.
635636 struct _mp_obj_dict_t * locals_dict ;
637+
638+ #elif MICROPY_OBJ_TYPE_REPR == MICROPY_OBJ_TYPE_REPR_SLOT_INDEX
639+
640+ // Ideally these would be only 4 bits, but the extra overhead of
641+ // accessing them adds more code, and we also need to be able to
642+ // take the address of them for mp_obj_class_lookup.
643+ uint8_t slot_index_print ;
644+ uint8_t slot_index_call ;
645+ uint8_t slot_index_unary_op ;
646+ uint8_t slot_index_binary_op ;
647+ uint8_t slot_index_attr ;
648+ uint8_t slot_index_subscr ;
649+ uint8_t slot_index_getiter ;
650+ uint8_t slot_index_iternext ;
651+ uint8_t slot_index_buffer ;
652+ uint8_t slot_index_protocol ;
653+ uint8_t slot_index_parent ;
654+ uint8_t slot_index_locals_dict ;
655+
656+ const void * slots [];
657+
658+ #endif
636659};
637660
638661// Non-variable sized versions of mp_obj_type_t to be used as a member
639662// in other structs or for dynamic allocation. The fields are exactly
640663// as in mp_obj_type_t, but with a fixed size for the flexible array
641664// members.
665+ #if MICROPY_OBJ_TYPE_REPR == MICROPY_OBJ_TYPE_REPR_FULL
642666typedef mp_obj_type_t mp_obj_empty_type_t ;
643667typedef mp_obj_type_t mp_obj_full_type_t ;
668+ #else
669+ typedef struct _mp_obj_empty_type_t {
670+ mp_obj_base_t base ;
671+ uint16_t flags ;
672+ uint16_t name ;
673+ mp_make_new_fun_t make_new ;
674+
675+ uint8_t slot_index_print ;
676+ uint8_t slot_index_call ;
677+ uint8_t slot_index_unary_op ;
678+ uint8_t slot_index_binary_op ;
679+ uint8_t slot_index_attr ;
680+ uint8_t slot_index_subscr ;
681+ uint8_t slot_index_getiter ;
682+ uint8_t slot_index_iternext ;
683+ uint8_t slot_index_buffer ;
684+ uint8_t slot_index_protocol ;
685+ uint8_t slot_index_parent ;
686+ uint8_t slot_index_locals_dict ;
687+
688+ // No slots member.
689+ } mp_obj_empty_type_t ;
690+
691+ typedef struct _mp_obj_full_type_t {
692+ mp_obj_base_t base ;
693+ uint16_t flags ;
694+ uint16_t name ;
695+ mp_make_new_fun_t make_new ;
696+
697+ uint8_t slot_index_print ;
698+ uint8_t slot_index_call ;
699+ uint8_t slot_index_unary_op ;
700+ uint8_t slot_index_binary_op ;
701+ uint8_t slot_index_attr ;
702+ uint8_t slot_index_subscr ;
703+ uint8_t slot_index_getiter ;
704+ uint8_t slot_index_iternext ;
705+ uint8_t slot_index_buffer ;
706+ uint8_t slot_index_protocol ;
707+ uint8_t slot_index_parent ;
708+ uint8_t slot_index_locals_dict ;
709+
710+ // Explicitly add 12 slots.
711+ const void * slots [12 ];
712+ } mp_obj_full_type_t ;
713+ #endif
644714
645715#define MP_TYPE_NULL_MAKE_NEW (NULL)
646716
717+ #if MICROPY_OBJ_TYPE_REPR == MICROPY_OBJ_TYPE_REPR_FULL
647718// Implementation of MP_DEFINE_CONST_OBJ_TYPE for each number of arguments.
648719// Do not use these directly, instead use MP_DEFINE_CONST_OBJ_TYPE.
649720#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_0 (_struct_type , _typename , _name , _flags , _make_new ) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new }
@@ -670,6 +741,50 @@ typedef mp_obj_type_t mp_obj_full_type_t;
670741#define MP_OBJ_TYPE_OFFSETOF_SLOT (f ) (offsetof(mp_obj_type_t, f))
671742#define MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET (t , offset ) (*(void **)((char *)(t) + (offset)) != NULL)
672743
744+ #elif MICROPY_OBJ_TYPE_REPR == MICROPY_OBJ_TYPE_REPR_SLOT_INDEX
745+
746+ #define _MP_OBJ_TYPE_SLOT_TYPE_print (mp_print_fun_t)
747+ #define _MP_OBJ_TYPE_SLOT_TYPE_call (mp_call_fun_t)
748+ #define _MP_OBJ_TYPE_SLOT_TYPE_unary_op (mp_unary_op_fun_t)
749+ #define _MP_OBJ_TYPE_SLOT_TYPE_binary_op (mp_binary_op_fun_t)
750+ #define _MP_OBJ_TYPE_SLOT_TYPE_attr (mp_attr_fun_t)
751+ #define _MP_OBJ_TYPE_SLOT_TYPE_subscr (mp_subscr_fun_t)
752+ #define _MP_OBJ_TYPE_SLOT_TYPE_getiter (mp_getiter_fun_t)
753+ #define _MP_OBJ_TYPE_SLOT_TYPE_iternext (mp_fun_1_t)
754+ #define _MP_OBJ_TYPE_SLOT_TYPE_buffer (mp_buffer_fun_t)
755+ #define _MP_OBJ_TYPE_SLOT_TYPE_protocol (const void *)
756+ #define _MP_OBJ_TYPE_SLOT_TYPE_parent (const void *)
757+ #define _MP_OBJ_TYPE_SLOT_TYPE_locals_dict (struct _mp_obj_dict_t *)
758+
759+ // Implementation of MP_DEFINE_CONST_OBJ_TYPE for each number of arguments.
760+ // Do not use these directly, instead use MP_DEFINE_CONST_OBJ_TYPE.
761+ // Generated with:
762+ // for i in range(13):
763+ // print(f"#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_{i}(_struct_type, _typename, _name, _flags, _make_new{''.join(f', f{j+1}, v{j+1}' for j in range(i))}) const _struct_type _typename = {{ .base = {{ &mp_type_type }}, .name = _name, .flags = _flags, .make_new = _make_new{''.join(f', .slot_index_##f{j+1} = {j+1}' for j in range(i))}{', .slots = { ' + ''.join(f'v{j+1}, ' for j in range(i)) + '}' if i else '' } }}")
764+ #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_0 (_struct_type , _typename , _name , _flags , _make_new ) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new }
765+ #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_1 (_struct_type , _typename , _name , _flags , _make_new , f1 , v1 ) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slots = { v1, } }
766+ #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_2 (_struct_type , _typename , _name , _flags , _make_new , f1 , v1 , f2 , v2 ) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slots = { v1, v2, } }
767+ #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_3 (_struct_type , _typename , _name , _flags , _make_new , f1 , v1 , f2 , v2 , f3 , v3 ) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slots = { v1, v2, v3, } }
768+ #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_4 (_struct_type , _typename , _name , _flags , _make_new , f1 , v1 , f2 , v2 , f3 , v3 , f4 , v4 ) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slots = { v1, v2, v3, v4, } }
769+ #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_5 (_struct_type , _typename , _name , _flags , _make_new , f1 , v1 , f2 , v2 , f3 , v3 , f4 , v4 , f5 , v5 ) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slots = { v1, v2, v3, v4, v5, } }
770+ #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_6 (_struct_type , _typename , _name , _flags , _make_new , f1 , v1 , f2 , v2 , f3 , v3 , f4 , v4 , f5 , v5 , f6 , v6 ) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slots = { v1, v2, v3, v4, v5, v6, } }
771+ #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_7 (_struct_type , _typename , _name , _flags , _make_new , f1 , v1 , f2 , v2 , f3 , v3 , f4 , v4 , f5 , v5 , f6 , v6 , f7 , v7 ) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slots = { v1, v2, v3, v4, v5, v6, v7, } }
772+ #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_8 (_struct_type , _typename , _name , _flags , _make_new , f1 , v1 , f2 , v2 , f3 , v3 , f4 , v4 , f5 , v5 , f6 , v6 , f7 , v7 , f8 , v8 ) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, } }
773+ #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_9 (_struct_type , _typename , _name , _flags , _make_new , f1 , v1 , f2 , v2 , f3 , v3 , f4 , v4 , f5 , v5 , f6 , v6 , f7 , v7 , f8 , v8 , f9 , v9 ) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, } }
774+ #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_10 (_struct_type , _typename , _name , _flags , _make_new , f1 , v1 , f2 , v2 , f3 , v3 , f4 , v4 , f5 , v5 , f6 , v6 , f7 , v7 , f8 , v8 , f9 , v9 , f10 , v10 ) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slot_index_##f10 = 10, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, } }
775+ #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_11 (_struct_type , _typename , _name , _flags , _make_new , f1 , v1 , f2 , v2 , f3 , v3 , f4 , v4 , f5 , v5 , f6 , v6 , f7 , v7 , f8 , v8 , f9 , v9 , f10 , v10 , f11 , v11 ) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slot_index_##f10 = 10, .slot_index_##f11 = 11, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, } }
776+ #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_12 (_struct_type , _typename , _name , _flags , _make_new , f1 , v1 , f2 , v2 , f3 , v3 , f4 , v4 , f5 , v5 , f6 , v6 , f7 , v7 , f8 , v8 , f9 , v9 , f10 , v10 , f11 , v11 , f12 , v12 ) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .slot_index_##f1 = 1, .slot_index_##f2 = 2, .slot_index_##f3 = 3, .slot_index_##f4 = 4, .slot_index_##f5 = 5, .slot_index_##f6 = 6, .slot_index_##f7 = 7, .slot_index_##f8 = 8, .slot_index_##f9 = 9, .slot_index_##f10 = 10, .slot_index_##f11 = 11, .slot_index_##f12 = 12, .slots = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, } }
777+
778+ #define MP_OBJ_TYPE_HAS_SLOT (t , f ) ((t)->slot_index_##f)
779+ #define MP_OBJ_TYPE_GET_SLOT (t , f ) (_MP_OBJ_TYPE_SLOT_TYPE_##f(t)->slots[(t)->slot_index_##f - 1])
780+ #define MP_OBJ_TYPE_GET_SLOT_OR_NULL (t , f ) (_MP_OBJ_TYPE_SLOT_TYPE_##f(MP_OBJ_TYPE_HAS_SLOT(t, f) ? MP_OBJ_TYPE_GET_SLOT(t, f) : NULL))
781+ #define MP_OBJ_TYPE_SET_SLOT (t , f , v , n ) ((t)->slot_index_##f = (n) + 1, (t)->slots[(t)->slot_index_##f - 1] = (void *)v)
782+ #define MP_OBJ_TYPE_OFFSETOF_SLOT (f ) (offsetof(mp_obj_type_t, slot_index_##f))
783+ // For everything except make_new, the offset is to the uint8_t index. For make_new, we need to check the pointer.
784+ #define MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET (t , offset ) (*(uint8_t *)((char *)(t) + (offset)) != 0 || (offset == offsetof(mp_obj_type_t, make_new) && t->make_new))
785+
786+ #endif
787+
673788// Workaround for https://docs.microsoft.com/en-us/cpp/preprocessor/preprocessor-experimental-overview?view=msvc-160#macro-arguments-are-unpacked
674789#define MP_DEFINE_CONST_OBJ_TYPE_EXPAND (x ) x
675790
0 commit comments