From 1ea2f7a8ce0353e423253135e417c02dc6466405 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 16 Feb 2017 16:15:04 +1100 Subject: py/objdict: Convert mp_uint_t to size_t where appropriate. --- py/objdict.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'py/objdict.c') diff --git a/py/objdict.c b/py/objdict.c index 4942d3779..640df7b62 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -41,11 +41,11 @@ STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwarg // This is a helper function to iterate through a dictionary. The state of // the iteration is held in *cur and should be initialised with zero for the // first call. Will return NULL when no more elements are available. -STATIC mp_map_elem_t *dict_iter_next(mp_obj_dict_t *dict, mp_uint_t *cur) { - mp_uint_t max = dict->map.alloc; +STATIC mp_map_elem_t *dict_iter_next(mp_obj_dict_t *dict, size_t *cur) { + size_t max = dict->map.alloc; mp_map_t *map = &dict->map; - for (mp_uint_t i = *cur; i < max; i++) { + for (size_t i = *cur; i < max; i++) { if (MP_MAP_SLOT_IS_FILLED(map, i)) { *cur = i + 1; return &(map->table[i]); @@ -65,7 +65,7 @@ STATIC void dict_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_ mp_printf(print, "%q(", self->base.type->name); } mp_print_str(print, "{"); - mp_uint_t cur = 0; + size_t cur = 0; mp_map_elem_t *next = NULL; while ((next = dict_iter_next(self, &cur)) != NULL) { if (!first) { @@ -121,7 +121,7 @@ STATIC mp_obj_t dict_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { if (MP_UNLIKELY(MP_OBJ_IS_TYPE(lhs_in, &mp_type_ordereddict) && MP_OBJ_IS_TYPE(rhs_in, &mp_type_ordereddict))) { // Iterate through both dictionaries simultaneously and compare keys and values. mp_obj_dict_t *rhs = MP_OBJ_TO_PTR(rhs_in); - mp_uint_t c1 = 0, c2 = 0; + size_t c1 = 0, c2 = 0; mp_map_elem_t *e1 = dict_iter_next(o, &c1), *e2 = dict_iter_next(rhs, &c2); for (; e1 != NULL && e2 != NULL; e1 = dict_iter_next(o, &c1), e2 = dict_iter_next(rhs, &c2)) { if (!mp_obj_equal(e1->key, e2->key) || !mp_obj_equal(e1->value, e2->value)) { @@ -137,7 +137,7 @@ STATIC mp_obj_t dict_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { return mp_const_false; } - mp_uint_t cur = 0; + size_t cur = 0; mp_map_elem_t *next = NULL; while ((next = dict_iter_next(o, &cur)) != NULL) { mp_map_elem_t *elem = mp_map_lookup(&rhs->map, next->key, MP_MAP_LOOKUP); @@ -196,7 +196,7 @@ typedef struct _mp_obj_dict_it_t { mp_obj_base_t base; mp_fun_1_t iternext; mp_obj_t dict; - mp_uint_t cur; + size_t cur; } mp_obj_dict_it_t; STATIC mp_obj_t dict_it_iternext(mp_obj_t self_in) { @@ -340,7 +340,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(dict_setdefault_obj, 2, 3, dict_setde STATIC mp_obj_t dict_popitem(mp_obj_t self_in) { mp_check_self(MP_OBJ_IS_DICT_TYPE(self_in)); mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in); - mp_uint_t cur = 0; + size_t cur = 0; mp_map_elem_t *next = dict_iter_next(self, &cur); if (next == NULL) { mp_raise_msg(&mp_type_KeyError, "popitem(): dictionary is empty"); @@ -367,7 +367,7 @@ STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwarg if (MP_OBJ_IS_DICT_TYPE(args[1])) { // update from other dictionary (make sure other is not self) if (args[1] != args[0]) { - mp_uint_t cur = 0; + size_t cur = 0; mp_map_elem_t *elem = NULL; while ((elem = dict_iter_next((mp_obj_dict_t*)MP_OBJ_TO_PTR(args[1]), &cur)) != NULL) { mp_map_lookup(&self->map, elem->key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = elem->value; @@ -394,7 +394,7 @@ STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwarg } // update the dict with any keyword args - for (mp_uint_t i = 0; i < kwargs->alloc; i++) { + for (size_t i = 0; i < kwargs->alloc; i++) { if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { mp_map_lookup(&self->map, kwargs->table[i].key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = kwargs->table[i].value; } @@ -423,7 +423,7 @@ typedef struct _mp_obj_dict_view_it_t { mp_obj_base_t base; mp_dict_view_kind_t kind; mp_obj_t dict; - mp_uint_t cur; + size_t cur; } mp_obj_dict_view_it_t; typedef struct _mp_obj_dict_view_t { @@ -590,18 +590,18 @@ const mp_obj_type_t mp_type_ordereddict = { }; #endif -void mp_obj_dict_init(mp_obj_dict_t *dict, mp_uint_t n_args) { +void mp_obj_dict_init(mp_obj_dict_t *dict, size_t n_args) { dict->base.type = &mp_type_dict; mp_map_init(&dict->map, n_args); } -mp_obj_t mp_obj_new_dict(mp_uint_t n_args) { +mp_obj_t mp_obj_new_dict(size_t n_args) { mp_obj_dict_t *o = m_new_obj(mp_obj_dict_t); mp_obj_dict_init(o, n_args); return MP_OBJ_FROM_PTR(o); } -mp_uint_t mp_obj_dict_len(mp_obj_t self_in) { +size_t mp_obj_dict_len(mp_obj_t self_in) { mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in); return self->map.used; } -- cgit v1.2.3 From ae8d86758631e62466a55d179897d2111c3cb1c1 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 9 Jan 2016 23:14:54 +0000 Subject: 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. --- cc3200/mods/pybuart.c | 2 +- esp8266/machine_uart.c | 2 +- extmod/modbtree.c | 3 ++- extmod/vfs_fat_file.c | 4 ++-- py/emitnative.c | 1 + py/modbuiltins.c | 14 +++++++++----- py/obj.c | 5 +++++ py/obj.h | 15 +++++++++++++-- py/objarray.c | 14 +++++++++----- py/objdict.c | 24 +++++++++++++++--------- py/objenumerate.c | 6 +++--- py/objfilter.c | 4 ++-- py/objgenerator.c | 2 +- py/objgetitemiter.c | 7 ++++--- py/objlist.c | 14 ++++++++------ py/objmap.c | 4 ++-- py/objpolyiter.c | 2 +- py/objrange.c | 11 ++++++----- py/objreversed.c | 2 +- py/objset.c | 26 +++++++++++++++++--------- py/objstr.c | 17 ++++++++++------- py/objstringio.c | 4 ++-- py/objstrunicode.c | 7 ++++--- py/objtuple.c | 18 +++++++----------- py/objtuple.h | 2 +- py/objtype.c | 4 ++-- py/objzip.c | 4 ++-- py/runtime.c | 26 ++++++++++++++++++-------- py/runtime.h | 2 +- py/vm.c | 2 +- stmhal/pybstdio.c | 4 ++-- stmhal/uart.c | 2 +- stmhal/usb.c | 2 +- unix/file.c | 4 ++-- unix/modffi.c | 6 ++++-- unix/moduselect.c | 2 +- 36 files changed, 162 insertions(+), 106 deletions(-) (limited to 'py/objdict.c') diff --git a/cc3200/mods/pybuart.c b/cc3200/mods/pybuart.c index fe710be92..dceb842d5 100644 --- a/cc3200/mods/pybuart.c +++ b/cc3200/mods/pybuart.c @@ -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, diff --git a/esp8266/machine_uart.c b/esp8266/machine_uart.c index efdfafd1a..ef52e8c9a 100644 --- a/esp8266/machine_uart.c +++ b/esp8266/machine_uart.c @@ -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, diff --git a/extmod/modbtree.c b/extmod/modbtree.c index bb75845b1..27f700eea 100644 --- a/extmod/modbtree.c +++ b/extmod/modbtree.c @@ -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(), diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c index 62da23f94..6263492cb 100644 --- a/extmod/vfs_fat_file.c +++ b/extmod/vfs_fat_file.c @@ -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, diff --git a/py/emitnative.c b/py/emitnative.c index bdb590e77..e8e3754e1 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -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); } diff --git a/py/modbuiltins.c b/py/modbuiltins.c index a0c68930d..13312d229 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -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); diff --git a/py/obj.c b/py/obj.c index 1d0c80ab9..4534ef1b2 100644 --- a/py/obj.c +++ b/py/obj.c @@ -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) { diff --git a/py/obj.h b/py/obj.h index 1169a9095..79a6d56fa 100644 --- a/py/obj.h +++ b/py/obj.h @@ -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 { diff --git a/py/objarray.c b/py/objarray.c index f23791857..c81aebb50 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -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; diff --git a/py/objdict.c b/py/objdict.c index 640df7b62..c52403f71 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -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) { diff --git a/py/objenumerate.c b/py/objenumerate.c index 2b646ca45..faae6516c 100644 --- a/py/objenumerate.c +++ b/py/objenumerate.c @@ -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) { diff --git a/py/objfilter.c b/py/objfilter.c index a5c85b2ce..a655b8a78 100644 --- a/py/objfilter.c +++ b/py/objfilter.c @@ -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, }; diff --git a/py/objgenerator.c b/py/objgenerator.c index 0be9b8d59..654b18670 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -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, }; diff --git a/py/objgetitemiter.c b/py/objgetitemiter.c index 526180fdb..a3c754448 100644 --- a/py/objgetitemiter.c +++ b/py/objgetitemiter.c @@ -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]; diff --git a/py/objlist.c b/py/objlist.c index 210140388..28da10991 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -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; diff --git a/py/objmap.c b/py/objmap.c index ed0291435..0b2189016 100644 --- a/py/objmap.c +++ b/py/objmap.c @@ -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, }; diff --git a/py/objpolyiter.c b/py/objpolyiter.c index 9bba538c5..61bd1e0ac 100644 --- a/py/objpolyiter.c +++ b/py/objpolyiter.c @@ -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, }; diff --git a/py/objrange.c b/py/objrange.c index 79459316b..dd074a98a 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -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); } diff --git a/py/objreversed.c b/py/objreversed.c index 4343c1978..fc85e72bf 100644 --- a/py/objreversed.c +++ b/py/objreversed.c @@ -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, }; diff --git a/py/objset.c b/py/objset.c index b9da44a44..99e1e8ca5 100644 --- a/py/objset.c +++ b/py/objset.c @@ -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); diff --git a/py/objstr.c b/py/objstr.c index 262b89ddd..c137afe67 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -38,7 +38,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_t *args, mp_obj_t dict); -STATIC mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str); +STATIC mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf); STATIC NORETURN void bad_implicit_conversion(mp_obj_t self_in); /******************************************************************************/ @@ -231,7 +231,8 @@ STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, size vstr_init(&vstr, len); } - 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_int_t val = mp_obj_get_int(item); @@ -1942,7 +1943,7 @@ STATIC const mp_rom_map_elem_t str8_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(str8_locals_dict, str8_locals_dict_table); #if !MICROPY_PY_BUILTINS_STR_UNICODE -STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str); +STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf); const mp_obj_type_t mp_type_str = { { &mp_type_type }, @@ -2142,8 +2143,9 @@ STATIC mp_obj_t str_it_iternext(mp_obj_t self_in) { } } -STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str) { - mp_obj_str8_it_t *o = m_new_obj(mp_obj_str8_it_t); +STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf) { + assert(sizeof(mp_obj_str8_it_t) <= sizeof(mp_obj_iter_buf_t)); + mp_obj_str8_it_t *o = (mp_obj_str8_it_t*)iter_buf; o->base.type = &mp_type_polymorph_iter; o->iternext = str_it_iternext; o->str = str; @@ -2164,8 +2166,9 @@ STATIC mp_obj_t bytes_it_iternext(mp_obj_t self_in) { } } -mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str) { - mp_obj_str8_it_t *o = m_new_obj(mp_obj_str8_it_t); +mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf) { + assert(sizeof(mp_obj_str8_it_t) <= sizeof(mp_obj_iter_buf_t)); + mp_obj_str8_it_t *o = (mp_obj_str8_it_t*)iter_buf; o->base.type = &mp_type_polymorph_iter; o->iternext = bytes_it_iternext; o->str = str; diff --git a/py/objstringio.c b/py/objstringio.c index a77ffae24..61a30752e 100644 --- a/py/objstringio.c +++ b/py/objstringio.c @@ -215,7 +215,7 @@ const mp_obj_type_t mp_type_stringio = { .name = MP_QSTR_StringIO, .print = stringio_print, .make_new = stringio_make_new, - .getiter = mp_identity, + .getiter = mp_identity_getiter, .iternext = mp_stream_unbuffered_iter, .protocol = &stringio_stream_p, .locals_dict = (mp_obj_dict_t*)&stringio_locals_dict, @@ -227,7 +227,7 @@ const mp_obj_type_t mp_type_bytesio = { .name = MP_QSTR_BytesIO, .print = stringio_print, .make_new = stringio_make_new, - .getiter = mp_identity, + .getiter = mp_identity_getiter, .iternext = mp_stream_unbuffered_iter, .protocol = &bytesio_stream_p, .locals_dict = (mp_obj_dict_t*)&stringio_locals_dict, diff --git a/py/objstrunicode.c b/py/objstrunicode.c index 0091edd72..441ec293d 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -36,7 +36,7 @@ #if MICROPY_PY_BUILTINS_STR_UNICODE -STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str); +STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf); /******************************************************************************/ /* str */ @@ -301,8 +301,9 @@ STATIC mp_obj_t str_it_iternext(mp_obj_t self_in) { } } -STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str) { - mp_obj_str_it_t *o = m_new_obj(mp_obj_str_it_t); +STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf) { + assert(sizeof(mp_obj_str_it_t) <= sizeof(mp_obj_iter_buf_t)); + mp_obj_str_it_t *o = (mp_obj_str_it_t*)iter_buf; o->base.type = &mp_type_polymorph_iter; o->iternext = str_it_iternext; o->str = str; diff --git a/py/objtuple.c b/py/objtuple.c index 1935a6709..ad45696ca 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -32,8 +32,6 @@ #include "py/runtime0.h" #include "py/runtime.h" -STATIC mp_obj_t mp_obj_new_tuple_iterator(mp_obj_tuple_t *tuple, size_t cur); - /******************************************************************************/ /* tuple */ @@ -84,7 +82,8 @@ STATIC mp_obj_t mp_obj_tuple_make_new(const mp_obj_type_t *type_in, size_t n_arg size_t len = 0; mp_obj_t *items = m_new(mp_obj_t, alloc); - 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) { if (len >= alloc) { @@ -195,10 +194,6 @@ mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { } } -mp_obj_t mp_obj_tuple_getiter(mp_obj_t o_in) { - return mp_obj_new_tuple_iterator(MP_OBJ_TO_PTR(o_in), 0); -} - STATIC mp_obj_t tuple_count(mp_obj_t self_in, mp_obj_t value) { mp_check_self(MP_OBJ_IS_TYPE(self_in, &mp_type_tuple)); mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in); @@ -284,11 +279,12 @@ STATIC mp_obj_t tuple_it_iternext(mp_obj_t self_in) { } } -STATIC mp_obj_t mp_obj_new_tuple_iterator(mp_obj_tuple_t *tuple, size_t cur) { - mp_obj_tuple_it_t *o = m_new_obj(mp_obj_tuple_it_t); +mp_obj_t mp_obj_tuple_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) { + assert(sizeof(mp_obj_tuple_it_t) <= sizeof(mp_obj_iter_buf_t)); + mp_obj_tuple_it_t *o = (mp_obj_tuple_it_t*)iter_buf; o->base.type = &mp_type_polymorph_iter; o->iternext = tuple_it_iternext; - o->tuple = tuple; - o->cur = cur; + o->tuple = MP_OBJ_TO_PTR(o_in); + o->cur = 0; return MP_OBJ_FROM_PTR(o); } diff --git a/py/objtuple.h b/py/objtuple.h index 760135f86..555c3b3c2 100644 --- a/py/objtuple.h +++ b/py/objtuple.h @@ -44,7 +44,7 @@ void mp_obj_tuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t mp_obj_t mp_obj_tuple_unary_op(mp_uint_t op, mp_obj_t self_in); mp_obj_t mp_obj_tuple_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs); mp_obj_t mp_obj_tuple_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value); -mp_obj_t mp_obj_tuple_getiter(mp_obj_t o_in); +mp_obj_t mp_obj_tuple_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf); extern const mp_obj_type_t mp_type_attrtuple; diff --git a/py/objtype.c b/py/objtype.c index 60f630c3d..a4c424929 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -758,7 +758,7 @@ mp_obj_t mp_obj_instance_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons return mp_call_method_self_n_kw(member[0], member[1], n_args, n_kw, args); } -STATIC mp_obj_t instance_getiter(mp_obj_t self_in) { +STATIC mp_obj_t instance_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) { mp_obj_instance_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_t member[2] = {MP_OBJ_NULL}; struct class_lookup_data lookup = { @@ -773,7 +773,7 @@ STATIC mp_obj_t instance_getiter(mp_obj_t self_in) { return MP_OBJ_NULL; } else if (member[0] == MP_OBJ_SENTINEL) { mp_obj_type_t *type = mp_obj_get_type(self->subobj[0]); - return type->getiter(self->subobj[0]); + return type->getiter(self->subobj[0], iter_buf); } else { return mp_call_method_n_kw(0, 0, member); } diff --git a/py/objzip.c b/py/objzip.c index 6edefc361..5d9ba48e7 100644 --- a/py/objzip.c +++ b/py/objzip.c @@ -43,7 +43,7 @@ STATIC mp_obj_t zip_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_ o->base.type = type; o->n_iters = n_args; for (mp_uint_t i = 0; i < n_args; i++) { - o->iters[i] = mp_getiter(args[i]); + o->iters[i] = mp_getiter(args[i], NULL); } return MP_OBJ_FROM_PTR(o); } @@ -71,6 +71,6 @@ const mp_obj_type_t mp_type_zip = { { &mp_type_type }, .name = MP_QSTR_zip, .make_new = zip_make_new, - .getiter = mp_identity, + .getiter = mp_identity_getiter, .iternext = zip_iternext, }; diff --git a/py/runtime.c b/py/runtime.c index 3ac30f58e..b9d7b72dc 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -520,7 +520,8 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { } if (type->getiter != NULL) { /* second attempt, walk the iterator */ - mp_obj_t iter = mp_getiter(rhs); + mp_obj_iter_buf_t iter_buf; + mp_obj_t iter = mp_getiter(rhs, &iter_buf); mp_obj_t next; while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { if (mp_obj_equal(next, lhs)) { @@ -698,7 +699,8 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_ args2_len += n_args; // extract the variable position args from the iterator - mp_obj_t iterable = mp_getiter(pos_seq); + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(pos_seq, &iter_buf); mp_obj_t item; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { if (args2_len >= args2_alloc) { @@ -743,7 +745,8 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_ // get the keys iterable mp_obj_t dest[3]; mp_load_method(kw_dict, MP_QSTR_keys, dest); - mp_obj_t iterable = mp_getiter(mp_call_method_n_kw(0, 0, dest)); + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(mp_call_method_n_kw(0, 0, dest), &iter_buf); mp_obj_t key; while ((key = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { @@ -809,7 +812,8 @@ void mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items) { items[i] = seq_items[num - 1 - i]; } } else { - mp_obj_t iterable = mp_getiter(seq_in); + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(seq_in, &iter_buf); for (seq_len = 0; seq_len < num; seq_len++) { mp_obj_t el = mp_iternext(iterable); @@ -873,7 +877,8 @@ void mp_unpack_ex(mp_obj_t seq_in, size_t num_in, mp_obj_t *items) { // items destination array, then the rest to a dynamically created list. Once the // iterable is exhausted, we take from this list for the right part of the items. // TODO Improve to waste less memory in the dynamically created list. - mp_obj_t iterable = mp_getiter(seq_in); + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(seq_in, &iter_buf); mp_obj_t item; for (seq_len = 0; seq_len < num_left; seq_len++) { item = mp_iternext(iterable); @@ -1096,13 +1101,18 @@ void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) { } } -mp_obj_t mp_getiter(mp_obj_t o_in) { +mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) { assert(o_in); + // if caller did not provide a buffer then allocate one on the heap + if (iter_buf == NULL) { + iter_buf = m_new_obj(mp_obj_iter_buf_t); + } + // check for native getiter (corresponds to __iter__) mp_obj_type_t *type = mp_obj_get_type(o_in); if (type->getiter != NULL) { - mp_obj_t iter = type->getiter(o_in); + mp_obj_t iter = type->getiter(o_in, iter_buf); if (iter != MP_OBJ_NULL) { return iter; } @@ -1113,7 +1123,7 @@ mp_obj_t mp_getiter(mp_obj_t o_in) { mp_load_method_maybe(o_in, MP_QSTR___getitem__, dest); if (dest[0] != MP_OBJ_NULL) { // __getitem__ exists, create and return an iterator - return mp_obj_new_getitem_iter(dest); + return mp_obj_new_getitem_iter(dest, iter_buf); } // object not iterable diff --git a/py/runtime.h b/py/runtime.h index e25f2a483..954833b67 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -123,7 +123,7 @@ void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest); void mp_load_method_maybe(mp_obj_t base, qstr attr, mp_obj_t *dest); void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t val); -mp_obj_t mp_getiter(mp_obj_t o); +mp_obj_t mp_getiter(mp_obj_t o, mp_obj_iter_buf_t *iter_buf); mp_obj_t mp_iternext_allow_raise(mp_obj_t o); // may return MP_OBJ_STOP_ITERATION instead of raising StopIteration() mp_obj_t mp_iternext(mp_obj_t o); // will always return MP_OBJ_STOP_ITERATION instead of raising StopIteration(...) mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val); diff --git a/py/vm.c b/py/vm.c index 97f344b08..917d41a11 100644 --- a/py/vm.c +++ b/py/vm.c @@ -723,7 +723,7 @@ unwind_jump:; ENTRY(MP_BC_GET_ITER): MARK_EXC_IP_SELECTIVE(); - SET_TOP(mp_getiter(TOP())); + SET_TOP(mp_getiter(TOP(), NULL)); DISPATCH(); ENTRY(MP_BC_FOR_ITER): { diff --git a/stmhal/pybstdio.c b/stmhal/pybstdio.c index dec4f227a..9b1bfff90 100644 --- a/stmhal/pybstdio.c +++ b/stmhal/pybstdio.c @@ -120,7 +120,7 @@ STATIC const mp_obj_type_t stdio_obj_type = { .name = MP_QSTR_FileIO, // TODO .make_new? .print = stdio_obj_print, - .getiter = mp_identity, + .getiter = mp_identity_getiter, .iternext = mp_stream_unbuffered_iter, .protocol = &stdio_obj_stream_p, .locals_dict = (mp_obj_t)&stdio_locals_dict, @@ -153,7 +153,7 @@ STATIC const mp_obj_type_t stdio_buffer_obj_type = { { &mp_type_type }, .name = MP_QSTR_FileIO, .print = stdio_obj_print, - .getiter = mp_identity, + .getiter = mp_identity_getiter, .iternext = mp_stream_unbuffered_iter, .protocol = &stdio_buffer_obj_stream_p, .locals_dict = (mp_obj_t)&stdio_locals_dict, diff --git a/stmhal/uart.c b/stmhal/uart.c index d53ca5b80..4fae3a80c 100644 --- a/stmhal/uart.c +++ b/stmhal/uart.c @@ -1037,7 +1037,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, diff --git a/stmhal/usb.c b/stmhal/usb.c index c413ce4ba..f71c70665 100644 --- a/stmhal/usb.c +++ b/stmhal/usb.c @@ -518,7 +518,7 @@ const mp_obj_type_t pyb_usb_vcp_type = { .name = MP_QSTR_USB_VCP, .print = pyb_usb_vcp_print, .make_new = pyb_usb_vcp_make_new, - .getiter = mp_identity, + .getiter = mp_identity_getiter, .iternext = mp_stream_unbuffered_iter, .protocol = &pyb_usb_vcp_stream_p, .locals_dict = (mp_obj_t)&pyb_usb_vcp_locals_dict, diff --git a/unix/file.c b/unix/file.c index 96fe78c49..a60840c81 100644 --- a/unix/file.c +++ b/unix/file.c @@ -244,7 +244,7 @@ const mp_obj_type_t mp_type_fileio = { .name = MP_QSTR_FileIO, .print = fdfile_print, .make_new = fdfile_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, @@ -263,7 +263,7 @@ const mp_obj_type_t mp_type_textio = { .name = MP_QSTR_TextIOWrapper, .print = fdfile_print, .make_new = fdfile_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, diff --git a/unix/modffi.c b/unix/modffi.c index cae16c579..74194e2cc 100644 --- a/unix/modffi.c +++ b/unix/modffi.c @@ -194,7 +194,8 @@ STATIC mp_obj_t make_func(mp_obj_t rettype_in, void *func, mp_obj_t argtypes_in) o->rettype = *rettype; o->argtypes = argtypes; - mp_obj_t iterable = mp_getiter(argtypes_in); + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(argtypes_in, &iter_buf); mp_obj_t item; int i = 0; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { @@ -251,7 +252,8 @@ STATIC mp_obj_t mod_ffi_callback(mp_obj_t rettype_in, mp_obj_t func_in, mp_obj_t o->rettype = *rettype; - mp_obj_t iterable = mp_getiter(paramtypes_in); + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(paramtypes_in, &iter_buf); mp_obj_t item; int i = 0; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { diff --git a/unix/moduselect.c b/unix/moduselect.c index f966efa41..76938329f 100644 --- a/unix/moduselect.c +++ b/unix/moduselect.c @@ -288,7 +288,7 @@ STATIC MP_DEFINE_CONST_DICT(poll_locals_dict, poll_locals_dict_table); STATIC const mp_obj_type_t mp_type_poll = { { &mp_type_type }, .name = MP_QSTR_poll, - .getiter = mp_identity, + .getiter = mp_identity_getiter, .iternext = poll_iternext, .locals_dict = (void*)&poll_locals_dict, }; -- cgit v1.2.3 From e6003f466e6f5b7eddd01740666230b62ab5a872 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 13 Feb 2017 15:44:31 +1100 Subject: py: De-optimise some uses of mp_getiter, so they don't use the C stack. In these cases the heap is anyway used to create a new object so no real need to use the C stack for iterating. It saves a few bytes of code size. --- py/objarray.c | 3 +-- py/objdict.c | 9 +++------ py/objlist.c | 3 +-- py/objset.c | 15 +++++---------- py/objtuple.c | 3 +-- py/runtime.c | 6 ++---- 6 files changed, 13 insertions(+), 26 deletions(-) (limited to 'py/objdict.c') diff --git a/py/objarray.c b/py/objarray.c index c81aebb50..1b590f3c0 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -141,8 +141,7 @@ STATIC mp_obj_t array_construct(char typecode, mp_obj_t initializer) { mp_obj_array_t *array = array_new(typecode, len); - mp_obj_iter_buf_t iter_buf; - mp_obj_t iterable = mp_getiter(initializer, &iter_buf); + mp_obj_t iterable = mp_getiter(initializer, NULL); mp_obj_t item; size_t i = 0; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { diff --git a/py/objdict.c b/py/objdict.c index c52403f71..013cc0a04 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -250,8 +250,7 @@ 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_iter_buf_t iter_buf; - mp_obj_t iter = mp_getiter(args[1], &iter_buf); + mp_obj_t iter = mp_getiter(args[1], NULL); mp_obj_t value = mp_const_none; mp_obj_t next = MP_OBJ_NULL; @@ -377,12 +376,10 @@ 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_iter_buf_t iter_buf; - mp_obj_t iter = mp_getiter(args[1], &iter_buf); + mp_obj_t iter = mp_getiter(args[1], NULL); mp_obj_t next = MP_OBJ_NULL; while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { - mp_obj_iter_buf_t inner_iter_buf; - mp_obj_t inneriter = mp_getiter(next, &inner_iter_buf); + mp_obj_t inneriter = mp_getiter(next, NULL); mp_obj_t key = mp_iternext(inneriter); mp_obj_t value = mp_iternext(inneriter); mp_obj_t stop = mp_iternext(inneriter); diff --git a/py/objlist.c b/py/objlist.c index 28da10991..55ee19120 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -60,8 +60,7 @@ 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_iter_buf_t iter_buf; - mp_obj_t iter = mp_getiter(iterable, &iter_buf); + mp_obj_t iter = mp_getiter(iterable, NULL); mp_obj_t item; while ((item = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { mp_obj_list_append(list, item); diff --git a/py/objset.c b/py/objset.c index 99e1e8ca5..f74bc74a0 100644 --- a/py/objset.c +++ b/py/objset.c @@ -129,8 +129,7 @@ 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_iter_buf_t iter_buf; - mp_obj_t iterable = mp_getiter(args[0], &iter_buf); + mp_obj_t iterable = mp_getiter(args[0], NULL); mp_obj_t item; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { mp_obj_set_store(set, item); @@ -235,8 +234,7 @@ 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_iter_buf_t iter_buf; - mp_obj_t iter = mp_getiter(other, &iter_buf); + mp_obj_t iter = mp_getiter(other, NULL); mp_obj_t next; while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { set_discard(self, next); @@ -273,8 +271,7 @@ 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_iter_buf_t iter_buf; - mp_obj_t iter = mp_getiter(other, &iter_buf); + mp_obj_t iter = mp_getiter(other, NULL); mp_obj_t next; while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { if (mp_set_lookup(&self->set, next, MP_MAP_LOOKUP)) { @@ -414,8 +411,7 @@ 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_iter_buf_t iter_buf; - mp_obj_t iter = mp_getiter(other_in, &iter_buf); + mp_obj_t iter = mp_getiter(other_in, NULL); 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); @@ -434,8 +430,7 @@ 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_iter_buf_t iter_buf; - mp_obj_t iter = mp_getiter(other_in, &iter_buf); + mp_obj_t iter = mp_getiter(other_in, NULL); 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); diff --git a/py/objtuple.c b/py/objtuple.c index ad45696ca..b28807c0d 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -82,8 +82,7 @@ STATIC mp_obj_t mp_obj_tuple_make_new(const mp_obj_type_t *type_in, size_t n_arg size_t len = 0; mp_obj_t *items = m_new(mp_obj_t, alloc); - mp_obj_iter_buf_t iter_buf; - mp_obj_t iterable = mp_getiter(args[0], &iter_buf); + mp_obj_t iterable = mp_getiter(args[0], NULL); mp_obj_t item; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { if (len >= alloc) { diff --git a/py/runtime.c b/py/runtime.c index b792eabe7..db6a6f18f 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -745,8 +745,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_ // get the keys iterable mp_obj_t dest[3]; mp_load_method(kw_dict, MP_QSTR_keys, dest); - mp_obj_iter_buf_t iter_buf; - mp_obj_t iterable = mp_getiter(mp_call_method_n_kw(0, 0, dest), &iter_buf); + mp_obj_t iterable = mp_getiter(mp_call_method_n_kw(0, 0, dest), NULL); mp_obj_t key; while ((key = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { @@ -877,8 +876,7 @@ void mp_unpack_ex(mp_obj_t seq_in, size_t num_in, mp_obj_t *items) { // items destination array, then the rest to a dynamically created list. Once the // iterable is exhausted, we take from this list for the right part of the items. // TODO Improve to waste less memory in the dynamically created list. - mp_obj_iter_buf_t iter_buf; - mp_obj_t iterable = mp_getiter(seq_in, &iter_buf); + mp_obj_t iterable = mp_getiter(seq_in, NULL); mp_obj_t item; for (seq_len = 0; seq_len < num_left; seq_len++) { item = mp_iternext(iterable); -- cgit v1.2.3 From 94c41bb06f6482ece0717c5bd63266b8da063caa Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 28 Mar 2017 22:37:26 +1100 Subject: py: Use mp_raise_TypeError/mp_raise_ValueError helpers where possible. Saves 168 bytes on bare-arm. --- py/argcheck.c | 8 ++++---- py/bc.c | 4 ++-- py/builtinevex.c | 2 +- py/builtinimport.c | 2 +- py/modbuiltins.c | 8 ++++---- py/modthread.c | 2 +- py/obj.c | 20 ++++++++++---------- py/objarray.c | 2 +- py/objdict.c | 2 +- py/objgenerator.c | 2 +- py/objint_mpz.c | 2 +- py/objobject.c | 2 +- py/objstringio.c | 2 +- py/objtype.c | 16 ++++++++-------- py/parsenum.c | 2 +- py/runtime.c | 28 ++++++++++++++-------------- py/sequence.c | 2 +- 17 files changed, 53 insertions(+), 53 deletions(-) (limited to 'py/objdict.c') diff --git a/py/argcheck.c b/py/argcheck.c index 8cef10b16..9f225345d 100644 --- a/py/argcheck.c +++ b/py/argcheck.c @@ -37,7 +37,7 @@ void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_ar if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_arg_error_terse_mismatch(); } else { - mp_raise_msg(&mp_type_TypeError, "function does not take keyword arguments"); + mp_raise_TypeError("function does not take keyword arguments"); } } @@ -115,7 +115,7 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n mp_arg_error_terse_mismatch(); } else { // TODO better error message - mp_raise_msg(&mp_type_TypeError, "extra positional arguments given"); + mp_raise_TypeError("extra positional arguments given"); } } if (kws_found < kws->used) { @@ -123,7 +123,7 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n mp_arg_error_terse_mismatch(); } else { // TODO better error message - mp_raise_msg(&mp_type_TypeError, "extra keyword arguments given"); + mp_raise_TypeError("extra keyword arguments given"); } } } @@ -136,7 +136,7 @@ void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args, #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE || _MSC_VER NORETURN void mp_arg_error_terse_mismatch(void) { - mp_raise_msg(&mp_type_TypeError, "argument num/types mismatch"); + mp_raise_TypeError("argument num/types mismatch"); } #endif diff --git a/py/bc.c b/py/bc.c index 12887645b..4c0eb5391 100644 --- a/py/bc.c +++ b/py/bc.c @@ -197,7 +197,7 @@ void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw // Didn't find name match with positional args if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) == 0) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "unexpected keyword argument"); + mp_raise_TypeError("unexpected keyword argument"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unexpected keyword argument '%q'", MP_OBJ_QSTR_VALUE(wanted_arg_name))); @@ -250,7 +250,7 @@ continue2:; } else { // no keyword arguments given if (n_kwonly_args != 0) { - mp_raise_msg(&mp_type_TypeError, "function missing keyword-only argument"); + mp_raise_TypeError("function missing keyword-only argument"); } if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) { *var_pos_kw_args = mp_obj_new_dict(0); diff --git a/py/builtinevex.c b/py/builtinevex.c index b0514ee99..89fcc2fe1 100644 --- a/py/builtinevex.c +++ b/py/builtinevex.c @@ -95,7 +95,7 @@ STATIC mp_obj_t mp_builtin_compile(size_t n_args, const mp_obj_t *args) { case MP_QSTR_exec: parse_input_kind = MP_PARSE_FILE_INPUT; break; case MP_QSTR_eval: parse_input_kind = MP_PARSE_EVAL_INPUT; break; default: - mp_raise_msg(&mp_type_ValueError, "bad compile mode"); + mp_raise_ValueError("bad compile mode"); } mp_obj_code_t *code = m_new_obj(mp_obj_code_t); diff --git a/py/builtinimport.c b/py/builtinimport.c index 96846b963..17c1622ef 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -341,7 +341,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { qstr new_mod_q = qstr_from_strn(new_mod, new_mod_l); DEBUG_printf("Resolved base name for relative import: '%s'\n", qstr_str(new_mod_q)); if (new_mod_q == MP_QSTR_) { - mp_raise_msg(&mp_type_ValueError, "cannot perform relative import"); + mp_raise_ValueError("cannot perform relative import"); } module_name = MP_OBJ_NEW_QSTR(new_mod_q); mod_str = new_mod; diff --git a/py/modbuiltins.c b/py/modbuiltins.c index bd325014d..f1d703a6d 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -180,7 +180,7 @@ STATIC mp_obj_t mp_builtin_chr(mp_obj_t o_in) { str[3] = (c & 0x3F) | 0x80; len = 4; } else { - mp_raise_msg(&mp_type_ValueError, "chr() arg not in range(0x110000)"); + mp_raise_ValueError("chr() arg not in range(0x110000)"); } return mp_obj_new_str(str, len, true); #else @@ -189,7 +189,7 @@ STATIC mp_obj_t mp_builtin_chr(mp_obj_t o_in) { char str[1] = {ord}; return mp_obj_new_str(str, 1, true); } else { - mp_raise_msg(&mp_type_ValueError, "chr() arg not in range(256)"); + mp_raise_ValueError("chr() arg not in range(256)"); } #endif } @@ -289,7 +289,7 @@ STATIC mp_obj_t mp_builtin_min_max(size_t n_args, const mp_obj_t *args, mp_map_t if (default_elem != NULL) { best_obj = default_elem->value; } else { - mp_raise_msg(&mp_type_ValueError, "arg is an empty sequence"); + mp_raise_ValueError("arg is an empty sequence"); } } return best_obj; @@ -504,7 +504,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_sum_obj, 1, 2, mp_builtin_sum); STATIC mp_obj_t mp_builtin_sorted(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { if (n_args > 1) { - mp_raise_msg(&mp_type_TypeError, "must use keyword argument for key function"); + mp_raise_TypeError("must use keyword argument for key function"); } mp_obj_t self = mp_type_list.make_new(&mp_type_list, 1, 0, args); mp_obj_list_sort(1, &self, kwargs); diff --git a/py/modthread.c b/py/modthread.c index dda9e9348..ecf470527 100644 --- a/py/modthread.c +++ b/py/modthread.c @@ -227,7 +227,7 @@ STATIC mp_obj_t mod_thread_start_new_thread(size_t n_args, const mp_obj_t *args) } else { // positional and keyword arguments if (mp_obj_get_type(args[2]) != &mp_type_dict) { - mp_raise_msg(&mp_type_TypeError, "expecting a dict for keyword args"); + mp_raise_TypeError("expecting a dict for keyword args"); } mp_map_t *map = &((mp_obj_dict_t*)MP_OBJ_TO_PTR(args[2]))->map; th_args = m_new_obj_var(thread_entry_args_t, mp_obj_t, pos_args_len + 2 * map->used); diff --git a/py/obj.c b/py/obj.c index c065a3bfc..4b5fe2532 100644 --- a/py/obj.c +++ b/py/obj.c @@ -229,7 +229,7 @@ mp_int_t mp_obj_get_int(mp_const_obj_t arg) { return mp_obj_int_get_checked(arg); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "can't convert to int"); + mp_raise_TypeError("can't convert to int"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to int", mp_obj_get_type_str(arg))); @@ -279,7 +279,7 @@ mp_float_t mp_obj_get_float(mp_obj_t arg) { return mp_obj_float_get(arg); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "can't convert to float"); + mp_raise_TypeError("can't convert to float"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to float", mp_obj_get_type_str(arg))); @@ -310,7 +310,7 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) { mp_obj_complex_get(arg, real, imag); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "can't convert to complex"); + mp_raise_TypeError("can't convert to complex"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to complex", mp_obj_get_type_str(arg))); @@ -328,7 +328,7 @@ void mp_obj_get_array(mp_obj_t o, mp_uint_t *len, mp_obj_t **items) { mp_obj_list_get(o, len, items); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "expected tuple/list"); + mp_raise_TypeError("expected tuple/list"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "object '%s' is not a tuple or list", mp_obj_get_type_str(o))); @@ -342,7 +342,7 @@ void mp_obj_get_array_fixed_n(mp_obj_t o, size_t len, mp_obj_t **items) { mp_obj_get_array(o, &seq_len, items); if (seq_len != len) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_ValueError, "tuple/list has wrong length"); + mp_raise_ValueError("tuple/list has wrong length"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "requested length %d but object has length %d", (int)len, (int)seq_len)); @@ -357,7 +357,7 @@ size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool i = MP_OBJ_SMALL_INT_VALUE(index); } else if (!mp_obj_get_int_maybe(index, &i)) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "indices must be integers"); + mp_raise_TypeError("indices must be integers"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "%q indices must be integers, not %s", @@ -412,7 +412,7 @@ mp_obj_t mp_obj_len(mp_obj_t o_in) { mp_obj_t len = mp_obj_len_maybe(o_in); if (len == MP_OBJ_NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "object has no len"); + mp_raise_TypeError("object has no len"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "object of type '%s' has no len()", mp_obj_get_type_str(o_in))); @@ -453,7 +453,7 @@ mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) { } if (value == MP_OBJ_NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "object does not support item deletion"); + mp_raise_TypeError("object does not support item deletion"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object does not support item deletion", mp_obj_get_type_str(base))); @@ -468,7 +468,7 @@ mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) { } } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "object does not support item assignment"); + mp_raise_TypeError("object does not support item assignment"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object does not support item assignment", mp_obj_get_type_str(base))); @@ -502,7 +502,7 @@ bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) { void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) { if (!mp_get_buffer(obj, bufinfo, flags)) { - mp_raise_msg(&mp_type_TypeError, "object with buffer protocol required"); + mp_raise_TypeError("object with buffer protocol required"); } } diff --git a/py/objarray.c b/py/objarray.c index 05d28c8a8..21479a800 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -391,7 +391,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value mp_obj_array_t *src_slice = MP_OBJ_TO_PTR(value); if (item_sz != mp_binary_get_size('@', src_slice->typecode & TYPECODE_MASK, NULL)) { compat_error: - mp_raise_msg(&mp_type_ValueError, "lhs and rhs should be compatible"); + mp_raise_ValueError("lhs and rhs should be compatible"); } src_len = src_slice->len; src_items = src_slice->items; diff --git a/py/objdict.c b/py/objdict.c index 013cc0a04..5f84d71c7 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -386,7 +386,7 @@ STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwarg if (key == MP_OBJ_STOP_ITERATION || value == MP_OBJ_STOP_ITERATION || stop != MP_OBJ_STOP_ITERATION) { - mp_raise_msg(&mp_type_ValueError, "dictionary update sequence has the wrong length"); + mp_raise_ValueError("dictionary update sequence has the wrong length"); } else { mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; } diff --git a/py/objgenerator.c b/py/objgenerator.c index e59ff3a9c..2e57fdf4b 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -105,7 +105,7 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_ } if (self->code_state.sp == self->code_state.state - 1) { if (send_value != mp_const_none) { - mp_raise_msg(&mp_type_TypeError, "can't send non-None value to a just-started generator"); + mp_raise_TypeError("can't send non-None value to a just-started generator"); } } else { *self->code_state.sp = send_value; diff --git a/py/objint_mpz.c b/py/objint_mpz.c index 2cdf22505..ca989e8ad 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -277,7 +277,7 @@ mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { case MP_BINARY_OP_INPLACE_RSHIFT: { mp_int_t irhs = mp_obj_int_get_checked(rhs_in); if (irhs < 0) { - mp_raise_msg(&mp_type_ValueError, "negative shift count"); + mp_raise_ValueError("negative shift count"); } if (op == MP_BINARY_OP_LSHIFT || op == MP_BINARY_OP_INPLACE_LSHIFT) { mpz_shl_inpl(&res->mpz, zlhs, irhs); diff --git a/py/objobject.c b/py/objobject.c index b33dc491c..f9a7d17c3 100644 --- a/py/objobject.c +++ b/py/objobject.c @@ -50,7 +50,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(object___init___obj, object___init__); STATIC mp_obj_t object___new__(mp_obj_t cls) { if (!MP_OBJ_IS_TYPE(cls, &mp_type_type) || !mp_obj_is_instance_type((mp_obj_type_t*)MP_OBJ_TO_PTR(cls))) { - mp_raise_msg(&mp_type_TypeError, "__new__ arg must be a user-type"); + mp_raise_TypeError("__new__ arg must be a user-type"); } mp_obj_t o = MP_OBJ_SENTINEL; mp_obj_t res = mp_obj_instance_make_new(MP_OBJ_TO_PTR(cls), 1, 0, &o); diff --git a/py/objstringio.c b/py/objstringio.c index 61a30752e..88659deb8 100644 --- a/py/objstringio.c +++ b/py/objstringio.c @@ -39,7 +39,7 @@ #if MICROPY_CPYTHON_COMPAT STATIC void check_stringio_is_open(const mp_obj_stringio_t *o) { if (o->vstr == NULL) { - mp_raise_msg(&mp_type_ValueError, "I/O operation on closed file"); + mp_raise_ValueError("I/O operation on closed file"); } } #else diff --git a/py/objtype.c b/py/objtype.c index a747a34f8..a64832c1f 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -311,7 +311,7 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size } if (init_ret != mp_const_none) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "__init__() should return None"); + mp_raise_TypeError("__init__() should return None"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "__init__() should return None, not '%s'", mp_obj_get_type_str(init_ret))); @@ -744,7 +744,7 @@ mp_obj_t mp_obj_instance_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons mp_obj_t call = mp_obj_instance_get_call(self_in, member); if (call == MP_OBJ_NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "object not callable"); + mp_raise_TypeError("object not callable"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not callable", mp_obj_get_type_str(self_in))); @@ -826,7 +826,7 @@ STATIC mp_obj_t type_make_new(const mp_obj_type_t *type_in, size_t n_args, size_ return mp_obj_new_type(mp_obj_str_get_qstr(args[0]), args[1], args[2]); default: - mp_raise_msg(&mp_type_TypeError, "type takes 1 or 3 arguments"); + mp_raise_TypeError("type takes 1 or 3 arguments"); } } @@ -837,7 +837,7 @@ STATIC mp_obj_t type_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp if (self->make_new == NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "cannot create instance"); + mp_raise_TypeError("cannot create instance"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "cannot create '%q' instances", self->name)); @@ -925,7 +925,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) // TODO: Verify with CPy, tested on function type if (t->make_new == NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "type is not an acceptable base type"); + mp_raise_TypeError("type is not an acceptable base type"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "type '%q' is not an acceptable base type", t->name)); @@ -959,7 +959,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) const mp_obj_type_t *native_base; size_t num_native_bases = instance_count_native_bases(o, &native_base); if (num_native_bases > 1) { - mp_raise_msg(&mp_type_TypeError, "multiple bases have instance lay-out conflict"); + mp_raise_TypeError("multiple bases have instance lay-out conflict"); } mp_map_t *locals_map = &o->locals_dict->map; @@ -1106,7 +1106,7 @@ STATIC mp_obj_t mp_obj_is_subclass(mp_obj_t object, mp_obj_t classinfo) { } else if (MP_OBJ_IS_TYPE(classinfo, &mp_type_tuple)) { mp_obj_tuple_get(classinfo, &len, &items); } else { - mp_raise_msg(&mp_type_TypeError, "issubclass() arg 2 must be a class or a tuple of classes"); + mp_raise_TypeError("issubclass() arg 2 must be a class or a tuple of classes"); } for (size_t i = 0; i < len; i++) { @@ -1120,7 +1120,7 @@ STATIC mp_obj_t mp_obj_is_subclass(mp_obj_t object, mp_obj_t classinfo) { STATIC mp_obj_t mp_builtin_issubclass(mp_obj_t object, mp_obj_t classinfo) { if (!MP_OBJ_IS_TYPE(object, &mp_type_type)) { - mp_raise_msg(&mp_type_TypeError, "issubclass() arg 1 must be a class"); + mp_raise_TypeError("issubclass() arg 1 must be a class"); } return mp_obj_is_subclass(object, classinfo); } diff --git a/py/parsenum.c b/py/parsenum.c index 2e41801ee..177118843 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -55,7 +55,7 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m // check radix base if ((base != 0 && base < 2) || base > 36) { // this won't be reached if lex!=NULL - mp_raise_msg(&mp_type_ValueError, "int() arg 2 must be >= 2 and <= 36"); + mp_raise_ValueError("int() arg 2 must be >= 2 and <= 36"); } // skip leading space diff --git a/py/runtime.c b/py/runtime.c index 13dffc4ad..9f6c654ab 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -252,7 +252,7 @@ mp_obj_t mp_unary_op(mp_uint_t op, mp_obj_t arg) { } } if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "unsupported type for operator"); + mp_raise_TypeError("unsupported type for operator"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unsupported type for %q: '%s'", @@ -344,7 +344,7 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { case MP_BINARY_OP_INPLACE_LSHIFT: { if (rhs_val < 0) { // negative shift not allowed - mp_raise_msg(&mp_type_ValueError, "negative shift count"); + mp_raise_ValueError("negative shift count"); } else if (rhs_val >= (mp_int_t)BITS_PER_WORD || lhs_val > (MP_SMALL_INT_MAX >> rhs_val) || lhs_val < (MP_SMALL_INT_MIN >> rhs_val)) { // left-shift will overflow, so use higher precision integer lhs = mp_obj_new_int_from_ll(lhs_val); @@ -359,7 +359,7 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { case MP_BINARY_OP_INPLACE_RSHIFT: if (rhs_val < 0) { // negative shift not allowed - mp_raise_msg(&mp_type_ValueError, "negative shift count"); + mp_raise_ValueError("negative shift count"); } else { // standard precision is enough for right-shift if (rhs_val >= (mp_int_t)BITS_PER_WORD) { @@ -435,7 +435,7 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { lhs = mp_obj_new_float(lhs_val); goto generic_binary_op; #else - mp_raise_msg(&mp_type_ValueError, "negative power with no float support"); + mp_raise_ValueError("negative power with no float support"); #endif } else { mp_int_t ans = 1; @@ -537,7 +537,7 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { } if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "object not iterable"); + mp_raise_TypeError("object not iterable"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not iterable", mp_obj_get_type_str(rhs))); @@ -559,7 +559,7 @@ generic_binary_op: unsupported_op: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "unsupported type for operator"); + mp_raise_TypeError("unsupported type for operator"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unsupported types for %q: '%s', '%s'", @@ -601,7 +601,7 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, size_t n_args, size_t n_kw, cons } if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "object not callable"); + mp_raise_TypeError("object not callable"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not callable", mp_obj_get_type_str(fun_in))); @@ -830,14 +830,14 @@ void mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items) { too_short: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_ValueError, "wrong number of values to unpack"); + mp_raise_ValueError("wrong number of values to unpack"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "need more than %d values to unpack", (int)seq_len)); } too_long: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_ValueError, "wrong number of values to unpack"); + mp_raise_ValueError("wrong number of values to unpack"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "too many values to unpack (expected %d)", (int)num)); @@ -894,7 +894,7 @@ void mp_unpack_ex(mp_obj_t seq_in, size_t num_in, mp_obj_t *items) { too_short: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_ValueError, "wrong number of values to unpack"); + mp_raise_ValueError("wrong number of values to unpack"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "need more than %d values to unpack", (int)seq_len)); @@ -933,7 +933,7 @@ STATIC mp_obj_t checked_fun_call(mp_obj_t self_in, size_t n_args, size_t n_kw, c const mp_obj_type_t *arg0_type = mp_obj_get_type(args[0]); if (arg0_type != self->type) { if (MICROPY_ERROR_REPORTING != MICROPY_ERROR_REPORTING_DETAILED) { - mp_raise_msg(&mp_type_TypeError, "argument has wrong type"); + mp_raise_TypeError("argument has wrong type"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "argument should be a '%q' not a '%q'", self->type->name, arg0_type->name)); @@ -1124,7 +1124,7 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) { // object not iterable if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "object not iterable"); + mp_raise_TypeError("object not iterable"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not iterable", mp_obj_get_type_str(o_in))); @@ -1146,7 +1146,7 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) { return mp_call_method_n_kw(0, 0, dest); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "object not an iterator"); + mp_raise_TypeError("object not an iterator"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not an iterator", mp_obj_get_type_str(o_in))); @@ -1182,7 +1182,7 @@ mp_obj_t mp_iternext(mp_obj_t o_in) { } } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "object not an iterator"); + mp_raise_TypeError("object not an iterator"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not an iterator", mp_obj_get_type_str(o_in))); diff --git a/py/sequence.c b/py/sequence.c index 11761f651..cd1a96617 100644 --- a/py/sequence.c +++ b/py/sequence.c @@ -256,7 +256,7 @@ mp_obj_t mp_seq_index_obj(const mp_obj_t *items, size_t len, size_t n_args, cons } } - mp_raise_msg(&mp_type_ValueError, "object not in sequence"); + mp_raise_ValueError("object not in sequence"); } mp_obj_t mp_seq_count_obj(const mp_obj_t *items, size_t len, mp_obj_t value) { -- cgit v1.2.3 From 18c059febfd713271155d25a3a28661e8911ef8d Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 29 Mar 2017 12:36:46 +1100 Subject: py: Shorten a couple of error messages. --- py/compile.c | 2 +- py/objdict.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'py/objdict.c') diff --git a/py/compile.c b/py/compile.c index 1f9eb84fe..4fe59853c 100644 --- a/py/compile.c +++ b/py/compile.c @@ -1524,7 +1524,7 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_ if (MP_PARSE_NODE_IS_NULL(pns_except->nodes[0])) { // this is a catch all exception handler if (i + 1 != n_except) { - compile_syntax_error(comp, pn_excepts[i], "default 'except:' must be last"); + compile_syntax_error(comp, pn_excepts[i], "default 'except' must be last"); compile_decrease_except_level(comp); return; } diff --git a/py/objdict.c b/py/objdict.c index 5f84d71c7..f6929d23f 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -386,7 +386,7 @@ STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwarg if (key == MP_OBJ_STOP_ITERATION || value == MP_OBJ_STOP_ITERATION || stop != MP_OBJ_STOP_ITERATION) { - mp_raise_ValueError("dictionary update sequence has the wrong length"); + mp_raise_ValueError("dict update sequence has wrong length"); } else { mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; } -- cgit v1.2.3 From 816413e4b20ccd463321558458bb63c310712bca Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 6 Apr 2017 12:09:01 +1000 Subject: py: Optimise types for common case where type has a single parent type. The common cases for inheritance are 0 or 1 parent types, for both built-in types (eg built-in exceptions) as well as user defined types. So it makes sense to optimise the case of 1 parent type by storing just the type and not a tuple of 1 value (that value being the single parent type). This patch makes such an optimisation. Even though there is a bit more code to handle the two cases (either a single type or a tuple with 2 or more values) it helps reduce overall code size because it eliminates the need to create a static tuple to hold single parents (eg for the built-in exceptions). It also helps reduce RAM usage for user defined types that only derive from a single parent. Changes in code size (in bytes) due to this patch: bare-arm: -16 minimal (x86): -176 unix (x86-64): -320 unix nanbox: -384 stmhal: -64 cc3200: -32 esp8266: -108 --- py/obj.h | 7 ++- py/objdict.c | 4 +- py/objexcept.c | 17 +----- py/objnamedtuple.c | 4 +- py/objtype.c | 166 ++++++++++++++++++++++++++++++----------------------- 5 files changed, 102 insertions(+), 96 deletions(-) (limited to 'py/objdict.c') diff --git a/py/obj.h b/py/obj.h index 45579ce8f..597c7c8d9 100644 --- a/py/obj.h +++ b/py/obj.h @@ -525,8 +525,11 @@ struct _mp_obj_type_t { // One of disjoint protocols (interfaces), like mp_stream_p_t, etc. const void *protocol; - // A tuple containing all the base types of this type. - struct _mp_obj_tuple_t *bases_tuple; + // A pointer to the parents of this type: + // - 0 parents: pointer is NULL (object is implicitly the single parent) + // - 1 parent: a pointer to the type of that parent + // - 2 or more parents: pointer to a tuple object containing the parent types + const void *parent; // A dict mapping qstrs to objects local methods/constants/etc. struct _mp_obj_dict_t *locals_dict; diff --git a/py/objdict.c b/py/objdict.c index f6929d23f..12ba61b2e 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -577,8 +577,6 @@ const mp_obj_type_t mp_type_dict = { }; #if MICROPY_PY_COLLECTIONS_ORDEREDDICT -STATIC const mp_rom_obj_tuple_t ordereddict_base_tuple = {{&mp_type_tuple}, 1, {MP_ROM_PTR(&mp_type_dict)}}; - const mp_obj_type_t mp_type_ordereddict = { { &mp_type_type }, .name = MP_QSTR_OrderedDict, @@ -588,7 +586,7 @@ const mp_obj_type_t mp_type_ordereddict = { .binary_op = dict_binary_op, .subscr = dict_subscr, .getiter = dict_getiter, - .bases_tuple = (mp_obj_tuple_t*)(mp_rom_obj_tuple_t*)&ordereddict_base_tuple, + .parent = &mp_type_dict, .locals_dict = (mp_obj_dict_t*)&dict_locals_dict, }; #endif diff --git a/py/objexcept.c b/py/objexcept.c index dcc7800dc..4722aca91 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -197,9 +197,6 @@ const mp_obj_type_t mp_type_BaseException = { .locals_dict = (mp_obj_dict_t*)&exc_locals_dict, }; -#define MP_DEFINE_EXCEPTION_BASE(base_name) \ -STATIC const mp_rom_obj_tuple_t mp_type_ ## base_name ## _base_tuple = {{&mp_type_tuple}, 1, {MP_ROM_PTR(&mp_type_ ## base_name)}};\ - #define MP_DEFINE_EXCEPTION(exc_name, base_name) \ const mp_obj_type_t mp_type_ ## exc_name = { \ { &mp_type_type }, \ @@ -207,23 +204,20 @@ const mp_obj_type_t mp_type_ ## exc_name = { \ .print = mp_obj_exception_print, \ .make_new = mp_obj_exception_make_new, \ .attr = exception_attr, \ - .bases_tuple = (mp_obj_tuple_t*)(mp_rom_obj_tuple_t*)&mp_type_ ## base_name ## _base_tuple, \ + .parent = &mp_type_ ## base_name, \ }; // List of all exceptions, arranged as in the table at: // http://docs.python.org/3/library/exceptions.html -MP_DEFINE_EXCEPTION_BASE(BaseException) MP_DEFINE_EXCEPTION(SystemExit, BaseException) MP_DEFINE_EXCEPTION(KeyboardInterrupt, BaseException) MP_DEFINE_EXCEPTION(GeneratorExit, BaseException) MP_DEFINE_EXCEPTION(Exception, BaseException) - MP_DEFINE_EXCEPTION_BASE(Exception) #if MICROPY_PY_ASYNC_AWAIT MP_DEFINE_EXCEPTION(StopAsyncIteration, Exception) #endif MP_DEFINE_EXCEPTION(StopIteration, Exception) MP_DEFINE_EXCEPTION(ArithmeticError, Exception) - MP_DEFINE_EXCEPTION_BASE(ArithmeticError) //MP_DEFINE_EXCEPTION(FloatingPointError, ArithmeticError) MP_DEFINE_EXCEPTION(OverflowError, ArithmeticError) MP_DEFINE_EXCEPTION(ZeroDivisionError, ArithmeticError) @@ -235,18 +229,15 @@ MP_DEFINE_EXCEPTION(Exception, BaseException) MP_DEFINE_EXCEPTION(ImportError, Exception) //MP_DEFINE_EXCEPTION(IOError, Exception) use OSError instead MP_DEFINE_EXCEPTION(LookupError, Exception) - MP_DEFINE_EXCEPTION_BASE(LookupError) MP_DEFINE_EXCEPTION(IndexError, LookupError) MP_DEFINE_EXCEPTION(KeyError, LookupError) MP_DEFINE_EXCEPTION(MemoryError, Exception) MP_DEFINE_EXCEPTION(NameError, Exception) /* - MP_DEFINE_EXCEPTION_BASE(NameError) MP_DEFINE_EXCEPTION(UnboundLocalError, NameError) */ MP_DEFINE_EXCEPTION(OSError, Exception) #if MICROPY_PY_BUILTINS_TIMEOUTERROR - MP_DEFINE_EXCEPTION_BASE(OSError) MP_DEFINE_EXCEPTION(TimeoutError, OSError) #endif /* @@ -267,30 +258,24 @@ MP_DEFINE_EXCEPTION(Exception, BaseException) MP_DEFINE_EXCEPTION(ReferenceError, Exception) */ MP_DEFINE_EXCEPTION(RuntimeError, Exception) - MP_DEFINE_EXCEPTION_BASE(RuntimeError) MP_DEFINE_EXCEPTION(NotImplementedError, RuntimeError) MP_DEFINE_EXCEPTION(SyntaxError, Exception) - MP_DEFINE_EXCEPTION_BASE(SyntaxError) MP_DEFINE_EXCEPTION(IndentationError, SyntaxError) /* - MP_DEFINE_EXCEPTION_BASE(IndentationError) MP_DEFINE_EXCEPTION(TabError, IndentationError) */ //MP_DEFINE_EXCEPTION(SystemError, Exception) MP_DEFINE_EXCEPTION(TypeError, Exception) #if MICROPY_EMIT_NATIVE - MP_DEFINE_EXCEPTION_BASE(TypeError) MP_DEFINE_EXCEPTION(ViperTypeError, TypeError) #endif MP_DEFINE_EXCEPTION(ValueError, Exception) #if MICROPY_PY_BUILTINS_STR_UNICODE - MP_DEFINE_EXCEPTION_BASE(ValueError) MP_DEFINE_EXCEPTION(UnicodeError, ValueError) //TODO: Implement more UnicodeError subclasses which take arguments #endif /* MP_DEFINE_EXCEPTION(Warning, Exception) - MP_DEFINE_EXCEPTION_BASE(Warning) MP_DEFINE_EXCEPTION(DeprecationWarning, Warning) MP_DEFINE_EXCEPTION(PendingDeprecationWarning, Warning) MP_DEFINE_EXCEPTION(RuntimeWarning, Warning) diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index 52468747b..cbd845dce 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -134,8 +134,6 @@ STATIC mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, return MP_OBJ_FROM_PTR(tuple); } -STATIC const mp_rom_obj_tuple_t namedtuple_base_tuple = {{&mp_type_tuple}, 1, {MP_ROM_PTR(&mp_type_tuple)}}; - STATIC mp_obj_t mp_obj_new_namedtuple_type(qstr name, size_t n_fields, mp_obj_t *fields) { mp_obj_namedtuple_type_t *o = m_new_obj_var(mp_obj_namedtuple_type_t, qstr, n_fields); memset(&o->base, 0, sizeof(o->base)); @@ -148,7 +146,7 @@ STATIC mp_obj_t mp_obj_new_namedtuple_type(qstr name, size_t n_fields, mp_obj_t o->base.attr = namedtuple_attr; o->base.subscr = mp_obj_tuple_subscr; o->base.getiter = mp_obj_tuple_getiter; - o->base.bases_tuple = (mp_obj_tuple_t*)(mp_rom_obj_tuple_t*)&namedtuple_base_tuple; + o->base.parent = &mp_type_tuple; o->n_fields = n_fields; for (size_t i = 0; i < n_fields; i++) { o->fields[i] = mp_obj_str_get_qstr(fields[i]); diff --git a/py/objtype.c b/py/objtype.c index dd170b4c6..5e522bed2 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -57,26 +57,34 @@ STATIC mp_obj_t mp_obj_new_instance(const mp_obj_type_t *class, size_t subobjs) } STATIC int instance_count_native_bases(const mp_obj_type_t *type, const mp_obj_type_t **last_native_base) { - size_t len = type->bases_tuple->len; - mp_obj_t *items = type->bases_tuple->items; - int count = 0; - for (size_t i = 0; i < len; i++) { - assert(MP_OBJ_IS_TYPE(items[i], &mp_type_type)); - const mp_obj_type_t *bt = (const mp_obj_type_t *)MP_OBJ_TO_PTR(items[i]); - if (bt == &mp_type_object) { - // Not a "real" type - continue; - } - if (mp_obj_is_native_type(bt)) { - *last_native_base = bt; - count++; + for (;;) { + if (type == &mp_type_object) { + // Not a "real" type, end search here. + return count; + } else if (mp_obj_is_native_type(type)) { + // 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) { + // No parents so end search here. + return count; + } else if (((mp_obj_base_t*)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_t *item = parent_tuple->items; + const mp_obj_t *top = item + parent_tuple->len; + for (; item < top; ++item) { + assert(MP_OBJ_IS_TYPE(*item, &mp_type_type)); + const mp_obj_type_t *bt = (const mp_obj_type_t *)MP_OBJ_TO_PTR(*item); + count += instance_count_native_bases(bt, last_native_base); + } + return count; } else { - count += instance_count_native_bases(bt, last_native_base); + // A single parent, use iteration to continue the search. + type = type->parent; } } - - return count; } // TODO @@ -160,32 +168,31 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_ // attribute not found, keep searching base classes - // for a const struct, this entry might be NULL - if (type->bases_tuple == NULL) { - return; - } - - size_t len = type->bases_tuple->len; - mp_obj_t *items = type->bases_tuple->items; - if (len == 0) { + if (type->parent == NULL) { return; - } - for (size_t i = 0; i < len - 1; i++) { - assert(MP_OBJ_IS_TYPE(items[i], &mp_type_type)); - mp_obj_type_t *bt = (mp_obj_type_t*)MP_OBJ_TO_PTR(items[i]); - if (bt == &mp_type_object) { - // Not a "real" type - continue; - } - mp_obj_class_lookup(lookup, bt); - if (lookup->dest[0] != MP_OBJ_NULL) { - return; + } else if (((mp_obj_base_t*)type->parent)->type == &mp_type_tuple) { + const mp_obj_tuple_t *parent_tuple = type->parent; + const mp_obj_t *item = parent_tuple->items; + const mp_obj_t *top = item + parent_tuple->len - 1; + for (; item < top; ++item) { + assert(MP_OBJ_IS_TYPE(*item, &mp_type_type)); + mp_obj_type_t *bt = (mp_obj_type_t*)MP_OBJ_TO_PTR(*item); + if (bt == &mp_type_object) { + // Not a "real" type + continue; + } + mp_obj_class_lookup(lookup, bt); + if (lookup->dest[0] != MP_OBJ_NULL) { + return; + } } - } - // search last base (simple tail recursion elimination) - assert(MP_OBJ_IS_TYPE(items[len - 1], &mp_type_type)); - type = (mp_obj_type_t*)MP_OBJ_TO_PTR(items[len - 1]); + // search last base (simple tail recursion elimination) + assert(MP_OBJ_IS_TYPE(*item, &mp_type_type)); + type = (mp_obj_type_t*)MP_OBJ_TO_PTR(*item); + } else { + type = type->parent; + } if (type == &mp_type_object) { // Not a "real" type return; @@ -946,14 +953,21 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) o->getiter = instance_getiter; //o->iternext = ; not implemented o->buffer_p.get_buffer = instance_get_buffer; - // 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. + if (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(items[0]))->protocol; + + if (len >= 2) { + o->parent = MP_OBJ_TO_PTR(bases_tuple); + } else { + o->parent = MP_OBJ_TO_PTR(items[0]); + } } - o->bases_tuple = MP_OBJ_TO_PTR(bases_tuple); + o->locals_dict = MP_OBJ_TO_PTR(locals_dict); const mp_obj_type_t *native_base; @@ -1015,13 +1029,6 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { mp_obj_type_t *type = MP_OBJ_TO_PTR(self->type); - // for a const struct, this entry might be NULL - if (type->bases_tuple == NULL) { - return; - } - - size_t len = type->bases_tuple->len; - mp_obj_t *items = type->bases_tuple->items; struct class_lookup_data lookup = { .obj = MP_OBJ_TO_PTR(self->obj), .attr = attr, @@ -1029,13 +1036,27 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { .dest = dest, .is_type = false, }; - for (size_t i = 0; i < len; i++) { - assert(MP_OBJ_IS_TYPE(items[i], &mp_type_type)); - mp_obj_class_lookup(&lookup, (mp_obj_type_t*)MP_OBJ_TO_PTR(items[i])); + + if (type->parent == NULL) { + // no parents, do nothing + } else if (((mp_obj_base_t*)type->parent)->type == &mp_type_tuple) { + const mp_obj_tuple_t *parent_tuple = type->parent; + size_t len = parent_tuple->len; + const mp_obj_t *items = parent_tuple->items; + for (size_t i = 0; i < len; i++) { + assert(MP_OBJ_IS_TYPE(items[i], &mp_type_type)); + mp_obj_class_lookup(&lookup, (mp_obj_type_t*)MP_OBJ_TO_PTR(items[i])); + if (dest[0] != MP_OBJ_NULL) { + return; + } + } + } else { + mp_obj_class_lookup(&lookup, type->parent); if (dest[0] != MP_OBJ_NULL) { return; } } + mp_obj_class_lookup(&lookup, &mp_type_object); } @@ -1073,27 +1094,28 @@ 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); - // for a const struct, this entry might be NULL - if (self->bases_tuple == NULL) { - return false; - } - - // get the base objects (they should be type objects) - size_t len = self->bases_tuple->len; - mp_obj_t *items = self->bases_tuple->items; - if (len == 0) { + if (self->parent == NULL) { + // type has no parents return false; - } - - // iterate through the base objects - for (size_t i = 0; i < len - 1; i++) { - if (mp_obj_is_subclass_fast(items[i], classinfo)) { - return true; + } else if (((mp_obj_base_t*)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_t *item = parent_tuple->items; + const mp_obj_t *top = item + parent_tuple->len - 1; + + // iterate through the base objects + for (; item < top; ++item) { + if (mp_obj_is_subclass_fast(*item, classinfo)) { + return true; + } } - } - // search last base (simple tail recursion elimination) - object = items[len - 1]; + // search last base (simple tail recursion elimination) + object = *item; + } else { + // type has 1 parent + object = MP_OBJ_FROM_PTR(self->parent); + } } } -- cgit v1.2.3