summaryrefslogtreecommitdiffstatshomepage
path: root/py/objtype.c
diff options
context:
space:
mode:
authorJim Mussared <jim.mussared@gmail.com>2022-09-16 23:57:38 +1000
committerDamien George <damien@micropython.org>2022-09-19 19:06:13 +1000
commit6da41b59007c9e9a2443ae17278d32210034a63f (patch)
tree7acd771be49b744b64571426c3e4c185abf31175 /py/objtype.c
parent3c6127dfcfc63a2b48c31f751d1ae2c385874c8a (diff)
downloadmicropython-6da41b59007c9e9a2443ae17278d32210034a63f.tar.gz
micropython-6da41b59007c9e9a2443ae17278d32210034a63f.zip
py/obj: Merge getiter and iternext mp_obj_type_t slots.
The goal here is to remove a slot (making way to turn make_new into a slot) as well as reduce code size by the ~40 references to mp_identity_getiter and mp_stream_unbuffered_iter. This introduces two new type flags: - MP_TYPE_FLAG_ITER_IS_ITERNEXT: This means that the "iter" slot in the type is "iternext", and should use the identity getiter. - MP_TYPE_FLAG_ITER_IS_CUSTOM: This means that the "iter" slot is a pointer to a mp_getiter_iternext_custom_t instance, which then defines both getiter and iternext. And a third flag that is the OR of both, MP_TYPE_FLAG_ITER_IS_STREAM: This means that the type should use the identity getiter, and mp_stream_unbuffered_iter as iternext. Finally, MP_TYPE_FLAG_ITER_IS_GETITER is defined as a no-op flag to give the default case where "iter" is "getiter". Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
Diffstat (limited to 'py/objtype.c')
-rw-r--r--py/objtype.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/py/objtype.c b/py/objtype.c
index 5b4e375bcc..183dce071e 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -142,7 +142,10 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_t
// this should not be applied to class types, as will result in extra
// lookup either.
if (lookup->slot_offset != 0 && mp_obj_is_native_type(type)) {
- if (MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(type, lookup->slot_offset)) {
+ // Check if there is a non-zero value in the specified slot index,
+ // with a special case for getiter where the slot won't be set
+ // for MP_TYPE_FLAG_ITER_IS_STREAM.
+ if (MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(type, lookup->slot_offset) || (lookup->slot_offset == MP_OBJ_TYPE_OFFSETOF_SLOT(iter) && type->flags & MP_TYPE_FLAG_ITER_IS_STREAM)) {
DEBUG_printf("mp_obj_class_lookup: Matched special meth slot (off=%d) for %s\n",
lookup->slot_offset, qstr_str(lookup->attr));
lookup->dest[0] = MP_OBJ_SENTINEL;
@@ -889,7 +892,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__,
- .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(getiter),
+ .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(iter),
.dest = member,
.is_type = false,
};
@@ -898,10 +901,14 @@ mp_obj_t mp_obj_instance_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf)
return MP_OBJ_NULL;
} else if (member[0] == MP_OBJ_SENTINEL) {
const mp_obj_type_t *type = mp_obj_get_type(self->subobj[0]);
- if (iter_buf == NULL) {
- iter_buf = m_new_obj(mp_obj_iter_buf_t);
+ if (type->flags & MP_TYPE_FLAG_ITER_IS_ITERNEXT) {
+ return self->subobj[0];
+ } else {
+ if (iter_buf == NULL) {
+ iter_buf = m_new_obj(mp_obj_iter_buf_t);
+ }
+ return ((mp_getiter_fun_t)MP_OBJ_TYPE_GET_SLOT(type, iter))(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);
}
@@ -1122,7 +1129,9 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
// Basic validation of base classes
uint16_t base_flags = MP_TYPE_FLAG_EQ_NOT_REFLEXIVE
- | MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_EQ_HAS_NEQ_TEST;
+ | MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE
+ | MP_TYPE_FLAG_EQ_HAS_NEQ_TEST
+ | MP_TYPE_FLAG_ITER_IS_GETITER;
size_t bases_len;
mp_obj_t *bases_items;
mp_obj_tuple_get(bases_tuple, &bases_len, &bases_items);
@@ -1167,7 +1176,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
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, iter, 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);