Skip to content

Commit cd119ca

Browse files
committed
Introduce, use getters for fields which will be optional in types
1 parent 23baa02 commit cd119ca

10 files changed

Lines changed: 178 additions & 81 deletions

File tree

ports/unix/modffi.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -455,19 +455,22 @@ STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
455455
} else if (mp_obj_is_str(a)) {
456456
const char *s = mp_obj_str_get_str(a);
457457
values[i].ffi = (ffi_arg)(intptr_t)s;
458-
} else if (((mp_obj_base_t *)MP_OBJ_TO_PTR(a))->type->buffer_p.get_buffer != NULL) {
459-
mp_obj_base_t *o = (mp_obj_base_t *)MP_OBJ_TO_PTR(a);
460-
mp_buffer_info_t bufinfo;
461-
int ret = o->type->buffer_p.get_buffer(MP_OBJ_FROM_PTR(o), &bufinfo, MP_BUFFER_READ); // TODO: MP_BUFFER_READ?
462-
if (ret != 0) {
458+
} else {
459+
mp_getbuffer_fun_t get_buffer = mp_type_getbuffer(((mp_obj_base_t *)MP_OBJ_TO_PTR(a))->type);
460+
if (get_buffer != NULL) {
461+
mp_obj_base_t *o = (mp_obj_base_t *)MP_OBJ_TO_PTR(a);
462+
mp_buffer_info_t bufinfo;
463+
int ret = get_buffer(MP_OBJ_FROM_PTR(o), &bufinfo, MP_BUFFER_READ); // TODO: MP_BUFFER_READ?
464+
if (ret != 0) {
465+
goto error;
466+
}
467+
values[i].ffi = (ffi_arg)(intptr_t)bufinfo.buf;
468+
} else if (mp_obj_is_type(a, &fficallback_type)) {
469+
mp_obj_fficallback_t *p = MP_OBJ_TO_PTR(a);
470+
values[i].ffi = (ffi_arg)(intptr_t)p->func;
471+
} else {
463472
goto error;
464473
}
465-
values[i].ffi = (ffi_arg)(intptr_t)bufinfo.buf;
466-
} else if (mp_obj_is_type(a, &fficallback_type)) {
467-
mp_obj_fficallback_t *p = MP_OBJ_TO_PTR(a);
468-
values[i].ffi = (ffi_arg)(intptr_t)p->func;
469-
} else {
470-
goto error;
471474
}
472475
valueptrs[i] = &values[i];
473476
}

