Commit 7efc5b3f authored by Damien George's avatar Damien George
Browse files

py: Make globals and locals proper dictionary objects.

Finishes addressing issue #424.

In the end this was a very neat refactor that now makes things a lot
more consistent across the py code base.  It allowed some
simplifications in certain places, now that everything is a dict object.

Also converted builtins tables to dictionaries.  This will be useful
when we need to turn builtins into a proper module.
parent 8b0535e2
......@@ -20,10 +20,10 @@
STATIC mp_obj_t mp_builtin___build_class__(uint n_args, const mp_obj_t *args) {
assert(2 <= n_args);
// we differ from CPython: we set the new __locals__ object here
mp_map_t *old_locals = mp_locals_get();
// set the new classes __locals__ object
mp_obj_dict_t *old_locals = mp_locals_get();
mp_obj_t class_locals = mp_obj_new_dict(0);
mp_locals_set(mp_obj_dict_get_map(class_locals));
mp_locals_set(class_locals);
// call the class code
mp_obj_t cell = mp_call_function_0(args[0]);
......@@ -150,14 +150,14 @@ MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_chr_obj, mp_builtin_chr);
STATIC mp_obj_t mp_builtin_dir(uint n_args, const mp_obj_t *args) {
// TODO make this function more general and less of a hack
mp_map_t *map = NULL;
mp_obj_dict_t *dict = NULL;
if (n_args == 0) {
// make a list of names in the local name space
map = mp_locals_get();
dict = mp_locals_get();
} else { // n_args == 1
// make a list of names in the given object
if (MP_OBJ_IS_TYPE(args[0], &mp_type_module)) {
map = mp_obj_dict_get_map(mp_obj_module_get_globals(args[0]));
dict = mp_obj_module_get_globals(args[0]);
} else {
mp_obj_type_t *type;
if (MP_OBJ_IS_TYPE(args[0], &mp_type_type)) {
......@@ -166,16 +166,16 @@ STATIC mp_obj_t mp_builtin_dir(uint n_args, const mp_obj_t *args) {
type = mp_obj_get_type(args[0]);
}
if (type->locals_dict != MP_OBJ_NULL && MP_OBJ_IS_TYPE(type->locals_dict, &mp_type_dict)) {
map = mp_obj_dict_get_map(type->locals_dict);
dict = type->locals_dict;
}
}
}
mp_obj_t dir = mp_obj_new_list(0, NULL);
if (map != NULL) {
for (uint i = 0; i < map->alloc; i++) {
if (MP_MAP_SLOT_IS_FILLED(map, i)) {
mp_obj_list_append(dir, map->table[i].key);
if (dict != NULL) {
for (uint i = 0; i < dict->map.alloc; i++) {
if (MP_MAP_SLOT_IS_FILLED(&dict->map, i)) {
mp_obj_list_append(dir, dict->map.table[i].key);
}
}
}
......
......@@ -54,8 +54,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_eval_obj, mp_builtin_eval);
STATIC mp_obj_t mp_builtin_exec(uint n_args, const mp_obj_t *args) {
// Unconditional getting/setting assumes that these operations
// are cheap, which is the case when this comment was written.
mp_map_t *old_globals = mp_globals_get();
mp_map_t *old_locals = mp_locals_get();
mp_obj_dict_t *old_globals = mp_globals_get();
mp_obj_dict_t *old_locals = mp_locals_get();
if (n_args > 1) {
mp_obj_t globals = args[1];
mp_obj_t locals;
......@@ -64,8 +64,8 @@ STATIC mp_obj_t mp_builtin_exec(uint n_args, const mp_obj_t *args) {
} else {
locals = globals;
}
mp_globals_set(mp_obj_dict_get_map(globals));
mp_locals_set(mp_obj_dict_get_map(locals));
mp_globals_set(globals);
mp_locals_set(locals);
}
mp_obj_t res = parse_compile_execute(args[0], MP_PARSE_FILE_INPUT);
// TODO if the above call throws an exception, then we never get to reset the globals/locals
......
......@@ -83,12 +83,12 @@ void do_load(mp_obj_t module_obj, vstr_t *file) {
qstr source_name = mp_lexer_source_name(lex);
// save the old context
mp_map_t *old_locals = mp_locals_get();
mp_map_t *old_globals = mp_globals_get();
mp_obj_dict_t *old_locals = mp_locals_get();
mp_obj_dict_t *old_globals = mp_globals_get();
// set the new context
mp_locals_set(mp_obj_dict_get_map(mp_obj_module_get_globals(module_obj)));
mp_globals_set(mp_obj_dict_get_map(mp_obj_module_get_globals(module_obj)));
mp_locals_set(mp_obj_module_get_globals(module_obj));
mp_globals_set(mp_obj_module_get_globals(module_obj));
// parse the imported script
mp_parse_error_kind_t parse_error_kind;
......
......@@ -8,148 +8,139 @@
#include "builtintables.h"
#include "objarray.h"
// builtins
// we put these tables in ROM because they're always needed and take up quite a bit of room in RAM
// in fact, it uses less ROM here in table form than the equivalent in code form initialising a dynamic mp_map_t object in RAM
// at the moment it's a linear table, but we could convert it to a const mp_map_t table with a simple preprocessing script
typedef struct _mp_builtin_elem_t {
qstr qstr;
mp_obj_t elem;
} mp_builtin_elem_t;
STATIC const mp_builtin_elem_t builtin_object_table[] = {
STATIC const mp_map_elem_t mp_builtin_object_table[] = {
// built-in core functions
{ MP_QSTR___build_class__, (mp_obj_t)&mp_builtin___build_class___obj },
{ MP_QSTR___import__, (mp_obj_t)&mp_builtin___import___obj },
{ MP_QSTR___repl_print__, (mp_obj_t)&mp_builtin___repl_print___obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR___build_class__), (mp_obj_t)&mp_builtin___build_class___obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR___import__), (mp_obj_t)&mp_builtin___import___obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR___repl_print__), (mp_obj_t)&mp_builtin___repl_print___obj },
// built-in types
{ MP_QSTR_bool, (mp_obj_t)&mp_type_bool },
{ MP_QSTR_bytes, (mp_obj_t)&mp_type_bytes },
{ MP_OBJ_NEW_QSTR(MP_QSTR_bool), (mp_obj_t)&mp_type_bool },
{ MP_OBJ_NEW_QSTR(MP_QSTR_bytes), (mp_obj_t)&mp_type_bytes },
#if MICROPY_ENABLE_FLOAT
{ MP_QSTR_complex, (mp_obj_t)&mp_type_complex },
{ MP_OBJ_NEW_QSTR(MP_QSTR_complex), (mp_obj_t)&mp_type_complex },
#endif
{ MP_QSTR_dict, (mp_obj_t)&mp_type_dict },
{ MP_QSTR_enumerate, (mp_obj_t)&mp_type_enumerate },
{ MP_QSTR_filter, (mp_obj_t)&mp_type_filter },
{ MP_OBJ_NEW_QSTR(MP_QSTR_dict), (mp_obj_t)&mp_type_dict },
{ MP_OBJ_NEW_QSTR(MP_QSTR_enumerate), (mp_obj_t)&mp_type_enumerate },
{ MP_OBJ_NEW_QSTR(MP_QSTR_filter), (mp_obj_t)&mp_type_filter },
#if MICROPY_ENABLE_FLOAT
{ MP_QSTR_float, (mp_obj_t)&mp_type_float },
{ MP_OBJ_NEW_QSTR(MP_QSTR_float), (mp_obj_t)&mp_type_float },
#endif
{ MP_QSTR_int, (mp_obj_t)&mp_type_int },
{ MP_QSTR_list, (mp_obj_t)&mp_type_list },
{ MP_QSTR_map, (mp_obj_t)&mp_type_map },
{ MP_QSTR_object, (mp_obj_t)&mp_type_object },
{ MP_QSTR_set, (mp_obj_t)&mp_type_set },
{ MP_QSTR_str, (mp_obj_t)&mp_type_str },
{ MP_QSTR_super, (mp_obj_t)&mp_type_super },
{ MP_QSTR_tuple, (mp_obj_t)&mp_type_tuple },
{ MP_QSTR_type, (mp_obj_t)&mp_type_type },
{ MP_QSTR_zip, (mp_obj_t)&mp_type_zip },
{ MP_QSTR_classmethod, (mp_obj_t)&mp_type_classmethod },
{ MP_QSTR_staticmethod, (mp_obj_t)&mp_type_staticmethod },
{ MP_OBJ_NEW_QSTR(MP_QSTR_int), (mp_obj_t)&mp_type_int },
{ MP_OBJ_NEW_QSTR(MP_QSTR_list), (mp_obj_t)&mp_type_list },
{ MP_OBJ_NEW_QSTR(MP_QSTR_map), (mp_obj_t)&mp_type_map },
{ MP_OBJ_NEW_QSTR(MP_QSTR_object), (mp_obj_t)&mp_type_object },
{ MP_OBJ_NEW_QSTR(MP_QSTR_set), (mp_obj_t)&mp_type_set },
{ MP_OBJ_NEW_QSTR(MP_QSTR_str), (mp_obj_t)&mp_type_str },
{ MP_OBJ_NEW_QSTR(MP_QSTR_super), (mp_obj_t)&mp_type_super },
{ MP_OBJ_NEW_QSTR(MP_QSTR_tuple), (mp_obj_t)&mp_type_tuple },
{ MP_OBJ_NEW_QSTR(MP_QSTR_type), (mp_obj_t)&mp_type_type },
{ MP_OBJ_NEW_QSTR(MP_QSTR_zip), (mp_obj_t)&mp_type_zip },
{ MP_OBJ_NEW_QSTR(MP_QSTR_classmethod), (mp_obj_t)&mp_type_classmethod },
{ MP_OBJ_NEW_QSTR(MP_QSTR_staticmethod), (mp_obj_t)&mp_type_staticmethod },
// built-in objects
{ MP_QSTR_Ellipsis, (mp_obj_t)&mp_const_ellipsis_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_Ellipsis), (mp_obj_t)&mp_const_ellipsis_obj },
// built-in user functions
{ MP_QSTR_abs, (mp_obj_t)&mp_builtin_abs_obj },
{ MP_QSTR_all, (mp_obj_t)&mp_builtin_all_obj },
{ MP_QSTR_any, (mp_obj_t)&mp_builtin_any_obj },
{ MP_QSTR_callable, (mp_obj_t)&mp_builtin_callable_obj },
{ MP_QSTR_chr, (mp_obj_t)&mp_builtin_chr_obj },
{ MP_QSTR_dir, (mp_obj_t)&mp_builtin_dir_obj },
{ MP_QSTR_divmod, (mp_obj_t)&mp_builtin_divmod_obj },
{ MP_QSTR_eval, (mp_obj_t)&mp_builtin_eval_obj },
{ MP_QSTR_exec, (mp_obj_t)&mp_builtin_exec_obj },
{ MP_QSTR_getattr, (mp_obj_t)&mp_builtin_getattr_obj },
{ MP_QSTR_hash, (mp_obj_t)&mp_builtin_hash_obj },
{ MP_QSTR_id, (mp_obj_t)&mp_builtin_id_obj },
{ MP_QSTR_isinstance, (mp_obj_t)&mp_builtin_isinstance_obj },
{ MP_QSTR_issubclass, (mp_obj_t)&mp_builtin_issubclass_obj },
{ MP_QSTR_iter, (mp_obj_t)&mp_builtin_iter_obj },
{ MP_QSTR_len, (mp_obj_t)&mp_builtin_len_obj },
{ MP_QSTR_max, (mp_obj_t)&mp_builtin_max_obj },
{ MP_QSTR_min, (mp_obj_t)&mp_builtin_min_obj },
{ MP_QSTR_next, (mp_obj_t)&mp_builtin_next_obj },
{ MP_QSTR_ord, (mp_obj_t)&mp_builtin_ord_obj },
{ MP_QSTR_pow, (mp_obj_t)&mp_builtin_pow_obj },
{ MP_QSTR_print, (mp_obj_t)&mp_builtin_print_obj },
{ MP_QSTR_range, (mp_obj_t)&mp_builtin_range_obj },
{ MP_QSTR_repr, (mp_obj_t)&mp_builtin_repr_obj },
{ MP_QSTR_sorted, (mp_obj_t)&mp_builtin_sorted_obj },
{ MP_QSTR_sum, (mp_obj_t)&mp_builtin_sum_obj },
{ MP_QSTR_bytearray, (mp_obj_t)&mp_builtin_bytearray_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_abs), (mp_obj_t)&mp_builtin_abs_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_all), (mp_obj_t)&mp_builtin_all_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_any), (mp_obj_t)&mp_builtin_any_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_callable), (mp_obj_t)&mp_builtin_callable_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_chr), (mp_obj_t)&mp_builtin_chr_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_dir), (mp_obj_t)&mp_builtin_dir_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_divmod), (mp_obj_t)&mp_builtin_divmod_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_eval), (mp_obj_t)&mp_builtin_eval_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_exec), (mp_obj_t)&mp_builtin_exec_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_getattr), (mp_obj_t)&mp_builtin_getattr_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_hash), (mp_obj_t)&mp_builtin_hash_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_id), (mp_obj_t)&mp_builtin_id_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_isinstance), (mp_obj_t)&mp_builtin_isinstance_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_issubclass), (mp_obj_t)&mp_builtin_issubclass_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_iter), (mp_obj_t)&mp_builtin_iter_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_len), (mp_obj_t)&mp_builtin_len_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_max), (mp_obj_t)&mp_builtin_max_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_min), (mp_obj_t)&mp_builtin_min_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_next), (mp_obj_t)&mp_builtin_next_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_ord), (mp_obj_t)&mp_builtin_ord_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_pow), (mp_obj_t)&mp_builtin_pow_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_print), (mp_obj_t)&mp_builtin_print_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_range), (mp_obj_t)&mp_builtin_range_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_repr), (mp_obj_t)&mp_builtin_repr_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_sorted), (mp_obj_t)&mp_builtin_sorted_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_sum), (mp_obj_t)&mp_builtin_sum_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_bytearray), (mp_obj_t)&mp_builtin_bytearray_obj },
// built-in exceptions
{ MP_QSTR_BaseException, (mp_obj_t)&mp_type_BaseException },
{ MP_QSTR_ArithmeticError, (mp_obj_t)&mp_type_ArithmeticError },
{ MP_QSTR_AssertionError, (mp_obj_t)&mp_type_AssertionError },
{ MP_QSTR_AttributeError, (mp_obj_t)&mp_type_AttributeError },
{ MP_QSTR_EOFError, (mp_obj_t)&mp_type_EOFError },
{ MP_QSTR_Exception, (mp_obj_t)&mp_type_Exception },
{ MP_QSTR_GeneratorExit, (mp_obj_t)&mp_type_GeneratorExit },
{ MP_QSTR_IOError, (mp_obj_t)&mp_type_IOError },
{ MP_QSTR_ImportError, (mp_obj_t)&mp_type_ImportError },
{ MP_QSTR_IndentationError, (mp_obj_t)&mp_type_IndentationError },
{ MP_QSTR_IndexError, (mp_obj_t)&mp_type_IndexError },
{ MP_QSTR_KeyError, (mp_obj_t)&mp_type_KeyError },
{ MP_QSTR_LookupError, (mp_obj_t)&mp_type_LookupError },
{ MP_QSTR_MemoryError, (mp_obj_t)&mp_type_MemoryError },
{ MP_QSTR_NameError, (mp_obj_t)&mp_type_NameError },
{ MP_QSTR_NotImplementedError, (mp_obj_t)&mp_type_NotImplementedError },
{ MP_QSTR_OSError, (mp_obj_t)&mp_type_OSError },
{ MP_QSTR_OverflowError, (mp_obj_t)&mp_type_OverflowError },
{ MP_QSTR_RuntimeError, (mp_obj_t)&mp_type_RuntimeError },
{ MP_QSTR_StopIteration, (mp_obj_t)&mp_type_StopIteration },
{ MP_QSTR_SyntaxError, (mp_obj_t)&mp_type_SyntaxError },
{ MP_QSTR_SystemError, (mp_obj_t)&mp_type_SystemError },
{ MP_QSTR_TypeError, (mp_obj_t)&mp_type_TypeError },
{ MP_QSTR_ValueError, (mp_obj_t)&mp_type_ValueError },
{ MP_QSTR_ZeroDivisionError, (mp_obj_t)&mp_type_ZeroDivisionError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_BaseException), (mp_obj_t)&mp_type_BaseException },
{ MP_OBJ_NEW_QSTR(MP_QSTR_ArithmeticError), (mp_obj_t)&mp_type_ArithmeticError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_AssertionError), (mp_obj_t)&mp_type_AssertionError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_AttributeError), (mp_obj_t)&mp_type_AttributeError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_EOFError), (mp_obj_t)&mp_type_EOFError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_Exception), (mp_obj_t)&mp_type_Exception },
{ MP_OBJ_NEW_QSTR(MP_QSTR_GeneratorExit), (mp_obj_t)&mp_type_GeneratorExit },
{ MP_OBJ_NEW_QSTR(MP_QSTR_IOError), (mp_obj_t)&mp_type_IOError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_ImportError), (mp_obj_t)&mp_type_ImportError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_IndentationError), (mp_obj_t)&mp_type_IndentationError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_IndexError), (mp_obj_t)&mp_type_IndexError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_KeyError), (mp_obj_t)&mp_type_KeyError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_LookupError), (mp_obj_t)&mp_type_LookupError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_MemoryError), (mp_obj_t)&mp_type_MemoryError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_NameError), (mp_obj_t)&mp_type_NameError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_NotImplementedError), (mp_obj_t)&mp_type_NotImplementedError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_OSError), (mp_obj_t)&mp_type_OSError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_OverflowError), (mp_obj_t)&mp_type_OverflowError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_RuntimeError), (mp_obj_t)&mp_type_RuntimeError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_StopIteration), (mp_obj_t)&mp_type_StopIteration },
{ MP_OBJ_NEW_QSTR(MP_QSTR_SyntaxError), (mp_obj_t)&mp_type_SyntaxError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_SystemError), (mp_obj_t)&mp_type_SystemError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_TypeError), (mp_obj_t)&mp_type_TypeError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_ValueError), (mp_obj_t)&mp_type_ValueError },
{ MP_OBJ_NEW_QSTR(MP_QSTR_ZeroDivisionError), (mp_obj_t)&mp_type_ZeroDivisionError },
// Somehow CPython managed to have OverflowError not inherit from ValueError ;-/
// TODO: For MICROPY_CPYTHON_COMPAT==0 use ValueError to avoid exc proliferation
// Extra builtins as defined by a port
MICROPY_EXTRA_BUILTINS
};
{ MP_QSTR_, MP_OBJ_NULL }, // end of list sentinel
const mp_obj_dict_t mp_builtin_object_dict_obj = {
.base = {&mp_type_dict},
.map = {
.all_keys_are_qstrs = 1,
.table_is_fixed_array = 1,
.used = sizeof(mp_builtin_object_table) / sizeof(mp_map_elem_t),
.alloc = sizeof(mp_builtin_object_table) / sizeof(mp_map_elem_t),
.table = (mp_map_elem_t*)mp_builtin_object_table,
},
};
STATIC const mp_builtin_elem_t builtin_module_table[] = {
{ MP_QSTR___main__, (mp_obj_t)&mp_module___main__ },
{ MP_QSTR_micropython, (mp_obj_t)&mp_module_micropython },
STATIC const mp_map_elem_t mp_builtin_module_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___main__), (mp_obj_t)&mp_module___main__ },
{ MP_OBJ_NEW_QSTR(MP_QSTR_micropython), (mp_obj_t)&mp_module_micropython },
{ MP_QSTR_array, (mp_obj_t)&mp_module_array },
{ MP_OBJ_NEW_QSTR(MP_QSTR_array), (mp_obj_t)&mp_module_array },
#if MICROPY_ENABLE_MOD_IO
{ MP_QSTR_io, (mp_obj_t)&mp_module_io },
{ MP_OBJ_NEW_QSTR(MP_QSTR_io), (mp_obj_t)&mp_module_io },
#endif
{ MP_QSTR_collections, (mp_obj_t)&mp_module_collections },
{ MP_OBJ_NEW_QSTR(MP_QSTR_collections), (mp_obj_t)&mp_module_collections },
#if MICROPY_ENABLE_FLOAT
{ MP_QSTR_math, (mp_obj_t)&mp_module_math },
{ MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&mp_module_math },
#endif
// extra builtin modules as defined by a port
MICROPY_EXTRA_BUILTIN_MODULES
{ MP_QSTR_, MP_OBJ_NULL }, // end of list sentinel
};
STATIC mp_obj_t mp_builtin_tables_lookup(const mp_builtin_elem_t *table, qstr q) {
for (; table->qstr != MP_QSTR_; table++) {
if (table->qstr == q) {
return table->elem;
}
}
return MP_OBJ_NULL;
}
mp_obj_t mp_builtin_tables_lookup_object(qstr q) {
return mp_builtin_tables_lookup(&builtin_object_table[0], q);
}
mp_obj_t mp_builtin_tables_lookup_module(qstr q) {
return mp_builtin_tables_lookup(&builtin_module_table[0], q);
}
const mp_obj_dict_t mp_builtin_module_dict_obj = {
.base = {&mp_type_dict},
.map = {
.all_keys_are_qstrs = 1,
.table_is_fixed_array = 1,
.used = sizeof(mp_builtin_module_table) / sizeof(mp_map_elem_t),
.alloc = sizeof(mp_builtin_module_table) / sizeof(mp_map_elem_t),
.table = (mp_map_elem_t*)mp_builtin_module_table,
},
};
mp_obj_t mp_builtin_tables_lookup_object(qstr q);
mp_obj_t mp_builtin_tables_lookup_module(qstr q);
extern const mp_obj_dict_t mp_builtin_object_dict_obj;
extern const mp_obj_dict_t mp_builtin_module_dict_obj;
......@@ -152,7 +152,7 @@ mp_obj_t mp_make_function_var_between(int n_args_min, int n_args_max, mp_fun_var
typedef struct _mp_obj_fun_bc_t {
mp_obj_base_t base;
mp_map_t *globals; // the context within which this function was defined
mp_obj_dict_t *globals; // the context within which this function was defined
machine_uint_t n_args : 15; // number of arguments this function takes
machine_uint_t n_def_args : 15; // number of default arguments
machine_uint_t takes_var_args : 1; // set if this function takes variable args
......@@ -326,7 +326,7 @@ continue2:;
}
}
mp_map_t *old_globals = mp_globals_get();
mp_obj_dict_t *old_globals = mp_globals_get();
mp_globals_set(self->globals);
mp_obj_t result;
DEBUG_printf("Calling: args=%p, n_args=%d, extra_args=%p, n_extra_args=%d\n", args, n_args, extra_args, n_extra_args);
......
......@@ -86,14 +86,16 @@ mp_obj_t mp_module_get(qstr module_name) {
// lookup module
mp_map_elem_t *el = mp_map_lookup(&mp_loaded_modules_map, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP);
// module found, return it
if (el != NULL) {
return el->value;
if (el == NULL) {
// module not found, look for builtin module names
el = mp_map_lookup((mp_map_t*)&mp_builtin_module_dict_obj.map, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP);
if (el == NULL) {
return MP_OBJ_NULL;
}
}
// module not found, look for builtin module names
// it will return MP_OBJ_NULL if nothing found
return mp_builtin_tables_lookup_module(module_name);
// module found, return it
return el->value;
}
void mp_module_register(qstr qstr, mp_obj_t module) {
......
......@@ -29,10 +29,10 @@
#endif
// locals and globals need to be pointers because they can be the same in outer module scope
STATIC mp_map_t *map_locals;
STATIC mp_map_t *map_globals;
STATIC mp_map_t map_builtins;
STATIC mp_obj_dict_t *dict_locals;
STATIC mp_obj_dict_t *dict_globals;
// dictionary for the __main__ module
STATIC mp_obj_dict_t dict_main;
const mp_obj_module_t mp_module___main__ = {
......@@ -47,15 +47,12 @@ void mp_init(void) {
// init global module stuff
mp_module_init();
// initialise the __main__ module
mp_obj_dict_init(&dict_main, 1);
// add some builtins that can't be done in ROM
mp_obj_dict_store(&dict_main, MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR___main__));
// locals = globals for outer module (see Objects/frameobject.c/PyFrame_New())
map_locals = map_globals = &dict_main.map;
// init built-in hash table
mp_map_init(&map_builtins, 3);
dict_locals = dict_globals = &dict_main;
#if MICROPY_CPYTHON_COMPAT
// Precreate sys module, so "import sys" didn't throw exceptions.
......@@ -70,8 +67,7 @@ void mp_init(void) {
}
void mp_deinit(void) {
mp_map_free(map_globals);
mp_map_deinit(&map_builtins);
//mp_obj_dict_free(&dict_main);
mp_module_deinit();
mp_emit_glue_deinit();
}
......@@ -97,10 +93,10 @@ mp_obj_t mp_load_const_bytes(qstr qstr) {
mp_obj_t mp_load_name(qstr qstr) {
// logic: search locals, globals, builtins
DEBUG_OP_printf("load name %s\n", map_locals, qstr_str(qstr));
DEBUG_OP_printf("load name %s\n", qstr_str(qstr));
// If we're at the outer scope (locals == globals), dispatch to load_global right away
if (map_locals != map_globals) {
mp_map_elem_t *elem = mp_map_lookup(map_locals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP);
if (dict_locals != dict_globals) {
mp_map_elem_t *elem = mp_map_lookup(&dict_locals->map, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP);
if (elem != NULL) {
return elem->value;
}
......@@ -111,14 +107,11 @@ mp_obj_t mp_load_name(qstr qstr) {
mp_obj_t mp_load_global(qstr qstr) {
// logic: search globals, builtins
DEBUG_OP_printf("load global %s\n", qstr_str(qstr));
mp_map_elem_t *elem = mp_map_lookup(map_globals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP);
mp_map_elem_t *elem = mp_map_lookup(&dict_globals->map, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP);
if (elem == NULL) {
elem = mp_map_lookup(&map_builtins, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP);
// TODO lookup in dynamic table of builtins first
elem = mp_map_lookup((mp_map_t*)&mp_builtin_object_dict_obj.map, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP);
if (elem == NULL) {
mp_obj_t o = mp_builtin_tables_lookup_object(qstr);
if (o != MP_OBJ_NULL) {
return o;
}
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_NameError, "name '%s' is not defined", qstr_str(qstr)));
}
}
......@@ -127,31 +120,25 @@ mp_obj_t mp_load_global(qstr qstr) {
mp_obj_t mp_load_build_class(void) {
DEBUG_OP_printf("load_build_class\n");
// lookup __build_class__ in dynamic table of builtins first
mp_map_elem_t *elem = mp_map_lookup(&map_builtins, MP_OBJ_NEW_QSTR(MP_QSTR___build_class__), MP_MAP_LOOKUP);
if (elem != NULL) {
// found user-defined __build_class__, return it
return elem->value;
} else {
// no user-defined __build_class__, return builtin one
return (mp_obj_t)&mp_builtin___build_class___obj;
}
// TODO lookup __build_class__ in dynamic table of builtins first
// ... else no user-defined __build_class__, return builtin one
return (mp_obj_t)&mp_builtin___build_class___obj;
}
void mp_store_name(qstr qstr, mp_obj_t obj) {
DEBUG_OP_printf("store name %s <- %p\n", qstr_str(qstr), obj);
mp_map_lookup(map_locals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = obj;
mp_obj_dict_store(dict_locals, MP_OBJ_NEW_QSTR(qstr), obj);
}
void mp_delete_name(qstr qstr) {
DEBUG_OP_printf("delete name %s\n", qstr_str(qstr));
// TODO raise NameError if qstr not found
mp_map_lookup(map_locals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_REMOVE_IF_FOUND);
mp_map_lookup(&dict_locals->map, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_REMOVE_IF_FOUND);
}
void mp_store_global(qstr qstr, mp_obj_t obj) {
DEBUG_OP_printf("store global %s <- %p\n", qstr_str(qstr), obj);
mp_map_lookup(map_globals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = obj;
mp_obj_dict_store(dict_globals, MP_OBJ_NEW_QSTR(qstr), obj);
}
mp_obj_t mp_unary_op(int op, mp_obj_t arg) {
......@@ -1020,22 +1007,22 @@ void mp_import_all(mp_obj_t module) {
}
}
mp_map_t *mp_locals_get(void) {
return map_locals;
mp_obj_dict_t *mp_locals_get(void) {
return dict_locals;
}
void mp_locals_set(mp_map_t *m) {
DEBUG_OP_printf("mp_locals_set(%p)\n", m);
map_locals = m;
void mp_locals_set(mp_obj_dict_t *d) {
DEBUG_OP_printf("mp_locals_set(%p)\n", d);
dict_locals = d;
}
mp_map_t *mp_globals_get(void) {
return map_globals;
mp_obj_dict_t *mp_globals_get(void) {
return dict_globals;
}
void mp_globals_set(mp_map_t *m) {
DEBUG_OP_printf("mp_globals_set(%p)\n", m);
map_globals = m;
void mp_globals_set(mp_obj_dict_t *d) {
DEBUG_OP_printf("mp_globals_set(%p)\n", d);
dict_globals = d;
}
void *m_malloc_fail(int num_bytes) {
......
......@@ -9,10 +9,10 @@ void mp_deinit(void);
void mp_check_nargs(int n_args, machine_uint_t n_args_min, machine_uint_t n_args_max, int n_kw, bool is_kw);
mp_map_t *mp_locals_get(void);
void mp_locals_set(mp_map_t *m);
mp_map_t *mp_globals_get(void);
void mp_globals_set(mp_map_t *m);
mp_obj_dict_t *mp_locals_get(void);
void mp_locals_set(mp_obj_dict_t *d);
mp_obj_dict_t *mp_globals_get(void);
void mp_globals_set(mp_obj_dict_t *d);
mp_obj_t mp_load_name(qstr qstr);
mp_obj_t mp_load_global(qstr qstr);
......
......@@ -24,18 +24,18 @@ extern const struct _mp_obj_fun_native_t mp_builtin_help_obj;
extern const struct _mp_obj_fun_native_t mp_builtin_input_obj;
extern const struct _mp_obj_fun_native_t mp_builtin_open_obj;
#define MICROPY_EXTRA_BUILTINS \
{ MP_QSTR_help, (mp_obj_t)&mp_builtin_help_obj }, \
{ MP_QSTR_input, (mp_obj_t)&mp_builtin_input_obj }, \
{ MP_QSTR_open, (mp_obj_t)&mp_builtin_open_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_help), (mp_obj_t)&mp_builtin_help_obj }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_input), (mp_obj_t)&mp_builtin_input_obj }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj },
// extra built in modules to add to the list of known ones
extern const struct _mp_obj_module_t os_module;
extern const struct _mp_obj_module_t pyb_module;
extern const struct _mp_obj_module_t time_module;
#define MICROPY_EXTRA_BUILTIN_MODULES \
{ MP_QSTR_os, (mp_obj_t)&os_module }, \
{ MP_QSTR_pyb, (mp_obj_t)&pyb_module }, \
{ MP_QSTR_time, (mp_obj_t)&time_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_os), (mp_obj_t)&os_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_pyb), (mp_obj_t)&pyb_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \
// type definitions for the specific machine
......
......@@ -34,4 +34,4 @@ typedef const void *machine_const_ptr_t; // must be of pointer size
struct _mp_obj_fun_native_t;
extern const struct _mp_obj_fun_native_t mp_builtin_open_obj;
#define MICROPY_EXTRA_BUILTINS \
{ MP_QSTR_open, (mp_obj_t)&mp_builtin_open_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj },
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment