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) {
// 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
......
......@@ -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 */
......
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);
......
......@@ -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 {
......
......@@ -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
......
......@@ -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
......
......@@ -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, "<value>"));
} 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, "<value>"));
} 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;
}
......@@ -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;
}
......
......@@ -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;
}
......@@ -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);
......
......@@ -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;
}
......
......@@ -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);