py/dynruntime.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ static inline mp_obj_t mp_obj_cast_to_native_base_dyn(mp_obj_t self_in, mp_const
140140

141141
if (MP_OBJ_FROM_PTR(self_type) == native_type) {
142142
return self_in;
143-
} else if (self_type->parent != native_type) {
143+
}
144+
mp_parent_t parent = mp_type_parent(self_type);
145+
if (parent != native_type) {
144146
// The self_in object is not a direct descendant of native_type, so fail the cast.
145147
// This is a very simple version of mp_obj_is_subclass_fast that could be improved.
146148
return MP_OBJ_NULL;

py/obj.c

Lines changed: 70 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,9 @@ bool PLACE_IN_ITCM(mp_obj_is_true)(mp_obj_t arg) {
195195
}
196196
} else {
197197
const mp_obj_type_t *type = mp_obj_get_type(arg);
198-
if (type->unary_op != NULL) {
199-
mp_obj_t result = type->unary_op(MP_UNARY_OP_BOOL, arg);
198+
mp_unary_op_fun_t unary_op = mp_type_unary_op(type);
199+
if (unary_op) {
200+
mp_obj_t result = unary_op(MP_UNARY_OP_BOOL, arg);
200201
if (result != MP_OBJ_NULL) {
201202
return result == mp_const_true;
202203
}
@@ -214,7 +215,7 @@ bool PLACE_IN_ITCM(mp_obj_is_true)(mp_obj_t arg) {
214215
}
215216

216217
bool mp_obj_is_callable(mp_obj_t o_in) {
217-
const mp_call_fun_t call = mp_obj_get_type(o_in)->call;
218+
const mp_call_fun_t call = mp_type_call(mp_obj_get_type(o_in));
218219
if (call != mp_obj_instance_call) {
219220
return call != NULL;
220221
}
@@ -281,19 +282,20 @@ mp_obj_t mp_obj_equal_not_equal(mp_binary_op_t op, mp_obj_t o1, mp_obj_t o2) {
281282
const mp_obj_type_t *type = mp_obj_get_type(o1);
282283
// If a full equality test is not needed and the other object is a different
283284
// type then we don't need to bother trying the comparison.
284-
if (type->binary_op != NULL &&
285+
mp_binary_op_fun_t binary_op = mp_type_binary_op(type);
286+
if (binary_op != NULL &&
285287
((type->flags & MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE) || mp_obj_get_type(o2) == type)) {
286288
// CPython is asymmetric: it will try __eq__ if there's no __ne__ but not the
287289
// other way around. If the class doesn't need a full test we can skip __ne__.
288290
if (op == MP_BINARY_OP_NOT_EQUAL && (type->flags & MP_TYPE_FLAG_EQ_HAS_NEQ_TEST)) {
289-
mp_obj_t r = type->binary_op(MP_BINARY_OP_NOT_EQUAL, o1, o2);
291+
mp_obj_t r = binary_op(MP_BINARY_OP_NOT_EQUAL, o1, o2);
290292
if (r != MP_OBJ_NULL) {
291293
return r;
292294
}
293295
}
294296

295297
// Try calling __eq__.
296-
mp_obj_t r = type->binary_op(MP_BINARY_OP_EQUAL, o1, o2);
298+
mp_obj_t r = binary_op(MP_BINARY_OP_EQUAL, o1, o2);
297299
if (r != MP_OBJ_NULL) {
298300
if (op == MP_BINARY_OP_EQUAL) {
299301
return r;
@@ -556,8 +558,9 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) {
556558
return MP_OBJ_NEW_SMALL_INT(l);
557559
} else {
558560
const mp_obj_type_t *type = mp_obj_get_type(o_in);
559-
if (type->unary_op != NULL) {
560-
return type->unary_op(MP_UNARY_OP_LEN, o_in);
561+
mp_unary_op_fun_t unary_op = mp_type_unary_op(type);
562+
if (unary_op != NULL) {
563+
return unary_op(MP_UNARY_OP_LEN, o_in);
561564
} else {
562565
return MP_OBJ_NULL;
563566
}
@@ -566,8 +569,9 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) {
566569

567570
mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) {
568571
const mp_obj_type_t *type = mp_obj_get_type(base);
569-
if (type->subscr != NULL) {
570-
mp_obj_t ret = type->subscr(base, index, value);
572+
mp_subscr_fun_t subscr = mp_type_subscr(type);
573+
if (subscr != NULL) {
574+
mp_obj_t ret = subscr(base, index, value);
571575
// May have called port specific C code. Make sure it didn't mess up the heap.
572576
assert_heap_ok();
573577
if (ret != MP_OBJ_NULL) {
@@ -620,7 +624,7 @@ typedef struct {
620624
STATIC mp_obj_t generic_it_iternext(mp_obj_t self_in) {
621625
mp_obj_generic_it_t *self = MP_OBJ_TO_PTR(self_in);
622626
const mp_obj_type_t *type = mp_obj_get_type(self->obj);
623-
mp_obj_t current_length = type->unary_op(MP_UNARY_OP_LEN, self->obj);
627+
mp_obj_t current_length = mp_type_unary_op(type)(MP_UNARY_OP_LEN, self->obj);
624628
if (self->cur < MP_OBJ_SMALL_INT_VALUE(current_length)) {
625629
mp_obj_t o_out = type->subscr(self->obj, MP_OBJ_NEW_SMALL_INT(self->cur), MP_OBJ_SENTINEL);
626630
self->cur += 1;
@@ -642,10 +646,11 @@ mp_obj_t mp_obj_new_generic_iterator(mp_obj_t obj, mp_obj_iter_buf_t *iter_buf)
642646

643647
bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
644648
const mp_obj_type_t *type = mp_obj_get_type(obj);
645-
if (type->buffer_p.get_buffer == NULL) {
649+
const mp_getbuffer_fun_t get_buffer = mp_type_getbuffer(type);
650+
if (get_buffer == NULL) {
646651
return false;
647652
}
648-
int ret = type->buffer_p.get_buffer(obj, bufinfo, flags);
653+
int ret = get_buffer(obj, bufinfo, flags);
649654
if (ret != 0) {
650655
return false;
651656
}
@@ -666,3 +671,55 @@ mp_obj_t mp_generic_unary_op(mp_unary_op_t op, mp_obj_t o_in) {
666671
return MP_OBJ_NULL; // op not supported
667672
}
668673
}
674+
675+
mp_call_fun_t mp_type_call(const mp_obj_type_t *type) {
676+
return type->call;
677+
}
678+
679+
mp_unary_op_fun_t mp_type_unary_op(const mp_obj_type_t *type) {
680+
return type->unary_op;
681+
}
682+
683+
684+
mp_binary_op_fun_t mp_type_binary_op(const mp_obj_type_t *type) {
685+
return type->binary_op;
686+
}
687+
688+
689+
mp_attr_fun_t mp_type_attr(const mp_obj_type_t *type) {
690+
return type->attr;
691+
}
692+
693+
694+
mp_subscr_fun_t mp_type_subscr(const mp_obj_type_t *type) {
695+
return type->subscr;
696+
}
697+
698+
699+
mp_getiter_fun_t mp_type_getiter(const mp_obj_type_t *type) {
700+
return type->getiter;
701+
}
702+
703+
704+
mp_fun_1_t mp_type_iternext(const mp_obj_type_t *type) {
705+
return type->iternext;
706+
}
707+
708+
709+
mp_getbuffer_fun_t mp_type_getbuffer(const mp_obj_type_t *type) {
710+
return type->buffer_p.get_buffer;
711+
}
712+
713+
714+
const void *mp_type_protocol(const mp_obj_type_t *type) {
715+
return type->protocol;
716+
}
717+
718+
719+
const void *mp_type_parent(const mp_obj_type_t *type) {
720+
return type->parent;
721+
}
722+
723+
size_t mp_type_size(const mp_obj_type_t *type) {
724+
return sizeof(mp_obj_type_t);
725+
}

py/obj.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,8 @@ typedef struct _mp_obj_iter_buf_t {
534534
// It's rounded up in case mp_obj_base_t is smaller than mp_obj_t (eg for OBJ_REPR_D).
535535
#define MP_OBJ_ITER_BUF_NSLOTS ((sizeof(mp_obj_iter_buf_t) + sizeof(mp_obj_t) - 1) / sizeof(mp_obj_t))
536536

537+
struct _mp_buffer_info_t;
538+
537539
typedef void (*mp_print_fun_t)(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind);
538540
typedef mp_obj_t (*mp_make_new_fun_t)(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args);
539541
typedef mp_obj_t (*mp_call_fun_t)(mp_obj_t fun, size_t n_args, size_t n_kw, const mp_obj_t *args);
@@ -542,6 +544,7 @@ typedef mp_obj_t (*mp_binary_op_fun_t)(mp_binary_op_t op, mp_obj_t, mp_obj_t);
542544
typedef void (*mp_attr_fun_t)(mp_obj_t self_in, qstr attr, mp_obj_t *dest);
543545
typedef mp_obj_t (*mp_subscr_fun_t)(mp_obj_t self_in, mp_obj_t index, mp_obj_t value);
544546
typedef mp_obj_t (*mp_getiter_fun_t)(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf);
547+
typedef mp_int_t (*mp_getbuffer_fun_t)(mp_obj_t obj, struct _mp_buffer_info_t *bufinfo, mp_uint_t flags);
545548

546549
// Buffer protocol
547550
typedef struct _mp_buffer_info_t {
@@ -627,6 +630,18 @@ struct _mp_obj_type_t {
627630
struct _mp_obj_dict_t *locals_dict;
628631
};
629632

633+
extern size_t mp_type_size(const mp_obj_type_t *);
634+
extern mp_call_fun_t mp_type_call(const mp_obj_type_t *);
635+
extern mp_unary_op_fun_t mp_type_unary_op(const mp_obj_type_t *);
636+
extern mp_binary_op_fun_t mp_type_binary_op(const mp_obj_type_t *);
637+
extern mp_attr_fun_t mp_type_attr(const mp_obj_type_t *);
638+
extern mp_subscr_fun_t mp_type_subscr(const mp_obj_type_t *);
639+
extern mp_getiter_fun_t mp_type_getiter(const mp_obj_type_t *);
640+
extern mp_fun_1_t mp_type_iternext(const mp_obj_type_t *);
641+
extern mp_getbuffer_fun_t mp_type_getbuffer(const mp_obj_type_t *);
642+
extern const void *mp_type_protocol(const mp_obj_type_t *);
643+
extern const void *mp_type_parent(const mp_obj_type_t *);
644+
630645
// Constant types, globally accessible
631646
extern const mp_obj_type_t mp_type_type;
632647
extern const mp_obj_type_t mp_type_object;
@@ -761,11 +776,11 @@ extern const struct _mp_obj_exception_t mp_const_GeneratorExit_obj;
761776
#endif
762777
#define mp_obj_is_int(o) (mp_obj_is_small_int(o) || mp_obj_is_type(o, &mp_type_int))
763778
#define mp_obj_is_str(o) (mp_obj_is_qstr(o) || mp_obj_is_type(o, &mp_type_str))
764-
#define mp_obj_is_str_or_bytes(o) (mp_obj_is_qstr(o) || (mp_obj_is_obj(o) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->binary_op == mp_obj_str_binary_op))
779+
#define mp_obj_is_str_or_bytes(o) (mp_obj_is_qstr(o) || (mp_obj_is_obj(o) && mp_type_binary_op(((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type) == mp_obj_str_binary_op))
765780
#define mp_obj_is_dict_or_ordereddict(o) (mp_obj_is_obj(o) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->make_new == mp_obj_dict_make_new)
766781
#define mp_obj_is_fun(o) (mp_obj_is_obj(o) && (((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->name == MP_QSTR_function))
767782
// type check is done on getiter method to allow tuple, namedtuple, attrtuple
768-
#define mp_obj_is_tuple_compatible(o) (mp_obj_get_type(o)->getiter == mp_obj_tuple_getiter)
783+
#define mp_obj_is_tuple_compatible(o) (mp_type_getiter(mp_obj_get_type(o)) == mp_obj_tuple_getiter)
769784

770785
mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict);
771786
static inline mp_obj_t mp_obj_new_bool(mp_int_t x) {

py/objarray.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
564564
size_t src_len;
565565
void *src_items;
566566
size_t item_sz = mp_binary_get_size('@', o->typecode & TYPECODE_MASK, NULL);
567-
if (mp_obj_is_obj(value) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(value))->type->subscr == array_subscr) {
567+
if (mp_obj_is_obj(value) && mp_type_subscr(((mp_obj_base_t *)MP_OBJ_TO_PTR(value))->type) == array_subscr) {
568568
// value is array, bytearray or memoryview
569569
mp_obj_array_t *src_slice = MP_OBJ_TO_PTR(value);
570570
if (item_sz != mp_binary_get_size('@', src_slice->typecode & TYPECODE_MASK, NULL)) {

py/objtuple.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ STATIC mp_obj_t tuple_cmp_helper(mp_uint_t op, mp_obj_t self_in, mp_obj_t anothe
108108
mp_check_self(mp_obj_is_tuple_compatible(self_in));
109109
const mp_obj_type_t *another_type = mp_obj_get_type(another_in);
110110
mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in);
111-
if (another_type->getiter != mp_obj_tuple_getiter) {
111+
if (mp_type_getiter(another_type) != mp_obj_tuple_getiter) {
112112
// Slow path for user subclasses
113113
another_in = mp_obj_cast_to_native_base(another_in, MP_OBJ_FROM_PTR(&mp_type_tuple));
114114
if (another_in == MP_OBJ_NULL) {
@@ -184,7 +184,7 @@ mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
184184
// load
185185
mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in);
186186
// when called with a native type (eg namedtuple) using mp_obj_tuple_subscr, get the native self
187-
if (self->base.type->subscr != &mp_obj_tuple_subscr) {
187+
if (mp_type_subscr(self->base.type) != &mp_obj_tuple_subscr) {
188188
self = mp_obj_cast_to_native_base(self_in, &mp_type_tuple);
189189
}
190190

0 commit comments

Comments
 (0)