8000 py/obj.h: Add slot-index mp_obj_type_t representation. · jimmo/micropython@2ddabe4 · GitHub 8000
[go: up one dir, main page]

Skip to content

Commit 2ddabe4

Browse files
committed
py/obj.h: Add slot-index mp_obj_type_t representation.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
1 parent d88d2a6 commit 2ddabe4

File tree

2 files changed

+125
-3
lines changed

2 files changed

+125
-3
lines changed

py/mpconfig.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,13 @@
145145
#define MICROPY_OBJ_IMMEDIATE_OBJS (MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_D)
146146
#endif
147147

148+
#define MICROPY_OBJ_TYPE_REPR_FULL (0)
149+
#define MICROPY_OBJ_TYPE_REPR_SLOT_INDEX (1)
150+
151+
#ifndef MICROPY_OBJ_TYPE_REPR
152+
#define MICROPY_OBJ_TYPE_REPR (MICROPY_OBJ_TYPE_REPR_FULL)
153+
#endif
154+
148155
/*****************************************************************************/
149156
/* Memory allocation policy */
150157

py/obj.h

Lines changed: 118 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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
642666
typedef mp_obj_type_t mp_obj_empty_type_t;
643667
typedef 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

Comments
 (0)
0