Skip to content

Commit d4a874b

Browse files
committed
extmod/moductypes: sizeof operation depends on layout type of structure.
Previously, sizeof() blindly assumed LAYOUT_NATIVE and tried to align size even for packed LAYOUT_LITTLE_ENDIAN & LAYOUT_BIG_ENDIAN. As sizeof() is implemented on a strucuture descriptor dictionary (not an structure object), resolving this required passing layout type around.
1 parent 5a4a2b1 commit d4a874b

1 file changed

Lines changed: 17 additions & 13 deletions

File tree

extmod/moductypes.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ STATIC void uctypes_struct_print(const mp_print_t *print, mp_obj_t self_in, mp_p
155155
}
156156

157157
// Get size of any type descriptor
158-
STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, mp_uint_t *max_field_size);
158+
STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, int layout_type, mp_uint_t *max_field_size);
159159

160160
// Get size of scalar type descriptor
161161
static inline mp_uint_t uctypes_struct_scalar_size(int val_type) {
@@ -167,15 +167,15 @@ static inline mp_uint_t uctypes_struct_scalar_size(int val_type) {
167167
}
168168

169169
// Get size of aggregate type descriptor
170-
STATIC mp_uint_t uctypes_struct_agg_size(mp_obj_tuple_t *t, mp_uint_t *max_field_size) {
170+
STATIC mp_uint_t uctypes_struct_agg_size(mp_obj_tuple_t *t, int layout_type, mp_uint_t *max_field_size) {
171171
mp_uint_t total_size = 0;
172172

173173
mp_int_t offset_ = MP_OBJ_SMALL_INT_VALUE(t->items[0]);
174174
mp_uint_t agg_type = GET_TYPE(offset_, AGG_TYPE_BITS);
175175

176176
switch (agg_type) {
177177
case STRUCT:
178-
return uctypes_struct_size(t->items[1], max_field_size);
178+
return uctypes_struct_size(t->items[1], layout_type, max_field_size);
179179
case PTR:
180180
if (sizeof(void*) > *max_field_size) {
181181
*max_field_size = sizeof(void*);
@@ -194,7 +194,7 @@ STATIC mp_uint_t uctypes_struct_agg_size(mp_obj_tuple_t *t, mp_uint_t *max_field
194194
}
195195
} else {
196196
// Elements of array are aggregates
197-
item_s = uctypes_struct_size(t->items[2], max_field_size);
197+
item_s = uctypes_struct_size(t->items[2], layout_type, max_field_size);
198198
}
199199

200200
return item_s * arr_sz;
@@ -206,10 +206,10 @@ STATIC mp_uint_t uctypes_struct_agg_size(mp_obj_tuple_t *t, mp_uint_t *max_field
206206
return total_size;
207207
}
208208

209-
STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, mp_uint_t *max_field_size) {
209+
STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, int layout_type, mp_uint_t *max_field_size) {
210210
if (!MP_OBJ_IS_TYPE(desc_in, &mp_type_dict)) {
211211
if (MP_OBJ_IS_TYPE(desc_in, &mp_type_tuple)) {
212-
return uctypes_struct_agg_size((mp_obj_tuple_t*)MP_OBJ_TO_PTR(desc_in), max_field_size);
212+
return uctypes_struct_agg_size((mp_obj_tuple_t*)MP_OBJ_TO_PTR(desc_in), layout_type, max_field_size);
213213
} else if (MP_OBJ_IS_SMALL_INT(desc_in)) {
214214
// We allow sizeof on both type definitions and structures/structure fields,
215215
// but scalar structure field is lowered into native Python int, so all
@@ -244,7 +244,7 @@ STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, mp_uint_t *max_field_size
244244
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(v);
245245
mp_int_t offset = MP_OBJ_SMALL_INT_VALUE(t->items[0]);
246246
offset &= VALUE_MASK(AGG_TYPE_BITS);
247-
mp_uint_t s = uctypes_struct_agg_size(t, max_field_size);
247+
mp_uint_t s = uctypes_struct_agg_size(t, layout_type, max_field_size);
248248
if (offset + s > total_size) {
249249
total_size = offset + s;
250250
}
@@ -253,7 +253,9 @@ STATIC mp_uint_t uctypes_struct_size(mp_obj_t desc_in, mp_uint_t *max_field_size
253253
}
254254

255255
// Round size up to alignment of biggest field
256-
total_size = (total_size + *max_field_size - 1) & ~(*max_field_size - 1);
256+
if (layout_type == LAYOUT_NATIVE) {
257+
total_size = (total_size + *max_field_size - 1) & ~(*max_field_size - 1);
258+
}
257259
return total_size;
258260
}
259261

@@ -262,14 +264,16 @@ STATIC mp_obj_t uctypes_struct_sizeof(mp_obj_t obj_in) {
262264
if (MP_OBJ_IS_TYPE(obj_in, &mp_type_bytearray)) {
263265
return mp_obj_len(obj_in);
264266
}
267+
int layout_type = LAYOUT_NATIVE;
265268
// We can apply sizeof either to structure definition (a dict)
266269
// or to instantiated structure
267270
if (MP_OBJ_IS_TYPE(obj_in, &uctypes_struct_type)) {
268271
// Extract structure definition
269272
mp_obj_uctypes_struct_t *obj = MP_OBJ_TO_PTR(obj_in);
270273
obj_in = obj->desc;
274+
layout_type = obj->flags;
271275
}
272-
mp_uint_t size = uctypes_struct_size(obj_in, &max_field_size);
276+
mp_uint_t size = uctypes_struct_size(obj_in, layout_type, &max_field_size);
273277
return MP_OBJ_NEW_SMALL_INT(size);
274278
}
275279
STATIC MP_DEFINE_CONST_FUN_OBJ_1(uctypes_struct_sizeof_obj, uctypes_struct_sizeof);
@@ -470,7 +474,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set
470474
case ARRAY: {
471475
mp_uint_t dummy;
472476
if (IS_SCALAR_ARRAY(sub) && IS_SCALAR_ARRAY_OF_BYTES(sub)) {
473-
return mp_obj_new_bytearray_by_ref(uctypes_struct_agg_size(sub, &dummy), self->addr + offset);
477+
return mp_obj_new_bytearray_by_ref(uctypes_struct_agg_size(sub, self->flags, &dummy), self->addr + offset);
474478
}
475479
// Fall thru to return uctypes struct object
476480
}
@@ -533,7 +537,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_ob
533537
return get_unaligned(val_type, p, self->flags);
534538
} else {
535539
mp_uint_t dummy = 0;
536-
mp_uint_t size = uctypes_struct_size(t->items[2], &dummy);
540+
mp_uint_t size = uctypes_struct_size(t->items[2], self->flags, &dummy);
537541
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
538542
o->base.type = &uctypes_struct_type;
539543
o->desc = t->items[2];
@@ -548,7 +552,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_ob
548552
return get_aligned(val_type, p, index);
549553
} else {
550554
mp_uint_t dummy = 0;
551-
mp_uint_t size = uctypes_struct_size(t->items[1], &dummy);
555+
mp_uint_t size = uctypes_struct_size(t->items[1], self->flags, &dummy);
552556
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
553557
o->base.type = &uctypes_struct_type;
554558
o->desc = t->items[1];
@@ -570,7 +574,7 @@ STATIC mp_int_t uctypes_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo,
570574
(void)flags;
571575
mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in);
572576
mp_uint_t max_field_size = 0;
573-
mp_uint_t size = uctypes_struct_size(self->desc, &max_field_size);
577+
mp_uint_t size = uctypes_struct_size(self->desc, self->flags, &max_field_size);
574578

575579
bufinfo->buf = self->addr;
576580
bufinfo->len = size;

0 commit comments

Comments
 (0)