From 38a2da68c2e02b8fc5ae308ca9e3b667f8a0aedc Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 8 Jan 2014 17:33:12 +0000 Subject: [PATCH] py: Stuff qstr in object pointer; keys for mp_map_t are now always mp_obj_t. --- py/builtin.c | 2 +- py/map.c | 43 +++++++++---------- py/map.h | 22 +++++----- py/obj.c | 6 +++ py/obj.h | 16 +++++-- py/objclass.c | 2 +- py/objdict.c | 26 +++++------ py/objfun.c | 6 +-- py/objinstance.c | 14 +++--- py/objlist.c | 6 +-- py/objmodule.c | 4 +- py/runtime.c | 109 +++++++++++++++++++++++++---------------------- stm/pybwlan.c | 2 +- 13 files changed, 135 insertions(+), 123 deletions(-) diff --git a/py/builtin.c b/py/builtin.c index 4ee5c57c62..0d18508aff 100644 --- a/py/builtin.c +++ b/py/builtin.c @@ -23,7 +23,7 @@ mp_obj_t mp_builtin___build_class__(int n_args, const mp_obj_t *args) { // we differ from CPython: we set the new __locals__ object here mp_map_t *old_locals = rt_locals_get(); - mp_map_t *class_locals = mp_map_new(MP_MAP_QSTR, 0); + mp_map_t *class_locals = mp_map_new(0); rt_locals_set(class_locals); // call the class code diff --git a/py/map.c b/py/map.c index b88181989d..e44cf33d26 100644 --- a/py/map.c +++ b/py/map.c @@ -26,21 +26,22 @@ int get_doubling_prime_greater_or_equal_to(int x) { /******************************************************************************/ /* map */ -void mp_map_init(mp_map_t *map, mp_map_kind_t kind, int n) { - map->kind = kind; - map->used = 0; +void mp_map_init(mp_map_t *map, int n) { map->alloc = get_doubling_prime_greater_or_equal_to(n + 1); + map->used = 0; + map->all_keys_are_qstrs = 1; map->table = m_new0(mp_map_elem_t, map->alloc); } -mp_map_t *mp_map_new(mp_map_kind_t kind, int n) { +mp_map_t *mp_map_new(int n) { mp_map_t *map = m_new(mp_map_t, 1); - mp_map_init(map, kind, n); + mp_map_init(map, n); return map; } void mp_map_clear(mp_map_t *map) { map->used = 0; + map->all_keys_are_qstrs = 1; machine_uint_t a = map->alloc; map->alloc = 0; map->table = m_renew(mp_map_elem_t, map->table, a, map->alloc); @@ -50,30 +51,26 @@ void mp_map_clear(mp_map_t *map) { } } -static void mp_map_rehash (mp_map_t *map) { +static void mp_map_rehash(mp_map_t *map) { int old_alloc = map->alloc; mp_map_elem_t *old_table = map->table; map->alloc = get_doubling_prime_greater_or_equal_to(map->alloc + 1); map->used = 0; + map->all_keys_are_qstrs = 1; map->table = m_new0(mp_map_elem_t, map->alloc); for (int i = 0; i < old_alloc; i++) { if (old_table[i].key != NULL) { - mp_map_lookup_helper(map, old_table[i].key, true, false)->value = old_table[i].value; + mp_map_lookup(map, old_table[i].key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = old_table[i].value; } } m_del(mp_map_elem_t, old_table, old_alloc); } -mp_map_elem_t* mp_map_lookup_helper(mp_map_t *map, mp_obj_t index, bool add_if_not_found, bool remove_if_found) { - bool is_map_mp_obj = (map->kind == MP_MAP_OBJ); +mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind) { machine_uint_t hash; - if (is_map_mp_obj) { - hash = mp_obj_hash(index); - } else { - hash = (machine_uint_t)index; - } + hash = mp_obj_hash(index); if (map->alloc == 0) { - if (add_if_not_found) { + if (lookup_kind == MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) { mp_map_rehash(map); } else { return NULL; @@ -84,7 +81,7 @@ mp_map_elem_t* mp_map_lookup_helper(mp_map_t *map, mp_obj_t index, bool add_if_n mp_map_elem_t *elem = &map->table[pos]; if (elem->key == NULL) { // not in table - if (add_if_not_found) { + if (lookup_kind == MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) { if (map->used + 1 >= map->alloc) { // not enough room in table, rehash it mp_map_rehash(map); @@ -93,21 +90,24 @@ mp_map_elem_t* mp_map_lookup_helper(mp_map_t *map, mp_obj_t index, bool add_if_n } else { map->used += 1; elem->key = index; + if (!MP_OBJ_IS_QSTR(index)) { + map->all_keys_are_qstrs = 0; + } return elem; } } else { return NULL; } - } else if (elem->key == index || (is_map_mp_obj && mp_obj_equal(elem->key, index))) { + } else if (elem->key == index || (!map->all_keys_are_qstrs && mp_obj_equal(elem->key, index))) { // found it /* it seems CPython does not replace the index; try x={True:'true'};x[1]='one';x if (add_if_not_found) { elem->key = index; } */ - if (remove_if_found) { + if (lookup_kind == MP_MAP_LOOKUP_REMOVE_IF_FOUND) { map->used--; - /* this leaks this memory (but see dict_get_helper) */ + // this leaks this memory (but see dict_get_helper) mp_map_elem_t *retval = m_new(mp_map_elem_t, 1); retval->key = elem->key; retval->value = elem->value; @@ -123,11 +123,6 @@ mp_map_elem_t* mp_map_lookup_helper(mp_map_t *map, mp_obj_t index, bool add_if_n } } -mp_map_elem_t* mp_qstr_map_lookup(mp_map_t *map, qstr index, bool add_if_not_found) { - mp_obj_t o = (mp_obj_t)(machine_uint_t)index; - return mp_map_lookup_helper(map, o, add_if_not_found, false); -} - /******************************************************************************/ /* set */ diff --git a/py/map.h b/py/map.h index f0a57758c5..4905f5bc18 100644 --- a/py/map.h +++ b/py/map.h @@ -1,8 +1,3 @@ -typedef enum { - MP_MAP_QSTR, - MP_MAP_OBJ, -} mp_map_kind_t; - typedef struct _mp_map_elem_t { mp_obj_t key; mp_obj_t value; @@ -10,8 +5,8 @@ typedef struct _mp_map_elem_t { typedef struct _mp_map_t { struct { - mp_map_kind_t kind : 1; - machine_uint_t used : (8 * BYTES_PER_WORD - 1); + machine_uint_t all_keys_are_qstrs : 1; + machine_uint_t used : (8 * sizeof(machine_uint_t) - 1); }; machine_uint_t alloc; mp_map_elem_t *table; @@ -23,11 +18,16 @@ typedef struct _mp_set_t { mp_obj_t *table; } mp_set_t; +typedef enum { + MP_MAP_LOOKUP, + MP_MAP_LOOKUP_ADD_IF_NOT_FOUND, + MP_MAP_LOOKUP_REMOVE_IF_FOUND, +} mp_map_lookup_kind_t; + int get_doubling_prime_greater_or_equal_to(int x); -void mp_map_init(mp_map_t *map, mp_map_kind_t kind, int n); -mp_map_t *mp_map_new(mp_map_kind_t kind, int n); -mp_map_elem_t* mp_map_lookup_helper(mp_map_t *map, mp_obj_t index, bool add_if_not_found, bool remove_if_found); -mp_map_elem_t* mp_qstr_map_lookup(mp_map_t *map, qstr index, bool add_if_not_found); +void mp_map_init(mp_map_t *map, int n); +mp_map_t *mp_map_new(int n); +mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind); void mp_map_clear(mp_map_t *map); void mp_set_init(mp_set_t *set, int n); diff --git a/py/obj.c b/py/obj.c index 7d0122c8fe..866be227aa 100644 --- a/py/obj.c +++ b/py/obj.c @@ -16,6 +16,8 @@ mp_obj_t mp_obj_get_type(mp_obj_t o_in) { if (MP_OBJ_IS_SMALL_INT(o_in)) { return (mp_obj_t)&int_type; + } else if (MP_OBJ_IS_QSTR(o_in)) { + return (mp_obj_t)&str_type; } else { mp_obj_base_t *o = o_in; return (mp_obj_t)o->type; @@ -71,6 +73,8 @@ machine_int_t mp_obj_hash(mp_obj_t o_in) { return 1; // needs to hash to same as the integer 1, since True==1 } else if (MP_OBJ_IS_SMALL_INT(o_in)) { return MP_OBJ_SMALL_INT_VALUE(o_in); + } else if (MP_OBJ_IS_QSTR(o_in)) { + return MP_OBJ_QSTR_VALUE(o_in); } else if (MP_OBJ_IS_TYPE(o_in, &none_type)) { return (machine_int_t)o_in; } else if (MP_OBJ_IS_TYPE(o_in, &str_type)) { @@ -107,6 +111,8 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) { return false; } } + } else if (MP_OBJ_IS_QSTR(o1) || MP_OBJ_IS_QSTR(o2)) { + return false; } else if (MP_OBJ_IS_TYPE(o1, &str_type) && MP_OBJ_IS_TYPE(o2, &str_type)) { return mp_obj_str_get(o1) == mp_obj_str_get(o2); } else { diff --git a/py/obj.h b/py/obj.h index 208b23442f..f8bc790121 100644 --- a/py/obj.h +++ b/py/obj.h @@ -29,13 +29,21 @@ typedef struct _mp_obj_base_t mp_obj_base_t; #define MP_OBJ_NULL ((mp_obj_t)NULL) -// These macros check for small int or object, and access small int values +// These macros check for small int, qstr or object, and access small int and qstr values +// - xxxx...xxx1: a small int, bits 1 and above are the value +// - xxxx...xx10: a qstr, bits 2 and above are the value +// - xxxx...xx00: a pointer to an mp_obj_base_t -#define MP_OBJ_IS_OBJ(o) ((((mp_small_int_t)(o)) & 1) == 0) #define MP_OBJ_IS_SMALL_INT(o) ((((mp_small_int_t)(o)) & 1) != 0) -#define MP_OBJ_IS_TYPE(o, t) (((((mp_small_int_t)(o)) & 1) == 0) && (((mp_obj_base_t*)(o))->type == (t))) +#define MP_OBJ_IS_QSTR(o) ((((mp_small_int_t)(o)) & 3) == 2) +#define MP_OBJ_IS_OBJ(o) ((((mp_small_int_t)(o)) & 3) == 0) +#define MP_OBJ_IS_TYPE(o, t) (MP_OBJ_IS_OBJ(o) && (((mp_obj_base_t*)(o))->type == (t))) + #define MP_OBJ_SMALL_INT_VALUE(o) (((mp_small_int_t)(o)) >> 1) -#define MP_OBJ_NEW_SMALL_INT(o) ((mp_obj_t)(((o) << 1) | 1)) +#define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)(((small_int) << 1) | 1)) + +#define MP_OBJ_QSTR_VALUE(o) (((mp_small_int_t)(o)) >> 2) +#define MP_OBJ_NEW_QSTR(qstr) ((mp_obj_t)((((machine_uint_t)qstr) << 2) | 2)) // These macros are used to declare and define constant function objects // You can put "static" in front of the definitions to make them local diff --git a/py/objclass.c b/py/objclass.c index d13d1775a4..3ecce54739 100644 --- a/py/objclass.c +++ b/py/objclass.c @@ -26,7 +26,7 @@ mp_obj_t class_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) { mp_obj_t o = mp_obj_new_instance(self_in); // look for __init__ function - mp_map_elem_t *init_fn = mp_qstr_map_lookup(self->locals, MP_QSTR___init__, false); + mp_map_elem_t *init_fn = mp_map_lookup(self->locals, MP_OBJ_NEW_QSTR(MP_QSTR___init__), MP_MAP_LOOKUP); if (init_fn != NULL) { // call __init__ function diff --git a/py/objdict.c b/py/objdict.c index c36d4ccb03..20e3e570d5 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -50,7 +50,7 @@ static mp_obj_t dict_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { case RT_BINARY_OP_SUBSCR: { // dict load - mp_map_elem_t *elem = mp_map_lookup_helper(&o->map, rhs_in, false, false); + mp_map_elem_t *elem = mp_map_lookup(&o->map, rhs_in, MP_MAP_LOOKUP); if (elem == NULL) { nlr_jump(mp_obj_new_exception_msg(MP_QSTR_KeyError, "")); } else { @@ -139,12 +139,12 @@ static mp_obj_t dict_copy(mp_obj_t self_in) { } static MP_DEFINE_CONST_FUN_OBJ_1(dict_copy_obj, dict_copy); -static mp_obj_t dict_get_helper(mp_map_t *self, mp_obj_t key, mp_obj_t deflt, bool pop, bool set) { - mp_map_elem_t *elem = mp_map_lookup_helper(self, key, set, pop); +static mp_obj_t dict_get_helper(mp_map_t *self, mp_obj_t key, mp_obj_t deflt, mp_map_lookup_kind_t lookup_kind) { + mp_map_elem_t *elem = mp_map_lookup(self, key, lookup_kind); mp_obj_t value; if (elem == NULL || elem->value == NULL) { if (deflt == NULL) { - if (pop) { + if (lookup_kind == MP_MAP_LOOKUP_REMOVE_IF_FOUND) { nlr_jump(mp_obj_new_exception_msg(MP_QSTR_KeyError, "")); } else { value = mp_const_none; @@ -154,12 +154,12 @@ static mp_obj_t dict_get_helper(mp_map_t *self, mp_obj_t key, mp_obj_t deflt, bo } } else { value = elem->value; - if (pop) { - /* catch the leak (from mp_map_lookup_helper) */ + if (lookup_kind == MP_MAP_LOOKUP_REMOVE_IF_FOUND) { + // catch the leak (from mp_map_lookup) m_free(elem, sizeof(mp_map_elem_t)); } } - if (set) { + if (lookup_kind == MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) { elem->value = value; } return value; @@ -172,7 +172,7 @@ static mp_obj_t dict_get(int n_args, const mp_obj_t *args) { return dict_get_helper(&((mp_obj_dict_t *)args[0])->map, args[1], n_args == 3 ? args[2] : NULL, - false, false); + MP_MAP_LOOKUP); } static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(dict_get_obj, 2, 3, dict_get); @@ -183,7 +183,7 @@ static mp_obj_t dict_pop(int n_args, const mp_obj_t *args) { return dict_get_helper(&((mp_obj_dict_t *)args[0])->map, args[1], n_args == 3 ? args[2] : NULL, - true, false); + MP_MAP_LOOKUP_REMOVE_IF_FOUND); } static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(dict_pop_obj, 2, 3, dict_pop); @@ -195,7 +195,7 @@ static mp_obj_t dict_setdefault(int n_args, const mp_obj_t *args) { return dict_get_helper(&((mp_obj_dict_t *)args[0])->map, args[1], n_args == 3 ? args[2] : NULL, - false, true); + MP_MAP_LOOKUP_ADD_IF_NOT_FOUND); } static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(dict_setdefault_obj, 2, 3, dict_setdefault); @@ -237,7 +237,7 @@ static mp_obj_t dict_update(mp_obj_t self_in, mp_obj_t iterable) { MP_QSTR_ValueError, "dictionary update sequence has the wrong length")); } else { - mp_map_lookup_helper(&self->map, key, true, false)->value = value; + mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; } } @@ -273,7 +273,7 @@ const mp_obj_type_t dict_type = { mp_obj_t mp_obj_new_dict(int n_args) { mp_obj_dict_t *o = m_new_obj(mp_obj_dict_t); o->base.type = &dict_type; - mp_map_init(&o->map, MP_MAP_OBJ, n_args); + mp_map_init(&o->map, n_args); return o; } @@ -284,6 +284,6 @@ uint mp_obj_dict_len(mp_obj_t self_in) { mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value) { assert(MP_OBJ_IS_TYPE(self_in, &dict_type)); mp_obj_dict_t *self = self_in; - mp_map_lookup_helper(&self->map, key, true, false)->value = value; + mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; return self_in; } diff --git a/py/objfun.c b/py/objfun.c index 395824b046..afac3889fd 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -81,13 +81,13 @@ mp_obj_t fun_native_call_n_kw(mp_obj_t self_in, int n_args, int n_kw, const mp_o } mp_obj_t *vargs = mp_obj_new_tuple_reverse(n_args, args + 2*n_kw); - mp_map_t *kw_args = mp_map_new(MP_MAP_QSTR, n_kw); + mp_map_t *kw_args = mp_map_new(n_kw); for (int i = 0; i < 2*n_kw; i+=2) { qstr name = mp_obj_str_get(args[i+1]); - mp_qstr_map_lookup(kw_args, name, true)->value = args[i]; + mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(name), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = args[i]; } mp_obj_t res = ((mp_fun_kw_t)self->fun)(vargs, kw_args); - /* TODO clean up vargs and kw_args */ + // TODO clean up vargs and kw_args return res; } diff --git a/py/objinstance.c b/py/objinstance.c index 209643e2bf..9bb9acbd72 100644 --- a/py/objinstance.c +++ b/py/objinstance.c @@ -30,12 +30,12 @@ type needs to be specified dynamically mp_obj_t mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr) { // logic: look in obj members then class locals (TODO check this against CPython) mp_obj_instance_t *self = self_in; - mp_map_elem_t *elem = mp_qstr_map_lookup(self->members, attr, false); + mp_map_elem_t *elem = mp_map_lookup(self->members, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP); if (elem != NULL) { // object member, always treated as a value return elem->value; } - elem = mp_qstr_map_lookup(mp_obj_class_get_locals(self->class), attr, false); + elem = mp_map_lookup(mp_obj_class_get_locals(self->class), MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP); if (elem != NULL) { if (mp_obj_is_callable(elem->value)) { // class member is callable so build a bound method @@ -51,14 +51,14 @@ mp_obj_t mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr) { void mp_obj_instance_load_method(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { // logic: look in obj members then class locals (TODO check this against CPython) mp_obj_instance_t *self = self_in; - mp_map_elem_t *elem = mp_qstr_map_lookup(self->members, attr, false); + mp_map_elem_t *elem = mp_map_lookup(self->members, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP); if (elem != NULL) { // object member, always treated as a value dest[1] = elem->value; dest[0] = NULL; return; } - elem = mp_qstr_map_lookup(mp_obj_class_get_locals(self->class), attr, false); + elem = mp_map_lookup(mp_obj_class_get_locals(self->class), MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP); if (elem != NULL) { if (mp_obj_is_callable(elem->value)) { // class member is callable so build a bound method @@ -81,11 +81,11 @@ void mp_obj_instance_load_method(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { void mp_obj_instance_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) { // logic: look in class locals (no add) then obj members (add) (TODO check this against CPython) mp_obj_instance_t *self = self_in; - mp_map_elem_t *elem = mp_qstr_map_lookup(mp_obj_class_get_locals(self->class), attr, false); + mp_map_elem_t *elem = mp_map_lookup(mp_obj_class_get_locals(self->class), MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP); if (elem != NULL) { elem->value = value; } else { - mp_qstr_map_lookup(self->members, attr, true)->value = value; + mp_map_lookup(self->members, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; } } @@ -98,6 +98,6 @@ mp_obj_t mp_obj_new_instance(mp_obj_t class) { mp_obj_instance_t *o = m_new_obj(mp_obj_instance_t); o->base.type = &instance_type; o->class = class; - o->members = mp_map_new(MP_MAP_QSTR, 0); + o->members = mp_map_new(0); return o; } diff --git a/py/objlist.c b/py/objlist.c index e3d92b9e92..9d8caee339 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -146,8 +146,6 @@ static void mp_quicksort(mp_obj_t *head, mp_obj_t *tail, mp_obj_t key_fn, bool r static mp_obj_t list_sort(mp_obj_t args, mp_map_t *kwargs) { mp_obj_t *args_items = NULL; uint args_len = 0; - qstr key_idx = qstr_from_str_static("key"); - qstr reverse_idx = qstr_from_str_static("reverse"); assert(MP_OBJ_IS_TYPE(args, &tuple_type)); mp_obj_tuple_get(args, &args_len, &args_items); @@ -158,8 +156,8 @@ static mp_obj_t list_sort(mp_obj_t args, mp_map_t *kwargs) { } mp_obj_list_t *self = args_items[0]; if (self->len > 1) { - mp_map_elem_t *keyfun = mp_qstr_map_lookup(kwargs, key_idx, false); - mp_map_elem_t *reverse = mp_qstr_map_lookup(kwargs, reverse_idx, false); + mp_map_elem_t *keyfun = mp_map_lookup(kwargs, MP_OBJ_NEW_QSTR(qstr_from_str_static("key")), MP_MAP_LOOKUP); + mp_map_elem_t *reverse = mp_map_lookup(kwargs, MP_OBJ_NEW_QSTR(qstr_from_str_static("reverse")), MP_MAP_LOOKUP); mp_quicksort(self->items, self->items + self->len - 1, keyfun ? keyfun->value : NULL, reverse && reverse->value ? rt_is_true(reverse->value) : false); diff --git a/py/objmodule.c b/py/objmodule.c index 7b92b76f42..a5183b51e3 100644 --- a/py/objmodule.c +++ b/py/objmodule.c @@ -32,8 +32,8 @@ mp_obj_t mp_obj_new_module(qstr module_name) { mp_obj_module_t *o = m_new_obj(mp_obj_module_t); o->base.type = &module_type; o->name = module_name; - o->globals = mp_map_new(MP_MAP_QSTR, 1); - mp_qstr_map_lookup(o->globals, MP_QSTR___name__, true)->value = mp_obj_new_str(module_name); + o->globals = mp_map_new(1); + mp_map_lookup(o->globals, MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = mp_obj_new_str(module_name); return o; } diff --git a/py/runtime.c b/py/runtime.c index c0ed3b1fac..84a902f2f4 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -68,64 +68,69 @@ static mp_code_t *unique_codes = NULL; FILE *fp_write_code = NULL; #endif +// a good optimising compiler will inline this if necessary +static void mp_map_add_qstr(mp_map_t *map, qstr qstr, mp_obj_t value) { + mp_map_lookup(map, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; +} + void rt_init(void) { // locals = globals for outer module (see Objects/frameobject.c/PyFrame_New()) - map_locals = map_globals = mp_map_new(MP_MAP_QSTR, 1); - mp_qstr_map_lookup(map_globals, MP_QSTR___name__, true)->value = mp_obj_new_str(MP_QSTR___main__); + map_locals = map_globals = mp_map_new(1); + mp_map_add_qstr(map_globals, MP_QSTR___name__, mp_obj_new_str(MP_QSTR___main__)); // init built-in hash table - mp_map_init(&map_builtins, MP_MAP_QSTR, 3); + mp_map_init(&map_builtins, 3); // built-in exceptions (TODO, make these proper classes) - mp_qstr_map_lookup(&map_builtins, MP_QSTR_AttributeError, true)->value = mp_obj_new_exception(MP_QSTR_AttributeError); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_IndexError, true)->value = mp_obj_new_exception(MP_QSTR_IndexError); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_KeyError, true)->value = mp_obj_new_exception(MP_QSTR_KeyError); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_NameError, true)->value = mp_obj_new_exception(MP_QSTR_NameError); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_TypeError, true)->value = mp_obj_new_exception(MP_QSTR_TypeError); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_SyntaxError, true)->value = mp_obj_new_exception(MP_QSTR_SyntaxError); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_ValueError, true)->value = mp_obj_new_exception(MP_QSTR_ValueError); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_OSError, true)->value = mp_obj_new_exception(MP_QSTR_OSError); + mp_map_add_qstr(&map_builtins, MP_QSTR_AttributeError, mp_obj_new_exception(MP_QSTR_AttributeError)); + mp_map_add_qstr(&map_builtins, MP_QSTR_IndexError, mp_obj_new_exception(MP_QSTR_IndexError)); + mp_map_add_qstr(&map_builtins, MP_QSTR_KeyError, mp_obj_new_exception(MP_QSTR_KeyError)); + mp_map_add_qstr(&map_builtins, MP_QSTR_NameError, mp_obj_new_exception(MP_QSTR_NameError)); + mp_map_add_qstr(&map_builtins, MP_QSTR_TypeError, mp_obj_new_exception(MP_QSTR_TypeError)); + mp_map_add_qstr(&map_builtins, MP_QSTR_SyntaxError, mp_obj_new_exception(MP_QSTR_SyntaxError)); + mp_map_add_qstr(&map_builtins, MP_QSTR_ValueError, mp_obj_new_exception(MP_QSTR_ValueError)); + mp_map_add_qstr(&map_builtins, MP_QSTR_OSError, mp_obj_new_exception(MP_QSTR_OSError)); // built-in objects - mp_qstr_map_lookup(&map_builtins, MP_QSTR_Ellipsis, true)->value = mp_const_ellipsis; + mp_map_add_qstr(&map_builtins, MP_QSTR_Ellipsis, mp_const_ellipsis); // built-in core functions - mp_qstr_map_lookup(&map_builtins, MP_QSTR___build_class__, true)->value = (mp_obj_t)&mp_builtin___build_class___obj; - mp_qstr_map_lookup(&map_builtins, MP_QSTR___repl_print__, true)->value = rt_make_function_1(mp_builtin___repl_print__); + mp_map_add_qstr(&map_builtins, MP_QSTR___build_class__, (mp_obj_t)&mp_builtin___build_class___obj); + mp_map_add_qstr(&map_builtins, MP_QSTR___repl_print__, rt_make_function_1(mp_builtin___repl_print__)); // built-in types - mp_qstr_map_lookup(&map_builtins, MP_QSTR_bool, true)->value = (mp_obj_t)&bool_type; + mp_map_add_qstr(&map_builtins, MP_QSTR_bool, (mp_obj_t)&bool_type); #if MICROPY_ENABLE_FLOAT - mp_qstr_map_lookup(&map_builtins, MP_QSTR_complex, true)->value = (mp_obj_t)&complex_type; + mp_map_add_qstr(&map_builtins, MP_QSTR_complex, (mp_obj_t)&complex_type); #endif - mp_qstr_map_lookup(&map_builtins, MP_QSTR_dict, true)->value = (mp_obj_t)&dict_type; + mp_map_add_qstr(&map_builtins, MP_QSTR_dict, (mp_obj_t)&dict_type); #if MICROPY_ENABLE_FLOAT - mp_qstr_map_lookup(&map_builtins, MP_QSTR_float, true)->value = (mp_obj_t)&float_type; + mp_map_add_qstr(&map_builtins, MP_QSTR_float, (mp_obj_t)&float_type); #endif - mp_qstr_map_lookup(&map_builtins, MP_QSTR_int, true)->value = (mp_obj_t)&int_type; - mp_qstr_map_lookup(&map_builtins, MP_QSTR_list, true)->value = (mp_obj_t)&list_type; - mp_qstr_map_lookup(&map_builtins, MP_QSTR_set, true)->value = (mp_obj_t)&set_type; - mp_qstr_map_lookup(&map_builtins, MP_QSTR_tuple, true)->value = (mp_obj_t)&tuple_type; - mp_qstr_map_lookup(&map_builtins, MP_QSTR_type, true)->value = (mp_obj_t)&mp_builtin_type_obj; // TODO + mp_map_add_qstr(&map_builtins, MP_QSTR_int, (mp_obj_t)&int_type); + mp_map_add_qstr(&map_builtins, MP_QSTR_list, (mp_obj_t)&list_type); + mp_map_add_qstr(&map_builtins, MP_QSTR_set, (mp_obj_t)&set_type); + mp_map_add_qstr(&map_builtins, MP_QSTR_tuple, (mp_obj_t)&tuple_type); + mp_map_add_qstr(&map_builtins, MP_QSTR_type, (mp_obj_t)&mp_builtin_type_obj); // TODO // built-in user functions; TODO covert all to &mp_builtin_xxx's - mp_qstr_map_lookup(&map_builtins, MP_QSTR_abs, true)->value = rt_make_function_1(mp_builtin_abs); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_all, true)->value = rt_make_function_1(mp_builtin_all); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_any, true)->value = rt_make_function_1(mp_builtin_any); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_callable, true)->value = rt_make_function_1(mp_builtin_callable); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_chr, true)->value = rt_make_function_1(mp_builtin_chr); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_divmod, true)->value = rt_make_function_2(mp_builtin_divmod); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_hash, true)->value = (mp_obj_t)&mp_builtin_hash_obj; - mp_qstr_map_lookup(&map_builtins, MP_QSTR_iter, true)->value = (mp_obj_t)&mp_builtin_iter_obj; - mp_qstr_map_lookup(&map_builtins, MP_QSTR_len, true)->value = rt_make_function_1(mp_builtin_len); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_max, true)->value = rt_make_function_var(1, mp_builtin_max); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_min, true)->value = rt_make_function_var(1, mp_builtin_min); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_next, true)->value = (mp_obj_t)&mp_builtin_next_obj; - mp_qstr_map_lookup(&map_builtins, MP_QSTR_ord, true)->value = rt_make_function_1(mp_builtin_ord); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_pow, true)->value = rt_make_function_var(2, mp_builtin_pow); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_print, true)->value = rt_make_function_var(0, mp_builtin_print); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_range, true)->value = rt_make_function_var(1, mp_builtin_range); - mp_qstr_map_lookup(&map_builtins, MP_QSTR_sum, true)->value = rt_make_function_var(1, mp_builtin_sum); + mp_map_add_qstr(&map_builtins, MP_QSTR_abs, rt_make_function_1(mp_builtin_abs)); + mp_map_add_qstr(&map_builtins, MP_QSTR_all, rt_make_function_1(mp_builtin_all)); + mp_map_add_qstr(&map_builtins, MP_QSTR_any, rt_make_function_1(mp_builtin_any)); + mp_map_add_qstr(&map_builtins, MP_QSTR_callable, rt_make_function_1(mp_builtin_callable)); + mp_map_add_qstr(&map_builtins, MP_QSTR_chr, rt_make_function_1(mp_builtin_chr)); + mp_map_add_qstr(&map_builtins, MP_QSTR_divmod, rt_make_function_2(mp_builtin_divmod)); + mp_map_add_qstr(&map_builtins, MP_QSTR_hash, (mp_obj_t)&mp_builtin_hash_obj); + mp_map_add_qstr(&map_builtins, MP_QSTR_iter, (mp_obj_t)&mp_builtin_iter_obj); + mp_map_add_qstr(&map_builtins, MP_QSTR_len, rt_make_function_1(mp_builtin_len)); + mp_map_add_qstr(&map_builtins, MP_QSTR_max, rt_make_function_var(1, mp_builtin_max)); + mp_map_add_qstr(&map_builtins, MP_QSTR_min, rt_make_function_var(1, mp_builtin_min)); + mp_map_add_qstr(&map_builtins, MP_QSTR_next, (mp_obj_t)&mp_builtin_next_obj); + mp_map_add_qstr(&map_builtins, MP_QSTR_ord, rt_make_function_1(mp_builtin_ord)); + mp_map_add_qstr(&map_builtins, MP_QSTR_pow, rt_make_function_var(2, mp_builtin_pow)); + mp_map_add_qstr(&map_builtins, MP_QSTR_print, rt_make_function_var(0, mp_builtin_print)); + mp_map_add_qstr(&map_builtins, MP_QSTR_range, rt_make_function_var(1, mp_builtin_range)); + mp_map_add_qstr(&map_builtins, MP_QSTR_sum, rt_make_function_var(1, mp_builtin_sum)); next_unique_code_id = 1; // 0 indicates "no code" unique_codes_alloc = 0; @@ -362,11 +367,11 @@ mp_obj_t rt_load_const_str(qstr qstr) { mp_obj_t rt_load_name(qstr qstr) { // logic: search locals, globals, builtins DEBUG_OP_printf("load name %s\n", qstr_str(qstr)); - mp_map_elem_t *elem = mp_qstr_map_lookup(map_locals, qstr, false); + mp_map_elem_t *elem = mp_map_lookup(map_locals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP); if (elem == NULL) { - elem = mp_qstr_map_lookup(map_globals, qstr, false); + elem = mp_map_lookup(map_globals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP); if (elem == NULL) { - elem = mp_qstr_map_lookup(&map_builtins, qstr, false); + elem = mp_map_lookup(&map_builtins, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP); if (elem == NULL) { nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_NameError, "name '%s' is not defined", qstr_str(qstr))); } @@ -378,9 +383,9 @@ mp_obj_t rt_load_name(qstr qstr) { mp_obj_t rt_load_global(qstr qstr) { // logic: search globals, builtins DEBUG_OP_printf("load global %s\n", qstr_str(qstr)); - mp_map_elem_t *elem = mp_qstr_map_lookup(map_globals, qstr, false); + mp_map_elem_t *elem = mp_map_lookup(map_globals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP); if (elem == NULL) { - elem = mp_qstr_map_lookup(&map_builtins, qstr, false); + elem = mp_map_lookup(&map_builtins, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP); if (elem == NULL) { nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_NameError, "name '%s' is not defined", qstr_str(qstr))); } @@ -390,7 +395,7 @@ mp_obj_t rt_load_global(qstr qstr) { mp_obj_t rt_load_build_class(void) { DEBUG_OP_printf("load_build_class\n"); - mp_map_elem_t *elem = mp_qstr_map_lookup(&map_builtins, MP_QSTR___build_class__, false); + mp_map_elem_t *elem = mp_map_lookup(&map_builtins, MP_OBJ_NEW_QSTR(MP_QSTR___build_class__), MP_MAP_LOOKUP); if (elem == NULL) { nlr_jump(mp_obj_new_exception_msg(MP_QSTR_NameError, "name '__build_class__' is not defined")); } @@ -407,12 +412,12 @@ void rt_set_cell(mp_obj_t cell, mp_obj_t val) { void rt_store_name(qstr qstr, mp_obj_t obj) { DEBUG_OP_printf("store name %s <- %p\n", qstr_str(qstr), obj); - mp_qstr_map_lookup(map_locals, qstr, true)->value = obj; + mp_map_lookup(map_locals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = obj; } void rt_store_global(qstr qstr, mp_obj_t obj) { DEBUG_OP_printf("store global %s <- %p\n", qstr_str(qstr), obj); - mp_qstr_map_lookup(map_globals, qstr, true)->value = obj; + mp_map_lookup(map_globals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = obj; } mp_obj_t rt_unary_op(int op, mp_obj_t arg) { @@ -772,7 +777,7 @@ mp_obj_t rt_store_map(mp_obj_t map, mp_obj_t key, mp_obj_t value) { mp_obj_t rt_load_attr(mp_obj_t base, qstr attr) { DEBUG_OP_printf("load attr %s\n", qstr_str(attr)); if (MP_OBJ_IS_TYPE(base, &class_type)) { - mp_map_elem_t *elem = mp_qstr_map_lookup(mp_obj_class_get_locals(base), attr, false); + mp_map_elem_t *elem = mp_map_lookup(mp_obj_class_get_locals(base), MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP); if (elem == NULL) { // TODO what about generic method lookup? goto no_attr; @@ -782,7 +787,7 @@ mp_obj_t rt_load_attr(mp_obj_t base, qstr attr) { return mp_obj_instance_load_attr(base, attr); } else if (MP_OBJ_IS_TYPE(base, &module_type)) { DEBUG_OP_printf("lookup module map %p\n", mp_obj_module_get_globals(base)); - mp_map_elem_t *elem = mp_qstr_map_lookup(mp_obj_module_get_globals(base), attr, false); + mp_map_elem_t *elem = mp_map_lookup(mp_obj_module_get_globals(base), MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP); if (elem == NULL) { // TODO what about generic method lookup? goto no_attr; @@ -839,13 +844,13 @@ void rt_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) { if (MP_OBJ_IS_TYPE(base, &class_type)) { // TODO CPython allows STORE_ATTR to a class, but is this the correct implementation? mp_map_t *locals = mp_obj_class_get_locals(base); - mp_qstr_map_lookup(locals, attr, true)->value = value; + mp_map_lookup(locals, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; } else if (MP_OBJ_IS_TYPE(base, &instance_type)) { mp_obj_instance_store_attr(base, attr, value); } else if (MP_OBJ_IS_TYPE(base, &module_type)) { // TODO CPython allows STORE_ATTR to a module, but is this the correct implementation? mp_map_t *globals = mp_obj_module_get_globals(base); - mp_qstr_map_lookup(globals, attr, true)->value = value; + mp_map_lookup(globals, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; } else { nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(base), qstr_str(attr))); } diff --git a/stm/pybwlan.c b/stm/pybwlan.c index 6988f1c848..8da7bb937b 100644 --- a/stm/pybwlan.c +++ b/stm/pybwlan.c @@ -74,7 +74,7 @@ mp_obj_t pyb_wlan_get_ip(void) { return mp_const_none; } - mp_obj_t data = mp_obj_new_class(mp_map_new(MP_MAP_QSTR, 0)); // TODO should this be an instance of a class? + mp_obj_t data = mp_obj_new_class(mp_map_new(0)); // TODO should this be an instance of a class? decode_addr_and_store(data, qstr_from_str_static("ip"), &ipconfig.aucIP[0], 4); decode_addr_and_store(data, qstr_from_str_static("subnet"), &ipconfig.aucSubnetMask[0], 4); decode_addr_and_store(data, qstr_from_str_static("gateway"), &ipconfig.aucDefaultGateway[0], 4);