py/obj: Add "full" and "empty" non-variable-length mp_obj_type_t.

This will always have the maximum/minimum size of a mp_obj_type_t
representation and can be used as a member in other structs.

Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This commit is contained in:
Jim Mussared 2022-04-22 13:05:56 +10:00 committed by Damien George
parent 5ddf671944
commit e8355eb163
15 changed files with 40 additions and 21 deletions

View File

@ -94,7 +94,7 @@ int mp_stream_posix_fsync(void *stream) {
return res;
}
mp_obj_type_t btree_type;
mp_obj_full_type_t btree_type;
#include "extmod/modbtree.c"

View File

@ -8,7 +8,7 @@ void *memset(void *s, int c, size_t n) {
}
#endif
mp_obj_type_t mp_type_framebuf;
mp_obj_full_type_t mp_type_framebuf;
#include "extmod/modframebuf.c"

View File

@ -32,8 +32,8 @@ void *memmove(void *dest, const void *src, size_t n) {
return mp_fun_table.memmove_(dest, src, n);
}
mp_obj_type_t match_type;
mp_obj_type_t re_type;
mp_obj_full_type_t match_type;
mp_obj_full_type_t re_type;
#include "extmod/modure.c"

View File

@ -8,7 +8,7 @@ void *memset(void *s, int c, size_t n) {
}
#endif
mp_obj_type_t decompio_type;
mp_obj_full_type_t decompio_type;
#include "extmod/moduzlib.c"

View File

