Commit ae8d8675 authored by Damien George's avatar Damien George
Browse files

py: Add iter_buf to getiter type method.

Allows to iterate over the following without allocating on the heap:
- tuple
- list
- string, bytes
- bytearray, array
- dict (not dict.keys, dict.values, dict.items)
- set, frozenset

Allows to call the following without heap memory:
- all, any, min, max, sum

TODO: still need to allocate stack memory in bytecode for iter_buf.
parent 101886f5
......@@ -664,7 +664,7 @@ const mp_obj_type_t pyb_uart_type = {
.name = MP_QSTR_UART,
.print = pyb_uart_print,
.make_new = pyb_uart_make_new,
.getiter = mp_identity,
.getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter,
.protocol = &uart_stream_p,
.locals_dict = (mp_obj_t)&pyb_uart_locals_dict,
......
......@@ -285,7 +285,7 @@ const mp_obj_type_t pyb_uart_type = {
.name = MP_QSTR_UART,
.print = pyb_uart_print,
.make_new = pyb_uart_make_new,
.getiter = mp_identity,
.getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter,
.protocol = &uart_stream_p,
.locals_dict = (mp_obj_dict_t*)&pyb_uart_locals_dict,
......
......@@ -184,7 +184,8 @@ STATIC mp_obj_t btree_items(size_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_items_obj, 1, 4, btree_items);
STATIC mp_obj_t btree_getiter(mp_obj_t self_in) {
STATIC mp_obj_t btree_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) {
(void)iter_buf;
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
if (self->next_flags != 0) {
// If we're called immediately after keys(), values(), or items(),
......
......@@ -264,7 +264,7 @@ const mp_obj_type_t mp_type_fileio = {
.name = MP_QSTR_FileIO,
.print = file_obj_print,
.make_new = file_obj_make_new,
.getiter = mp_identity,
.getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter,
.protocol = &fileio_stream_p,
.locals_dict = (mp_obj_dict_t*)&rawfile_locals_dict,
......@@ -283,7 +283,7 @@ const mp_obj_type_t mp_type_textio = {
.name = MP_QSTR_TextIOWrapper,
.print = file_obj_print,
.make_new = file_obj_make_new,
.getiter = mp_identity,
.getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter,
.protocol = &textio_stream_p,
.locals_dict = (mp_obj_dict_t*)&rawfile_locals_dict,
......
......@@ -1806,6 +1806,7 @@ STATIC void emit_native_get_iter(emit_t *emit) {
vtype_kind_t vtype;
emit_pre_pop_reg(emit, &vtype, REG_ARG_1);
assert(vtype == VTYPE_PYOBJ);
assert(0); // TODO allocate memory for iter_buf
emit_call(emit, MP_F_GETITER);
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
}
......
......@@ -117,7 +117,8 @@ STATIC mp_obj_t mp_builtin_abs(mp_obj_t o_in) {
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_abs_obj, mp_builtin_abs);
STATIC mp_obj_t mp_builtin_all(mp_obj_t o_in) {
mp_obj_t iterable = mp_getiter(o_in);
mp_obj_iter_buf_t iter_buf;
mp_obj_t iterable = mp_getiter(o_in, &iter_buf);
mp_obj_t item;
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
if (!mp_obj_is_true(item)) {
......@@ -129,7 +130,8 @@ STATIC mp_obj_t mp_builtin_all(mp_obj_t o_in) {
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_all_obj, mp_builtin_all);
STATIC mp_obj_t mp_builtin_any(mp_obj_t o_in) {
mp_obj_t iterable = mp_getiter(o_in);
mp_obj_iter_buf_t iter_buf;
mp_obj_t iterable = mp_getiter(o_in, &iter_buf);
mp_obj_t item;
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
if (mp_obj_is_true(item)) {
......@@ -258,7 +260,7 @@ STATIC mp_obj_t mp_builtin_hex(mp_obj_t o_in) {
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_hex_obj, mp_builtin_hex);
STATIC mp_obj_t mp_builtin_iter(mp_obj_t o_in) {
return mp_getiter(o_in);
return mp_getiter(o_in, NULL);
}
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_iter_obj, mp_builtin_iter);
......@@ -270,7 +272,8 @@ STATIC mp_obj_t mp_builtin_min_max(size_t n_args, const mp_obj_t *args, mp_map_t
mp_obj_t key_fn = key_elem == NULL ? MP_OBJ_NULL : key_elem->value;
if (n_args == 1) {
// given an iterable
mp_obj_t iterable = mp_getiter(args[0]);
mp_obj_iter_buf_t iter_buf;
mp_obj_t iterable = mp_getiter(args[0], &iter_buf);
mp_obj_t best_key = MP_OBJ_NULL;
mp_obj_t best_obj = MP_OBJ_NULL;
mp_obj_t item;
......@@ -495,7 +498,8 @@ STATIC mp_obj_t mp_builtin_sum(size_t n_args, const mp_obj_t *args) {
case 1: value = MP_OBJ_NEW_SMALL_INT(0); break;
default: value = args[1]; break;
}
mp_obj_t iterable = mp_getiter(args[0]);
mp_obj_iter_buf_t iter_buf;
mp_obj_t iterable = mp_getiter(args[0], &iter_buf);
mp_obj_t item;
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
value = mp_binary_op(MP_BINARY_OP_ADD, value, item);
......
......@@ -481,6 +481,11 @@ mp_obj_t mp_identity(mp_obj_t self) {
}
MP_DEFINE_CONST_FUN_OBJ_1(mp_identity_obj, mp_identity);
mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf) {
(void)iter_buf;
return self;
}
bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
mp_obj_type_t *type = mp_obj_get_type(obj);
if (type->buffer_p.get_buffer == NULL) {
......
......@@ -417,6 +417,11 @@ typedef enum {
PRINT_EXC_SUBCLASS = 0x80, // Internal flag for printing exception subclasses
} mp_print_kind_t;
typedef struct _mp_obj_iter_buf_t {
mp_obj_base_t base;
mp_obj_t buf[3];
} mp_obj_iter_buf_t;
typedef void (*mp_print_fun_t)(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind);
typedef mp_obj_t (*mp_make_new_fun_t)(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args);
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);
......@@ -424,6 +429,7 @@ typedef mp_obj_t (*mp_unary_op_fun_t)(mp_uint_t op, mp_obj_t);
typedef mp_obj_t (*mp_binary_op_fun_t)(mp_uint_t op, mp_obj_t, mp_obj_t);
typedef void (*mp_attr_fun_t)(mp_obj_t self_in, qstr attr, mp_obj_t *dest);
typedef mp_obj_t (*mp_subscr_fun_t)(mp_obj_t self_in, mp_obj_t index, mp_obj_t value);
typedef mp_obj_t (*mp_getiter_fun_t)(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf);
// Buffer protocol
typedef struct _mp_buffer_info_t {
......@@ -486,7 +492,11 @@ struct _mp_obj_type_t {
// value=MP_OBJ_NULL means delete, value=MP_OBJ_SENTINEL means load, else store
// can return MP_OBJ_NULL if op not supported
mp_fun_1_t getiter; // corresponds to __iter__ special method
// corresponds to __iter__ special method
// can use given mp_obj_iter_buf_t to store iterator
// otherwise can return a pointer to an object on the heap
mp_getiter_fun_t getiter;
mp_fun_1_t iternext; // may return MP_OBJ_STOP_ITERATION as an optimisation instead of raising StopIteration() (with no args)
mp_buffer_p_t buffer_p;
......@@ -637,7 +647,7 @@ mp_obj_t mp_obj_new_set(size_t n_args, mp_obj_t *items);
mp_obj_t mp_obj_new_slice(mp_obj_t start, mp_obj_t stop, mp_obj_t step);
mp_obj_t mp_obj_new_super(mp_obj_t type, mp_obj_t obj);
mp_obj_t mp_obj_new_bound_meth(mp_obj_t meth, mp_obj_t self);
mp_obj_t mp_obj_new_getitem_iter(mp_obj_t *args);
mp_obj_t mp_obj_new_getitem_iter(mp_obj_t *args, mp_obj_iter_buf_t *iter_buf);
mp_obj_t mp_obj_new_module(qstr module_name);
mp_obj_t mp_obj_new_memoryview(byte typecode, size_t nitems, void *items);
......@@ -775,6 +785,7 @@ qstr mp_obj_code_get_name(const byte *code_info);
mp_obj_t mp_identity(mp_obj_t self);
MP_DECLARE_CONST_FUN_OBJ_1(mp_identity_obj);
mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf);
// module
typedef struct _mp_obj_module_t {
......
......@@ -59,7 +59,7 @@
#define TYPECODE_MASK (~(size_t)0)
#endif
STATIC mp_obj_t array_iterator_new(mp_obj_t array_in);
STATIC mp_obj_t array_iterator_new(mp_obj_t array_in, mp_obj_iter_buf_t *iter_buf);
STATIC mp_obj_t array_append(mp_obj_t self_in, mp_obj_t arg);
STATIC mp_obj_t array_extend(mp_obj_t self_in, mp_obj_t arg_in);
STATIC mp_int_t array_get_buffer(mp_obj_t o_in, mp_buffer_info_t *bufinfo, mp_uint_t flags);
......@@ -141,7 +141,8 @@ STATIC mp_obj_t array_construct(char typecode, mp_obj_t initializer) {
mp_obj_array_t *array = array_new(typecode, len);
mp_obj_t iterable = mp_getiter(initializer);
mp_obj_iter_buf_t iter_buf;
mp_obj_t iterable = mp_getiter(initializer, &iter_buf);
mp_obj_t item;
size_t i = 0;
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
......@@ -608,15 +609,18 @@ STATIC mp_obj_t array_it_iternext(mp_obj_t self_in) {
STATIC const mp_obj_type_t array_it_type = {
{ &mp_type_type },
.name = MP_QSTR_iterator,
.getiter = mp_identity,
.getiter = mp_identity_getiter,
.iternext = array_it_iternext,
};
STATIC mp_obj_t array_iterator_new(mp_obj_t array_in) {
STATIC mp_obj_t array_iterator_new(mp_obj_t array_in, mp_obj_iter_buf_t *iter_buf) {
assert(sizeof(mp_obj_array_t) <= sizeof(mp_obj_iter_buf_t));
mp_obj_array_t *array = MP_OBJ_TO_PTR(array_in);
mp_obj_array_it_t *o = m_new0(mp_obj_array_it_t, 1);
mp_obj_array_it_t *o = (mp_obj_array_it_t*)iter_buf;
o->base.type = &array_it_type;
o->array = array;
o->offset = 0;
o->cur = 0;
#if MICROPY_PY_BUILTINS_MEMORYVIEW
if (array->base.type == &mp_type_memoryview) {
o->offset = array->free;
......
......@@ -210,8 +210,9 @@ STATIC mp_obj_t dict_it_iternext(mp_obj_t self_in) {
}
}
STATIC mp_obj_t dict_getiter(mp_obj_t self_in) {
mp_obj_dict_it_t *o = m_new_obj(mp_obj_dict_it_t);
STATIC mp_obj_t dict_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) {
assert(sizeof(mp_obj_dict_it_t) <= sizeof(mp_obj_iter_buf_t));
mp_obj_dict_it_t *o = (mp_obj_dict_it_t*)iter_buf;
o->base.type = &mp_type_polymorph_iter;
o->iternext = dict_it_iternext;
o->dict = self_in;
......@@ -249,7 +250,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(dict_copy_obj, dict_copy);
// this is a classmethod
STATIC mp_obj_t dict_fromkeys(size_t n_args, const mp_obj_t *args) {
mp_obj_t iter = mp_getiter(args[1]);
mp_obj_iter_buf_t iter_buf;
mp_obj_t iter = mp_getiter(args[1], &iter_buf);
mp_obj_t value = mp_const_none;
mp_obj_t next = MP_OBJ_NULL;
......@@ -375,10 +377,12 @@ STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwarg
}
} else {
// update from a generic iterable of pairs
mp_obj_t iter = mp_getiter(args[1]);
mp_obj_iter_buf_t iter_buf;
mp_obj_t iter = mp_getiter(args[1], &iter_buf);
mp_obj_t next = MP_OBJ_NULL;
while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
mp_obj_t inneriter = mp_getiter(next);
mp_obj_iter_buf_t inner_iter_buf;
mp_obj_t inneriter = mp_getiter(next, &inner_iter_buf);
mp_obj_t key = mp_iternext(inneriter);
mp_obj_t value = mp_iternext(inneriter);
mp_obj_t stop = mp_iternext(inneriter);
......@@ -457,14 +461,15 @@ STATIC mp_obj_t dict_view_it_iternext(mp_obj_t self_in) {
STATIC const mp_obj_type_t dict_view_it_type = {
{ &mp_type_type },
.name = MP_QSTR_iterator,
.getiter = mp_identity,
.getiter = mp_identity_getiter,
.iternext = dict_view_it_iternext,
};
STATIC mp_obj_t dict_view_getiter(mp_obj_t view_in) {
STATIC mp_obj_t dict_view_getiter(mp_obj_t view_in, mp_obj_iter_buf_t *iter_buf) {
assert(sizeof(mp_obj_dict_view_it_t) <= sizeof(mp_obj_iter_buf_t));
mp_check_self(MP_OBJ_IS_TYPE(view_in, &dict_view_type));
mp_obj_dict_view_t *view = MP_OBJ_TO_PTR(view_in);
mp_obj_dict_view_it_t *o = m_new_obj(mp_obj_dict_view_it_t);
mp_obj_dict_view_it_t *o = (mp_obj_dict_view_it_t*)iter_buf;
o->base.type = &dict_view_it_type;
o->kind = view->kind;
o->dict = view->dict;
......@@ -479,7 +484,8 @@ STATIC void dict_view_print(const mp_print_t *print, mp_obj_t self_in, mp_print_
bool first = true;
mp_print_str(print, mp_dict_view_names[self->kind]);
mp_print_str(print, "([");
mp_obj_t self_iter = dict_view_getiter(self_in);
mp_obj_iter_buf_t iter_buf;
mp_obj_t self_iter = dict_view_getiter(self_in, &iter_buf);
mp_obj_t next = MP_OBJ_NULL;
while ((next = dict_view_it_iternext(self_iter)) != MP_OBJ_STOP_ITERATION) {
if (!first) {
......
......@@ -56,13 +56,13 @@ STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, siz
// create enumerate object
mp_obj_enumerate_t *o = m_new_obj(mp_obj_enumerate_t);
o->base.type = type;
o->iter = mp_getiter(arg_vals.iterable.u_obj);
o->iter = mp_getiter(arg_vals.iterable.u_obj, NULL);
o->cur = arg_vals.start.u_int;
#else
(void)n_kw;
mp_obj_enumerate_t *o = m_new_obj(mp_obj_enumerate_t);
o->base.type = type;
o->iter = mp_getiter(args[0]);
o->iter = mp_getiter(args[0], NULL);
o->cur = n_args > 1 ? mp_obj_get_int(args[1]) : 0;
#endif
......@@ -74,7 +74,7 @@ const mp_obj_type_t mp_type_enumerate = {
.name = MP_QSTR_enumerate,
.make_new = enumerate_make_new,
.iternext = enumerate_iternext,
.getiter = mp_identity,
.getiter = mp_identity_getiter,
};
STATIC mp_obj_t enumerate_iternext(mp_obj_t self_in) {
......
......@@ -39,7 +39,7 @@ STATIC mp_obj_t filter_make_new(const mp_obj_type_t *type, size_t n_args, size_t
mp_obj_filter_t *o = m_new_obj(mp_obj_filter_t);
o->base.type = type;
o->fun = args[0];
o->iter = mp_getiter(args[1]);
o->iter = mp_getiter(args[1], NULL);
return MP_OBJ_FROM_PTR(o);
}
......@@ -65,7 +65,7 @@ const mp_obj_type_t mp_type_filter = {
{ &mp_type_type },
.name = MP_QSTR_filter,
.make_new = filter_make_new,
.getiter = mp_identity,
.getiter = mp_identity_getiter,
.iternext = filter_iternext,
};
......
......@@ -236,7 +236,7 @@ const mp_obj_type_t mp_type_gen_instance = {
{ &mp_type_type },
.name = MP_QSTR_generator,
.print = gen_instance_print,
.getiter = mp_identity,
.getiter = mp_identity_getiter,
.iternext = gen_instance_iternext,
.locals_dict = (mp_obj_dict_t*)&gen_instance_locals_dict,
};
......@@ -61,13 +61,14 @@ STATIC mp_obj_t it_iternext(mp_obj_t self_in) {
STATIC const mp_obj_type_t it_type = {
{ &mp_type_type },
.name = MP_QSTR_iterator,
.getiter = mp_identity,
.getiter = mp_identity_getiter,
.iternext = it_iternext,
};
// args are those returned from mp_load_method_maybe (ie either an attribute or a method)
mp_obj_t mp_obj_new_getitem_iter(mp_obj_t *args) {
mp_obj_getitem_iter_t *o = m_new_obj(mp_obj_getitem_iter_t);
mp_obj_t mp_obj_new_getitem_iter(mp_obj_t *args, mp_obj_iter_buf_t *iter_buf) {
assert(sizeof(mp_obj_getitem_iter_t) <= sizeof(mp_obj_iter_buf_t));
mp_obj_getitem_iter_t *o = (mp_obj_getitem_iter_t*)iter_buf;
o->base.type = &it_type;
o->args[0] = args[0];
o->args[1] = args[1];
......
......@@ -33,7 +33,7 @@
#include "py/runtime.h"
#include "py/stackctrl.h"
STATIC mp_obj_t mp_obj_new_list_iterator(mp_obj_t list, size_t cur);
STATIC mp_obj_t mp_obj_new_list_iterator(mp_obj_t list, size_t cur, mp_obj_iter_buf_t *iter_buf);
STATIC mp_obj_list_t *list_new(size_t n);
STATIC mp_obj_t list_extend(mp_obj_t self_in, mp_obj_t arg_in);
STATIC mp_obj_t list_pop(size_t n_args, const mp_obj_t *args);
......@@ -60,7 +60,8 @@ STATIC void list_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t k
}
STATIC mp_obj_t list_extend_from_iter(mp_obj_t list, mp_obj_t iterable) {
mp_obj_t iter = mp_getiter(iterable);
mp_obj_iter_buf_t iter_buf;
mp_obj_t iter = mp_getiter(iterable, &iter_buf);
mp_obj_t item;
while ((item = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
mp_obj_list_append(list, item);
......@@ -225,8 +226,8 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
}
}
STATIC mp_obj_t list_getiter(mp_obj_t o_in) {
return mp_obj_new_list_iterator(o_in, 0);
STATIC mp_obj_t list_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) {
return mp_obj_new_list_iterator(o_in, 0, iter_buf);
}
mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg) {
......@@ -516,8 +517,9 @@ STATIC mp_obj_t list_it_iternext(mp_obj_t self_in) {
}
}
mp_obj_t mp_obj_new_list_iterator(mp_obj_t list, size_t cur) {
mp_obj_list_it_t *o = m_new_obj(mp_obj_list_it_t);
mp_obj_t mp_obj_new_list_iterator(mp_obj_t list, size_t cur, mp_obj_iter_buf_t *iter_buf) {
assert(sizeof(mp_obj_list_it_t) <= sizeof(mp_obj_iter_buf_t));
mp_obj_list_it_t *o = (mp_obj_list_it_t*)iter_buf;
o->base.type = &mp_type_polymorph_iter;
o->iternext = list_it_iternext;
o->list = list;
......
......@@ -43,7 +43,7 @@ STATIC mp_obj_t map_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
o->n_iters = n_args - 1;
o->fun = args[0];
for (mp_uint_t i = 0; i < n_args - 1; i++) {
o->iters[i] = mp_getiter(args[i + 1]);
o->iters[i] = mp_getiter(args[i + 1], NULL);
}
return MP_OBJ_FROM_PTR(o);
}
......@@ -68,6 +68,6 @@ const mp_obj_type_t mp_type_map = {
{ &mp_type_type },
.name = MP_QSTR_map,
.make_new = map_make_new,
.getiter = mp_identity,
.getiter = mp_identity_getiter,
.iternext = map_iternext,
};
......@@ -49,6 +49,6 @@ STATIC mp_obj_t polymorph_it_iternext(mp_obj_t self_in) {
const mp_obj_type_t mp_type_polymorph_iter = {
{ &mp_type_type },
.name = MP_QSTR_iterator,
.getiter = mp_identity,
.getiter = mp_identity_getiter,
.iternext = polymorph_it_iternext,
};
......@@ -55,12 +55,13 @@ STATIC mp_obj_t range_it_iternext(mp_obj_t o_in) {
STATIC const mp_obj_type_t range_it_type = {
{ &mp_type_type },
.name = MP_QSTR_iterator,
.getiter = mp_identity,
.getiter = mp_identity_getiter,
.iternext = range_it_iternext,
};
STATIC mp_obj_t mp_obj_new_range_iterator(mp_int_t cur, mp_int_t stop, mp_int_t step) {
mp_obj_range_it_t *o = m_new_obj(mp_obj_range_it_t);
STATIC mp_obj_t mp_obj_new_range_iterator(mp_int_t cur, mp_int_t stop, mp_int_t step, mp_obj_iter_buf_t *iter_buf) {
assert(sizeof(mp_obj_range_it_t) <= sizeof(mp_obj_iter_buf_t));
mp_obj_range_it_t *o = (mp_obj_range_it_t*)iter_buf;
o->base.type = &range_it_type;
o->cur = cur;
o->stop = stop;
......@@ -161,9 +162,9 @@ STATIC mp_obj_t range_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
}
}
STATIC mp_obj_t range_getiter(mp_obj_t o_in) {
STATIC mp_obj_t range_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) {
mp_obj_range_t *o = MP_OBJ_TO_PTR(o_in);
return mp_obj_new_range_iterator(o->start, o->stop, o->step);
return mp_obj_new_range_iterator(o->start, o->stop, o->step, iter_buf);
}
......
......@@ -74,7 +74,7 @@ const mp_obj_type_t mp_type_reversed = {
{ &mp_type_type },
.name = MP_QSTR_reversed,
.make_new = reversed_make_new,
.getiter = mp_identity,
.getiter = mp_identity_getiter,
.iternext = reversed_iternext,
};
......
......@@ -129,7 +129,8 @@ STATIC mp_obj_t set_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
default: { // can only be 0 or 1 arg
// 1 argument, an iterable from which we make a new set
mp_obj_t set = mp_obj_new_set(0, NULL);
mp_obj_t iterable = mp_getiter(args[0]);
mp_obj_iter_buf_t iter_buf;
mp_obj_t iterable = mp_getiter(args[0], &iter_buf);
mp_obj_t item;
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
mp_obj_set_store(set, item);
......@@ -156,8 +157,9 @@ STATIC mp_obj_t set_it_iternext(mp_obj_t self_in) {
return MP_OBJ_STOP_ITERATION;
}
STATIC mp_obj_t set_getiter(mp_obj_t set_in) {
mp_obj_set_it_t *o = m_new_obj(mp_obj_set_it_t);
STATIC mp_obj_t set_getiter(mp_obj_t set_in, mp_obj_iter_buf_t *iter_buf) {
assert(sizeof(mp_obj_set_it_t) <= sizeof(mp_obj_iter_buf_t));
mp_obj_set_it_t *o = (mp_obj_set_it_t*)iter_buf;
o->base.type = &mp_type_polymorph_iter;
o->iternext = set_it_iternext;
o->set = (mp_obj_set_t *)MP_OBJ_TO_PTR(set_in);
......@@ -233,7 +235,8 @@ STATIC mp_obj_t set_diff_int(size_t n_args, const mp_obj_t *args, bool update) {
if (self == other) {
set_clear(self);
} else {
mp_obj_t iter = mp_getiter(other);
mp_obj_iter_buf_t iter_buf;
mp_obj_t iter = mp_getiter(other, &iter_buf);
mp_obj_t next;
while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
set_discard(self, next);
......@@ -270,7 +273,8 @@ STATIC mp_obj_t set_intersect_int(mp_obj_t self_in, mp_obj_t other, bool update)
mp_obj_set_t *self = MP_OBJ_TO_PTR(self_in);
mp_obj_set_t *out = MP_OBJ_TO_PTR(mp_obj_new_set(0, NULL));
mp_obj_t iter = mp_getiter(other);
mp_obj_iter_buf_t iter_buf;
mp_obj_t iter = mp_getiter(other, &iter_buf);
mp_obj_t next;
while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
if (mp_set_lookup(&self->set, next, MP_MAP_LOOKUP)) {
......@@ -302,7 +306,8 @@ STATIC mp_obj_t set_isdisjoint(mp_obj_t self_in, mp_obj_t other) {
check_set_or_frozenset(self_in);
mp_obj_set_t *self = MP_OBJ_TO_PTR(self_in);
mp_obj_t iter = mp_getiter(other);
mp_obj_iter_buf_t iter_buf;
mp_obj_t iter = mp_getiter(other, &iter_buf);
mp_obj_t next;
while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
if (mp_set_lookup(&self->set, next, MP_MAP_LOOKUP)) {
......@@ -335,7 +340,8 @@ STATIC mp_obj_t set_issubset_internal(mp_obj_t self_in, mp_obj_t other_in, bool
if (proper && self->set.used == other->set.used) {
out = false;
} else {
mp_obj_t iter = set_getiter(MP_OBJ_FROM_PTR(self));
mp_obj_iter_buf_t iter_buf;
mp_obj_t iter = set_getiter(MP_OBJ_FROM_PTR(self), &iter_buf);
mp_obj_t next;
while ((next = set_it_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
if (!mp_set_lookup(&other->set, next, MP_MAP_LOOKUP)) {
......@@ -408,7 +414,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(set_remove_obj, set_remove);
STATIC mp_obj_t set_symmetric_difference_update(mp_obj_t self_in, mp_obj_t other_in) {
check_set(self_in);
mp_obj_set_t *self = MP_OBJ_TO_PTR(self_in);
mp_obj_t iter = mp_getiter(other_in);
mp_obj_iter_buf_t iter_buf;
mp_obj_t iter = mp_getiter(other_in, &iter_buf);
mp_obj_t next;
while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
mp_set_lookup(&self->set, next, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND_OR_REMOVE_IF_FOUND);
......@@ -427,7 +434,8 @@ STATIC mp_obj_t set_symmetric_difference(mp_obj_t self_in, mp_obj_t other_in) {
STATIC MP_DEFINE_CONST_FUN_OBJ_2(set_symmetric_difference_obj, set_symmetric_difference);
STATIC void set_update_int(mp_obj_set_t *self, mp_obj_t other_in) {
mp_obj_t iter = mp_getiter(other_in);
mp_obj_iter_buf_t iter_buf;
mp_obj_t iter = mp_getiter(other_in, &iter_buf);
mp_obj_t next;
while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
mp_set_lookup(&self->set, next, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment