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 = { ...@@ -664,7 +664,7 @@ const mp_obj_type_t pyb_uart_type = {
.name = MP_QSTR_UART, .name = MP_QSTR_UART,
.print = pyb_uart_print, .print = pyb_uart_print,
.make_new = pyb_uart_make_new, .make_new = pyb_uart_make_new,
.getiter = mp_identity, .getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter, .iternext = mp_stream_unbuffered_iter,
.protocol = &uart_stream_p, .protocol = &uart_stream_p,
.locals_dict = (mp_obj_t)&pyb_uart_locals_dict, .locals_dict = (mp_obj_t)&pyb_uart_locals_dict,
......
...@@ -285,7 +285,7 @@ const mp_obj_type_t pyb_uart_type = { ...@@ -285,7 +285,7 @@ const mp_obj_type_t pyb_uart_type = {
.name = MP_QSTR_UART, .name = MP_QSTR_UART,
.print = pyb_uart_print, .print = pyb_uart_print,
.make_new = pyb_uart_make_new, .make_new = pyb_uart_make_new,
.getiter = mp_identity, .getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter, .iternext = mp_stream_unbuffered_iter,
.protocol = &uart_stream_p, .protocol = &uart_stream_p,
.locals_dict = (mp_obj_dict_t*)&pyb_uart_locals_dict, .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) { ...@@ -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_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); mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
if (self->next_flags != 0) { if (self->next_flags != 0) {
// If we're called immediately after keys(), values(), or items(), // If we're called immediately after keys(), values(), or items(),
......
...@@ -264,7 +264,7 @@ const mp_obj_type_t mp_type_fileio = { ...@@ -264,7 +264,7 @@ const mp_obj_type_t mp_type_fileio = {
.name = MP_QSTR_FileIO, .name = MP_QSTR_FileIO,
.print = file_obj_print, .print = file_obj_print,
.make_new = file_obj_make_new, .make_new = file_obj_make_new,
.getiter = mp_identity, .getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter, .iternext = mp_stream_unbuffered_iter,
.protocol = &fileio_stream_p, .protocol = &fileio_stream_p,
.locals_dict = (mp_obj_dict_t*)&rawfile_locals_dict, .locals_dict = (mp_obj_dict_t*)&rawfile_locals_dict,
...@@ -283,7 +283,7 @@ const mp_obj_type_t mp_type_textio = { ...@@ -283,7 +283,7 @@ const mp_obj_type_t mp_type_textio = {
.name = MP_QSTR_TextIOWrapper, .name = MP_QSTR_TextIOWrapper,
.print = file_obj_print, .print = file_obj_print,
.make_new = file_obj_make_new, .make_new = file_obj_make_new,
.getiter = mp_identity, .getiter = mp_identity_getiter,
.iternext = mp_stream_unbuffered_iter, .iternext = mp_stream_unbuffered_iter,
.protocol = &textio_stream_p, .protocol = &textio_stream_p,
.locals_dict = (mp_obj_dict_t*)&rawfile_locals_dict, .locals_dict = (mp_obj_dict_t*)&rawfile_locals_dict,
......
...@@ -1806,6 +1806,7 @@ STATIC void emit_native_get_iter(emit_t *emit) { ...@@ -1806,6 +1806,7 @@ STATIC void emit_native_get_iter(emit_t *emit) {
vtype_kind_t vtype; vtype_kind_t vtype;
emit_pre_pop_reg(emit, &vtype, REG_ARG_1); emit_pre_pop_reg(emit, &vtype, REG_ARG_1);
assert(vtype == VTYPE_PYOBJ); assert(vtype == VTYPE_PYOBJ);
assert(0); // TODO allocate memory for iter_buf
emit_call(emit, MP_F_GETITER); emit_call(emit, MP_F_GETITER);
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); 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) { ...@@ -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); 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) { 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; mp_obj_t item;
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
if (!mp_obj_is_true(item)) { if (!mp_obj_is_true(item)) {
...@@ -129,7 +130,8 @@ STATIC mp_obj_t mp_builtin_all(mp_obj_t o_in) { ...@@ -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); 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) { 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; mp_obj_t item;
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
if (mp_obj_is_true(item)) { if (mp_obj_is_true(item)) {
...@@ -258,7 +260,7 @@ STATIC mp_obj_t mp_builtin_hex(mp_obj_t o_in) { ...@@ -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); 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) { 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); 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 ...@@ -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; mp_obj_t key_fn = key_elem == NULL ? MP_OBJ_NULL : key_elem->value;
if (n_args == 1) { if (n_args == 1) {
// given an iterable // 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_key = MP_OBJ_NULL;
mp_obj_t best_obj = MP_OBJ_NULL; mp_obj_t best_obj = MP_OBJ_NULL;
mp_obj_t item; mp_obj_t item;
...@@ -495,7 +498,8 @@ STATIC mp_obj_t mp_builtin_sum(size_t n_args, const mp_obj_t *args) { ...@@ -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; case 1: value = MP_OBJ_NEW_SMALL_INT(0); break;
default: value = args[1]; 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; mp_obj_t item;
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
value = mp_binary_op(MP_BINARY_OP_ADD, value, item); value = mp_binary_op(MP_BINARY_OP_ADD, value, item);
......
...@@ -481,6 +481,11 @@ mp_obj_t mp_identity(mp_obj_t self) { ...@@ -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_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) { 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); mp_obj_type_t *type = mp_obj_get_type(obj);
if (type->buffer_p.get_buffer == NULL) { if (type->buffer_p.get_buffer == NULL) {
......
...@@ -417,6 +417,11 @@ typedef enum { ...@@ -417,6 +417,11 @@ typedef enum {
PRINT_EXC_SUBCLASS = 0x80, // Internal flag for printing exception subclasses PRINT_EXC_SUBCLASS = 0x80, // Internal flag for printing exception subclasses
} mp_print_kind_t; } 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 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_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); 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); ...@@ -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 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 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_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 // Buffer protocol
typedef struct _mp_buffer_info_t { typedef struct _mp_buffer_info_t {
...@@ -486,7 +492,11 @@ struct _mp_obj_type_t { ...@@ -486,7 +492,11 @@ struct _mp_obj_type_t {
// value=MP_OBJ_NULL means delete, value=MP_OBJ_SENTINEL means load, else store // value=MP_OBJ_NULL means delete, value=MP_OBJ_SENTINEL means load, else store
// can return MP_OBJ_NULL if op not supported // 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_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; 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); ...@@ -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_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_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_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_module(qstr module_name);
mp_obj_t mp_obj_new_memoryview(byte typecode, size_t nitems, void *items); 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); ...@@ -775,6 +785,7 @@ qstr mp_obj_code_get_name(const byte *code_info);
mp_obj_t mp_identity(mp_obj_t self); mp_obj_t mp_identity(mp_obj_t self);
MP_DECLARE_CONST_FUN_OBJ_1(mp_identity_obj); 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 // module
typedef struct _mp_obj_module_t { typedef struct _mp_obj_module_t {
......
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
#define TYPECODE_MASK (~(size_t)0) #define TYPECODE_MASK (~(size_t)0)
#endif #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_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_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); 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) { ...@@ -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_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; mp_obj_t item;
size_t i = 0; size_t i = 0;
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { 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) { ...@@ -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 = { STATIC const mp_obj_type_t array_it_type = {
{ &mp_type_type }, { &mp_type_type },
.name = MP_QSTR_iterator, .name = MP_QSTR_iterator,
.getiter = mp_identity, .getiter = mp_identity_getiter,
.iternext = array_it_iternext, .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_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->base.type = &array_it_type;
o->array = array; o->array = array;
o->offset = 0;
o->cur = 0;
#if MICROPY_PY_BUILTINS_MEMORYVIEW #if MICROPY_PY_BUILTINS_MEMORYVIEW
if (array->base.type == &mp_type_memoryview) { if (array->base.type == &mp_type_memoryview) {
o->offset = array->free; o->offset = array->free;
......
...@@ -210,8 +210,9 @@ STATIC mp_obj_t dict_it_iternext(mp_obj_t self_in) { ...@@ -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) { STATIC mp_obj_t dict_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) {
mp_obj_dict_it_t *o = m_new_obj(mp_obj_dict_it_t); 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->base.type = &mp_type_polymorph_iter;
o->iternext = dict_it_iternext; o->iternext = dict_it_iternext;
o->dict = self_in; o->dict = self_in;
...@@ -249,7 +250,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(dict_copy_obj, dict_copy); ...@@ -249,7 +250,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(dict_copy_obj, dict_copy);
// this is a classmethod // this is a classmethod
STATIC mp_obj_t dict_fromkeys(size_t n_args, const mp_obj_t *args) { 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 value = mp_const_none;
mp_obj_t next = MP_OBJ_NULL; 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 ...@@ -375,10 +377,12 @@ STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwarg
} }
} else { } else {
// update from a generic iterable of pairs // 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; mp_obj_t next = MP_OBJ_NULL;
while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { 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 key = mp_iternext(inneriter);
mp_obj_t value = mp_iternext(inneriter); mp_obj_t value = mp_iternext(inneriter);
mp_obj_t stop = 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) { ...@@ -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 = { STATIC const mp_obj_type_t dict_view_it_type = {
{ &mp_type_type }, { &mp_type_type },
.name = MP_QSTR_iterator, .name = MP_QSTR_iterator,
.getiter = mp_identity, .getiter = mp_identity_getiter,
.iternext = dict_view_it_iternext, .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_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_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->base.type = &dict_view_it_type;
o->kind = view->kind; o->kind = view->kind;
o->dict = view->dict; 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_ ...@@ -479,7 +484,8 @@ STATIC void dict_view_print(const mp_print_t *print, mp_obj_t self_in, mp_print_
bool first = true; bool first = true;
mp_print_str(print, mp_dict_view_names[self->kind]); mp_print_str(print, mp_dict_view_names[self->kind]);
mp_print_str(print, "(["); 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; mp_obj_t next = MP_OBJ_NULL;
while ((next = dict_view_it_iternext(self_iter)) != MP_OBJ_STOP_ITERATION) { while ((next = dict_view_it_iternext(self_iter)) != MP_OBJ_STOP_ITERATION) {
if (!first) { if (!first) {
......
...@@ -56,13 +56,13 @@ STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, siz ...@@ -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 // create enumerate object
mp_obj_enumerate_t *o = m_new_obj(mp_obj_enumerate_t); mp_obj_enumerate_t *o = m_new_obj(mp_obj_enumerate_t);
o->base.type = type; 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; o->cur = arg_vals.start.u_int;
#else #else
(void)n_kw; (void)n_kw;
mp_obj_enumerate_t *o = m_new_obj(mp_obj_enumerate_t); mp_obj_enumerate_t *o = m_new_obj(mp_obj_enumerate_t);
o->base.type = type; 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; o->cur = n_args > 1 ? mp_obj_get_int(args[1]) : 0;
#endif #endif
...@@ -74,7 +74,7 @@ const mp_obj_type_t mp_type_enumerate = { ...@@ -74,7 +74,7 @@ const mp_obj_type_t mp_type_enumerate = {
.name = MP_QSTR_enumerate, .name = MP_QSTR_enumerate,
.make_new = enumerate_make_new, .make_new = enumerate_make_new,
.iternext = enumerate_iternext, .iternext = enumerate_iternext,
.getiter = mp_identity, .getiter = mp_identity_getiter,
}; };
STATIC mp_obj_t enumerate_iternext(mp_obj_t self_in) { 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 ...@@ -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); mp_obj_filter_t *o = m_new_obj(mp_obj_filter_t);
o->base.type = type; o->base.type = type;
o->fun = args[0]; o->fun = args[0];
o->iter = mp_getiter(args[1]); o->iter = mp_getiter(args[1], NULL);
return MP_OBJ_FROM_PTR(o); return MP_OBJ_FROM_PTR(o);
} }
...@@ -65,7 +65,7 @@ const mp_obj_type_t mp_type_filter = { ...@@ -65,7 +65,7 @@ const mp_obj_type_t mp_type_filter = {
{ &mp_type_type }, { &mp_type_type },
.name = MP_QSTR_filter, .name = MP_QSTR_filter,
.make_new = filter_make_new, .make_new = filter_make_new,
.getiter = mp_identity, .getiter = mp_identity_getiter,
.iternext = filter_iternext, .iternext = filter_iternext,
}; };
......
...@@ -236,7 +236,7 @@ const mp_obj_type_t mp_type_gen_instance = { ...@@ -236,7 +236,7 @@ const mp_obj_type_t mp_type_gen_instance = {
{ &mp_type_type }, { &mp_type_type },
.name = MP_QSTR_generator, .name = MP_QSTR_generator,
.print = gen_instance_print, .print = gen_instance_print,
.getiter = mp_identity, .getiter = mp_identity_getiter,
.iternext = gen_instance_iternext, .iternext = gen_instance_iternext,
.locals_dict = (mp_obj_dict_t*)&gen_instance_locals_dict, .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) { ...@@ -61,13 +61,14 @@ STATIC mp_obj_t it_iternext(mp_obj_t self_in) {
STATIC const mp_obj_type_t it_type = { STATIC const mp_obj_type_t it_type = {
{ &mp_type_type }, { &mp_type_type },
.name = MP_QSTR_iterator, .name = MP_QSTR_iterator,
.getiter = mp_identity, .getiter = mp_identity_getiter,
.iternext = it_iternext, .iternext = it_iternext,
}; };
// args are those returned from mp_load_method_maybe (ie either an attribute or a method) // 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_t mp_obj_new_getitem_iter(mp_obj_t *args, mp_obj_iter_buf_t *iter_buf) {
mp_obj_getitem_iter_t *o = m_new_obj(mp_obj_getitem_iter_t); 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->base.type = &it_type;
o->args[0] = args[0]; o->args[0] = args[0];
o->args[1] = args[1]; o->args[1] = args[1];
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include "py/runtime.h" #include "py/runtime.h"
#include "py/stackctrl.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_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_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); 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 ...@@ -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) { 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; mp_obj_t item;
while ((item = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { while ((item = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
mp_obj_list_append(list, item); 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) { ...@@ -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) { 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); 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) { 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) { ...@@ -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_t mp_obj_new_list_iterator(mp_obj_t list, size_t cur, mp_obj_iter_buf_t *iter_buf) {
mp_obj_list_it_t *o = m_new_obj(mp_obj_list_it_t); 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->base.type = &mp_type_polymorph_iter;
o->iternext = list_it_iternext; o->iternext = list_it_iternext;
o->list = list; 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_ ...@@ -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->n_iters = n_args - 1;
o->fun = args[0]; o->fun = args[0];
for (mp_uint_t i = 0; i < n_args - 1; i++) { 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); return MP_OBJ_FROM_PTR(o);
} }
...@@ -68,6 +68,6 @@ const mp_obj_type_t mp_type_map = { ...@@ -68,6 +68,6 @@ const mp_obj_type_t mp_type_map = {
{ &mp_type_type }, { &mp_type_type },
.name = MP_QSTR_map, .name = MP_QSTR_map,
.make_new = map_make_new, .make_new = map_make_new,
.getiter = mp_identity, .getiter = mp_identity_getiter,
.iternext = map_iternext, .iternext = map_iternext,
}; };
...@@ -49,6 +49,6 @@ STATIC mp_obj_t polymorph_it_iternext(mp_obj_t self_in) { ...@@ -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 = { const mp_obj_type_t mp_type_polymorph_iter = {
{ &mp_type_type }, { &mp_type_type },
.name = MP_QSTR_iterator, .name = MP_QSTR_iterator,
.getiter = mp_identity, .getiter = mp_identity_getiter,
.iternext = polymorph_it_iternext, .iternext = polymorph_it_iternext,
}; };