Commit 38a2da68 authored by Damien George's avatar Damien George
Browse files

py: Stuff qstr in object pointer; keys for mp_map_t are now always mp_obj_t.

parent ea9e441a
...@@ -23,7 +23,7 @@ mp_obj_t mp_builtin___build_class__(int n_args, const mp_obj_t *args) { ...@@ -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 // we differ from CPython: we set the new __locals__ object here
mp_map_t *old_locals = rt_locals_get(); 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); rt_locals_set(class_locals);
// call the class code // call the class code
......
...@@ -26,21 +26,22 @@ int get_doubling_prime_greater_or_equal_to(int x) { ...@@ -26,21 +26,22 @@ int get_doubling_prime_greater_or_equal_to(int x) {
/******************************************************************************/ /******************************************************************************/
/* map */ /* map */
void mp_map_init(mp_map_t *map, mp_map_kind_t kind, int n) { void mp_map_init(mp_map_t *map, int n) {
map->kind = kind;
map->used = 0;
map->alloc = get_doubling_prime_greater_or_equal_to(n + 1); 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); 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_t *map = m_new(mp_map_t, 1);
mp_map_init(map, kind, n); mp_map_init(map, n);
return map; return map;
} }
void mp_map_clear(mp_map_t *map) { void mp_map_clear(mp_map_t *map) {
map->used = 0; map->used = 0;
map->all_keys_are_qstrs = 1;
machine_uint_t a = map->alloc; machine_uint_t a = map->alloc;
map->alloc = 0; map->alloc = 0;
map->table = m_renew(mp_map_elem_t, map->table, a, map->alloc); 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) { ...@@ -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; int old_alloc = map->alloc;
mp_map_elem_t *old_table = map->table; mp_map_elem_t *old_table = map->table;
map->alloc = get_doubling_prime_greater_or_equal_to(map->alloc + 1); map->alloc = get_doubling_prime_greater_or_equal_to(map->alloc + 1);
map->used = 0; map->used = 0;
map->all_keys_are_qstrs = 1;
map->table = m_new0(mp_map_elem_t, map->alloc); map->table = m_new0(mp_map_elem_t, map->alloc);
for (int i = 0; i < old_alloc; i++) { for (int i = 0; i < old_alloc; i++) {
if (old_table[i].key != NULL) { 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); 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) { mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind) {
bool is_map_mp_obj = (map->kind == MP_MAP_OBJ);
machine_uint_t hash; machine_uint_t hash;
if (is_map_mp_obj) { hash = mp_obj_hash(index);
hash = mp_obj_hash(index);
} else {
hash = (machine_uint_t)index;
}
if (map->alloc == 0) { if (map->alloc == 0) {
if (add_if_not_found) { if (lookup_kind == MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) {
mp_map_rehash(map); mp_map_rehash(map);
} else { } else {
return NULL; 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 ...@@ -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]; mp_map_elem_t *elem = &map->table[pos];
if (elem->key == NULL) { if (elem->key == NULL) {
// not in table // not in table
if (add_if_not_found) { if (lookup_kind == MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) {
if (map->used + 1 >= map->alloc) { if (map->used + 1 >= map->alloc) {
// not enough room in table, rehash it // not enough room in table, rehash it
mp_map_rehash(map); 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 ...@@ -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 { } else {
map->used += 1; map->used += 1;
elem->key = index; elem->key = index;
if (!MP_OBJ_IS_QSTR(index)) {
map->all_keys_are_qstrs = 0;
}
return elem; return elem;
} }
} else { } else {
return NULL; 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 // found it
/* it seems CPython does not replace the index; try x={True:'true'};x[1]='one';x /* it seems CPython does not replace the index; try x={True:'true'};x[1]='one';x
if (add_if_not_found) { if (add_if_not_found) {
elem->key = index; elem->key = index;
} }
*/ */
if (remove_if_found) { if (lookup_kind == MP_MAP_LOOKUP_REMOVE_IF_FOUND) {
map->used--; 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); mp_map_elem_t *retval = m_new(mp_map_elem_t, 1);
retval->key = elem->key; retval->key = elem->key;
retval->value = elem->value; 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 ...@@ -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 */ /* set */
......
typedef enum {
MP_MAP_QSTR,
MP_MAP_OBJ,
} mp_map_kind_t;
typedef struct _mp_map_elem_t { typedef struct _mp_map_elem_t {
mp_obj_t key; mp_obj_t key;
mp_obj_t value; mp_obj_t value;
...@@ -10,8 +5,8 @@ typedef struct _mp_map_elem_t { ...@@ -10,8 +5,8 @@ typedef struct _mp_map_elem_t {
typedef struct _mp_map_t { typedef struct _mp_map_t {
struct { struct {
mp_map_kind_t kind : 1; machine_uint_t all_keys_are_qstrs : 1;
machine_uint_t used : (8 * BYTES_PER_WORD - 1); machine_uint_t used : (8 * sizeof(machine_uint_t) - 1);
}; };
machine_uint_t alloc; machine_uint_t alloc;
mp_map_elem_t *table; mp_map_elem_t *table;
...@@ -23,11 +18,16 @@ typedef struct _mp_set_t { ...@@ -23,11 +18,16 @@ typedef struct _mp_set_t {
mp_obj_t *table; mp_obj_t *table;
} mp_set_t; } 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); 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); void mp_map_init(mp_map_t *map, int n);
mp_map_t *mp_map_new(mp_map_kind_t kind, int n); mp_map_t *mp_map_new(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_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind);
mp_map_elem_t* mp_qstr_map_lookup(mp_map_t *map, qstr index, bool add_if_not_found);
void mp_map_clear(mp_map_t *map); void mp_map_clear(mp_map_t *map);
void mp_set_init(mp_set_t *set, int n); void mp_set_init(mp_set_t *set, int n);
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
mp_obj_t mp_obj_get_type(mp_obj_t o_in) { mp_obj_t mp_obj_get_type(mp_obj_t o_in) {
if (MP_OBJ_IS_SMALL_INT(o_in)) { if (MP_OBJ_IS_SMALL_INT(o_in)) {
return (mp_obj_t)&int_type; return (mp_obj_t)&int_type;
} else if (MP_OBJ_IS_QSTR(o_in)) {
return (mp_obj_t)&str_type;
} else { } else {
mp_obj_base_t *o = o_in; mp_obj_base_t *o = o_in;
return (mp_obj_t)o->type; return (mp_obj_t)o->type;
...@@ -71,6 +73,8 @@ machine_int_t mp_obj_hash(mp_obj_t o_in) { ...@@ -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 return 1; // needs to hash to same as the integer 1, since True==1
} else if (MP_OBJ_IS_SMALL_INT(o_in)) { } else if (MP_OBJ_IS_SMALL_INT(o_in)) {
return MP_OBJ_SMALL_INT_VALUE(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)) { } else if (MP_OBJ_IS_TYPE(o_in, &none_type)) {
return (machine_int_t)o_in; return (machine_int_t)o_in;
} else if (MP_OBJ_IS_TYPE(o_in, &str_type)) { } 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) { ...@@ -107,6 +111,8 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) {
return false; 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)) { } 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); return mp_obj_str_get(o1) == mp_obj_str_get(o2);
} else { } else {
......
...@@ -29,13 +29,21 @@ typedef struct _mp_obj_base_t mp_obj_base_t; ...@@ -29,13 +29,21 @@ typedef struct _mp_obj_base_t mp_obj_base_t;
#define MP_OBJ_NULL ((mp_obj_t)NULL) #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_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_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 // These macros are used to declare and define constant function objects
// You can put "static" in front of the definitions to make them local // You can put "static" in front of the definitions to make them local
......
...@@ -26,7 +26,7 @@ mp_obj_t class_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) { ...@@ -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); mp_obj_t o = mp_obj_new_instance(self_in);
// look for __init__ function // 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) { if (init_fn != NULL) {
// call __init__ function // call __init__ function
......
...@@ -50,7 +50,7 @@ static mp_obj_t dict_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { ...@@ -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: case RT_BINARY_OP_SUBSCR:
{ {
// dict load // 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) { if (elem == NULL) {
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_KeyError, "<value>")); nlr_jump(mp_obj_new_exception_msg(MP_QSTR_KeyError, "<value>"));
} else { } else {
...@@ -139,12 +139,12 @@ static mp_obj_t dict_copy(mp_obj_t self_in) { ...@@ -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_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) { 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_helper(self, key, set, pop); mp_map_elem_t *elem = mp_map_lookup(self, key, lookup_kind);
mp_obj_t value; mp_obj_t value;
if (elem == NULL || elem->value == NULL) { if (elem == NULL || elem->value == NULL) {
if (deflt == 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, "<value>")); nlr_jump(mp_obj_new_exception_msg(MP_QSTR_KeyError, "<value>"));
} else { } else {
value = mp_const_none; 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 ...@@ -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 { } else {
value = elem->value; value = elem->value;
if (pop) { if (lookup_kind == MP_MAP_LOOKUP_REMOVE_IF_FOUND) {
/* catch the leak (from mp_map_lookup_helper) */ // catch the leak (from mp_map_lookup)
m_free(elem, sizeof(mp_map_elem_t)); m_free(elem, sizeof(mp_map_elem_t));
} }
} }
if (set) { if (lookup_kind == MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) {
elem->value = value; elem->value = value;
} }
return value; return value;
...@@ -172,7 +172,7 @@ static mp_obj_t dict_get(int n_args, const mp_obj_t *args) { ...@@ -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, return dict_get_helper(&((mp_obj_dict_t *)args[0])->map,
args[1], args[1],
n_args == 3 ? args[2] : NULL, 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); 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) { ...@@ -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, return dict_get_helper(&((mp_obj_dict_t *)args[0])->map,
args[1], args[1],
n_args == 3 ? args[2] : NULL, 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); 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) { ...@@ -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, return dict_get_helper(&((mp_obj_dict_t *)args[0])->map,
args[1], args[1],
n_args == 3 ? args[2] : NULL, 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); 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) { ...@@ -237,7 +237,7 @@ static mp_obj_t dict_update(mp_obj_t self_in, mp_obj_t iterable) {
MP_QSTR_ValueError, MP_QSTR_ValueError,
"dictionary update sequence has the wrong length")); "dictionary update sequence has the wrong length"));
} else { } 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 = { ...@@ -273,7 +273,7 @@ const mp_obj_type_t dict_type = {
mp_obj_t mp_obj_new_dict(int n_args) { mp_obj_t mp_obj_new_dict(int n_args) {
mp_obj_dict_t *o = m_new_obj(mp_obj_dict_t); mp_obj_dict_t *o = m_new_obj(mp_obj_dict_t);
o->base.type = &dict_type; o->base.type = &dict_type;
mp_map_init(&o->map, MP_MAP_OBJ, n_args); mp_map_init(&o->map, n_args);
return o; return o;
} }
...@@ -284,6 +284,6 @@ uint mp_obj_dict_len(mp_obj_t self_in) { ...@@ -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) { 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)); assert(MP_OBJ_IS_TYPE(self_in, &dict_type));
mp_obj_dict_t *self = self_in; 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; return self_in;
} }
...@@ -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 ...@@ -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_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) { for (int i = 0; i < 2*n_kw; i+=2) {
qstr name = mp_obj_str_get(args[i+1]); 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); 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; return res;
} }
......
...@@ -30,12 +30,12 @@ type needs to be specified dynamically ...@@ -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) { 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) // logic: look in obj members then class locals (TODO check this against CPython)
mp_obj_instance_t *self = self_in; 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) { if (elem != NULL) {
// object member, always treated as a value // object member, always treated as a value
return elem->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 (elem != NULL) {
if (mp_obj_is_callable(elem->value)) { if (mp_obj_is_callable(elem->value)) {
// class member is callable so build a bound method // 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) { ...@@ -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) { 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) // logic: look in obj members then class locals (TODO check this against CPython)
mp_obj_instance_t *self = self_in; 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) { if (elem != NULL) {
// object member, always treated as a value // object member, always treated as a value
dest[1] = elem->value; dest[1] = elem->value;
dest[0] = NULL; dest[0] = NULL;
return; 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 (elem != NULL) {
if (mp_obj_is_callable(elem->value)) { if (mp_obj_is_callable(elem->value)) {
// class member is callable so build a bound method // 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) { ...@@ -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) { 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) // logic: look in class locals (no add) then obj members (add) (TODO check this against CPython)
mp_obj_instance_t *self = self_in; 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) { if (elem != NULL) {
elem->value = value; elem->value = value;
} else { } 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) { ...@@ -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); mp_obj_instance_t *o = m_new_obj(mp_obj_instance_t);
o->base.type = &instance_type; o->base.type = &instance_type;
o->class = class; o->class = class;
o->members = mp_map_new(MP_MAP_QSTR, 0); o->members = mp_map_new(0);
return o; return o;
} }
...@@ -146,8 +146,6 @@ static void mp_quicksort(mp_obj_t *head, mp_obj_t *tail, mp_obj_t key_fn, bool r ...@@ -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) { static mp_obj_t list_sort(mp_obj_t args, mp_map_t *kwargs) {
mp_obj_t *args_items = NULL; mp_obj_t *args_items = NULL;
uint args_len = 0; 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)); assert(MP_OBJ_IS_TYPE(args, &tuple_type));
mp_obj_tuple_get(args, &args_len, &args_items); 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) { ...@@ -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]; mp_obj_list_t *self = args_items[0];
if (self->len > 1) { if (self->len > 1) {
mp_map_elem_t *keyfun = mp_qstr_map_lookup(kwargs, key_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_qstr_map_lookup(kwargs, reverse_idx, false); 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, mp_quicksort(self->items, self->items + self->len - 1,
keyfun ? keyfun->value : NULL, keyfun ? keyfun->value : NULL,
reverse && reverse->value ? rt_is_true(reverse->value) : false); reverse && reverse->value ? rt_is_true(reverse->value) : false);
......
...@@ -32,8 +32,8 @@ mp_obj_t mp_obj_new_module(qstr module_name) { ...@@ -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); mp_obj_module_t *o = m_new_obj(mp_obj_module_t);
o->base.type = &module_type; o->base.type = &module_type;
o->name = module_name; o->name = module_name;
o->globals = mp_map_new(MP_MAP_QSTR, 1); o->globals = mp_map_new(1);
mp_qstr_map_lookup(o->globals, MP_QSTR___name__, true)->value = mp_obj_new_str(module_name); 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; return o;
} }
......