"... object must have mp_obj_base_t" - what about mp_obj_namedtuple_type_t

C programming, build, interpreter/VM.
Target audience: MicroPython Developers.
Post Reply
jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

"... object must have mp_obj_base_t" - what about mp_obj_namedtuple_type_t

Post by jickster » Mon Mar 26, 2018 9:34 pm

I've been creating types and I've followed this rule

Code: Select all

// This mp_obj_type_t struct is a concrete MicroPython object which holds info
// about a type.  See below for actual definition of the struct.
typedef struct _mp_obj_type_t mp_obj_type_t;

// Anything that wants to be a concrete MicroPython object must have mp_obj_base_t
// as its first member (small ints, qstr objs and inline floats are not concrete).
struct _mp_obj_base_t {
    const mp_obj_type_t *type MICROPY_OBJ_BASE_ALIGNMENT;
};
typedef struct _mp_obj_base_t mp_obj_base_t;
// Anything that wants to be a concrete MicroPython object must have mp_obj_base_t
// as its first member (small ints, qstr objs and inline floats are not concrete).


and everything has worked out.

So then why are there native types that do not follow this rule?

Code: Select all

#if MICROPY_PY_COLLECTIONS

typedef struct _mp_obj_namedtuple_type_t {
    mp_obj_type_t base;
    size_t n_fields;
    qstr fields[];
} mp_obj_namedtuple_type_t;
I understand that the only difference between

Code: Select all

mp_obj_type_t 
and

Code: Select all

mp_obj_base_t 
is that

Code: Select all

mp_obj_base_t 
is a struct containing a

Code: Select all

mp_obj_type_t *
.

So why is it ok to use mp_obj_type_t directly?

User avatar
dhylands
Posts: 3176
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: "... object must have mp_obj_base_t" - what about mp_obj_namedtuple_type_t

Post by dhylands » Mon Mar 26, 2018 9:42 pm

I'm going to guess that it's just an oversight, and that it really should be an mp_obj_base_t.

The reason it happens to work is because mp_obj_base_t and mp_obj_type_t are both the same size.

mp_obj_base_t includes an alignment directive that the namedtuple is lacking, so declaring a static namedtuple might be problematic on say a 16-bit architecture like the pic16bit port.

jickster
Posts: 629
Joined: Thu Sep 07, 2017 8:57 pm

Re: "... object must have mp_obj_base_t" - what about mp_obj_namedtuple_type_t

Post by jickster » Tue Mar 27, 2018 2:11 pm

dhylands wrote:
Mon Mar 26, 2018 9:42 pm
I'm going to guess that it's just an oversight, and that it really should be an mp_obj_base_t.

The reason it happens to work is because mp_obj_base_t and mp_obj_type_t are both the same size.

mp_obj_base_t includes an alignment directive that the namedtuple is lacking, so declaring a static namedtuple might be problematic on say a 16-bit architecture like the pic16bit port.
They're not the same size. Nowhere near.

mp_obj_type_t is a struct containing many elements

Code: Select all

typedef struct _mp_obj_type_t mp_obj_type_t;

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;

    // The name of this type.
    qstr name;

    // Corresponds to __repr__ and __str__ special methods.
    mp_print_fun_t print;
...
mp_obj_base_t is a struct containing one item: a pointer to mp_obj_type_t

Code: Select all

struct _mp_obj_base_t {
    const mp_obj_type_t *type MICROPY_OBJ_BASE_ALIGNMENT;
};
typedef struct _mp_obj_base_t mp_obj_base_t;

User avatar
dhylands
Posts: 3176
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: "... object must have mp_obj_base_t" - what about mp_obj_namedtuple_type_t

Post by dhylands » Tue Mar 27, 2018 3:47 pm

My bad. I wasn't looking at the right thing.

The named tuple type has an mp_obj_type_t as its first member, and mp_obj_type_t has the base type as its first member, so the first 4 bytes of a named tuple is still a pointer to the base type.

I'd have to look at a bunch more of the code to see why it was done this way instead of the way the other native types were done.

Post Reply