From af622eb2a6aa50429eb64716e754ee58c3f87c2e Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 8 Feb 2017 11:00:15 +1100 Subject: py/map: Change mp_uint_t to size_t where appropriate. The internal map/set functions now use size_t exclusively for computing addresses. size_t is enough to reach all of available memory when computing addresses so is the right type to use. In particular, for nanbox builds it saves quite a bit of code size and RAM compared to the original use of mp_uint_t (which is 64-bits on nanbox builds). --- py/obj.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'py/obj.h') diff --git a/py/obj.h b/py/obj.h index 6106bbe19..071e38502 100644 --- a/py/obj.h +++ b/py/obj.h @@ -353,11 +353,11 @@ typedef struct _mp_rom_map_elem_t { // would also need a trucated dict structure typedef struct _mp_map_t { - mp_uint_t all_keys_are_qstrs : 1; - mp_uint_t is_fixed : 1; // a fixed array that can't be modified; must also be ordered - mp_uint_t is_ordered : 1; // an ordered array - mp_uint_t used : (8 * sizeof(mp_uint_t) - 3); - mp_uint_t alloc; + size_t all_keys_are_qstrs : 1; + size_t is_fixed : 1; // a fixed array that can't be modified; must also be ordered + size_t is_ordered : 1; // an ordered array + size_t used : (8 * sizeof(size_t) - 3); + size_t alloc; mp_map_elem_t *table; } mp_map_t; @@ -371,11 +371,11 @@ typedef enum _mp_map_lookup_kind_t { extern const mp_map_t mp_const_empty_map; -static inline bool MP_MAP_SLOT_IS_FILLED(const mp_map_t *map, mp_uint_t pos) { return ((map)->table[pos].key != MP_OBJ_NULL && (map)->table[pos].key != MP_OBJ_SENTINEL); } +static inline bool MP_MAP_SLOT_IS_FILLED(const mp_map_t *map, size_t pos) { return ((map)->table[pos].key != MP_OBJ_NULL && (map)->table[pos].key != MP_OBJ_SENTINEL); } -void mp_map_init(mp_map_t *map, mp_uint_t n); -void mp_map_init_fixed_table(mp_map_t *map, mp_uint_t n, const mp_obj_t *table); -mp_map_t *mp_map_new(mp_uint_t n); +void mp_map_init(mp_map_t *map, size_t n); +void mp_map_init_fixed_table(mp_map_t *map, size_t n, const mp_obj_t *table); +mp_map_t *mp_map_new(size_t n); void mp_map_deinit(mp_map_t *map); void mp_map_free(mp_map_t *map); mp_map_elem_t *mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind); @@ -385,14 +385,14 @@ void mp_map_dump(mp_map_t *map); // Underlying set implementation (not set object) typedef struct _mp_set_t { - mp_uint_t alloc; - mp_uint_t used; + size_t alloc; + size_t used; mp_obj_t *table; } mp_set_t; -static inline bool MP_SET_SLOT_IS_FILLED(const mp_set_t *set, mp_uint_t pos) { return ((set)->table[pos] != MP_OBJ_NULL && (set)->table[pos] != MP_OBJ_SENTINEL); } +static inline bool MP_SET_SLOT_IS_FILLED(const mp_set_t *set, size_t pos) { return ((set)->table[pos] != MP_OBJ_NULL && (set)->table[pos] != MP_OBJ_SENTINEL); } -void mp_set_init(mp_set_t *set, mp_uint_t n); +void mp_set_init(mp_set_t *set, size_t n); mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, mp_map_lookup_kind_t lookup_kind); mp_obj_t mp_set_remove_first(mp_set_t *set); void mp_set_clear(mp_set_t *set); -- cgit v1.2.3 From 229823942c79b1233c43dc155bae01c20a8cec57 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 16 Feb 2017 16:09:51 +1100 Subject: py/objtuple: Convert mp_uint_t to size_t where appropriate. --- py/obj.h | 2 +- py/objattrtuple.c | 10 +++++----- py/objtuple.c | 18 +++++++++--------- py/objtuple.h | 6 +++--- 4 files changed, 18 insertions(+), 18 deletions(-) (limited to 'py/obj.h') diff --git a/py/obj.h b/py/obj.h index 071e38502..95b6ec411 100644 --- a/py/obj.h +++ b/py/obj.h @@ -630,7 +630,7 @@ mp_obj_t mp_obj_new_fun_viper(mp_uint_t n_args, void *fun_data, mp_uint_t type_s mp_obj_t mp_obj_new_fun_asm(mp_uint_t n_args, void *fun_data, mp_uint_t type_sig); mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun); mp_obj_t mp_obj_new_closure(mp_obj_t fun, mp_uint_t n_closed, const mp_obj_t *closed); -mp_obj_t mp_obj_new_tuple(mp_uint_t n, const mp_obj_t *items); +mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items); mp_obj_t mp_obj_new_list(mp_uint_t n, mp_obj_t *items); mp_obj_t mp_obj_new_dict(mp_uint_t n_args); mp_obj_t mp_obj_new_set(mp_uint_t n_args, mp_obj_t *items); diff --git a/py/objattrtuple.c b/py/objattrtuple.c index c6dd3aeac..8c5e79575 100644 --- a/py/objattrtuple.c +++ b/py/objattrtuple.c @@ -34,7 +34,7 @@ STATIC #endif void mp_obj_attrtuple_print_helper(const mp_print_t *print, const qstr *fields, mp_obj_tuple_t *o) { mp_print_str(print, "("); - for (mp_uint_t i = 0; i < o->len; i++) { + for (size_t i = 0; i < o->len; i++) { if (i > 0) { mp_print_str(print, ", "); } @@ -59,9 +59,9 @@ STATIC void mp_obj_attrtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { if (dest[0] == MP_OBJ_NULL) { // load attribute mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in); - mp_uint_t len = self->len; + size_t len = self->len; const qstr *fields = (const qstr*)MP_OBJ_TO_PTR(self->items[len]); - for (mp_uint_t i = 0; i < len; i++) { + for (size_t i = 0; i < len; i++) { if (fields[i] == attr) { dest[0] = self->items[i]; return; @@ -70,11 +70,11 @@ STATIC void mp_obj_attrtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } } -mp_obj_t mp_obj_new_attrtuple(const qstr *fields, mp_uint_t n, const mp_obj_t *items) { +mp_obj_t mp_obj_new_attrtuple(const qstr *fields, size_t n, const mp_obj_t *items) { mp_obj_tuple_t *o = m_new_obj_var(mp_obj_tuple_t, mp_obj_t, n + 1); o->base.type = &mp_type_attrtuple; o->len = n; - for (mp_uint_t i = 0; i < n; i++) { + for (size_t i = 0; i < n; i++) { o->items[i] = items[i]; } o->items[n] = MP_OBJ_FROM_PTR(fields); diff --git a/py/objtuple.c b/py/objtuple.c index c547da940..1935a6709 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -32,7 +32,7 @@ #include "py/runtime0.h" #include "py/runtime.h" -STATIC mp_obj_t mp_obj_new_tuple_iterator(mp_obj_tuple_t *tuple, mp_uint_t cur); +STATIC mp_obj_t mp_obj_new_tuple_iterator(mp_obj_tuple_t *tuple, size_t cur); /******************************************************************************/ /* tuple */ @@ -45,7 +45,7 @@ void mp_obj_tuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t mp_print_str(print, "("); kind = PRINT_REPR; } - for (mp_uint_t i = 0; i < o->len; i++) { + for (size_t i = 0; i < o->len; i++) { if (i > 0) { mp_print_str(print, ", "); } @@ -80,8 +80,8 @@ STATIC mp_obj_t mp_obj_tuple_make_new(const mp_obj_type_t *type_in, size_t n_arg // TODO optimise for cases where we know the length of the iterator - mp_uint_t alloc = 4; - mp_uint_t len = 0; + size_t alloc = 4; + size_t len = 0; mp_obj_t *items = m_new(mp_obj_t, alloc); mp_obj_t iterable = mp_getiter(args[0]); @@ -127,7 +127,7 @@ mp_obj_t mp_obj_tuple_unary_op(mp_uint_t op, mp_obj_t self_in) { case MP_UNARY_OP_HASH: { // start hash with pointer to empty tuple, to make it fairly unique mp_int_t hash = (mp_int_t)mp_const_empty_tuple; - for (mp_uint_t i = 0; i < self->len; i++) { + for (size_t i = 0; i < self->len; i++) { hash += MP_OBJ_SMALL_INT_VALUE(mp_unary_op(MP_UNARY_OP_HASH, self->items[i])); } return MP_OBJ_NEW_SMALL_INT(hash); @@ -235,7 +235,7 @@ const mp_obj_type_t mp_type_tuple = { // the zero-length tuple const mp_obj_tuple_t mp_const_empty_tuple_obj = {{&mp_type_tuple}, 0}; -mp_obj_t mp_obj_new_tuple(mp_uint_t n, const mp_obj_t *items) { +mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items) { if (n == 0) { return mp_const_empty_tuple; } @@ -243,7 +243,7 @@ mp_obj_t mp_obj_new_tuple(mp_uint_t n, const mp_obj_t *items) { o->base.type = &mp_type_tuple; o->len = n; if (items) { - for (mp_uint_t i = 0; i < n; i++) { + for (size_t i = 0; i < n; i++) { o->items[i] = items[i]; } } @@ -270,7 +270,7 @@ typedef struct _mp_obj_tuple_it_t { mp_obj_base_t base; mp_fun_1_t iternext; mp_obj_tuple_t *tuple; - mp_uint_t cur; + size_t cur; } mp_obj_tuple_it_t; STATIC mp_obj_t tuple_it_iternext(mp_obj_t self_in) { @@ -284,7 +284,7 @@ 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, mp_uint_t cur) { +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); o->base.type = &mp_type_polymorph_iter; o->iternext = tuple_it_iternext; diff --git a/py/objtuple.h b/py/objtuple.h index ebfc5c406..760135f86 100644 --- a/py/objtuple.h +++ b/py/objtuple.h @@ -30,13 +30,13 @@ typedef struct _mp_obj_tuple_t { mp_obj_base_t base; - mp_uint_t len; + size_t len; mp_obj_t items[]; } mp_obj_tuple_t; typedef struct _mp_rom_obj_tuple_t { mp_obj_base_t base; - mp_uint_t len; + size_t len; mp_rom_obj_t items[]; } mp_rom_obj_tuple_t; @@ -59,6 +59,6 @@ extern const mp_obj_type_t mp_type_attrtuple; void mp_obj_attrtuple_print_helper(const mp_print_t *print, const qstr *fields, mp_obj_tuple_t *o); #endif -mp_obj_t mp_obj_new_attrtuple(const qstr *fields, mp_uint_t n, const mp_obj_t *items); +mp_obj_t mp_obj_new_attrtuple(const qstr *fields, size_t n, const mp_obj_t *items); #endif // __MICROPY_INCLUDED_PY_OBJTUPLE_H__ -- cgit v1.2.3 From 58d9eeb8d940a6c42f904af70fa01e03c760d832 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 16 Feb 2017 16:12:41 +1100 Subject: py/objlist: Convert mp_uint_t to size_t where appropriate. --- py/obj.h | 6 +++--- py/objlist.c | 22 +++++++++++----------- py/objlist.h | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) (limited to 'py/obj.h') diff --git a/py/obj.h b/py/obj.h index 95b6ec411..fb35b67aa 100644 --- a/py/obj.h +++ b/py/obj.h @@ -631,7 +631,7 @@ mp_obj_t mp_obj_new_fun_asm(mp_uint_t n_args, void *fun_data, mp_uint_t type_sig mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun); mp_obj_t mp_obj_new_closure(mp_obj_t fun, mp_uint_t n_closed, const mp_obj_t *closed); mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items); -mp_obj_t mp_obj_new_list(mp_uint_t n, mp_obj_t *items); +mp_obj_t mp_obj_new_list(size_t n, mp_obj_t *items); mp_obj_t mp_obj_new_dict(mp_uint_t n_args); mp_obj_t mp_obj_new_set(mp_uint_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); @@ -720,11 +720,11 @@ mp_int_t mp_obj_tuple_hash(mp_obj_t self_in); // list struct _mp_obj_list_t; -void mp_obj_list_init(struct _mp_obj_list_t *o, mp_uint_t n); +void mp_obj_list_init(struct _mp_obj_list_t *o, size_t n); mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg); mp_obj_t mp_obj_list_remove(mp_obj_t self_in, mp_obj_t value); void mp_obj_list_get(mp_obj_t self_in, mp_uint_t *len, mp_obj_t **items); -void mp_obj_list_set_len(mp_obj_t self_in, mp_uint_t len); +void mp_obj_list_set_len(mp_obj_t self_in, size_t len); void mp_obj_list_store(mp_obj_t self_in, mp_obj_t index, mp_obj_t value); mp_obj_t mp_obj_list_sort(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs); diff --git a/py/objlist.c b/py/objlist.c index 6d4a20a50..210140388 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -33,8 +33,8 @@ #include "py/runtime.h" #include "py/stackctrl.h" -STATIC mp_obj_t mp_obj_new_list_iterator(mp_obj_t list, mp_uint_t cur); -STATIC mp_obj_list_t *list_new(mp_uint_t n); +STATIC mp_obj_t mp_obj_new_list_iterator(mp_obj_t list, size_t cur); +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); @@ -50,7 +50,7 @@ STATIC void list_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t k kind = PRINT_REPR; } mp_print_str(print, "["); - for (mp_uint_t i = 0; i < o->len; i++) { + for (size_t i = 0; i < o->len; i++) { if (i > 0) { mp_print_str(print, ", "); } @@ -374,7 +374,7 @@ STATIC mp_obj_t list_insert(mp_obj_t self_in, mp_obj_t idx, mp_obj_t obj) { if (index < 0) { index = 0; } - if ((mp_uint_t)index > self->len) { + if ((size_t)index > self->len) { index = self->len; } @@ -451,7 +451,7 @@ const mp_obj_type_t mp_type_list = { .locals_dict = (mp_obj_dict_t*)&list_locals_dict, }; -void mp_obj_list_init(mp_obj_list_t *o, mp_uint_t n) { +void mp_obj_list_init(mp_obj_list_t *o, size_t n) { o->base.type = &mp_type_list; o->alloc = n < LIST_MIN_ALLOC ? LIST_MIN_ALLOC : n; o->len = n; @@ -459,16 +459,16 @@ void mp_obj_list_init(mp_obj_list_t *o, mp_uint_t n) { mp_seq_clear(o->items, n, o->alloc, sizeof(*o->items)); } -STATIC mp_obj_list_t *list_new(mp_uint_t n) { +STATIC mp_obj_list_t *list_new(size_t n) { mp_obj_list_t *o = m_new_obj(mp_obj_list_t); mp_obj_list_init(o, n); return o; } -mp_obj_t mp_obj_new_list(mp_uint_t n, mp_obj_t *items) { +mp_obj_t mp_obj_new_list(size_t n, mp_obj_t *items) { mp_obj_list_t *o = list_new(n); if (items != NULL) { - for (mp_uint_t i = 0; i < n; i++) { + for (size_t i = 0; i < n; i++) { o->items[i] = items[i]; } } @@ -481,7 +481,7 @@ void mp_obj_list_get(mp_obj_t self_in, mp_uint_t *len, mp_obj_t **items) { *items = self->items; } -void mp_obj_list_set_len(mp_obj_t self_in, mp_uint_t len) { +void mp_obj_list_set_len(mp_obj_t self_in, size_t len) { // trust that the caller knows what it's doing // TODO realloc if len got much smaller than alloc mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in); @@ -501,7 +501,7 @@ typedef struct _mp_obj_list_it_t { mp_obj_base_t base; mp_fun_1_t iternext; mp_obj_t list; - mp_uint_t cur; + size_t cur; } mp_obj_list_it_t; STATIC mp_obj_t list_it_iternext(mp_obj_t self_in) { @@ -516,7 +516,7 @@ STATIC mp_obj_t list_it_iternext(mp_obj_t self_in) { } } -mp_obj_t mp_obj_new_list_iterator(mp_obj_t list, mp_uint_t cur) { +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); o->base.type = &mp_type_polymorph_iter; o->iternext = list_it_iternext; diff --git a/py/objlist.h b/py/objlist.h index 443ede574..5b2d216fc 100644 --- a/py/objlist.h +++ b/py/objlist.h @@ -30,8 +30,8 @@ typedef struct _mp_obj_list_t { mp_obj_base_t base; - mp_uint_t alloc; - mp_uint_t len; + size_t alloc; + size_t len; mp_obj_t *items; } mp_obj_list_t; -- cgit v1.2.3 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/obj.h | 6 +++--- py/objdict.c | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 17 deletions(-) (limited to 'py/obj.h') diff --git a/py/obj.h b/py/obj.h index fb35b67aa..ab0410750 100644 --- a/py/obj.h +++ b/py/obj.h @@ -632,7 +632,7 @@ mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun); mp_obj_t mp_obj_new_closure(mp_obj_t fun, mp_uint_t n_closed, const mp_obj_t *closed); mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items); mp_obj_t mp_obj_new_list(size_t n, mp_obj_t *items); -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_t mp_obj_new_set(mp_uint_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); @@ -733,8 +733,8 @@ typedef struct _mp_obj_dict_t { mp_obj_base_t base; mp_map_t map; } mp_obj_dict_t; -void mp_obj_dict_init(mp_obj_dict_t *dict, mp_uint_t n_args); -mp_uint_t mp_obj_dict_len(mp_obj_t self_in); +void mp_obj_dict_init(mp_obj_dict_t *dict, size_t n_args); +size_t mp_obj_dict_len(mp_obj_t self_in); mp_obj_t mp_obj_dict_get(mp_obj_t self_in, mp_obj_t index); mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value); mp_obj_t mp_obj_dict_delete(mp_obj_t self_in, mp_obj_t key); 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 68cd3a93f0728b61b0d2407f4ae802806dddce4d Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 16 Feb 2017 16:16:33 +1100 Subject: py/objset: Convert mp_uint_t to size_t where appropriate. --- py/obj.h | 2 +- py/objset.c | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'py/obj.h') diff --git a/py/obj.h b/py/obj.h index ab0410750..2d0262442 100644 --- a/py/obj.h +++ b/py/obj.h @@ -633,7 +633,7 @@ mp_obj_t mp_obj_new_closure(mp_obj_t fun, mp_uint_t n_closed, const mp_obj_t *cl mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items); mp_obj_t mp_obj_new_list(size_t n, mp_obj_t *items); mp_obj_t mp_obj_new_dict(size_t n_args); -mp_obj_t mp_obj_new_set(mp_uint_t n_args, mp_obj_t *items); +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); diff --git a/py/objset.c b/py/objset.c index 778bbe15b..b9da44a44 100644 --- a/py/objset.c +++ b/py/objset.c @@ -44,7 +44,7 @@ typedef struct _mp_obj_set_it_t { mp_obj_base_t base; mp_fun_1_t iternext; mp_obj_set_t *set; - mp_uint_t cur; + size_t cur; } mp_obj_set_it_t; STATIC mp_obj_t set_it_iternext(mp_obj_t self_in); @@ -96,7 +96,7 @@ STATIC void set_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t } #endif mp_print_str(print, "{"); - for (mp_uint_t i = 0; i < self->set.alloc; i++) { + for (size_t i = 0; i < self->set.alloc; i++) { if (MP_SET_SLOT_IS_FILLED(&self->set, i)) { if (!first) { mp_print_str(print, ", "); @@ -143,10 +143,10 @@ STATIC mp_obj_t set_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_ STATIC mp_obj_t set_it_iternext(mp_obj_t self_in) { mp_obj_set_it_t *self = MP_OBJ_TO_PTR(self_in); - mp_uint_t max = self->set->set.alloc; + size_t max = self->set->set.alloc; mp_set_t *set = &self->set->set; - for (mp_uint_t i = self->cur; i < max; i++) { + for (size_t i = self->cur; i < max; i++) { if (MP_SET_SLOT_IS_FILLED(set, i)) { self->cur = i + 1; return set->table[i]; @@ -228,7 +228,7 @@ STATIC mp_obj_t set_diff_int(size_t n_args, const mp_obj_t *args, bool update) { } - for (mp_uint_t i = 1; i < n_args; i++) { + for (size_t i = 1; i < n_args; i++) { mp_obj_t other = args[i]; if (self == other) { set_clear(self); @@ -436,7 +436,7 @@ STATIC void set_update_int(mp_obj_set_t *self, mp_obj_t other_in) { STATIC mp_obj_t set_update(size_t n_args, const mp_obj_t *args) { check_set(args[0]); - for (mp_uint_t i = 1; i < n_args; i++) { + for (size_t i = 1; i < n_args; i++) { set_update_int(MP_OBJ_TO_PTR(args[0]), args[i]); } @@ -462,10 +462,10 @@ STATIC mp_obj_t set_unary_op(mp_uint_t op, mp_obj_t self_in) { if (MP_OBJ_IS_TYPE(self_in, &mp_type_frozenset)) { // start hash with unique value mp_int_t hash = (mp_int_t)(uintptr_t)&mp_type_frozenset; - mp_uint_t max = self->set.alloc; + size_t max = self->set.alloc; mp_set_t *set = &self->set; - for (mp_uint_t i = 0; i < max; i++) { + for (size_t i = 0; i < max; i++) { if (MP_SET_SLOT_IS_FILLED(set, i)) { hash += MP_OBJ_SMALL_INT_VALUE(mp_unary_op(MP_UNARY_OP_HASH, set->table[i])); } @@ -587,11 +587,11 @@ const mp_obj_type_t mp_type_frozenset = { }; #endif -mp_obj_t mp_obj_new_set(mp_uint_t n_args, mp_obj_t *items) { +mp_obj_t mp_obj_new_set(size_t n_args, mp_obj_t *items) { mp_obj_set_t *o = m_new_obj(mp_obj_set_t); o->base.type = &mp_type_set; mp_set_init(&o->set, n_args); - for (mp_uint_t i = 0; i < n_args; i++) { + for (size_t i = 0; i < n_args; i++) { mp_set_lookup(&o->set, items[i], MP_MAP_LOOKUP_ADD_IF_NOT_FOUND); } return MP_OBJ_FROM_PTR(o); -- cgit v1.2.3 From c0d9500eeefe57076f2f9a36afaa80186e9e30be Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 16 Feb 2017 16:26:48 +1100 Subject: py/objstr: Convert mp_uint_t to size_t (and use int) where appropriate. --- py/obj.h | 6 +++--- py/objstr.c | 54 +++++++++++++++++++++++++++--------------------------- py/objstr.h | 4 ++-- py/objstrunicode.c | 2 +- 4 files changed, 33 insertions(+), 33 deletions(-) (limited to 'py/obj.h') diff --git a/py/obj.h b/py/obj.h index 2d0262442..efb923413 100644 --- a/py/obj.h +++ b/py/obj.h @@ -610,9 +610,9 @@ mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value); mp_obj_t mp_obj_new_int_from_str_len(const char **str, mp_uint_t len, bool neg, mp_uint_t base); mp_obj_t mp_obj_new_int_from_ll(long long val); // this must return a multi-precision integer object (or raise an overflow exception) mp_obj_t mp_obj_new_int_from_ull(unsigned long long val); // this must return a multi-precision integer object (or raise an overflow exception) -mp_obj_t mp_obj_new_str(const char* data, mp_uint_t len, bool make_qstr_if_not_already); +mp_obj_t mp_obj_new_str(const char* data, size_t len, bool make_qstr_if_not_already); mp_obj_t mp_obj_new_str_from_vstr(const mp_obj_type_t *type, vstr_t *vstr); -mp_obj_t mp_obj_new_bytes(const byte* data, mp_uint_t len); +mp_obj_t mp_obj_new_bytes(const byte* data, size_t len); mp_obj_t mp_obj_new_bytearray(mp_uint_t n, void *items); mp_obj_t mp_obj_new_bytearray_by_ref(mp_uint_t n, void *items); #if MICROPY_PY_BUILTINS_FLOAT @@ -700,7 +700,7 @@ qstr mp_obj_str_get_qstr(mp_obj_t self_in); // use this if you will anyway conve const char *mp_obj_str_get_str(mp_obj_t self_in); // use this only if you need the string to be null terminated const char *mp_obj_str_get_data(mp_obj_t self_in, mp_uint_t *len); mp_obj_t mp_obj_str_intern(mp_obj_t str); -void mp_str_print_quoted(const mp_print_t *print, const byte *str_data, mp_uint_t str_len, bool is_bytes); +void mp_str_print_quoted(const mp_print_t *print, const byte *str_data, size_t str_len, bool is_bytes); #if MICROPY_PY_BUILTINS_FLOAT // float diff --git a/py/objstr.c b/py/objstr.c index b437d9795..262b89ddd 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -44,7 +44,7 @@ STATIC NORETURN void bad_implicit_conversion(mp_obj_t self_in); /******************************************************************************/ /* str */ -void mp_str_print_quoted(const mp_print_t *print, const byte *str_data, mp_uint_t str_len, bool is_bytes) { +void mp_str_print_quoted(const mp_print_t *print, const byte *str_data, size_t str_len, bool is_bytes) { // this escapes characters, but it will be very slow to print (calling print many times) bool has_single_quote = false; bool has_double_quote = false; @@ -251,9 +251,9 @@ wrong_args: // like strstr but with specified length and allows \0 bytes // TODO replace with something more efficient/standard -const byte *find_subbytes(const byte *haystack, mp_uint_t hlen, const byte *needle, mp_uint_t nlen, mp_int_t direction) { +const byte *find_subbytes(const byte *haystack, size_t hlen, const byte *needle, size_t nlen, int direction) { if (hlen >= nlen) { - mp_uint_t str_index, str_index_end; + size_t str_index, str_index_end; if (direction > 0) { str_index = 0; str_index_end = hlen - nlen; @@ -333,7 +333,7 @@ mp_obj_t mp_obj_str_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { // size and execution time so we don't. const byte *rhs_data; - mp_uint_t rhs_len; + size_t rhs_len; if (lhs_type == mp_obj_get_type(rhs_in)) { GET_STR_DATA_LEN(rhs_in, rhs_data_, rhs_len_); rhs_data = rhs_data_; @@ -441,8 +441,8 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { } // count required length - mp_uint_t required_len = 0; - for (mp_uint_t i = 0; i < seq_len; i++) { + size_t required_len = 0; + for (size_t i = 0; i < seq_len; i++) { if (mp_obj_get_type(seq_items[i]) != self_type) { mp_raise_TypeError( "join expects a list of str/bytes objects consistent with self object"); @@ -458,7 +458,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { vstr_t vstr; vstr_init_len(&vstr, required_len); byte *data = (byte*)vstr.buf; - for (mp_uint_t i = 0; i < seq_len; i++) { + for (size_t i = 0; i < seq_len; i++) { if (i > 0) { memcpy(data, sep_str, sep_len); data += sep_len; @@ -644,7 +644,7 @@ STATIC mp_obj_t str_rsplit(size_t n_args, const mp_obj_t *args) { } if (idx != 0) { // We split less parts than split limit, now go cleanup surplus - mp_int_t used = org_splits + 1 - idx; + size_t used = org_splits + 1 - idx; memmove(res->items, &res->items[idx], used * sizeof(mp_obj_t)); mp_seq_clear(res->items, used, res->alloc, sizeof(*res->items)); res->len = used; @@ -654,7 +654,7 @@ STATIC mp_obj_t str_rsplit(size_t n_args, const mp_obj_t *args) { return MP_OBJ_FROM_PTR(res); } -STATIC mp_obj_t str_finder(size_t n_args, const mp_obj_t *args, mp_int_t direction, bool is_index) { +STATIC mp_obj_t str_finder(size_t n_args, const mp_obj_t *args, int direction, bool is_index) { const mp_obj_type_t *self_type = mp_obj_get_type(args[0]); mp_check_self(MP_OBJ_IS_STR_OR_BYTES(args[0])); @@ -762,16 +762,16 @@ STATIC mp_obj_t str_uni_strip(int type, size_t n_args, const mp_obj_t *args) { GET_STR_DATA_LEN(args[0], orig_str, orig_str_len); - mp_uint_t first_good_char_pos = 0; + size_t first_good_char_pos = 0; bool first_good_char_pos_set = false; - mp_uint_t last_good_char_pos = 0; - mp_uint_t i = 0; - mp_int_t delta = 1; + size_t last_good_char_pos = 0; + size_t i = 0; + int delta = 1; if (type == RSTRIP) { i = orig_str_len - 1; delta = -1; } - for (mp_uint_t len = orig_str_len; len > 0; len--) { + for (size_t len = orig_str_len; len > 0; len--) { if (find_subbytes(chars_to_del, chars_to_del_len, &orig_str[i], 1, 1) == NULL) { if (!first_good_char_pos_set) { first_good_char_pos_set = true; @@ -801,7 +801,7 @@ STATIC mp_obj_t str_uni_strip(int type, size_t n_args, const mp_obj_t *args) { assert(last_good_char_pos >= first_good_char_pos); //+1 to accomodate the last character - mp_uint_t stripped_len = last_good_char_pos - first_good_char_pos + 1; + size_t stripped_len = last_good_char_pos - first_good_char_pos + 1; if (stripped_len == orig_str_len) { // If nothing was stripped, don't bother to dup original string // TODO: watch out for this case when we'll get to bytearray.strip() @@ -1588,11 +1588,11 @@ STATIC mp_obj_t str_replace(size_t n_args, const mp_obj_t *args) { // first pass computes the required length of the replaced string // second pass does the replacements for (;;) { - mp_uint_t replaced_str_index = 0; - mp_uint_t num_replacements_done = 0; + size_t replaced_str_index = 0; + size_t num_replacements_done = 0; const byte *old_occurrence; const byte *offset_ptr = str; - mp_uint_t str_len_remain = str_len; + size_t str_len_remain = str_len; if (old_len == 0) { // if old_str is empty, copy new_str to start of replaced string // copy the replacement string @@ -1602,7 +1602,7 @@ STATIC mp_obj_t str_replace(size_t n_args, const mp_obj_t *args) { replaced_str_index += new_len; num_replacements_done++; } - while (num_replacements_done != (mp_uint_t)max_rep && str_len_remain > 0 && (old_occurrence = find_subbytes(offset_ptr, str_len_remain, old, old_len, 1)) != NULL) { + while (num_replacements_done != (size_t)max_rep && str_len_remain > 0 && (old_occurrence = find_subbytes(offset_ptr, str_len_remain, old, old_len, 1)) != NULL) { if (old_len == 0) { old_occurrence += 1; } @@ -1688,7 +1688,7 @@ STATIC mp_obj_t str_count(size_t n_args, const mp_obj_t *args) { } #if MICROPY_PY_BUILTINS_STR_PARTITION -STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, mp_int_t direction) { +STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, int direction) { mp_check_self(MP_OBJ_IS_STR_OR_BYTES(self_in)); mp_obj_type_t *self_type = mp_obj_get_type(self_in); if (self_type != mp_obj_get_type(arg)) { @@ -1721,7 +1721,7 @@ STATIC mp_obj_t str_partitioner(mp_obj_t self_in, mp_obj_t arg, mp_int_t directi const byte *position_ptr = find_subbytes(str, str_len, sep, sep_len, direction); if (position_ptr != NULL) { - mp_uint_t position = position_ptr - str; + size_t position = position_ptr - str; result[0] = mp_obj_new_str_of_type(self_type, str, position); result[1] = arg; result[2] = mp_obj_new_str_of_type(self_type, str + position + sep_len, str_len - position - sep_len); @@ -1745,7 +1745,7 @@ STATIC mp_obj_t str_caseconv(unichar (*op)(unichar), mp_obj_t self_in) { vstr_t vstr; vstr_init_len(&vstr, self_len); byte *data = (byte*)vstr.buf; - for (mp_uint_t i = 0; i < self_len; i++) { + for (size_t i = 0; i < self_len; i++) { *data++ = op(*self_data++); } return mp_obj_new_str_from_vstr(mp_obj_get_type(self_in), &vstr); @@ -1767,7 +1767,7 @@ STATIC mp_obj_t str_uni_istype(bool (*f)(unichar), mp_obj_t self_in) { } if (f != unichar_isupper && f != unichar_islower) { - for (mp_uint_t i = 0; i < self_len; i++) { + for (size_t i = 0; i < self_len; i++) { if (!f(*self_data++)) { return mp_const_false; } @@ -1775,7 +1775,7 @@ STATIC mp_obj_t str_uni_istype(bool (*f)(unichar), mp_obj_t self_in) { } else { bool contains_alpha = false; - for (mp_uint_t i = 0; i < self_len; i++) { // only check alphanumeric characters + for (size_t i = 0; i < self_len; i++) { // only check alphanumeric characters if (unichar_isalpha(*self_data++)) { contains_alpha = true; if (!f(*(self_data - 1))) { // -1 because we already incremented above @@ -2019,7 +2019,7 @@ mp_obj_t mp_obj_new_str_from_vstr(const mp_obj_type_t *type, vstr_t *vstr) { return MP_OBJ_FROM_PTR(o); } -mp_obj_t mp_obj_new_str(const char* data, mp_uint_t len, bool make_qstr_if_not_already) { +mp_obj_t mp_obj_new_str(const char* data, size_t len, bool make_qstr_if_not_already) { if (make_qstr_if_not_already) { // use existing, or make a new qstr return MP_OBJ_NEW_QSTR(qstr_from_strn(data, len)); @@ -2040,7 +2040,7 @@ mp_obj_t mp_obj_str_intern(mp_obj_t str) { return MP_OBJ_NEW_QSTR(qstr_from_strn((const char*)data, len)); } -mp_obj_t mp_obj_new_bytes(const byte* data, mp_uint_t len) { +mp_obj_t mp_obj_new_bytes(const byte* data, size_t len) { return mp_obj_new_str_of_type(&mp_type_bytes, data, len); } @@ -2126,7 +2126,7 @@ typedef struct _mp_obj_str8_it_t { mp_obj_base_t base; mp_fun_1_t iternext; mp_obj_t str; - mp_uint_t cur; + size_t cur; } mp_obj_str8_it_t; #if !MICROPY_PY_BUILTINS_STR_UNICODE diff --git a/py/objstr.h b/py/objstr.h index ad2777afb..e92832d10 100644 --- a/py/objstr.h +++ b/py/objstr.h @@ -32,7 +32,7 @@ typedef struct _mp_obj_str_t { mp_obj_base_t base; mp_uint_t hash; // len == number of bytes used in data, alloc = len + 1 because (at the moment) we also append a null byte - mp_uint_t len; + size_t len; const byte *data; } mp_obj_str_t; @@ -72,7 +72,7 @@ mp_int_t mp_obj_str_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_u const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, size_t self_len, mp_obj_t index, bool is_slice); -const byte *find_subbytes(const byte *haystack, mp_uint_t hlen, const byte *needle, mp_uint_t nlen, mp_int_t direction); +const byte *find_subbytes(const byte *haystack, size_t hlen, const byte *needle, size_t nlen, int direction); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_encode_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_find_obj); diff --git a/py/objstrunicode.c b/py/objstrunicode.c index 8444a2689..0091edd72 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -284,7 +284,7 @@ typedef struct _mp_obj_str_it_t { mp_obj_base_t base; mp_fun_1_t iternext; mp_obj_t str; - mp_uint_t cur; + size_t cur; } mp_obj_str_it_t; STATIC mp_obj_t str_it_iternext(mp_obj_t self_in) { -- cgit v1.2.3 From ccc5254224801392e580cfc00b6cdd098fb7ad4a Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 16 Feb 2017 16:31:43 +1100 Subject: py/objarray: Convert mp_uint_t to size_t where appropriate. --- py/obj.h | 6 +++--- py/objarray.c | 32 ++++++++++++++++---------------- py/objarray.h | 6 +++--- 3 files changed, 22 insertions(+), 22 deletions(-) (limited to 'py/obj.h') diff --git a/py/obj.h b/py/obj.h index efb923413..a507a1096 100644 --- a/py/obj.h +++ b/py/obj.h @@ -613,8 +613,8 @@ mp_obj_t mp_obj_new_int_from_ull(unsigned long long val); // this must return a mp_obj_t mp_obj_new_str(const char* data, size_t len, bool make_qstr_if_not_already); mp_obj_t mp_obj_new_str_from_vstr(const mp_obj_type_t *type, vstr_t *vstr); mp_obj_t mp_obj_new_bytes(const byte* data, size_t len); -mp_obj_t mp_obj_new_bytearray(mp_uint_t n, void *items); -mp_obj_t mp_obj_new_bytearray_by_ref(mp_uint_t n, void *items); +mp_obj_t mp_obj_new_bytearray(size_t n, void *items); +mp_obj_t mp_obj_new_bytearray_by_ref(size_t n, void *items); #if MICROPY_PY_BUILTINS_FLOAT mp_obj_t mp_obj_new_int_from_float(mp_float_t val); mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag); @@ -639,7 +639,7 @@ 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_module(qstr module_name); -mp_obj_t mp_obj_new_memoryview(byte typecode, mp_uint_t nitems, void *items); +mp_obj_t mp_obj_new_memoryview(byte typecode, size_t nitems, void *items); mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in); const char *mp_obj_get_type_str(mp_const_obj_t o_in); diff --git a/py/objarray.c b/py/objarray.c index ed666df8f..f23791857 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -56,7 +56,7 @@ #if MICROPY_PY_BUILTINS_MEMORYVIEW #define TYPECODE_MASK (0x7f) #else -#define TYPECODE_MASK (~(mp_uint_t)0) +#define TYPECODE_MASK (~(size_t)0) #endif STATIC mp_obj_t array_iterator_new(mp_obj_t array_in); @@ -78,7 +78,7 @@ STATIC void array_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t mp_printf(print, "array('%c'", o->typecode); if (o->len > 0) { mp_print_str(print, ", ["); - for (mp_uint_t i = 0; i < o->len; i++) { + for (size_t i = 0; i < o->len; i++) { if (i > 0) { mp_print_str(print, ", "); } @@ -92,7 +92,7 @@ STATIC void array_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t #endif #if MICROPY_PY_BUILTINS_BYTEARRAY || MICROPY_PY_ARRAY -STATIC mp_obj_array_t *array_new(char typecode, mp_uint_t n) { +STATIC mp_obj_array_t *array_new(char typecode, size_t n) { int typecode_size = mp_binary_get_size('@', typecode, NULL); mp_obj_array_t *o = m_new_obj(mp_obj_array_t); #if MICROPY_PY_BUILTINS_BYTEARRAY && MICROPY_PY_ARRAY @@ -124,13 +124,13 @@ STATIC mp_obj_t array_construct(char typecode, mp_obj_t initializer) { // construct array from raw bytes // we round-down the len to make it a multiple of sz (CPython raises error) size_t sz = mp_binary_get_size('@', typecode, NULL); - mp_uint_t len = bufinfo.len / sz; + size_t len = bufinfo.len / sz; mp_obj_array_t *o = array_new(typecode, len); memcpy(o->items, bufinfo.buf, len * sz); return MP_OBJ_FROM_PTR(o); } - mp_uint_t len; + size_t len; // Try to create array of exact len if initializer len is known mp_obj_t len_in = mp_obj_len_maybe(initializer); if (len_in == MP_OBJ_NULL) { @@ -143,7 +143,7 @@ STATIC mp_obj_t array_construct(char typecode, mp_obj_t initializer) { mp_obj_t iterable = mp_getiter(initializer); mp_obj_t item; - mp_uint_t i = 0; + size_t i = 0; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { if (len == 0) { array_append(MP_OBJ_FROM_PTR(array), item); @@ -198,7 +198,7 @@ STATIC mp_obj_t bytearray_make_new(const mp_obj_type_t *type_in, size_t n_args, #if MICROPY_PY_BUILTINS_MEMORYVIEW -mp_obj_t mp_obj_new_memoryview(byte typecode, mp_uint_t nitems, void *items) { +mp_obj_t mp_obj_new_memoryview(byte typecode, size_t nitems, void *items) { mp_obj_array_t *self = m_new_obj(mp_obj_array_t); self->base.type = &mp_type_memoryview; self->typecode = typecode; @@ -254,7 +254,7 @@ STATIC mp_obj_t array_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) size_t sz = mp_binary_get_size('@', lhs_bufinfo.typecode, NULL); // convert byte count to element count (in case rhs is not multiple of sz) - mp_uint_t rhs_len = rhs_bufinfo.len / sz; + size_t rhs_len = rhs_bufinfo.len / sz; // note: lhs->len is element count of lhs, lhs_bufinfo.len is byte count mp_obj_array_t *res = array_new(lhs_bufinfo.typecode, lhs->len + rhs_len); @@ -345,7 +345,7 @@ STATIC mp_obj_t array_extend(mp_obj_t self_in, mp_obj_t arg_in) { size_t sz = mp_binary_get_size('@', self->typecode, NULL); // convert byte count to element count - mp_uint_t len = arg_bufinfo.len / sz; + size_t len = arg_bufinfo.len / sz; // make sure we have enough room to extend // TODO: alloc policy; at the moment we go conservative @@ -384,7 +384,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value if (value != MP_OBJ_SENTINEL) { #if MICROPY_PY_ARRAY_SLICE_ASSIGN // Assign - mp_uint_t src_len; + size_t src_len; void *src_items; size_t item_sz = mp_binary_get_size('@', o->typecode & TYPECODE_MASK, NULL); if (MP_OBJ_IS_OBJ(value) && ((mp_obj_base_t*)MP_OBJ_TO_PTR(value))->type->subscr == array_subscr) { @@ -501,7 +501,7 @@ STATIC mp_int_t array_get_buffer(mp_obj_t o_in, mp_buffer_info_t *bufinfo, mp_ui // read-only memoryview return 1; } - bufinfo->buf = (uint8_t*)bufinfo->buf + (mp_uint_t)o->free * sz; + bufinfo->buf = (uint8_t*)bufinfo->buf + (size_t)o->free * sz; } #else (void)flags; @@ -562,20 +562,20 @@ const mp_obj_type_t mp_type_memoryview = { #endif /* unused -mp_uint_t mp_obj_array_len(mp_obj_t self_in) { +size_t mp_obj_array_len(mp_obj_t self_in) { return ((mp_obj_array_t *)self_in)->len; } */ #if MICROPY_PY_BUILTINS_BYTEARRAY -mp_obj_t mp_obj_new_bytearray(mp_uint_t n, void *items) { +mp_obj_t mp_obj_new_bytearray(size_t n, void *items) { mp_obj_array_t *o = array_new(BYTEARRAY_TYPECODE, n); memcpy(o->items, items, n); return MP_OBJ_FROM_PTR(o); } // Create bytearray which references specified memory area -mp_obj_t mp_obj_new_bytearray_by_ref(mp_uint_t n, void *items) { +mp_obj_t mp_obj_new_bytearray_by_ref(size_t n, void *items) { mp_obj_array_t *o = m_new_obj(mp_obj_array_t); o->base.type = &mp_type_bytearray; o->typecode = BYTEARRAY_TYPECODE; @@ -592,8 +592,8 @@ mp_obj_t mp_obj_new_bytearray_by_ref(mp_uint_t n, void *items) { typedef struct _mp_obj_array_it_t { mp_obj_base_t base; mp_obj_array_t *array; - mp_uint_t offset; - mp_uint_t cur; + size_t offset; + size_t cur; } mp_obj_array_it_t; STATIC mp_obj_t array_it_iternext(mp_obj_t self_in) { diff --git a/py/objarray.h b/py/objarray.h index 013ac5be9..06a2a07ef 100644 --- a/py/objarray.h +++ b/py/objarray.h @@ -32,11 +32,11 @@ typedef struct _mp_obj_array_t { mp_obj_base_t base; - mp_uint_t typecode : 8; + size_t typecode : 8; // free is number of unused elements after len used elements // alloc size = len + free - mp_uint_t free : (8 * sizeof(mp_uint_t) - 8); - mp_uint_t len; // in elements + size_t free : (8 * sizeof(size_t) - 8); + size_t len; // in elements void *items; } mp_obj_array_t; -- cgit v1.2.3 From dbcdb9f8d8d5dd56ede1f0705355679a11b75658 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 16 Feb 2017 16:34:53 +1100 Subject: py/objfun: Convert mp_uint_t to size_t where appropriate. --- py/obj.h | 4 ++-- py/objfun.c | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'py/obj.h') diff --git a/py/obj.h b/py/obj.h index a507a1096..80294b3b4 100644 --- a/py/obj.h +++ b/py/obj.h @@ -626,8 +626,8 @@ mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!) mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args, mp_obj_t def_kw_args, const byte *code, const mp_uint_t *const_table); mp_obj_t mp_obj_new_fun_native(mp_obj_t def_args_in, mp_obj_t def_kw_args, const void *fun_data, const mp_uint_t *const_table); -mp_obj_t mp_obj_new_fun_viper(mp_uint_t n_args, void *fun_data, mp_uint_t type_sig); -mp_obj_t mp_obj_new_fun_asm(mp_uint_t n_args, void *fun_data, mp_uint_t type_sig); +mp_obj_t mp_obj_new_fun_viper(size_t n_args, void *fun_data, mp_uint_t type_sig); +mp_obj_t mp_obj_new_fun_asm(size_t n_args, void *fun_data, mp_uint_t type_sig); mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun); mp_obj_t mp_obj_new_closure(mp_obj_t fun, mp_uint_t n_closed, const mp_obj_t *closed); mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items); diff --git a/py/objfun.c b/py/objfun.c index 207e68a77..e5f6009dc 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -181,9 +181,9 @@ STATIC void fun_bc_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t #endif #if DEBUG_PRINT -STATIC void dump_args(const mp_obj_t *a, mp_uint_t sz) { +STATIC void dump_args(const mp_obj_t *a, size_t sz) { DEBUG_printf("%p: ", a); - for (mp_uint_t i = 0; i < sz; i++) { + for (size_t i = 0; i < sz; i++) { DEBUG_printf("%p ", a[i]); } DEBUG_printf("\n"); @@ -247,15 +247,15 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const const byte *ip = self->bytecode; // bytecode prelude: state size and exception stack size - mp_uint_t n_state = mp_decode_uint(&ip); - mp_uint_t n_exc_stack = mp_decode_uint(&ip); + size_t n_state = mp_decode_uint(&ip); + size_t n_exc_stack = mp_decode_uint(&ip); #if VM_DETECT_STACK_OVERFLOW n_state += 1; #endif // allocate state for locals and stack - mp_uint_t state_size = n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t); + size_t state_size = n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t); mp_code_state_t *code_state = NULL; if (state_size > VM_MAX_STATE_ON_STACK) { code_state = m_new_obj_var_maybe(mp_code_state_t, byte, state_size); @@ -288,7 +288,7 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const if (!(vm_return_kind == MP_VM_RETURN_EXCEPTION && self->n_pos_args + self->n_kwonly_args == 0)) { // Just check to see that we have at least 1 null object left in the state. bool overflow = true; - for (mp_uint_t i = 0; i < n_state - self->n_pos_args - self->n_kwonly_args; i++) { + for (size_t i = 0; i < n_state - self->n_pos_args - self->n_kwonly_args; i++) { if (code_state->state[i] == MP_OBJ_NULL) { overflow = false; break; @@ -350,8 +350,8 @@ const mp_obj_type_t mp_type_fun_bc = { }; mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args_in, mp_obj_t def_kw_args, const byte *code, const mp_uint_t *const_table) { - mp_uint_t n_def_args = 0; - mp_uint_t n_extra_args = 0; + size_t n_def_args = 0; + size_t n_extra_args = 0; mp_obj_tuple_t *def_args = MP_OBJ_TO_PTR(def_args_in); if (def_args_in != MP_OBJ_NULL) { assert(MP_OBJ_IS_TYPE(def_args_in, &mp_type_tuple)); @@ -409,7 +409,7 @@ mp_obj_t mp_obj_new_fun_native(mp_obj_t def_args_in, mp_obj_t def_kw_args, const typedef struct _mp_obj_fun_viper_t { mp_obj_base_t base; - mp_uint_t n_args; + size_t n_args; void *fun_data; // GC must be able to trace this pointer mp_uint_t type_sig; } mp_obj_fun_viper_t; @@ -457,7 +457,7 @@ STATIC const mp_obj_type_t mp_type_fun_viper = { .unary_op = mp_generic_unary_op, }; -mp_obj_t mp_obj_new_fun_viper(mp_uint_t n_args, void *fun_data, mp_uint_t type_sig) { +mp_obj_t mp_obj_new_fun_viper(size_t n_args, void *fun_data, mp_uint_t type_sig) { mp_obj_fun_viper_t *o = m_new_obj(mp_obj_fun_viper_t); o->base.type = &mp_type_fun_viper; o->n_args = n_args; @@ -475,7 +475,7 @@ mp_obj_t mp_obj_new_fun_viper(mp_uint_t n_args, void *fun_data, mp_uint_t type_s typedef struct _mp_obj_fun_asm_t { mp_obj_base_t base; - mp_uint_t n_args; + size_t n_args; void *fun_data; // GC must be able to trace this pointer mp_uint_t type_sig; } mp_obj_fun_asm_t; @@ -573,7 +573,7 @@ STATIC const mp_obj_type_t mp_type_fun_asm = { .unary_op = mp_generic_unary_op, }; -mp_obj_t mp_obj_new_fun_asm(mp_uint_t n_args, void *fun_data, mp_uint_t type_sig) { +mp_obj_t mp_obj_new_fun_asm(size_t n_args, void *fun_data, mp_uint_t type_sig) { mp_obj_fun_asm_t *o = m_new_obj(mp_obj_fun_asm_t); o->base.type = &mp_type_fun_asm; o->n_args = n_args; -- cgit v1.2.3 From efa629028ad453206c04104735e33a79ae60c8a2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 16 Feb 2017 16:36:04 +1100 Subject: py/objclosure: Convert mp_uint_t to size_t where appropriate. --- py/obj.h | 2 +- py/objclosure.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'py/obj.h') diff --git a/py/obj.h b/py/obj.h index 80294b3b4..d28623e64 100644 --- a/py/obj.h +++ b/py/obj.h @@ -629,7 +629,7 @@ mp_obj_t mp_obj_new_fun_native(mp_obj_t def_args_in, mp_obj_t def_kw_args, const mp_obj_t mp_obj_new_fun_viper(size_t n_args, void *fun_data, mp_uint_t type_sig); mp_obj_t mp_obj_new_fun_asm(size_t n_args, void *fun_data, mp_uint_t type_sig); mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun); -mp_obj_t mp_obj_new_closure(mp_obj_t fun, mp_uint_t n_closed, const mp_obj_t *closed); +mp_obj_t mp_obj_new_closure(mp_obj_t fun, size_t n_closed, const mp_obj_t *closed); mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items); mp_obj_t mp_obj_new_list(size_t n, mp_obj_t *items); mp_obj_t mp_obj_new_dict(size_t n_args); diff --git a/py/objclosure.c b/py/objclosure.c index 4b37d2dd1..3e12358bb 100644 --- a/py/objclosure.c +++ b/py/objclosure.c @@ -32,7 +32,7 @@ typedef struct _mp_obj_closure_t { mp_obj_base_t base; mp_obj_t fun; - mp_uint_t n_closed; + size_t n_closed; mp_obj_t closed[]; } mp_obj_closure_t; @@ -41,7 +41,7 @@ STATIC mp_obj_t closure_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const // need to concatenate closed-over-vars and args - mp_uint_t n_total = self->n_closed + n_args + 2 * n_kw; + size_t n_total = self->n_closed + n_args + 2 * n_kw; if (n_total <= 5) { // use stack to allocate temporary args array mp_obj_t args2[5]; @@ -66,7 +66,7 @@ STATIC void closure_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_ mp_print_str(print, "fun, PRINT_REPR); mp_printf(print, " at %p, n_closed=%u ", o, (int)o->n_closed); - for (mp_uint_t i = 0; i < o->n_closed; i++) { + for (size_t i = 0; i < o->n_closed; i++) { if (o->closed[i] == MP_OBJ_NULL) { mp_print_str(print, "(nil)"); } else { @@ -87,7 +87,7 @@ const mp_obj_type_t closure_type = { .call = closure_call, }; -mp_obj_t mp_obj_new_closure(mp_obj_t fun, mp_uint_t n_closed_over, const mp_obj_t *closed) { +mp_obj_t mp_obj_new_closure(mp_obj_t fun, size_t n_closed_over, const mp_obj_t *closed) { mp_obj_closure_t *o = m_new_obj_var(mp_obj_closure_t, mp_obj_t, n_closed_over); o->base.type = &closure_type; o->fun = fun; -- cgit v1.2.3 From fa5a591757569136a444715cce2248b63ad73512 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 16 Feb 2017 16:38:14 +1100 Subject: py/objexcept: Convert mp_uint_t to size_t where appropriate. --- py/obj.h | 2 +- py/objexcept.c | 2 +- py/objexcept.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'py/obj.h') diff --git a/py/obj.h b/py/obj.h index d28623e64..1b926ce14 100644 --- a/py/obj.h +++ b/py/obj.h @@ -621,7 +621,7 @@ mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag); #endif mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type); mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg); -mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, mp_uint_t n_args, const mp_obj_t *args); +mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, size_t n_args, const mp_obj_t *args); mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, const char *msg); mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char *fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!) mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args, mp_obj_t def_kw_args, const byte *code, const mp_uint_t *const_table); diff --git a/py/objexcept.c b/py/objexcept.c index 76d34f56e..1f1009ff7 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -312,7 +312,7 @@ mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg) return mp_obj_new_exception_args(exc_type, 1, &arg); } -mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, mp_uint_t n_args, const mp_obj_t *args) { +mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, size_t n_args, const mp_obj_t *args) { assert(exc_type->make_new == mp_obj_exception_make_new); return exc_type->make_new(exc_type, n_args, 0, args); } diff --git a/py/objexcept.h b/py/objexcept.h index 88bce2b37..3128fded7 100644 --- a/py/objexcept.h +++ b/py/objexcept.h @@ -31,8 +31,8 @@ typedef struct _mp_obj_exception_t { mp_obj_base_t base; - mp_uint_t traceback_alloc : (BITS_PER_WORD / 2); - mp_uint_t traceback_len : (BITS_PER_WORD / 2); + size_t traceback_alloc : (8 * sizeof(size_t) / 2); + size_t traceback_len : (8 * sizeof(size_t) / 2); size_t *traceback_data; mp_obj_tuple_t *args; } mp_obj_exception_t; -- cgit v1.2.3 From da36f5232dcf02c448ee9933e358b711cfe03f30 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 16 Feb 2017 16:41:43 +1100 Subject: py/objint: Convert mp_uint_t to size_t where appropriate. --- py/obj.h | 2 +- py/objint.c | 2 +- py/objint_longlong.c | 2 +- py/objint_mpz.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'py/obj.h') diff --git a/py/obj.h b/py/obj.h index 1b926ce14..1169a9095 100644 --- a/py/obj.h +++ b/py/obj.h @@ -607,7 +607,7 @@ static inline mp_obj_t mp_obj_new_bool(mp_int_t x) { return x ? mp_const_true : mp_obj_t mp_obj_new_cell(mp_obj_t obj); mp_obj_t mp_obj_new_int(mp_int_t value); mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value); -mp_obj_t mp_obj_new_int_from_str_len(const char **str, mp_uint_t len, bool neg, mp_uint_t base); +mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base); mp_obj_t mp_obj_new_int_from_ll(long long val); // this must return a multi-precision integer object (or raise an overflow exception) mp_obj_t mp_obj_new_int_from_ull(unsigned long long val); // this must return a multi-precision integer object (or raise an overflow exception) mp_obj_t mp_obj_new_str(const char* data, size_t len, bool make_qstr_if_not_already); diff --git a/py/objint.c b/py/objint.c index 222aa1de7..2a7e3f3fd 100644 --- a/py/objint.c +++ b/py/objint.c @@ -291,7 +291,7 @@ mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { } // This is called only with strings whose value doesn't fit in SMALL_INT -mp_obj_t mp_obj_new_int_from_str_len(const char **str, mp_uint_t len, bool neg, mp_uint_t base) { +mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base) { mp_raise_msg(&mp_type_OverflowError, "long int not supported in this build"); return mp_const_none; } diff --git a/py/objint_longlong.c b/py/objint_longlong.c index dbfb39809..b798c91cd 100644 --- a/py/objint_longlong.c +++ b/py/objint_longlong.c @@ -273,7 +273,7 @@ mp_obj_t mp_obj_new_int_from_float(mp_float_t val) { } #endif -mp_obj_t mp_obj_new_int_from_str_len(const char **str, mp_uint_t len, bool neg, mp_uint_t base) { +mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base) { // TODO this does not honor the given length of the string, but it all cases it should anyway be null terminated // TODO check overflow mp_obj_int_t *o = m_new_obj(mp_obj_int_t); diff --git a/py/objint_mpz.c b/py/objint_mpz.c index 2b27df4f6..2cdf22505 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -407,9 +407,9 @@ mp_obj_t mp_obj_new_int_from_float(mp_float_t val) { } #endif -mp_obj_t mp_obj_new_int_from_str_len(const char **str, mp_uint_t len, bool neg, mp_uint_t base) { +mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base) { mp_obj_int_t *o = mp_obj_int_new_mpz(); - mp_uint_t n = mpz_set_from_str(&o->mpz, *str, len, neg, base); + size_t n = mpz_set_from_str(&o->mpz, *str, len, neg, base); *str += n; return MP_OBJ_FROM_PTR(o); } -- 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/obj.h') 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 c88cfe165b0ab39c5d9392fb02dd12f22be1a28d Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 23 Mar 2017 16:17:40 +1100 Subject: py: Use size_t as len argument and return type of mp_get_index. These values are used to compute memory addresses and so size_t is the more appropriate type to use. --- py/obj.c | 6 ++++-- py/obj.h | 2 +- py/objarray.c | 2 +- py/objlist.c | 6 +++--- py/objrange.c | 2 +- py/objstr.c | 4 ++-- py/objstrunicode.c | 2 +- py/objtuple.c | 2 +- py/sequence.c | 6 +++--- 9 files changed, 17 insertions(+), 15 deletions(-) (limited to 'py/obj.h') diff --git a/py/obj.c b/py/obj.c index 4534ef1b2..65a35c86f 100644 --- a/py/obj.c +++ b/py/obj.c @@ -351,7 +351,7 @@ void mp_obj_get_array_fixed_n(mp_obj_t o, mp_uint_t len, mp_obj_t **items) { } // is_slice determines whether the index is a slice index -mp_uint_t mp_get_index(const mp_obj_type_t *type, mp_uint_t len, mp_obj_t index, bool is_slice) { +size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool is_slice) { mp_int_t i; if (MP_OBJ_IS_SMALL_INT(index)) { i = MP_OBJ_SMALL_INT_VALUE(index); @@ -384,7 +384,9 @@ mp_uint_t mp_get_index(const mp_obj_type_t *type, mp_uint_t len, mp_obj_t index, } } } - return i; + + // By this point 0 <= i <= len and so fits in a size_t + return (size_t)i; } mp_obj_t mp_obj_id(mp_obj_t o_in) { diff --git a/py/obj.h b/py/obj.h index 79a6d56fa..03dadeb07 100644 --- a/py/obj.h +++ b/py/obj.h @@ -674,7 +674,7 @@ void mp_obj_get_complex(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag); //qstr mp_obj_get_qstr(mp_obj_t arg); void mp_obj_get_array(mp_obj_t o, mp_uint_t *len, mp_obj_t **items); // *items may point inside a GC block void mp_obj_get_array_fixed_n(mp_obj_t o, mp_uint_t len, mp_obj_t **items); // *items may point inside a GC block -mp_uint_t mp_get_index(const mp_obj_type_t *type, mp_uint_t len, mp_obj_t index, bool is_slice); +size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool is_slice); mp_obj_t mp_obj_id(mp_obj_t o_in); mp_obj_t mp_obj_len(mp_obj_t o_in); mp_obj_t mp_obj_len_maybe(mp_obj_t o_in); // may return MP_OBJ_NULL diff --git a/py/objarray.c b/py/objarray.c index a84a63151..af75af917 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -471,7 +471,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value return MP_OBJ_FROM_PTR(res); #endif } else { - mp_uint_t index = mp_get_index(o->base.type, o->len, index_in, false); + size_t index = mp_get_index(o->base.type, o->len, index_in, false); #if MICROPY_PY_BUILTINS_MEMORYVIEW if (o->base.type == &mp_type_memoryview) { index += o->free; diff --git a/py/objlist.c b/py/objlist.c index ba7898415..312cef6d3 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -186,7 +186,7 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { return MP_OBJ_FROM_PTR(res); } #endif - mp_uint_t index_val = mp_get_index(self->base.type, self->len, index, false); + size_t index_val = mp_get_index(self->base.type, self->len, index, false); return self->items[index_val]; } else { #if MICROPY_PY_BUILTINS_SLICE @@ -268,7 +268,7 @@ STATIC mp_obj_t list_pop(size_t n_args, const mp_obj_t *args) { if (self->len == 0) { mp_raise_msg(&mp_type_IndexError, "pop from empty list"); } - mp_uint_t index = mp_get_index(self->base.type, self->len, n_args == 1 ? MP_OBJ_NEW_SMALL_INT(-1) : args[1], false); + size_t index = mp_get_index(self->base.type, self->len, n_args == 1 ? MP_OBJ_NEW_SMALL_INT(-1) : args[1], false); mp_obj_t ret = self->items[index]; self->len -= 1; memmove(self->items + index, self->items + index + 1, (self->len - index) * sizeof(mp_obj_t)); @@ -490,7 +490,7 @@ void mp_obj_list_set_len(mp_obj_t self_in, size_t len) { void mp_obj_list_store(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in); - mp_uint_t i = mp_get_index(self->base.type, self->len, index, false); + size_t i = mp_get_index(self->base.type, self->len, index, false); self->items[i] = value; } diff --git a/py/objrange.c b/py/objrange.c index dd074a98a..5bf0bc7a9 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -155,7 +155,7 @@ STATIC mp_obj_t range_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { return MP_OBJ_FROM_PTR(o); } #endif - uint index_val = mp_get_index(self->base.type, len, index, false); + size_t index_val = mp_get_index(self->base.type, len, index, false); return MP_OBJ_NEW_SMALL_INT(self->start + index_val * self->step); } else { return MP_OBJ_NULL; // op not supported diff --git a/py/objstr.c b/py/objstr.c index 1e71617bd..4053efb88 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -388,7 +388,7 @@ mp_obj_t mp_obj_str_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { // objstrunicode defines own version const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, size_t self_len, mp_obj_t index, bool is_slice) { - mp_uint_t index_val = mp_get_index(type, self_len, index, is_slice); + size_t index_val = mp_get_index(type, self_len, index, is_slice); return self_data + index_val; } #endif @@ -408,7 +408,7 @@ STATIC mp_obj_t bytes_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { return mp_obj_new_str_of_type(type, self_data + slice.start, slice.stop - slice.start); } #endif - mp_uint_t index_val = mp_get_index(type, self_len, index, false); + size_t index_val = mp_get_index(type, self_len, index, false); // If we have unicode enabled the type will always be bytes, so take the short cut. if (MICROPY_PY_BUILTINS_STR_UNICODE || type == &mp_type_bytes) { return MP_OBJ_NEW_SMALL_INT(self_data[index_val]); diff --git a/py/objstrunicode.c b/py/objstrunicode.c index 441ec293d..9a6ce9b9a 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -120,7 +120,7 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s // so it must handle bytes. if (type == &mp_type_bytes) { // Taken from objstr.c:str_index_to_ptr() - mp_uint_t index_val = mp_get_index(type, self_len, index, is_slice); + size_t index_val = mp_get_index(type, self_len, index, is_slice); return self_data + index_val; } diff --git a/py/objtuple.c b/py/objtuple.c index b28807c0d..a8efdc7f9 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -186,7 +186,7 @@ mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { return MP_OBJ_FROM_PTR(res); } #endif - mp_uint_t index_value = mp_get_index(self->base.type, self->len, index, false); + size_t index_value = mp_get_index(self->base.type, self->len, index, false); return self->items[index_value]; } else { return MP_OBJ_NULL; // op not supported diff --git a/py/sequence.c b/py/sequence.c index bc2cfc077..9aa3b6a89 100644 --- a/py/sequence.c +++ b/py/sequence.c @@ -239,8 +239,8 @@ bool mp_seq_cmp_objs(mp_uint_t op, const mp_obj_t *items1, mp_uint_t len1, const mp_obj_t mp_seq_index_obj(const mp_obj_t *items, mp_uint_t len, mp_uint_t n_args, const mp_obj_t *args) { mp_obj_type_t *type = mp_obj_get_type(args[0]); mp_obj_t value = args[1]; - uint start = 0; - uint stop = len; + size_t start = 0; + size_t stop = len; if (n_args >= 3) { start = mp_get_index(type, len, args[2], true); @@ -249,7 +249,7 @@ mp_obj_t mp_seq_index_obj(const mp_obj_t *items, mp_uint_t len, mp_uint_t n_args } } - for (mp_uint_t i = start; i < stop; i++) { + for (size_t i = start; i < stop; i++) { if (mp_obj_equal(items[i], value)) { // Common sense says this cannot overflow small int return MP_OBJ_NEW_SMALL_INT(i); -- cgit v1.2.3 From 507119f4d80cc70cc35249f97c9b0ee22b8965f4 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 23 Mar 2017 16:23:20 +1100 Subject: py/sequence: Convert mp_uint_t to size_t where appropriate. --- py/obj.h | 12 ++++++------ py/sequence.c | 30 +++++++++++++++--------------- 2 files changed, 21 insertions(+), 21 deletions(-) (limited to 'py/obj.h') diff --git a/py/obj.h b/py/obj.h index 03dadeb07..93078b81e 100644 --- a/py/obj.h +++ b/py/obj.h @@ -819,17 +819,17 @@ typedef struct { mp_int_t step; } mp_bound_slice_t; -void mp_seq_multiply(const void *items, mp_uint_t item_sz, mp_uint_t len, mp_uint_t times, void *dest); +void mp_seq_multiply(const void *items, size_t item_sz, size_t len, size_t times, void *dest); #if MICROPY_PY_BUILTINS_SLICE bool mp_seq_get_fast_slice_indexes(mp_uint_t len, mp_obj_t slice, mp_bound_slice_t *indexes); #endif #define mp_seq_copy(dest, src, len, item_t) memcpy(dest, src, len * sizeof(item_t)) #define mp_seq_cat(dest, src1, len1, src2, len2, item_t) { memcpy(dest, src1, (len1) * sizeof(item_t)); memcpy(dest + (len1), src2, (len2) * sizeof(item_t)); } -bool mp_seq_cmp_bytes(mp_uint_t op, const byte *data1, mp_uint_t len1, const byte *data2, mp_uint_t len2); -bool mp_seq_cmp_objs(mp_uint_t op, const mp_obj_t *items1, mp_uint_t len1, const mp_obj_t *items2, mp_uint_t len2); -mp_obj_t mp_seq_index_obj(const mp_obj_t *items, mp_uint_t len, mp_uint_t n_args, const mp_obj_t *args); -mp_obj_t mp_seq_count_obj(const mp_obj_t *items, mp_uint_t len, mp_obj_t value); -mp_obj_t mp_seq_extract_slice(mp_uint_t len, const mp_obj_t *seq, mp_bound_slice_t *indexes); +bool mp_seq_cmp_bytes(mp_uint_t op, const byte *data1, size_t len1, const byte *data2, size_t len2); +bool mp_seq_cmp_objs(mp_uint_t op, const mp_obj_t *items1, size_t len1, const mp_obj_t *items2, size_t len2); +mp_obj_t mp_seq_index_obj(const mp_obj_t *items, size_t len, size_t n_args, const mp_obj_t *args); +mp_obj_t mp_seq_count_obj(const mp_obj_t *items, size_t len, mp_obj_t value); +mp_obj_t mp_seq_extract_slice(size_t len, const mp_obj_t *seq, mp_bound_slice_t *indexes); // Helper to clear stale pointers from allocated, but unused memory, to preclude GC problems #define mp_seq_clear(start, len, alloc_len, item_sz) memset((byte*)(start) + (len) * (item_sz), 0, ((alloc_len) - (len)) * (item_sz)) #define mp_seq_replace_slice_no_grow(dest, dest_len, beg, end, slice, slice_len, item_sz) \ diff --git a/py/sequence.c b/py/sequence.c index 9aa3b6a89..11761f651 100644 --- a/py/sequence.c +++ b/py/sequence.c @@ -38,9 +38,9 @@ // Implements backend of sequence * integer operation. Assumes elements are // memory-adjacent in sequence. -void mp_seq_multiply(const void *items, mp_uint_t item_sz, mp_uint_t len, mp_uint_t times, void *dest) { - for (mp_uint_t i = 0; i < times; i++) { - uint copy_sz = item_sz * len; +void mp_seq_multiply(const void *items, size_t item_sz, size_t len, size_t times, void *dest) { + for (size_t i = 0; i < times; i++) { + size_t copy_sz = item_sz * len; memcpy(dest, items, copy_sz); dest = (char*)dest + copy_sz; } @@ -119,7 +119,7 @@ bool mp_seq_get_fast_slice_indexes(mp_uint_t len, mp_obj_t slice, mp_bound_slice #endif -mp_obj_t mp_seq_extract_slice(mp_uint_t len, const mp_obj_t *seq, mp_bound_slice_t *indexes) { +mp_obj_t mp_seq_extract_slice(size_t len, const mp_obj_t *seq, mp_bound_slice_t *indexes) { (void)len; // TODO can we remove len from the arg list? mp_int_t start = indexes->start, stop = indexes->stop; @@ -143,7 +143,7 @@ mp_obj_t mp_seq_extract_slice(mp_uint_t len, const mp_obj_t *seq, mp_bound_slice // Special-case comparison function for sequences of bytes // Don't pass MP_BINARY_OP_NOT_EQUAL here -bool mp_seq_cmp_bytes(mp_uint_t op, const byte *data1, mp_uint_t len1, const byte *data2, mp_uint_t len2) { +bool mp_seq_cmp_bytes(mp_uint_t op, const byte *data1, size_t len1, const byte *data2, size_t len2) { if (op == MP_BINARY_OP_EQUAL && len1 != len2) { return false; } @@ -151,14 +151,14 @@ bool mp_seq_cmp_bytes(mp_uint_t op, const byte *data1, mp_uint_t len1, const byt // Let's deal only with > & >= if (op == MP_BINARY_OP_LESS || op == MP_BINARY_OP_LESS_EQUAL) { SWAP(const byte*, data1, data2); - SWAP(uint, len1, len2); + SWAP(size_t, len1, len2); if (op == MP_BINARY_OP_LESS) { op = MP_BINARY_OP_MORE; } else { op = MP_BINARY_OP_MORE_EQUAL; } } - uint min_len = len1 < len2 ? len1 : len2; + size_t min_len = len1 < len2 ? len1 : len2; int res = memcmp(data1, data2, min_len); if (op == MP_BINARY_OP_EQUAL) { // If we are checking for equality, here're the answer @@ -187,7 +187,7 @@ bool mp_seq_cmp_bytes(mp_uint_t op, const byte *data1, mp_uint_t len1, const byt // Special-case comparison function for sequences of mp_obj_t // Don't pass MP_BINARY_OP_NOT_EQUAL here -bool mp_seq_cmp_objs(mp_uint_t op, const mp_obj_t *items1, mp_uint_t len1, const mp_obj_t *items2, mp_uint_t len2) { +bool mp_seq_cmp_objs(mp_uint_t op, const mp_obj_t *items1, size_t len1, const mp_obj_t *items2, size_t len2) { if (op == MP_BINARY_OP_EQUAL && len1 != len2) { return false; } @@ -195,7 +195,7 @@ bool mp_seq_cmp_objs(mp_uint_t op, const mp_obj_t *items1, mp_uint_t len1, const // Let's deal only with > & >= if (op == MP_BINARY_OP_LESS || op == MP_BINARY_OP_LESS_EQUAL) { SWAP(const mp_obj_t *, items1, items2); - SWAP(uint, len1, len2); + SWAP(size_t, len1, len2); if (op == MP_BINARY_OP_LESS) { op = MP_BINARY_OP_MORE; } else { @@ -203,8 +203,8 @@ bool mp_seq_cmp_objs(mp_uint_t op, const mp_obj_t *items1, mp_uint_t len1, const } } - mp_uint_t len = len1 < len2 ? len1 : len2; - for (mp_uint_t i = 0; i < len; i++) { + size_t len = len1 < len2 ? len1 : len2; + for (size_t i = 0; i < len; i++) { // If current elements equal, can't decide anything - go on if (mp_obj_equal(items1[i], items2[i])) { continue; @@ -236,7 +236,7 @@ bool mp_seq_cmp_objs(mp_uint_t op, const mp_obj_t *items1, mp_uint_t len1, const } // Special-case of index() which searches for mp_obj_t -mp_obj_t mp_seq_index_obj(const mp_obj_t *items, mp_uint_t len, mp_uint_t n_args, const mp_obj_t *args) { +mp_obj_t mp_seq_index_obj(const mp_obj_t *items, size_t len, size_t n_args, const mp_obj_t *args) { mp_obj_type_t *type = mp_obj_get_type(args[0]); mp_obj_t value = args[1]; size_t start = 0; @@ -259,9 +259,9 @@ mp_obj_t mp_seq_index_obj(const mp_obj_t *items, mp_uint_t len, mp_uint_t n_args mp_raise_msg(&mp_type_ValueError, "object not in sequence"); } -mp_obj_t mp_seq_count_obj(const mp_obj_t *items, mp_uint_t len, mp_obj_t value) { - mp_uint_t count = 0; - for (uint i = 0; i < len; i++) { +mp_obj_t mp_seq_count_obj(const mp_obj_t *items, size_t len, mp_obj_t value) { + size_t count = 0; + for (size_t i = 0; i < len; i++) { if (mp_obj_equal(items[i], value)) { count++; } -- cgit v1.2.3 From 60656eaea41df16557fbbdb51d9b8fc2cf7662a1 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 23 Mar 2017 16:36:08 +1100 Subject: py: Define and use MP_OBJ_ITER_BUF_NSLOTS to get size of stack iter buf. It improves readability of code and reduces the chance to make a mistake. This patch also fixes a bug with nan-boxing builds by rounding up the calculation of the new NSLOTS variable, giving the correct number of slots (being 4) even if mp_obj_t is larger than the native machine size. --- py/compile.c | 1 + py/emitbc.c | 6 +++--- py/emitnative.c | 8 ++++---- py/obj.h | 4 ++++ py/vm.c | 23 ++++++++++++----------- 5 files changed, 24 insertions(+), 18 deletions(-) (limited to 'py/obj.h') diff --git a/py/compile.c b/py/compile.c index ca21d8294..2fbc19cc3 100644 --- a/py/compile.c +++ b/py/compile.c @@ -3005,6 +3005,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { // There are 4 slots on the stack for the iterator, and the first one is // NULL to indicate that the second one points to the iterator object. if (scope->kind == SCOPE_GEN_EXPR) { + // TODO static assert that MP_OBJ_ITER_BUF_NSLOTS == 4 EMIT(load_null); compile_load_id(comp, qstr_arg); EMIT(load_null); diff --git a/py/emitbc.c b/py/emitbc.c index 0076c147e..673cd405f 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -735,7 +735,7 @@ void mp_emit_bc_unwind_jump(emit_t *emit, mp_uint_t label, mp_uint_t except_dept // need to pop the iterator if we are breaking out of a for loop emit_write_bytecode_byte(emit, MP_BC_POP_TOP); // also pop the iter_buf - for (size_t i = 0; i < sizeof(mp_obj_iter_buf_t) / sizeof(mp_obj_t) - 1; ++i) { + for (size_t i = 0; i < MP_OBJ_ITER_BUF_NSLOTS - 1; ++i) { emit_write_bytecode_byte(emit, MP_BC_POP_TOP); } } @@ -778,7 +778,7 @@ void mp_emit_bc_end_finally(emit_t *emit) { } void mp_emit_bc_get_iter(emit_t *emit, bool use_stack) { - emit_bc_pre(emit, use_stack ? sizeof(mp_obj_iter_buf_t) / sizeof(mp_obj_t) - 1 : 0); + emit_bc_pre(emit, use_stack ? MP_OBJ_ITER_BUF_NSLOTS - 1 : 0); emit_write_bytecode_byte(emit, use_stack ? MP_BC_GET_ITER_STACK : MP_BC_GET_ITER); } @@ -788,7 +788,7 @@ void mp_emit_bc_for_iter(emit_t *emit, mp_uint_t label) { } void mp_emit_bc_for_iter_end(emit_t *emit) { - emit_bc_pre(emit, -(sizeof(mp_obj_iter_buf_t) / sizeof(mp_obj_t))); + emit_bc_pre(emit, -MP_OBJ_ITER_BUF_NSLOTS); } void mp_emit_bc_pop_block(emit_t *emit) { diff --git a/py/emitnative.c b/py/emitnative.c index 4af68102b..3ab001f8d 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -1761,7 +1761,7 @@ STATIC void emit_native_get_iter(emit_t *emit, bool use_stack) { emit_pre_pop_reg(emit, &vtype, REG_ARG_1); assert(vtype == VTYPE_PYOBJ); if (use_stack) { - emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_2, sizeof(mp_obj_iter_buf_t) / sizeof(mp_obj_t)); + emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_2, MP_OBJ_ITER_BUF_NSLOTS); emit_call(emit, MP_F_NATIVE_GETITER); } else { // mp_getiter will allocate the iter_buf on the heap @@ -1773,8 +1773,8 @@ STATIC void emit_native_get_iter(emit_t *emit, bool use_stack) { STATIC void emit_native_for_iter(emit_t *emit, mp_uint_t label) { emit_native_pre(emit); - emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_1, sizeof(mp_obj_iter_buf_t) / sizeof(mp_obj_t)); - adjust_stack(emit, 4); + emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_1, MP_OBJ_ITER_BUF_NSLOTS); + adjust_stack(emit, MP_OBJ_ITER_BUF_NSLOTS); emit_call(emit, MP_F_NATIVE_ITERNEXT); ASM_MOV_IMM_TO_REG(emit->as, (mp_uint_t)MP_OBJ_STOP_ITERATION, REG_TEMP1); ASM_JUMP_IF_REG_EQ(emit->as, REG_RET, REG_TEMP1, label); @@ -1784,7 +1784,7 @@ STATIC void emit_native_for_iter(emit_t *emit, mp_uint_t label) { STATIC void emit_native_for_iter_end(emit_t *emit) { // adjust stack counter (we get here from for_iter ending, which popped the value for us) emit_native_pre(emit); - adjust_stack(emit, -(sizeof(mp_obj_iter_buf_t) / sizeof(mp_obj_t))); + adjust_stack(emit, -MP_OBJ_ITER_BUF_NSLOTS); emit_post(emit); } diff --git a/py/obj.h b/py/obj.h index 93078b81e..fc122c490 100644 --- a/py/obj.h +++ b/py/obj.h @@ -422,6 +422,10 @@ typedef struct _mp_obj_iter_buf_t { mp_obj_t buf[3]; } mp_obj_iter_buf_t; +// The number of slots that an mp_obj_iter_buf_t needs on the Python value stack. +// It's rounded up in case mp_obj_base_t is smaller than mp_obj_t (eg for OBJ_REPR_D). +#define MP_OBJ_ITER_BUF_NSLOTS ((sizeof(mp_obj_iter_buf_t) + sizeof(mp_obj_t) - 1) / sizeof(mp_obj_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); diff --git a/py/vm.c b/py/vm.c index ed8b9ec4d..96029664a 100644 --- a/py/vm.c +++ b/py/vm.c @@ -684,7 +684,7 @@ unwind_jump:; if (unum != 0) { // pop iter and iter_buf sp--; - sp -= sizeof(mp_obj_iter_buf_t) / sizeof(mp_obj_t); + sp -= MP_OBJ_ITER_BUF_NSLOTS; } DISPATCH_WITH_PEND_EXC_CHECK(); } @@ -729,19 +729,20 @@ unwind_jump:; SET_TOP(mp_getiter(TOP(), NULL)); DISPATCH(); - // An iterator for a for-loop takes 4 slots on the stack. They are either - // used to store the iterator object itself, or the first slot is NULL and + // An iterator for a for-loop takes MP_OBJ_ITER_BUF_NSLOTS slots on + // the Python value stack. These slots are either used to store the + // iterator object itself, or the first slot is MP_OBJ_NULL and // the second slot holds a reference to the iterator object. ENTRY(MP_BC_GET_ITER_STACK): { MARK_EXC_IP_SELECTIVE(); mp_obj_t obj = TOP(); mp_obj_iter_buf_t *iter_buf = (mp_obj_iter_buf_t*)sp; - sp += sizeof(mp_obj_iter_buf_t) / sizeof(mp_obj_t) - 1; + sp += MP_OBJ_ITER_BUF_NSLOTS - 1; obj = mp_getiter(obj, iter_buf); if (obj != MP_OBJ_FROM_PTR(iter_buf)) { // Iterator didn't use the stack so indicate that with MP_OBJ_NULL. - sp[-3] = MP_OBJ_NULL; - sp[-2] = obj; + sp[-MP_OBJ_ITER_BUF_NSLOTS + 1] = MP_OBJ_NULL; + sp[-MP_OBJ_ITER_BUF_NSLOTS + 2] = obj; } DISPATCH(); } @@ -751,14 +752,14 @@ unwind_jump:; DECODE_ULABEL; // the jump offset if iteration finishes; for labels are always forward code_state->sp = sp; mp_obj_t obj; - if (sp[-3] == MP_OBJ_NULL) { - obj = sp[-2]; + if (sp[-MP_OBJ_ITER_BUF_NSLOTS + 1] == MP_OBJ_NULL) { + obj = sp[-MP_OBJ_ITER_BUF_NSLOTS + 2]; } else { - obj = MP_OBJ_FROM_PTR(&sp[-3]); + obj = MP_OBJ_FROM_PTR(&sp[-MP_OBJ_ITER_BUF_NSLOTS + 1]); } mp_obj_t value = mp_iternext_allow_raise(obj); if (value == MP_OBJ_STOP_ITERATION) { - sp -= 4; // pop the exhausted iterator + sp -= MP_OBJ_ITER_BUF_NSLOTS; // pop the exhausted iterator ip += ulab; // jump to after for-block } else { PUSH(value); // push the next iteration value @@ -1334,7 +1335,7 @@ exception_handler: const byte *ip = code_state->ip + 1; DECODE_ULABEL; // the jump offset if iteration finishes; for labels are always forward code_state->ip = ip + ulab; // jump to after for-block - code_state->sp -= 4; // pop the exhausted iterator + code_state->sp -= MP_OBJ_ITER_BUF_NSLOTS; // pop the exhausted iterator goto outer_dispatch_loop; // continue with dispatch loop } else if (*code_state->ip == MP_BC_YIELD_FROM) { // StopIteration inside yield from call means return a value of -- cgit v1.2.3 From 3f810daeb310520beb1635510430c0c6b6123548 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 26 Mar 2017 19:20:06 +1100 Subject: py/obj: Change mp_uint_t to size_t for mp_obj_get_array_fixed_n len arg. --- py/obj.c | 2 +- py/obj.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'py/obj.h') diff --git a/py/obj.c b/py/obj.c index 65a35c86f..c065a3bfc 100644 --- a/py/obj.c +++ b/py/obj.c @@ -337,7 +337,7 @@ void mp_obj_get_array(mp_obj_t o, mp_uint_t *len, mp_obj_t **items) { } // note: returned value in *items may point to the interior of a GC block -void mp_obj_get_array_fixed_n(mp_obj_t o, mp_uint_t len, mp_obj_t **items) { +void mp_obj_get_array_fixed_n(mp_obj_t o, size_t len, mp_obj_t **items) { mp_uint_t seq_len; mp_obj_get_array(o, &seq_len, items); if (seq_len != len) { diff --git a/py/obj.h b/py/obj.h index fc122c490..71945f4f1 100644 --- a/py/obj.h +++ b/py/obj.h @@ -677,7 +677,7 @@ void mp_obj_get_complex(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag); #endif //qstr mp_obj_get_qstr(mp_obj_t arg); void mp_obj_get_array(mp_obj_t o, mp_uint_t *len, mp_obj_t **items); // *items may point inside a GC block -void mp_obj_get_array_fixed_n(mp_obj_t o, mp_uint_t len, mp_obj_t **items); // *items may point inside a GC block +void mp_obj_get_array_fixed_n(mp_obj_t o, size_t len, mp_obj_t **items); // *items may point inside a GC block size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool is_slice); mp_obj_t mp_obj_id(mp_obj_t o_in); mp_obj_t mp_obj_len(mp_obj_t o_in); -- cgit v1.2.3 From 6213ad7f466df12c734dc527993bbb46c9d9eb5c Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 25 Mar 2017 19:35:08 +1100 Subject: py: Convert mp_uint_t to size_t for tuple/list accessors. This patch changes mp_uint_t to size_t for the len argument of the following public facing C functions: mp_obj_tuple_get mp_obj_list_get mp_obj_get_array These functions take a pointer to the len argument (to be filled in by the function) and callers of these functions should update their code so the type of len is changed to size_t. For ports that don't use nan-boxing there should be no change in generate code because the size of the type remains the same (word sized), and in a lot of cases there won't even be a compiler warning if the type remains as mp_uint_t. The reason for this change is to standardise on the use of size_t for variables that count memory (or memory related) sizes/lengths. It helps builds that use nan-boxing. --- py/builtinimport.c | 2 +- py/modthread.c | 2 +- py/obj.c | 4 ++-- py/obj.h | 6 +++--- py/objfun.c | 2 +- py/objlist.c | 4 ++-- py/objnamedtuple.c | 2 +- py/objstr.c | 4 ++-- py/objtuple.c | 2 +- py/objtype.c | 4 ++-- py/runtime.c | 6 +++--- 11 files changed, 19 insertions(+), 19 deletions(-) (limited to 'py/obj.h') diff --git a/py/builtinimport.c b/py/builtinimport.c index 17c1622ef..8101d633f 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -97,7 +97,7 @@ STATIC mp_import_stat_t stat_dir_or_file(vstr_t *path) { STATIC mp_import_stat_t find_file(const char *file_str, uint file_len, vstr_t *dest) { #if MICROPY_PY_SYS // extract the list of paths - mp_uint_t path_num; + size_t path_num; mp_obj_t *path_items; mp_obj_list_get(mp_sys_path, &path_num, &path_items); diff --git a/py/modthread.c b/py/modthread.c index ecf470527..d0e71dad3 100644 --- a/py/modthread.c +++ b/py/modthread.c @@ -215,7 +215,7 @@ STATIC mp_obj_t mod_thread_start_new_thread(size_t n_args, const mp_obj_t *args) thread_entry_args_t *th_args; // get positional arguments - mp_uint_t pos_args_len; + size_t pos_args_len; mp_obj_t *pos_args_items; mp_obj_get_array(args[1], &pos_args_len, &pos_args_items); diff --git a/py/obj.c b/py/obj.c index 4b5fe2532..98ffa930b 100644 --- a/py/obj.c +++ b/py/obj.c @@ -321,7 +321,7 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) { #endif // note: returned value in *items may point to the interior of a GC block -void mp_obj_get_array(mp_obj_t o, mp_uint_t *len, mp_obj_t **items) { +void mp_obj_get_array(mp_obj_t o, size_t *len, mp_obj_t **items) { if (MP_OBJ_IS_TYPE(o, &mp_type_tuple)) { mp_obj_tuple_get(o, len, items); } else if (MP_OBJ_IS_TYPE(o, &mp_type_list)) { @@ -338,7 +338,7 @@ void mp_obj_get_array(mp_obj_t o, mp_uint_t *len, mp_obj_t **items) { // note: returned value in *items may point to the interior of a GC block void mp_obj_get_array_fixed_n(mp_obj_t o, size_t len, mp_obj_t **items) { - mp_uint_t seq_len; + size_t seq_len; mp_obj_get_array(o, &seq_len, items); if (seq_len != len) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { diff --git a/py/obj.h b/py/obj.h index 71945f4f1..65543b785 100644 --- a/py/obj.h +++ b/py/obj.h @@ -676,7 +676,7 @@ mp_float_t mp_obj_get_float(mp_obj_t self_in); void mp_obj_get_complex(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag); #endif //qstr mp_obj_get_qstr(mp_obj_t arg); -void mp_obj_get_array(mp_obj_t o, mp_uint_t *len, mp_obj_t **items); // *items may point inside a GC block +void mp_obj_get_array(mp_obj_t o, size_t *len, mp_obj_t **items); // *items may point inside a GC block void mp_obj_get_array_fixed_n(mp_obj_t o, size_t len, mp_obj_t **items); // *items may point inside a GC block size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool is_slice); mp_obj_t mp_obj_id(mp_obj_t o_in); @@ -728,7 +728,7 @@ mp_obj_t mp_obj_complex_binary_op(mp_uint_t op, mp_float_t lhs_real, mp_float_t #endif // tuple -void mp_obj_tuple_get(mp_obj_t self_in, mp_uint_t *len, mp_obj_t **items); +void mp_obj_tuple_get(mp_obj_t self_in, size_t *len, mp_obj_t **items); void mp_obj_tuple_del(mp_obj_t self_in); mp_int_t mp_obj_tuple_hash(mp_obj_t self_in); @@ -737,7 +737,7 @@ struct _mp_obj_list_t; void mp_obj_list_init(struct _mp_obj_list_t *o, size_t n); mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg); mp_obj_t mp_obj_list_remove(mp_obj_t self_in, mp_obj_t value); -void mp_obj_list_get(mp_obj_t self_in, mp_uint_t *len, mp_obj_t **items); +void mp_obj_list_get(mp_obj_t self_in, size_t *len, mp_obj_t **items); void mp_obj_list_set_len(mp_obj_t self_in, size_t len); void mp_obj_list_store(mp_obj_t self_in, mp_obj_t index, mp_obj_t value); mp_obj_t mp_obj_list_sort(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs); diff --git a/py/objfun.c b/py/objfun.c index 4670521b4..2ce33cb21 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -513,7 +513,7 @@ STATIC mp_uint_t convert_obj_for_inline_asm(mp_obj_t obj) { #endif } else if (type == &mp_type_tuple || type == &mp_type_list) { // pointer to start of tuple (could pass length, but then could use len(x) for that) - mp_uint_t len; + size_t len; mp_obj_t *items; mp_obj_get_array(obj, &len, &items); return (mp_uint_t)items; diff --git a/py/objlist.c b/py/objlist.c index 312cef6d3..45e69c8bc 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -192,7 +192,7 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { #if MICROPY_PY_BUILTINS_SLICE if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in); - mp_uint_t value_len; mp_obj_t *value_items; + size_t value_len; mp_obj_t *value_items; mp_obj_get_array(value, &value_len, &value_items); mp_bound_slice_t slice_out; if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice_out)) { @@ -475,7 +475,7 @@ mp_obj_t mp_obj_new_list(size_t n, mp_obj_t *items) { return MP_OBJ_FROM_PTR(o); } -void mp_obj_list_get(mp_obj_t self_in, mp_uint_t *len, mp_obj_t **items) { +void mp_obj_list_get(mp_obj_t self_in, size_t *len, mp_obj_t **items) { mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in); *len = self->len; *items = self->items; diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index 2371518b9..52468747b 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -158,7 +158,7 @@ STATIC mp_obj_t mp_obj_new_namedtuple_type(qstr name, size_t n_fields, mp_obj_t STATIC mp_obj_t new_namedtuple_type(mp_obj_t name_in, mp_obj_t fields_in) { qstr name = mp_obj_str_get_qstr(name_in); - mp_uint_t n_fields; + size_t n_fields; mp_obj_t *fields; #if MICROPY_CPYTHON_COMPAT if (MP_OBJ_IS_STR(fields_in)) { diff --git a/py/objstr.c b/py/objstr.c index 4053efb88..682bd2693 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -284,7 +284,7 @@ mp_obj_t mp_obj_str_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { // check for modulo if (op == MP_BINARY_OP_MODULO) { mp_obj_t *args = &rhs_in; - mp_uint_t n_args = 1; + size_t n_args = 1; mp_obj_t dict = MP_OBJ_NULL; if (MP_OBJ_IS_TYPE(rhs_in, &mp_type_tuple)) { // TODO: Support tuple subclasses? @@ -428,7 +428,7 @@ STATIC mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { GET_STR_DATA_LEN(self_in, sep_str, sep_len); // process args - mp_uint_t seq_len; + size_t seq_len; mp_obj_t *seq_items; if (!MP_OBJ_IS_TYPE(arg, &mp_type_list) && !MP_OBJ_IS_TYPE(arg, &mp_type_tuple)) { diff --git a/py/objtuple.c b/py/objtuple.c index a8efdc7f9..fa5309aae 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -244,7 +244,7 @@ mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items) { return MP_OBJ_FROM_PTR(o); } -void mp_obj_tuple_get(mp_obj_t self_in, mp_uint_t *len, mp_obj_t **items) { +void mp_obj_tuple_get(mp_obj_t self_in, size_t *len, mp_obj_t **items) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_tuple)); mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in); *len = self->len; diff --git a/py/objtype.c b/py/objtype.c index a64832c1f..dd170b4c6 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -916,7 +916,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) // TODO might need to make a copy of locals_dict; at least that's how CPython does it // Basic validation of base classes - mp_uint_t len; + size_t len; mp_obj_t *items; mp_obj_tuple_get(bases_tuple, &len, &items); for (size_t i = 0; i < len; i++) { @@ -1098,7 +1098,7 @@ bool mp_obj_is_subclass_fast(mp_const_obj_t object, mp_const_obj_t classinfo) { } STATIC mp_obj_t mp_obj_is_subclass(mp_obj_t object, mp_obj_t classinfo) { - mp_uint_t len; + size_t len; mp_obj_t *items; if (MP_OBJ_IS_TYPE(classinfo, &mp_type_type)) { len = 1; diff --git a/py/runtime.c b/py/runtime.c index 9f6c654ab..73886e10f 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -670,7 +670,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_ // optimise the case of a tuple and list // get the items - mp_uint_t len; + size_t len; mp_obj_t *items; mp_obj_get_array(pos_seq, &len, &items); @@ -799,7 +799,7 @@ mp_obj_t mp_call_method_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_ob // unpacked items are stored in reverse order into the array pointed to by items void mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items) { - mp_uint_t seq_len; + size_t seq_len; if (MP_OBJ_IS_TYPE(seq_in, &mp_type_tuple) || MP_OBJ_IS_TYPE(seq_in, &mp_type_list)) { mp_obj_t *seq_items; mp_obj_get_array(seq_in, &seq_len, &seq_items); @@ -849,7 +849,7 @@ void mp_unpack_ex(mp_obj_t seq_in, size_t num_in, mp_obj_t *items) { size_t num_left = num_in & 0xff; size_t num_right = (num_in >> 8) & 0xff; DEBUG_OP_printf("unpack ex " UINT_FMT " " UINT_FMT "\n", num_left, num_right); - mp_uint_t seq_len; + size_t seq_len; if (MP_OBJ_IS_TYPE(seq_in, &mp_type_tuple) || MP_OBJ_IS_TYPE(seq_in, &mp_type_list)) { mp_obj_t *seq_items; mp_obj_get_array(seq_in, &seq_len, &seq_items); -- cgit v1.2.3 From 6b341075376705ee1fe9e003b76b09afa59778f4 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 25 Mar 2017 19:48:18 +1100 Subject: py: Change mp_uint_t to size_t for mp_obj_str_get_data len arg. --- py/builtinevex.c | 4 ++-- py/builtinimport.c | 6 +++--- py/modbuiltins.c | 6 +++--- py/obj.h | 2 +- py/objcomplex.c | 2 +- py/objfloat.c | 2 +- py/objfun.c | 2 +- py/objint.c | 4 ++-- py/objstr.c | 12 ++++++------ py/repl.c | 6 +++--- py/runtime.c | 2 +- 11 files changed, 24 insertions(+), 24 deletions(-) (limited to 'py/obj.h') diff --git a/py/builtinevex.c b/py/builtinevex.c index 89fcc2fe1..d9a3833cc 100644 --- a/py/builtinevex.c +++ b/py/builtinevex.c @@ -78,7 +78,7 @@ STATIC mp_obj_t mp_builtin_compile(size_t n_args, const mp_obj_t *args) { (void)n_args; // get the source - mp_uint_t str_len; + size_t str_len; const char *str = mp_obj_str_get_data(args[0], &str_len); // get the filename @@ -128,7 +128,7 @@ STATIC mp_obj_t eval_exec_helper(size_t n_args, const mp_obj_t *args, mp_parse_i } #endif - mp_uint_t str_len; + size_t str_len; const char *str = mp_obj_str_get_data(args[0], &str_len); // create the lexer diff --git a/py/builtinimport.c b/py/builtinimport.c index 8101d633f..cf17d5305 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -111,7 +111,7 @@ STATIC mp_import_stat_t find_file(const char *file_str, uint file_len, vstr_t *d // go through each path looking for a directory or file for (mp_uint_t i = 0; i < path_num; i++) { vstr_reset(dest); - mp_uint_t p_len; + size_t p_len; const char *p = mp_obj_str_get_data(path_items[i], &p_len); if (p_len > 0) { vstr_add_strn(dest, p, p_len); @@ -265,7 +265,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { } } - mp_uint_t mod_len; + size_t mod_len; const char *mod_str = mp_obj_str_get_data(module_name, &mod_len); if (level != 0) { @@ -296,7 +296,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { DEBUG_printf("\n"); #endif - mp_uint_t this_name_l; + size_t this_name_l; const char *this_name = mp_obj_str_get_data(this_name_q, &this_name_l); const char *p = this_name + this_name_l; diff --git a/py/modbuiltins.c b/py/modbuiltins.c index f1d703a6d..e8119456d 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -336,7 +336,7 @@ STATIC mp_obj_t mp_builtin_oct(mp_obj_t o_in) { MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_oct_obj, mp_builtin_oct); STATIC mp_obj_t mp_builtin_ord(mp_obj_t o_in) { - mp_uint_t len; + size_t len; const char *str = mp_obj_str_get_data(o_in, &len); #if MICROPY_PY_BUILTINS_STR_UNICODE if (MP_OBJ_IS_STR(o_in)) { @@ -397,9 +397,9 @@ STATIC mp_obj_t mp_builtin_print(size_t n_args, const mp_obj_t *args, mp_map_t * mp_map_elem_t *sep_elem = mp_map_lookup(kwargs, MP_OBJ_NEW_QSTR(MP_QSTR_sep), MP_MAP_LOOKUP); mp_map_elem_t *end_elem = mp_map_lookup(kwargs, MP_OBJ_NEW_QSTR(MP_QSTR_end), MP_MAP_LOOKUP); const char *sep_data = " "; - mp_uint_t sep_len = 1; + size_t sep_len = 1; const char *end_data = "\n"; - mp_uint_t end_len = 1; + size_t end_len = 1; if (sep_elem != NULL && sep_elem->value != mp_const_none) { sep_data = mp_obj_str_get_data(sep_elem->value, &sep_len); } diff --git a/py/obj.h b/py/obj.h index 65543b785..580b814a8 100644 --- a/py/obj.h +++ b/py/obj.h @@ -712,7 +712,7 @@ void mp_init_emergency_exception_buf(void); bool mp_obj_str_equal(mp_obj_t s1, mp_obj_t s2); qstr mp_obj_str_get_qstr(mp_obj_t self_in); // use this if you will anyway convert the string to a qstr const char *mp_obj_str_get_str(mp_obj_t self_in); // use this only if you need the string to be null terminated -const char *mp_obj_str_get_data(mp_obj_t self_in, mp_uint_t *len); +const char *mp_obj_str_get_data(mp_obj_t self_in, size_t *len); mp_obj_t mp_obj_str_intern(mp_obj_t str); void mp_str_print_quoted(const mp_print_t *print, const byte *str_data, size_t str_len, bool is_bytes); diff --git a/py/objcomplex.c b/py/objcomplex.c index 426e76e5f..8118fb813 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -80,7 +80,7 @@ STATIC mp_obj_t complex_make_new(const mp_obj_type_t *type_in, size_t n_args, si case 1: if (MP_OBJ_IS_STR(args[0])) { // a string, parse it - mp_uint_t l; + size_t l; const char *s = mp_obj_str_get_data(args[0], &l); return mp_parse_num_decimal(s, l, true, true, NULL); } else if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) { diff --git a/py/objfloat.c b/py/objfloat.c index 9292490a9..6d80d6c0e 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -89,7 +89,7 @@ STATIC mp_obj_t float_make_new(const mp_obj_type_t *type_in, size_t n_args, size default: if (MP_OBJ_IS_STR(args[0])) { // a string, parse it - mp_uint_t l; + size_t l; const char *s = mp_obj_str_get_data(args[0], &l); return mp_parse_num_decimal(s, l, false, false, NULL); } else if (mp_obj_is_float(args[0])) { diff --git a/py/objfun.c b/py/objfun.c index 2ce33cb21..08d031c8d 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -501,7 +501,7 @@ STATIC mp_uint_t convert_obj_for_inline_asm(mp_obj_t obj) { return mp_obj_int_get_truncated(obj); } else if (MP_OBJ_IS_STR(obj)) { // pointer to the string (it's probably constant though!) - mp_uint_t l; + size_t l; return (mp_uint_t)mp_obj_str_get_data(obj, &l); } else { mp_obj_type_t *type = mp_obj_get_type(obj); diff --git a/py/objint.c b/py/objint.c index ce091549d..2e8fe4f22 100644 --- a/py/objint.c +++ b/py/objint.c @@ -56,7 +56,7 @@ STATIC mp_obj_t mp_obj_int_make_new(const mp_obj_type_t *type_in, size_t n_args, return args[0]; } else if (MP_OBJ_IS_STR_OR_BYTES(args[0])) { // a string, parse it - mp_uint_t l; + size_t l; const char *s = mp_obj_str_get_data(args[0], &l); return mp_parse_num_integer(s, l, 0, NULL); #if MICROPY_PY_BUILTINS_FLOAT @@ -72,7 +72,7 @@ STATIC mp_obj_t mp_obj_int_make_new(const mp_obj_type_t *type_in, size_t n_args, default: { // should be a string, parse it // TODO proper error checking of argument types - mp_uint_t l; + size_t l; const char *s = mp_obj_str_get_data(args[0], &l); return mp_parse_num_integer(s, l, mp_obj_get_int(args[1]), NULL); } diff --git a/py/objstr.c b/py/objstr.c index 682bd2693..60a26d45b 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -513,7 +513,7 @@ mp_obj_t mp_obj_str_split(size_t n_args, const mp_obj_t *args) { bad_implicit_conversion(sep); } - mp_uint_t sep_len; + size_t sep_len; const char *sep_str = mp_obj_str_get_data(sep, &sep_len); if (sep_len == 0) { @@ -611,7 +611,7 @@ STATIC mp_obj_t str_rsplit(size_t n_args, const mp_obj_t *args) { if (sep == mp_const_none) { mp_not_implemented("rsplit(None,n)"); } else { - mp_uint_t sep_len; + size_t sep_len; const char *sep_str = mp_obj_str_get_data(sep, &sep_len); if (sep_len == 0) { @@ -1306,12 +1306,12 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar switch (type) { case '\0': // no explicit format type implies 's' case 's': { - mp_uint_t slen; + size_t slen; const char *s = mp_obj_str_get_data(arg, &slen); if (precision < 0) { precision = slen; } - if (slen > (mp_uint_t)precision) { + if (slen > (size_t)precision) { slen = precision; } mp_print_strn(&print, s, slen, flags, fill, width); @@ -1452,7 +1452,7 @@ not_enough_args: switch (*str) { case 'c': if (MP_OBJ_IS_STR(arg)) { - mp_uint_t slen; + size_t slen; const char *s = mp_obj_str_get_data(arg, &slen); if (slen != 1) { mp_raise_TypeError("%%c requires int or char"); @@ -2097,7 +2097,7 @@ const char *mp_obj_str_get_str(mp_obj_t self_in) { } } -const char *mp_obj_str_get_data(mp_obj_t self_in, mp_uint_t *len) { +const char *mp_obj_str_get_data(mp_obj_t self_in, size_t *len) { if (MP_OBJ_IS_STR_OR_BYTES(self_in)) { GET_STR_DATA_LEN(self_in, s, l); *len = l; diff --git a/py/repl.c b/py/repl.c index 997d80005..6d8f7cca4 100644 --- a/py/repl.c +++ b/py/repl.c @@ -153,7 +153,7 @@ mp_uint_t mp_repl_autocomplete(const char *str, mp_uint_t len, const mp_print_t mp_obj_t obj = MP_OBJ_NULL; for (mp_uint_t i = 0; i < dict->map.alloc; i++) { if (MP_MAP_SLOT_IS_FILLED(&dict->map, i)) { - mp_uint_t d_len; + size_t d_len; const char *d_str = mp_obj_str_get_data(dict->map.table[i].key, &d_len); if (s_len == d_len && strncmp(s_start, d_str, d_len) == 0) { obj = dict->map.table[i].value; @@ -197,7 +197,7 @@ mp_uint_t mp_repl_autocomplete(const char *str, mp_uint_t len, const mp_print_t mp_uint_t match_len = 0; for (mp_uint_t i = 0; i < dict->map.alloc; i++) { if (MP_MAP_SLOT_IS_FILLED(&dict->map, i)) { - mp_uint_t d_len; + size_t d_len; const char *d_str = mp_obj_str_get_data(dict->map.table[i].key, &d_len); if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { if (match_str == NULL) { @@ -247,7 +247,7 @@ mp_uint_t mp_repl_autocomplete(const char *str, mp_uint_t len, const mp_print_t int line_len = MAX_LINE_LEN; // force a newline for first word for (mp_uint_t i = 0; i < dict->map.alloc; i++) { if (MP_MAP_SLOT_IS_FILLED(&dict->map, i)) { - mp_uint_t d_len; + size_t d_len; const char *d_str = mp_obj_str_get_data(dict->map.table[i].key, &d_len); if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { int gap = (line_len + WORD_SLOT_LEN - 1) / WORD_SLOT_LEN * WORD_SLOT_LEN - line_len; diff --git a/py/runtime.c b/py/runtime.c index 73886e10f..1df6740b2 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1330,7 +1330,7 @@ import_error: } mp_load_method_maybe(module, MP_QSTR___name__, dest); - mp_uint_t pkg_name_len; + size_t pkg_name_len; const char *pkg_name = mp_obj_str_get_data(dest[0], &pkg_name_len); const uint dot_name_len = pkg_name_len + 1 + qstr_len(name); -- cgit v1.2.3 From a5500a8aad263054e9530a03da18c0c0961424b2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 2 Apr 2017 17:28:24 +1000 Subject: py/obj.h: Make sequence grow more efficient and support overlapping. The first memmove now copies less bytes in some cases (because len_adj <= slice_len), and the memcpy is replaced with memmove to support the possibility that dest and slice regions are overlapping. --- py/obj.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'py/obj.h') diff --git a/py/obj.h b/py/obj.h index 580b814a8..b19aca29a 100644 --- a/py/obj.h +++ b/py/obj.h @@ -842,9 +842,10 @@ mp_obj_t mp_seq_extract_slice(size_t len, const mp_obj_t *seq, mp_bound_slice_t /*printf("memmove(%p, %p, %d)\n", dest + (beg + slice_len), dest + end, (dest_len - end) * (item_sz));*/ \ memmove(((char*)dest) + (beg + slice_len) * (item_sz), ((char*)dest) + (end) * (item_sz), (dest_len - end) * (item_sz)); +// Note: dest and slice regions may overlap #define mp_seq_replace_slice_grow_inplace(dest, dest_len, beg, end, slice, slice_len, len_adj, item_sz) \ /*printf("memmove(%p, %p, %d)\n", dest + beg + len_adj, dest + beg, (dest_len - beg) * (item_sz));*/ \ - memmove(((char*)dest) + (beg + len_adj) * (item_sz), ((char*)dest) + (beg) * (item_sz), (dest_len - beg) * (item_sz)); \ - memcpy(((char*)dest) + (beg) * (item_sz), slice, slice_len * (item_sz)); + memmove(((char*)dest) + (beg + slice_len) * (item_sz), ((char*)dest) + (end) * (item_sz), ((dest_len) + (len_adj) - ((beg) + (slice_len))) * (item_sz)); \ + memmove(((char*)dest) + (beg) * (item_sz), slice, slice_len * (item_sz)); #endif // __MICROPY_INCLUDED_PY_OBJ_H__ -- cgit v1.2.3 From 19f2e47d59b539f94a49137c379c88f0aed53cf1 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 4 Apr 2017 11:57:21 +1000 Subject: py: Add very simple but correct hashing for float and complex numbers. Hashing of float and complex numbers that are exact (real) integers should return the same integer hash value as hashing the corresponding integer value. Eg hash(1), hash(1.0) and hash(1+0j) should all be the same (this is how Python is specified: if x==y then hash(x)==hash(y)). This patch implements the simplest way of doing float/complex hashing by just converting the value to int and returning that value. --- py/obj.h | 1 + py/objcomplex.c | 1 + py/objfloat.c | 1 + 3 files changed, 3 insertions(+) (limited to 'py/obj.h') diff --git a/py/obj.h b/py/obj.h index b19aca29a..49ba645f7 100644 --- a/py/obj.h +++ b/py/obj.h @@ -718,6 +718,7 @@ void mp_str_print_quoted(const mp_print_t *print, const byte *str_data, size_t s #if MICROPY_PY_BUILTINS_FLOAT // float +static inline mp_int_t mp_float_hash(mp_float_t val) { return (mp_int_t)val; } mp_obj_t mp_obj_float_binary_op(mp_uint_t op, mp_float_t lhs_val, mp_obj_t rhs); // can return MP_OBJ_NULL if op not supported // complex diff --git a/py/objcomplex.c b/py/objcomplex.c index 8118fb813..7ec47edb5 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -117,6 +117,7 @@ STATIC mp_obj_t complex_unary_op(mp_uint_t op, mp_obj_t o_in) { mp_obj_complex_t *o = MP_OBJ_TO_PTR(o_in); switch (op) { case MP_UNARY_OP_BOOL: return mp_obj_new_bool(o->real != 0 || o->imag != 0); + case MP_UNARY_OP_HASH: return MP_OBJ_NEW_SMALL_INT(mp_float_hash(o->real) ^ mp_float_hash(o->imag)); case MP_UNARY_OP_POSITIVE: return o_in; case MP_UNARY_OP_NEGATIVE: return mp_obj_new_complex(-o->real, -o->imag); default: return MP_OBJ_NULL; // op not supported diff --git a/py/objfloat.c b/py/objfloat.c index 6d80d6c0e..2c355d355 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -106,6 +106,7 @@ STATIC mp_obj_t float_unary_op(mp_uint_t op, mp_obj_t o_in) { mp_float_t val = mp_obj_float_get(o_in); switch (op) { case MP_UNARY_OP_BOOL: return mp_obj_new_bool(val != 0); + case MP_UNARY_OP_HASH: return MP_OBJ_NEW_SMALL_INT(mp_float_hash(val)); case MP_UNARY_OP_POSITIVE: return o_in; case MP_UNARY_OP_NEGATIVE: return mp_obj_new_float(-val); default: return MP_OBJ_NULL; // op not supported -- cgit v1.2.3 From fc710169b7fd8738b285c141f1850b262b26c622 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 6 Apr 2017 10:25:32 +1000 Subject: py/obj: Clean up and add comments describing mp_obj_type_t struct. --- py/obj.h | 55 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 23 deletions(-) (limited to 'py/obj.h') diff --git a/py/obj.h b/py/obj.h index 49ba645f7..45579ce8f 100644 --- a/py/obj.h +++ b/py/obj.h @@ -470,16 +470,27 @@ typedef struct _mp_stream_p_t { } mp_stream_p_t; struct _mp_obj_type_t { + // A type is an object so must start with this entry, which points to mp_type_type. mp_obj_base_t base; + + // The name of this type. qstr name; + + // Corresponds to __repr__ and __str__ special methods. mp_print_fun_t print; - mp_make_new_fun_t make_new; // to make an instance of the type + // Corresponds to __new__ and __init__ special methods, to make an instance of the type. + mp_make_new_fun_t make_new; + + // Corresponds to __call__ special method, ie T(...). mp_call_fun_t call; - mp_unary_op_fun_t unary_op; // can return MP_OBJ_NULL if op not supported - mp_binary_op_fun_t binary_op; // can return MP_OBJ_NULL if op not supported - // implements load, store and delete attribute + // Implements unary and binary operations. + // Can return MP_OBJ_NULL if the operation is not supported. + mp_unary_op_fun_t unary_op; + mp_binary_op_fun_t binary_op; + + // Implements load, store and delete attribute. // // dest[0] = MP_OBJ_NULL means load // return: for fail, do nothing @@ -492,35 +503,33 @@ struct _mp_obj_type_t { // for success set dest[0] = MP_OBJ_NULL mp_attr_fun_t attr; - mp_subscr_fun_t subscr; // implements load, store, delete subscripting - // value=MP_OBJ_NULL means delete, value=MP_OBJ_SENTINEL means load, else store - // can return MP_OBJ_NULL if op not supported + // Implements load, store and delete subscripting: + // - value = MP_OBJ_SENTINEL means load + // - value = MP_OBJ_NULL means delete + // - all other values mean store the value + // Can return MP_OBJ_NULL if operation not supported. + mp_subscr_fun_t subscr; - // 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 + // Corresponds to __iter__ special method. + // Can use the given mp_obj_iter_buf_t to store iterator object, + // 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) + // Corresponds to __next__ special method. May return MP_OBJ_STOP_ITERATION + // as an optimisation instead of raising StopIteration() with no args. + mp_fun_1_t iternext; + // Implements the buffer protocol if supported by this type. mp_buffer_p_t buffer_p; + // One of disjoint protocols (interfaces), like mp_stream_p_t, etc. const void *protocol; - // these are for dynamically created types (classes) + // A tuple containing all the base types of this type. struct _mp_obj_tuple_t *bases_tuple; - struct _mp_obj_dict_t *locals_dict; - - /* - What we might need to add here: - len str tuple list map - abs float complex - hash bool int none str - equal int str - - unpack seq list tuple - */ + // A dict mapping qstrs to objects local methods/constants/etc. + struct _mp_obj_dict_t *locals_dict; }; // Constant types, globally accessible -- 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/obj.h') 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 From a73501b1d63e5240cbced95b884383b79f5d6efd Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 6 Apr 2017 17:27:33 +1000 Subject: py/objfloat: Add implementation of high-quality float hashing. Disabled by default. --- py/mpconfig.h | 6 ++++++ py/obj.h | 4 ++++ py/objfloat.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) (limited to 'py/obj.h') diff --git a/py/mpconfig.h b/py/mpconfig.h index 06c19f72b..05cb5daaf 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -548,6 +548,12 @@ typedef double mp_float_t; #define MICROPY_PY_BUILTINS_COMPLEX (MICROPY_PY_BUILTINS_FLOAT) #endif +// Whether to provide a high-quality hash for float and complex numbers. +// Otherwise the default is a very simple but correct hashing function. +#ifndef MICROPY_FLOAT_HIGH_QUALITY_HASH +#define MICROPY_FLOAT_HIGH_QUALITY_HASH (0) +#endif + // Enable features which improve CPython compatibility // but may lead to more code size/memory usage. // TODO: Originally intended as generic category to not diff --git a/py/obj.h b/py/obj.h index 597c7c8d9..b5a0c4190 100644 --- a/py/obj.h +++ b/py/obj.h @@ -730,7 +730,11 @@ void mp_str_print_quoted(const mp_print_t *print, const byte *str_data, size_t s #if MICROPY_PY_BUILTINS_FLOAT // float +#if MICROPY_FLOAT_HIGH_QUALITY_HASH +mp_int_t mp_float_hash(mp_float_t val); +#else static inline mp_int_t mp_float_hash(mp_float_t val) { return (mp_int_t)val; } +#endif mp_obj_t mp_obj_float_binary_op(mp_uint_t op, mp_float_t lhs_val, mp_obj_t rhs); // can return MP_OBJ_NULL if op not supported // complex diff --git a/py/objfloat.c b/py/objfloat.c index 2c355d355..5cf995417 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -59,6 +59,55 @@ const mp_obj_float_t mp_const_float_pi_obj = {{&mp_type_float}, M_PI}; #endif +#if MICROPY_FLOAT_HIGH_QUALITY_HASH +// must return actual integer value if it fits in mp_int_t +mp_int_t mp_float_hash(mp_float_t src) { +#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE +typedef uint64_t mp_float_uint_t; +#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT +typedef uint32_t mp_float_uint_t; +#endif + union { + mp_float_t f; + #if MP_ENDIANNESS_LITTLE + struct { mp_float_uint_t frc:MP_FLOAT_FRAC_BITS, exp:MP_FLOAT_EXP_BITS, sgn:1; } p; + #else + struct { mp_float_uint_t sgn:1, exp:MP_FLOAT_EXP_BITS, frc:MP_FLOAT_FRAC_BITS; } p; + #endif + mp_float_uint_t i; + } u = {.f = src}; + + mp_int_t val; + const int adj_exp = (int)u.p.exp - MP_FLOAT_EXP_BIAS; + if (adj_exp < 0) { + // value < 1; must be sure to handle 0.0 correctly (ie return 0) + val = u.i; + } else { + // if adj_exp is max then: u.p.frc==0 indicates inf, else NaN + // else: 1 <= value + mp_float_uint_t frc = u.p.frc | ((mp_float_uint_t)1 << MP_FLOAT_FRAC_BITS); + + if (adj_exp <= MP_FLOAT_FRAC_BITS) { + // number may have a fraction; xor the integer part with the fractional part + val = (frc >> (MP_FLOAT_FRAC_BITS - adj_exp)) + ^ (frc & ((1 << (MP_FLOAT_FRAC_BITS - adj_exp)) - 1)); + } else if ((unsigned int)adj_exp < BITS_PER_BYTE * sizeof(mp_int_t) - 1) { + // the number is a (big) whole integer and will fit in val's signed-width + val = (mp_int_t)frc << (adj_exp - MP_FLOAT_FRAC_BITS); + } else { + // integer part will overflow val's width so just use what bits we can + val = frc; + } + } + + if (u.p.sgn) { + val = -val; + } + + return val; +} +#endif + STATIC void float_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { (void)kind; mp_float_t o_val = mp_obj_float_get(o_in); -- cgit v1.2.3 From 4df013c8ccf2e122a1bd3dd75d3937d46019409a Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 22 Apr 2017 12:14:04 +1000 Subject: py/objtype: mp_obj_new_super doesn't need to be public, so inline it. Saves code size (20 bytes on bare-arm) and makes it a tiny bit more efficient. --- py/obj.h | 1 - py/objtype.c | 10 +++------- 2 files changed, 3 insertions(+), 8 deletions(-) (limited to 'py/obj.h') diff --git a/py/obj.h b/py/obj.h index b5a0c4190..a3c06a261 100644 --- a/py/obj.h +++ b/py/obj.h @@ -661,7 +661,6 @@ mp_obj_t mp_obj_new_list(size_t n, mp_obj_t *items); mp_obj_t mp_obj_new_dict(size_t n_args); 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_iter_buf_t *iter_buf); mp_obj_t mp_obj_new_module(qstr module_name); diff --git a/py/objtype.c b/py/objtype.c index 5e522bed2..de1ee8c42 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -1013,7 +1013,9 @@ STATIC mp_obj_t super_make_new(const mp_obj_type_t *type_in, size_t n_args, size // 0 arguments are turned into 2 in the compiler // 1 argument is not yet implemented mp_arg_check_num(n_args, n_kw, 2, 2, false); - return mp_obj_new_super(args[0], args[1]); + mp_obj_super_t *o = m_new_obj(mp_obj_super_t); + *o = (mp_obj_super_t){{type_in}, args[0], args[1]}; + return MP_OBJ_FROM_PTR(o); } STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { @@ -1068,12 +1070,6 @@ const mp_obj_type_t mp_type_super = { .attr = super_attr, }; -mp_obj_t mp_obj_new_super(mp_obj_t type, mp_obj_t obj) { - mp_obj_super_t *o = m_new_obj(mp_obj_super_t); - *o = (mp_obj_super_t){{&mp_type_super}, type, obj}; - return MP_OBJ_FROM_PTR(o); -} - /******************************************************************************/ // subclassing and built-ins specific to types -- cgit v1.2.3