@ -67,7 +67,7 @@ void __dbpanic(DB *db) {
}
STATIC mp_obj_btree_t *btree_new(DB *db, mp_obj_t stream) {
mp_obj_btree_t *o = mp_obj_malloc(mp_obj_btree_t, &btree_type);
mp_obj_btree_t *o = mp_obj_malloc(mp_obj_btree_t, (mp_obj_type_t *)&btree_type);
o->stream = stream;
o->db = db;
o->start_key = mp_const_none;

View File

@ -841,7 +841,7 @@ STATIC MP_DEFINE_CONST_OBJ_TYPE(
// this factory function is provided for backwards compatibility with old FrameBuffer1 class
STATIC mp_obj_t legacy_framebuffer1(size_t n_args, const mp_obj_t *args_in) {
mp_obj_framebuf_t *o = mp_obj_malloc(mp_obj_framebuf_t, &mp_type_framebuf);
mp_obj_framebuf_t *o = mp_obj_malloc(mp_obj_framebuf_t, (mp_obj_type_t *)&mp_type_framebuf);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args_in[0], &bufinfo, MP_BUFFER_WRITE);

View File

@ -62,7 +62,8 @@ mp_obj_t mod_network_nic_ifconfig(struct netif *netif, size_t n_args, const mp_o
struct _mod_network_socket_obj_t;
typedef struct _mod_network_nic_type_t {
mp_obj_type_t base;
// Ensure that this struct is big enough to hold any type size.
mp_obj_full_type_t base;
// API for non-socket operations
int (*gethostbyname)(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *ip_out);

View File

@ -198,7 +198,7 @@ STATIC void re_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
STATIC mp_obj_t ure_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
(void)n_args;
mp_obj_re_t *self;
if (mp_obj_is_type(args[0], &re_type)) {
if (mp_obj_is_type(args[0], (mp_obj_type_t *)&re_type)) {
self = MP_OBJ_TO_PTR(args[0]);
} else {
self = MP_OBJ_TO_PTR(mod_re_compile(1, args));
@ -217,7 +217,7 @@ STATIC mp_obj_t ure_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
return mp_const_none;
}
match->base.type = &match_type;
match->base.type = (mp_obj_type_t *)&match_type;
match->num_matches = caps_num / 2; // caps_num counts start and end pointers
match->str = args[1];
return MP_OBJ_FROM_PTR(match);
@ -282,7 +282,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_split_obj, 2, 3, re_split);
STATIC mp_obj_t re_sub_helper(size_t n_args, const mp_obj_t *args) {
mp_obj_re_t *self;
if (mp_obj_is_type(args[0], &re_type)) {
if (mp_obj_is_type(args[0], (mp_obj_type_t *)&re_type)) {
self = MP_OBJ_TO_PTR(args[0]);
} else {
self = MP_OBJ_TO_PTR(mod_re_compile(1, args));
@ -305,7 +305,7 @@ STATIC mp_obj_t re_sub_helper(size_t n_args, const mp_obj_t *args) {
vstr_t vstr_return;
vstr_return.buf = NULL; // We'll init the vstr after the first match
mp_obj_match_t *match = mp_local_alloc(sizeof(mp_obj_match_t) + caps_num * sizeof(char *));
match->base.type = &match_type;
match->base.type = (mp_obj_type_t *)&match_type;
match->num_matches = caps_num / 2; // caps_num counts start and end pointers
match->str = where;
@ -430,7 +430,7 @@ STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) {
if (size == -1) {
goto error;
}
mp_obj_re_t *o = mp_obj_malloc_var(mp_obj_re_t, char, size, &re_type);
mp_obj_re_t *o = mp_obj_malloc_var(mp_obj_re_t, char, size, (mp_obj_type_t *)&re_type);
#if MICROPY_PY_URE_DEBUG
int flags = 0;
if (n_args > 1) {

View File

@ -774,7 +774,7 @@ static const mp_rom_map_elem_t nina_locals_dict_table[] = {
static MP_DEFINE_CONST_DICT(nina_locals_dict, nina_locals_dict_table);
STATIC MP_DEFINE_CONST_OBJ_TYPE(
STATIC MP_DEFINE_CONST_OBJ_FULL_TYPE(
mod_network_nic_type_nina_base,
MP_QSTR_nina,
MP_TYPE_FLAG_NONE,

View File

@ -1024,7 +1024,7 @@ MP_DEFINE_CONST_OBJ_TYPE(
locals_dict, &wiznet5k_locals_dict
);
#else // WIZNET5K_PROVIDED_STACK
STATIC MP_DEFINE_CONST_OBJ_TYPE(
STATIC MP_DEFINE_CONST_OBJ_FULL_TYPE(
mod_network_nic_type_wiznet5k_base,
MP_QSTR_WIZNET5K,
MP_TYPE_FLAG_NONE,

View File

@ -36,7 +36,8 @@
DEFINE TYPES
******************************************************************************/
typedef struct _mod_network_nic_type_t {
mp_obj_type_t base;
// Ensure that this struct is big enough to hold any type size.
mp_obj_full_type_t base;
} mod_network_nic_type_t;
typedef struct _mod_network_socket_base_t {

View File

@ -1285,7 +1285,7 @@ STATIC const mp_rom_map_elem_t wlan_locals_dict_table[] = {
};
STATIC MP_DEFINE_CONST_DICT(wlan_locals_dict, wlan_locals_dict_table);
STATIC MP_DEFINE_CONST_OBJ_TYPE(
STATIC MP_DEFINE_CONST_OBJ_FULL_TYPE(
mod_network_nic_type_wlan_base,
MP_QSTR_WLAN,
MP_TYPE_FLAG_NONE,

View File

@ -562,6 +562,9 @@ typedef mp_int_t (*mp_buffer_fun_t)(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_
bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags);
void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags);
// This struct will be updated to become a variable sized struct. In order to
// use this as a member, or allocate dynamically, use the mp_obj_empty_type_t
// or mp_obj_full_type_t structs below (which must be kept in sync).
struct _mp_obj_type_t {
// A type is an object so must start with this entry, which points to mp_type_type.
mp_obj_base_t base;
@ -632,6 +635,13 @@ struct _mp_obj_type_t {
struct _mp_obj_dict_t *locals_dict;
};
// Non-variable sized versions of mp_obj_type_t to be used as a member
// in other structs or for dynamic allocation. The fields are exactly
// as in mp_obj_type_t, but with a fixed size for the flexible array
// members.
typedef mp_obj_type_t mp_obj_empty_type_t;
typedef mp_obj_type_t mp_obj_full_type_t;
#define MP_TYPE_NULL_MAKE_NEW (NULL)
// Implementation of MP_DEFINE_CONST_OBJ_TYPE for each number of arguments.
@ -657,14 +667,15 @@ struct _mp_obj_type_t {
// of the 30th argument (30 is 13*2 + 4).
#define MP_DEFINE_CONST_OBJ_TYPE_NARGS(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, N, ...) MP_DEFINE_CONST_OBJ_TYPE_NARGS_##N
// This macro is used to define a object type in ROM.
// These macros are used to define a object type in ROM.
// Invoke as MP_DEFINE_CONST_OBJ_TYPE(_typename, _name, _flags, _make_new [, slot, func]*)
// It uses the number of arguments to select which MP_DEFINE_CONST_OBJ_TYPE_*
// They use the number of arguments to select which MP_DEFINE_CONST_OBJ_TYPE_*
// macro to use based on the number of arguments. It works by shifting the
// numeric values 12, 11, ... 0 by the number of arguments, such that the
// 30th argument ends up being the number to use. The _INV values are
// placeholders because the slot arguments come in pairs.
#define MP_DEFINE_CONST_OBJ_TYPE(...) MP_DEFINE_CONST_OBJ_TYPE_EXPAND(MP_DEFINE_CONST_OBJ_TYPE_NARGS(__VA_ARGS__, _INV, 12, _INV, 11, _INV, 10, _INV, 9, _INV, 8, _INV, 7, _INV, 6, _INV, 5, _INV, 4, _INV, 3, _INV, 2, _INV, 1, _INV, 0)(mp_obj_type_t, __VA_ARGS__))
#define MP_DEFINE_CONST_OBJ_FULL_TYPE(...) MP_DEFINE_CONST_OBJ_TYPE_EXPAND(MP_DEFINE_CONST_OBJ_TYPE_NARGS(__VA_ARGS__, _INV, 12, _INV, 11, _INV, 10, _INV, 9, _INV, 8, _INV, 7, _INV, 6, _INV, 5, _INV, 4, _INV, 3, _INV, 2, _INV, 1, _INV, 0)(mp_obj_full_type_t, __VA_ARGS__))
// Constant types, globally accessible
extern const mp_obj_type_t mp_type_type;

View File

@ -29,7 +29,10 @@
#include "py/objtuple.h"
typedef struct _mp_obj_namedtuple_type_t {
mp_obj_type_t base;
// Must use the full-size version to avoid this being a variable sized member.
// This means that named tuples use slightly more RAM than necessary, but
// no worse than if we didn't have slots/split representation.
mp_obj_full_type_t base;
size_t n_fields;
qstr fields[];
} mp_obj_namedtuple_type_t;

View File

@ -1148,7 +1148,10 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
#endif
}
mp_obj_type_t *o = m_new0(mp_obj_type_t, 1);
// Allocate a full-sized mp_obj_full_type_t instance (i.e. all slots / extended fields).
// Given that Python types use almost all the slots anyway, this doesn't cost anything
// extra.
mp_obj_type_t *o = (mp_obj_type_t *)m_new0(mp_obj_full_type_t, 1);
o->base.type = &mp_type_type;
o->flags = base_flags;
o->name = name;