py/obj: Add accessors for type slots and use everywhere.
This is a no-op, but sets the stage for changing the mp_obj_type_t representation. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This commit is contained in:
committed by
Damien George
parent
e8355eb163
commit
a52cd5b07d
136
py/objtype.c
136
py/objtype.c
@@ -59,13 +59,13 @@ STATIC int instance_count_native_bases(const mp_obj_type_t *type, const mp_obj_t
|
||||
// Native types don't have parents (at least not from our perspective) so end.
|
||||
*last_native_base = type;
|
||||
return count + 1;
|
||||
} else if (type->parent == NULL) {
|
||||
} else if (!MP_OBJ_TYPE_HAS_SLOT(type, parent)) {
|
||||
// No parents so end search here.
|
||||
return count;
|
||||
#if MICROPY_MULTIPLE_INHERITANCE
|
||||
} else if (((mp_obj_base_t *)type->parent)->type == &mp_type_tuple) {
|
||||
} else if (((mp_obj_base_t *)MP_OBJ_TYPE_GET_SLOT(type, parent))->type == &mp_type_tuple) {
|
||||
// Multiple parents, search through them all recursively.
|
||||
const mp_obj_tuple_t *parent_tuple = type->parent;
|
||||
const mp_obj_tuple_t *parent_tuple = MP_OBJ_TYPE_GET_SLOT(type, parent);
|
||||
const mp_obj_t *item = parent_tuple->items;
|
||||
const mp_obj_t *top = item + parent_tuple->len;
|
||||
for (; item < top; ++item) {
|
||||
@@ -77,7 +77,7 @@ STATIC int instance_count_native_bases(const mp_obj_type_t *type, const mp_obj_t
|
||||
#endif
|
||||
} else {
|
||||
// A single parent, use iteration to continue the search.
|
||||
type = type->parent;
|
||||
type = MP_OBJ_TYPE_GET_SLOT(type, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,7 +118,7 @@ mp_obj_instance_t *mp_obj_new_instance(const mp_obj_type_t *class, const mp_obj_
|
||||
// will keep lookup->dest[0]'s value (should be MP_OBJ_NULL on invocation) if attribute
|
||||
// is not found
|
||||
// will set lookup->dest[0] to MP_OBJ_SENTINEL if special method was found in a native
|
||||
// type base via slot id (as specified by lookup->meth_offset). As there can be only one
|
||||
// type base via slot id (as specified by lookup->slot_offset). As there can be only one
|
||||
// native base, it's known that it applies to instance->subobj[0]. In most cases, we also
|
||||
// don't need to know which type it was - because instance->subobj[0] is of that type.
|
||||
// The only exception is when object is not yet constructed, then we need to know base
|
||||
@@ -127,7 +127,7 @@ mp_obj_instance_t *mp_obj_new_instance(const mp_obj_type_t *class, const mp_obj_
|
||||
struct class_lookup_data {
|
||||
mp_obj_instance_t *obj;
|
||||
qstr attr;
|
||||
size_t meth_offset;
|
||||
size_t slot_offset;
|
||||
mp_obj_t *dest;
|
||||
bool is_type;
|
||||
};
|
||||
@@ -141,19 +141,19 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_t
|
||||
// This avoids extra method_name => slot lookup. On the other hand,
|
||||
// this should not be applied to class types, as will result in extra
|
||||
// lookup either.
|
||||
if (lookup->meth_offset != 0 && mp_obj_is_native_type(type)) {
|
||||
if (*(void **)((char *)type + lookup->meth_offset) != NULL) {
|
||||
if (lookup->slot_offset != 0 && mp_obj_is_native_type(type)) {
|
||||
if (MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(type, lookup->slot_offset)) {
|
||||
DEBUG_printf("mp_obj_class_lookup: Matched special meth slot (off=%d) for %s\n",
|
||||
lookup->meth_offset, qstr_str(lookup->attr));
|
||||
lookup->slot_offset, qstr_str(lookup->attr));
|
||||
lookup->dest[0] = MP_OBJ_SENTINEL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (type->locals_dict != NULL) {
|
||||
if (MP_OBJ_TYPE_HAS_SLOT(type, locals_dict)) {
|
||||
// search locals_dict (the set of methods/attributes)
|
||||
assert(mp_obj_is_dict_or_ordereddict(MP_OBJ_FROM_PTR(type->locals_dict))); // MicroPython restriction, for now
|
||||
mp_map_t *locals_map = &type->locals_dict->map;
|
||||
assert(mp_obj_is_dict_or_ordereddict(MP_OBJ_FROM_PTR(MP_OBJ_TYPE_GET_SLOT(type, locals_dict)))); // MicroPython restriction, for now
|
||||
mp_map_t *locals_map = &MP_OBJ_TYPE_GET_SLOT(type, locals_dict)->map;
|
||||
mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(lookup->attr), MP_MAP_LOOKUP);
|
||||
if (elem != NULL) {
|
||||
if (lookup->is_type) {
|
||||
@@ -197,12 +197,12 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_t
|
||||
|
||||
// attribute not found, keep searching base classes
|
||||
|
||||
if (type->parent == NULL) {
|
||||
if (!MP_OBJ_TYPE_HAS_SLOT(type, parent)) {
|
||||
DEBUG_printf("mp_obj_class_lookup: No more parents\n");
|
||||
return;
|
||||
#if MICROPY_MULTIPLE_INHERITANCE
|
||||
} else if (((mp_obj_base_t *)type->parent)->type == &mp_type_tuple) {
|
||||
const mp_obj_tuple_t *parent_tuple = type->parent;
|
||||
} else if (((mp_obj_base_t *)MP_OBJ_TYPE_GET_SLOT(type, parent))->type == &mp_type_tuple) {
|
||||
const mp_obj_tuple_t *parent_tuple = MP_OBJ_TYPE_GET_SLOT(type, parent);
|
||||
const mp_obj_t *item = parent_tuple->items;
|
||||
const mp_obj_t *top = item + parent_tuple->len - 1;
|
||||
for (; item < top; ++item) {
|
||||
@@ -223,7 +223,7 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_t
|
||||
type = (mp_obj_type_t *)MP_OBJ_TO_PTR(*item);
|
||||
#endif
|
||||
} else {
|
||||
type = type->parent;
|
||||
type = MP_OBJ_TYPE_GET_SLOT(type, parent);
|
||||
}
|
||||
if (type == &mp_type_object) {
|
||||
// Not a "real" type
|
||||
@@ -239,7 +239,7 @@ STATIC void instance_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k
|
||||
struct class_lookup_data lookup = {
|
||||
.obj = self,
|
||||
.attr = meth,
|
||||
.meth_offset = offsetof(mp_obj_type_t, print),
|
||||
.slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(print),
|
||||
.dest = member,
|
||||
.is_type = false,
|
||||
};
|
||||
@@ -247,7 +247,7 @@ STATIC void instance_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k
|
||||
if (member[0] == MP_OBJ_NULL && kind == PRINT_STR) {
|
||||
// If there's no __str__, fall back to __repr__
|
||||
lookup.attr = MP_QSTR___repr__;
|
||||
lookup.meth_offset = 0;
|
||||
lookup.slot_offset = 0;
|
||||
mp_obj_class_lookup(&lookup, self->base.type);
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size
|
||||
struct class_lookup_data lookup = {
|
||||
.obj = NULL,
|
||||
.attr = MP_QSTR___new__,
|
||||
.meth_offset = offsetof(mp_obj_type_t, make_new),
|
||||
.slot_offset = offsetof(mp_obj_type_t, make_new),
|
||||
.dest = init_fn,
|
||||
.is_type = false,
|
||||
};
|
||||
@@ -332,7 +332,7 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size
|
||||
init_fn[0] = init_fn[1] = MP_OBJ_NULL;
|
||||
lookup.obj = o;
|
||||
lookup.attr = MP_QSTR___init__;
|
||||
lookup.meth_offset = 0;
|
||||
lookup.slot_offset = 0;
|
||||
mp_obj_class_lookup(&lookup, self);
|
||||
if (init_fn[0] != MP_OBJ_NULL) {
|
||||
mp_obj_t init_ret;
|
||||
@@ -414,7 +414,7 @@ STATIC mp_obj_t instance_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
|
||||
struct class_lookup_data lookup = {
|
||||
.obj = self,
|
||||
.attr = op_name,
|
||||
.meth_offset = offsetof(mp_obj_type_t, unary_op),
|
||||
.slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(unary_op),
|
||||
.dest = member,
|
||||
.is_type = false,
|
||||
};
|
||||
@@ -542,7 +542,7 @@ retry:;
|
||||
struct class_lookup_data lookup = {
|
||||
.obj = lhs,
|
||||
.attr = op_name,
|
||||
.meth_offset = offsetof(mp_obj_type_t, binary_op),
|
||||
.slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(binary_op),
|
||||
.dest = dest,
|
||||
.is_type = false,
|
||||
};
|
||||
@@ -608,7 +608,7 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des
|
||||
struct class_lookup_data lookup = {
|
||||
.obj = self,
|
||||
.attr = attr,
|
||||
.meth_offset = 0,
|
||||
.slot_offset = 0,
|
||||
.dest = dest,
|
||||
.is_type = false,
|
||||
};
|
||||
@@ -693,7 +693,7 @@ STATIC bool mp_obj_instance_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t val
|
||||
struct class_lookup_data lookup = {
|
||||
.obj = self,
|
||||
.attr = attr,
|
||||
.meth_offset = 0,
|
||||
.slot_offset = 0,
|
||||
.dest = member,
|
||||
.is_type = false,
|
||||
};
|
||||
@@ -815,7 +815,7 @@ STATIC mp_obj_t instance_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value
|
||||
mp_obj_t member[4] = {MP_OBJ_NULL, MP_OBJ_NULL, index, value};
|
||||
struct class_lookup_data lookup = {
|
||||
.obj = self,
|
||||
.meth_offset = offsetof(mp_obj_type_t, subscr),
|
||||
.slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(subscr),
|
||||
.dest = member,
|
||||
.is_type = false,
|
||||
};
|
||||
@@ -850,7 +850,7 @@ STATIC mp_obj_t mp_obj_instance_get_call(mp_obj_t self_in, mp_obj_t *member) {
|
||||
struct class_lookup_data lookup = {
|
||||
.obj = self,
|
||||
.attr = MP_QSTR___call__,
|
||||
.meth_offset = offsetof(mp_obj_type_t, call),
|
||||
.slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(call),
|
||||
.dest = member,
|
||||
.is_type = false,
|
||||
};
|
||||
@@ -889,7 +889,7 @@ mp_obj_t mp_obj_instance_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf)
|
||||
struct class_lookup_data lookup = {
|
||||
.obj = self,
|
||||
.attr = MP_QSTR___iter__,
|
||||
.meth_offset = offsetof(mp_obj_type_t, getiter),
|
||||
.slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(getiter),
|
||||
.dest = member,
|
||||
.is_type = false,
|
||||
};
|
||||
@@ -901,7 +901,7 @@ mp_obj_t mp_obj_instance_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf)
|
||||
if (iter_buf == NULL) {
|
||||
iter_buf = m_new_obj(mp_obj_iter_buf_t);
|
||||
}
|
||||
return type->getiter(self->subobj[0], iter_buf);
|
||||
return MP_OBJ_TYPE_GET_SLOT(type, getiter)(self->subobj[0], iter_buf);
|
||||
} else {
|
||||
return mp_call_method_n_kw(0, 0, member);
|
||||
}
|
||||
@@ -913,14 +913,14 @@ STATIC mp_int_t instance_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo,
|
||||
struct class_lookup_data lookup = {
|
||||
.obj = self,
|
||||
.attr = MP_QSTR_, // don't actually look for a method
|
||||
.meth_offset = offsetof(mp_obj_type_t, buffer),
|
||||
.slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(buffer),
|
||||
.dest = member,
|
||||
.is_type = false,
|
||||
};
|
||||
mp_obj_class_lookup(&lookup, self->base.type);
|
||||
if (member[0] == MP_OBJ_SENTINEL) {
|
||||
const mp_obj_type_t *type = mp_obj_get_type(self->subobj[0]);
|
||||
return type->buffer(self->subobj[0], bufinfo, flags);
|
||||
return MP_OBJ_TYPE_GET_SLOT(type, buffer)(self->subobj[0], bufinfo, flags);
|
||||
} else {
|
||||
return 1; // object does not support buffer protocol
|
||||
}
|
||||
@@ -1021,7 +1021,7 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||
if (attr == MP_QSTR___dict__) {
|
||||
// Returns a read-only dict of the class attributes.
|
||||
// If the internal locals is not fixed, a copy will be created.
|
||||
const mp_obj_dict_t *dict = self->locals_dict;
|
||||
const mp_obj_dict_t *dict = MP_OBJ_TYPE_GET_SLOT_OR_NULL(self, locals_dict);
|
||||
if (!dict) {
|
||||
dict = &mp_const_empty_dict_obj;
|
||||
}
|
||||
@@ -1040,7 +1040,7 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||
dest[0] = mp_const_empty_tuple;
|
||||
return;
|
||||
}
|
||||
mp_obj_t parent_obj = self->parent ? MP_OBJ_FROM_PTR(self->parent) : MP_OBJ_FROM_PTR(&mp_type_object);
|
||||
mp_obj_t parent_obj = MP_OBJ_TYPE_HAS_SLOT(self, parent) ? MP_OBJ_FROM_PTR(MP_OBJ_TYPE_GET_SLOT(self, parent)) : MP_OBJ_FROM_PTR(&mp_type_object);
|
||||
#if MICROPY_MULTIPLE_INHERITANCE
|
||||
if (mp_obj_is_type(parent_obj, &mp_type_tuple)) {
|
||||
dest[0] = parent_obj;
|
||||
@@ -1054,7 +1054,7 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||
struct class_lookup_data lookup = {
|
||||
.obj = (mp_obj_instance_t *)self,
|
||||
.attr = attr,
|
||||
.meth_offset = 0,
|
||||
.slot_offset = 0,
|
||||
.dest = dest,
|
||||
.is_type = true,
|
||||
};
|
||||
@@ -1062,9 +1062,9 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||
} else {
|
||||
// delete/store attribute
|
||||
|
||||
if (self->locals_dict != NULL) {
|
||||
assert(mp_obj_is_dict_or_ordereddict(MP_OBJ_FROM_PTR(self->locals_dict))); // MicroPython restriction, for now
|
||||
mp_map_t *locals_map = &self->locals_dict->map;
|
||||
if (MP_OBJ_TYPE_HAS_SLOT(self, locals_dict)) {
|
||||
assert(mp_obj_is_dict_or_ordereddict(MP_OBJ_FROM_PTR(MP_OBJ_TYPE_GET_SLOT(self, locals_dict)))); // MicroPython restriction, for now
|
||||
mp_map_t *locals_map = &MP_OBJ_TYPE_GET_SLOT(self, locals_dict)->map;
|
||||
if (locals_map->is_fixed) {
|
||||
// can't apply delete/store to a fixed map
|
||||
return;
|
||||
@@ -1155,43 +1155,44 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
|
||||
o->base.type = &mp_type_type;
|
||||
o->flags = base_flags;
|
||||
o->name = name;
|
||||
o->print = instance_print;
|
||||
o->make_new = mp_obj_instance_make_new;
|
||||
o->call = mp_obj_instance_call;
|
||||
o->unary_op = instance_unary_op;
|
||||
o->binary_op = instance_binary_op;
|
||||
o->attr = mp_obj_instance_attr;
|
||||
o->subscr = instance_subscr;
|
||||
o->getiter = mp_obj_instance_getiter;
|
||||
// o->iternext = ; not implemented
|
||||
o->buffer = instance_get_buffer;
|
||||
MP_OBJ_TYPE_SET_SLOT(o, print, instance_print, 0);
|
||||
MP_OBJ_TYPE_SET_SLOT(o, call, mp_obj_instance_call, 1);
|
||||
MP_OBJ_TYPE_SET_SLOT(o, unary_op, instance_unary_op, 2);
|
||||
MP_OBJ_TYPE_SET_SLOT(o, binary_op, instance_binary_op, 3);
|
||||
MP_OBJ_TYPE_SET_SLOT(o, attr, mp_obj_instance_attr, 4);
|
||||
MP_OBJ_TYPE_SET_SLOT(o, subscr, instance_subscr, 5);
|
||||
MP_OBJ_TYPE_SET_SLOT(o, getiter, mp_obj_instance_getiter, 6);
|
||||
// MP_OBJ_TYPE_SET_SLOT(o, iternext, not implemented)
|
||||
MP_OBJ_TYPE_SET_SLOT(o, buffer, instance_get_buffer, 7);
|
||||
|
||||
if (bases_len > 0) {
|
||||
// Inherit protocol from a base class. This allows to define an
|
||||
// abstract base class which would translate C-level protocol to
|
||||
// Python method calls, and any subclass inheriting from it will
|
||||
// support this feature.
|
||||
o->protocol = ((mp_obj_type_t *)MP_OBJ_TO_PTR(bases_items[0]))->protocol;
|
||||
MP_OBJ_TYPE_SET_SLOT(o, protocol, MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_type_t *)MP_OBJ_TO_PTR(bases_items[0])), protocol), 8);
|
||||
|
||||
if (bases_len >= 2) {
|
||||
#if MICROPY_MULTIPLE_INHERITANCE
|
||||
o->parent = MP_OBJ_TO_PTR(bases_tuple);
|
||||
MP_OBJ_TYPE_SET_SLOT(o, parent, MP_OBJ_TO_PTR(bases_tuple), 9);
|
||||
#else
|
||||
mp_raise_NotImplementedError(MP_ERROR_TEXT("multiple inheritance not supported"));
|
||||
#endif
|
||||
} else {
|
||||
o->parent = MP_OBJ_TO_PTR(bases_items[0]);
|
||||
MP_OBJ_TYPE_SET_SLOT(o, parent, MP_OBJ_TO_PTR(bases_items[0]), 9);
|
||||
}
|
||||
}
|
||||
|
||||
o->locals_dict = MP_OBJ_TO_PTR(locals_dict);
|
||||
mp_obj_dict_t *locals_ptr = MP_OBJ_TO_PTR(locals_dict);
|
||||
MP_OBJ_TYPE_SET_SLOT(o, locals_dict, locals_ptr, 10);
|
||||
|
||||
#if ENABLE_SPECIAL_ACCESSORS
|
||||
// Check if the class has any special accessor methods
|
||||
if (!(o->flags & MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS)) {
|
||||
for (size_t i = 0; i < o->locals_dict->map.alloc; i++) {
|
||||
if (mp_map_slot_is_filled(&o->locals_dict->map, i)) {
|
||||
const mp_map_elem_t *elem = &o->locals_dict->map.table[i];
|
||||
for (size_t i = 0; i < locals_ptr->map.alloc; i++) {
|
||||
if (mp_map_slot_is_filled(&locals_ptr->map, i)) {
|
||||
const mp_map_elem_t *elem = &locals_ptr->map.table[i];
|
||||
if (check_for_special_accessors(elem->key, elem->value)) {
|
||||
o->flags |= MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS;
|
||||
break;
|
||||
@@ -1207,7 +1208,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
|
||||
mp_raise_TypeError(MP_ERROR_TEXT("multiple bases have instance lay-out conflict"));
|
||||
}
|
||||
|
||||
mp_map_t *locals_map = &o->locals_dict->map;
|
||||
mp_map_t *locals_map = &MP_OBJ_TYPE_GET_SLOT(o, locals_dict)->map;
|
||||
mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(MP_QSTR___new__), MP_MAP_LOOKUP);
|
||||
if (elem != NULL) {
|
||||
// __new__ slot exists; check if it is a function
|
||||
@@ -1268,21 +1269,21 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||
struct class_lookup_data lookup = {
|
||||
.obj = MP_OBJ_TO_PTR(self->obj),
|
||||
.attr = attr,
|
||||
.meth_offset = 0,
|
||||
.slot_offset = 0,
|
||||
.dest = dest,
|
||||
.is_type = false,
|
||||
};
|
||||
|
||||
// Allow a call super().__init__() to reach any native base classes
|
||||
// Allow a call super().__init__() to reach any native base classes.
|
||||
if (attr == MP_QSTR___init__) {
|
||||
lookup.meth_offset = offsetof(mp_obj_type_t, make_new);
|
||||
lookup.slot_offset = offsetof(mp_obj_type_t, make_new);
|
||||
}
|
||||
|
||||
if (type->parent == NULL) {
|
||||
if (!MP_OBJ_TYPE_HAS_SLOT(type, parent)) {
|
||||
// no parents, do nothing
|
||||
#if MICROPY_MULTIPLE_INHERITANCE
|
||||
} else if (((mp_obj_base_t *)type->parent)->type == &mp_type_tuple) {
|
||||
const mp_obj_tuple_t *parent_tuple = type->parent;
|
||||
} else if (((mp_obj_base_t *)MP_OBJ_TYPE_GET_SLOT(type, parent))->type == &mp_type_tuple) {
|
||||
const mp_obj_tuple_t *parent_tuple = MP_OBJ_TYPE_GET_SLOT(type, parent);
|
||||
size_t len = parent_tuple->len;
|
||||
const mp_obj_t *items = parent_tuple->items;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
@@ -1292,14 +1293,15 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||
// and we don't want to lookup native methods in object.
|
||||
continue;
|
||||
}
|
||||
|
||||
mp_obj_class_lookup(&lookup, (mp_obj_type_t *)MP_OBJ_TO_PTR(items[i]));
|
||||
if (dest[0] != MP_OBJ_NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else if (type->parent != &mp_type_object) {
|
||||
mp_obj_class_lookup(&lookup, type->parent);
|
||||
} else if (MP_OBJ_TYPE_GET_SLOT(type, parent) != &mp_type_object) {
|
||||
mp_obj_class_lookup(&lookup, MP_OBJ_TYPE_GET_SLOT(type, parent));
|
||||
}
|
||||
|
||||
if (dest[0] != MP_OBJ_NULL) {
|
||||
@@ -1311,9 +1313,9 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset meth_offset so we don't look up any native methods in object,
|
||||
// Reset slot_offset so we don't look up any native methods in object,
|
||||
// because object never takes up the native base-class slot.
|
||||
lookup.meth_offset = 0;
|
||||
lookup.slot_offset = 0;
|
||||
|
||||
mp_obj_class_lookup(&lookup, &mp_type_object);
|
||||
}
|
||||
@@ -1352,13 +1354,13 @@ bool mp_obj_is_subclass_fast(mp_const_obj_t object, mp_const_obj_t classinfo) {
|
||||
|
||||
const mp_obj_type_t *self = MP_OBJ_TO_PTR(object);
|
||||
|
||||
if (self->parent == NULL) {
|
||||
if (!MP_OBJ_TYPE_HAS_SLOT(self, parent)) {
|
||||
// type has no parents
|
||||
return false;
|
||||
#if MICROPY_MULTIPLE_INHERITANCE
|
||||
} else if (((mp_obj_base_t *)self->parent)->type == &mp_type_tuple) {
|
||||
} else if (((mp_obj_base_t *)MP_OBJ_TYPE_GET_SLOT(self, parent))->type == &mp_type_tuple) {
|
||||
// get the base objects (they should be type objects)
|
||||
const mp_obj_tuple_t *parent_tuple = self->parent;
|
||||
const mp_obj_tuple_t *parent_tuple = MP_OBJ_TYPE_GET_SLOT(self, parent);
|
||||
const mp_obj_t *item = parent_tuple->items;
|
||||
const mp_obj_t *top = item + parent_tuple->len - 1;
|
||||
|
||||
@@ -1374,7 +1376,7 @@ bool mp_obj_is_subclass_fast(mp_const_obj_t object, mp_const_obj_t classinfo) {
|
||||
#endif
|
||||
} else {
|
||||
// type has 1 parent
|
||||
object = MP_OBJ_FROM_PTR(self->parent);
|
||||
object = MP_OBJ_FROM_PTR(MP_OBJ_TYPE_GET_SLOT(self, parent));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user