Commit caac542b authored by Damien George's avatar Damien George
Browse files

Proper support for registering builtin modules in ROM.

Comes with some refactoring of code and renaming of files.  All modules
are now named mod*.[ch].
parent 1dfde891
...@@ -32,5 +32,7 @@ MP_DECLARE_CONST_FUN_OBJ(mp_builtin_sum_obj); ...@@ -32,5 +32,7 @@ MP_DECLARE_CONST_FUN_OBJ(mp_builtin_sum_obj);
MP_DECLARE_CONST_FUN_OBJ(mp_namedtuple_obj); MP_DECLARE_CONST_FUN_OBJ(mp_namedtuple_obj);
extern const mp_obj_module_t mp_module_array;
extern const mp_obj_module_t mp_module_collections;
extern const mp_obj_module_t mp_module_math; extern const mp_obj_module_t mp_module_math;
extern const mp_obj_module_t mp_module_micropython; extern const mp_obj_module_t mp_module_micropython;
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "lexerunix.h" #include "lexerunix.h"
#include "parse.h" #include "parse.h"
#include "obj.h" #include "obj.h"
#include "objmodule.h"
#include "parsehelper.h" #include "parsehelper.h"
#include "compile.h" #include "compile.h"
#include "runtime0.h" #include "runtime0.h"
...@@ -156,7 +157,7 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) { ...@@ -156,7 +157,7 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) {
const char *mod_str = (const char*)mp_obj_str_get_data(args[0], &mod_len); const char *mod_str = (const char*)mp_obj_str_get_data(args[0], &mod_len);
// check if module already exists // check if module already exists
mp_obj_t module_obj = mp_obj_module_get(mp_obj_str_get_qstr(args[0])); mp_obj_t module_obj = mp_module_get(mp_obj_str_get_qstr(args[0]));
if (module_obj != MP_OBJ_NULL) { if (module_obj != MP_OBJ_NULL) {
// If it's not a package, return module right away // If it's not a package, return module right away
char *p = strchr(mod_str, '.'); char *p = strchr(mod_str, '.');
...@@ -169,7 +170,7 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) { ...@@ -169,7 +170,7 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) {
} }
// Otherwise, we need to return top-level package // Otherwise, we need to return top-level package
qstr pkg_name = qstr_from_strn(mod_str, p - mod_str); qstr pkg_name = qstr_from_strn(mod_str, p - mod_str);
return mp_obj_module_get(pkg_name); return mp_module_get(pkg_name);
} }
uint last = 0; uint last = 0;
...@@ -200,7 +201,7 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) { ...@@ -200,7 +201,7 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) {
nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "ImportError: No module named '%s'", qstr_str(mod_name))); nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "ImportError: No module named '%s'", qstr_str(mod_name)));
} }
module_obj = mp_obj_module_get(mod_name); module_obj = mp_module_get(mod_name);
if (module_obj == MP_OBJ_NULL) { if (module_obj == MP_OBJ_NULL) {
// module not already loaded, so load it! // module not already loaded, so load it!
......
#include <stdlib.h>
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "builtin.h"
#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[] = {
// 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 },
// built-in types
{ MP_QSTR_bool, (mp_obj_t)&bool_type },
{ MP_QSTR_bytes, (mp_obj_t)&bytes_type },
#if MICROPY_ENABLE_FLOAT
{ MP_QSTR_complex, (mp_obj_t)&mp_type_complex },
#endif
{ MP_QSTR_dict, (mp_obj_t)&dict_type },
{ MP_QSTR_enumerate, (mp_obj_t)&enumerate_type },
{ MP_QSTR_filter, (mp_obj_t)&filter_type },
#if MICROPY_ENABLE_FLOAT
{ MP_QSTR_float, (mp_obj_t)&mp_type_float },
#endif
{ MP_QSTR_int, (mp_obj_t)&int_type },
{ MP_QSTR_list, (mp_obj_t)&list_type },
{ MP_QSTR_map, (mp_obj_t)&map_type },
{ MP_QSTR_object, (mp_obj_t)&mp_type_object },
{ MP_QSTR_set, (mp_obj_t)&set_type },
{ MP_QSTR_str, (mp_obj_t)&str_type },
{ MP_QSTR_super, (mp_obj_t)&super_type },
{ MP_QSTR_tuple, (mp_obj_t)&tuple_type },
{ MP_QSTR_type, (mp_obj_t)&mp_type_type },
{ MP_QSTR_zip, (mp_obj_t)&zip_type },
{ MP_QSTR_classmethod, (mp_obj_t)&mp_type_classmethod },
{ MP_QSTR_staticmethod, (mp_obj_t)&mp_type_staticmethod },
// 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_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 },
// 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_BufferError, (mp_obj_t)&mp_type_BufferError },
{ MP_QSTR_EOFError, (mp_obj_t)&mp_type_EOFError },
{ MP_QSTR_EnvironmentError, (mp_obj_t)&mp_type_EnvironmentError },
{ MP_QSTR_Exception, (mp_obj_t)&mp_type_Exception },
{ MP_QSTR_FloatingPointError, (mp_obj_t)&mp_type_FloatingPointError },
{ 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_ReferenceError, (mp_obj_t)&mp_type_ReferenceError },
{ MP_QSTR_RuntimeError, (mp_obj_t)&mp_type_RuntimeError },
{ MP_QSTR_SyntaxError, (mp_obj_t)&mp_type_SyntaxError },
{ MP_QSTR_SystemError, (mp_obj_t)&mp_type_SystemError },
{ MP_QSTR_SystemExit, (mp_obj_t)&mp_type_SystemExit },
{ MP_QSTR_TabError, (mp_obj_t)&mp_type_TabError },
{ MP_QSTR_TypeError, (mp_obj_t)&mp_type_TypeError },
{ MP_QSTR_UnboundLocalError, (mp_obj_t)&mp_type_UnboundLocalError },
{ MP_QSTR_ValueError, (mp_obj_t)&mp_type_ValueError },
{ MP_QSTR_ZeroDivisionError, (mp_obj_t)&mp_type_ZeroDivisionError },
{ MP_QSTR_StopIteration, (mp_obj_t)&mp_type_StopIteration },
// 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
};
STATIC const mp_builtin_elem_t builtin_module_table[] = {
{ MP_QSTR_micropython, (mp_obj_t)&mp_module_micropython },
{ MP_QSTR_array, (mp_obj_t)&mp_module_array },
{ MP_QSTR_collections, (mp_obj_t)&mp_module_collections },
#if MICROPY_ENABLE_FLOAT
{ 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);
}
mp_obj_t mp_builtin_tables_lookup_object(qstr q);
mp_obj_t mp_builtin_tables_lookup_module(qstr q);
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "map.h"
#include "builtin.h"
STATIC const mp_map_elem_t mp_module_array_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_array) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_array), (mp_obj_t)&mp_type_array },
};
STATIC const mp_map_t mp_module_array_globals = {
.all_keys_are_qstrs = 1,
.table_is_fixed_array = 1,
.used = sizeof(mp_module_array_globals_table) / sizeof(mp_map_elem_t),
.alloc = sizeof(mp_module_array_globals_table) / sizeof(mp_map_elem_t),
.table = (mp_map_elem_t*)mp_module_array_globals_table,
};
const mp_obj_module_t mp_module_array = {
.base = { &mp_type_module },
.name = MP_QSTR_array,
.globals = (mp_map_t*)&mp_module_array_globals,
};
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "map.h"
#include "builtin.h"
STATIC const mp_map_elem_t mp_module_collections_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_collections) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_namedtuple), (mp_obj_t)&mp_namedtuple_obj },
};
STATIC const mp_map_t mp_module_collections_globals = {
.all_keys_are_qstrs = 1,
.table_is_fixed_array = 1,
.used = sizeof(mp_module_collections_globals_table) / sizeof(mp_map_elem_t),
.alloc = sizeof(mp_module_collections_globals_table) / sizeof(mp_map_elem_t),
.table = (mp_map_elem_t*)mp_module_collections_globals_table,
};
const mp_obj_module_t mp_module_collections = {
.base = { &mp_type_module },
.name = MP_QSTR_collections,
.globals = (mp_map_t*)&mp_module_collections_globals,
};
#include "misc.h" #include "misc.h"
#include "mpconfig.h" #include "mpconfig.h"
#include "qstr.h" #include "qstr.h"
......
...@@ -125,10 +125,16 @@ typedef double mp_float_t; ...@@ -125,10 +125,16 @@ typedef double mp_float_t;
#define MICROPY_PATH_MAX (512) #define MICROPY_PATH_MAX (512)
#endif #endif
// Additional builtin function definitions - see runtime.c:builtin_table for format. // Additional builtin function definitions - see builtintables.c:builtin_object_table for format.
#ifndef MICROPY_EXTRA_BUILTINS #ifndef MICROPY_EXTRA_BUILTINS
#define MICROPY_EXTRA_BUILTINS #define MICROPY_EXTRA_BUILTINS
#endif #endif
// Additional builtin module definitions - see builtintables.c:builtin_module_table for format.
#ifndef MICROPY_EXTRA_BUILTIN_MODULES
#define MICROPY_EXTRA_BUILTIN_MODULES
#endif
/*****************************************************************************/ /*****************************************************************************/
/* Miscellaneous settings */ /* Miscellaneous settings */
......
...@@ -417,7 +417,7 @@ void mp_obj_slice_get(mp_obj_t self_in, machine_int_t *start, machine_int_t *sto ...@@ -417,7 +417,7 @@ void mp_obj_slice_get(mp_obj_t self_in, machine_int_t *start, machine_int_t *sto
extern const mp_obj_type_t zip_type; extern const mp_obj_type_t zip_type;
// array // array
extern const mp_obj_type_t array_type; extern const mp_obj_type_t mp_type_array;
uint mp_obj_array_len(mp_obj_t self_in); uint mp_obj_array_len(mp_obj_t self_in);
mp_obj_t mp_obj_new_bytearray_by_ref(uint n, void *items); mp_obj_t mp_obj_new_bytearray_by_ref(uint n, void *items);
...@@ -454,9 +454,6 @@ typedef struct _mp_obj_module_t { ...@@ -454,9 +454,6 @@ typedef struct _mp_obj_module_t {
struct _mp_map_t *globals; struct _mp_map_t *globals;
} mp_obj_module_t; } mp_obj_module_t;
extern const mp_obj_type_t mp_type_module; extern const mp_obj_type_t mp_type_module;
mp_obj_t mp_obj_new_module(qstr module_name);
mp_obj_t mp_obj_module_get(qstr module_name);
void mp_obj_module_register(qstr qstr, mp_obj_t module); //use for loading statically allocated modules
struct _mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in); struct _mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in);
// staticmethod and classmethod types; defined here so we can make const versions // staticmethod and classmethod types; defined here so we can make const versions
......
...@@ -121,7 +121,7 @@ STATIC mp_obj_t array_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { ...@@ -121,7 +121,7 @@ STATIC mp_obj_t array_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
} }
STATIC mp_obj_t array_append(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t array_append(mp_obj_t self_in, mp_obj_t arg) {
assert(MP_OBJ_IS_TYPE(self_in, &array_type)); assert(MP_OBJ_IS_TYPE(self_in, &mp_type_array));
mp_obj_array_t *self = self_in; mp_obj_array_t *self = self_in;
if (self->free == 0) { if (self->free == 0) {
int item_sz = mp_binary_get_size(self->typecode); int item_sz = mp_binary_get_size(self->typecode);
...@@ -154,7 +154,7 @@ STATIC const mp_method_t array_type_methods[] = { ...@@ -154,7 +154,7 @@ STATIC const mp_method_t array_type_methods[] = {
{ NULL, NULL }, { NULL, NULL },
}; };
const mp_obj_type_t array_type = { const mp_obj_type_t mp_type_array = {
{ &mp_type_type }, { &mp_type_type },
.name = MP_QSTR_array, .name = MP_QSTR_array,
.print = array_print, .print = array_print,
...@@ -169,7 +169,7 @@ const mp_obj_type_t array_type = { ...@@ -169,7 +169,7 @@ const mp_obj_type_t array_type = {
STATIC mp_obj_array_t *array_new(char typecode, uint n) { STATIC mp_obj_array_t *array_new(char typecode, uint n) {
mp_obj_array_t *o = m_new_obj(mp_obj_array_t); mp_obj_array_t *o = m_new_obj(mp_obj_array_t);
o->base.type = &array_type; o->base.type = &mp_type_array;
o->typecode = typecode; o->typecode = typecode;
o->free = 0; o->free = 0;
o->len = n; o->len = n;
...@@ -190,7 +190,7 @@ mp_obj_t mp_obj_new_bytearray(uint n, void *items) { ...@@ -190,7 +190,7 @@ mp_obj_t mp_obj_new_bytearray(uint n, void *items) {
// Create bytearray which references specified memory area // Create bytearray which references specified memory area
mp_obj_t mp_obj_new_bytearray_by_ref(uint n, void *items) { mp_obj_t mp_obj_new_bytearray_by_ref(uint n, void *items) {
mp_obj_array_t *o = m_new_obj(mp_obj_array_t); mp_obj_array_t *o = m_new_obj(mp_obj_array_t);
o->base.type = &array_type; o->base.type = &mp_type_array;
o->typecode = BYTEARRAY_TYPECODE; o->typecode = BYTEARRAY_TYPECODE;
o->free = 0; o->free = 0;
o->len = n; o->len = n;
...@@ -207,7 +207,7 @@ typedef struct _mp_obj_array_it_t { ...@@ -207,7 +207,7 @@ typedef struct _mp_obj_array_it_t {
machine_uint_t cur; machine_uint_t cur;
} mp_obj_array_it_t; } mp_obj_array_it_t;
mp_obj_t array_it_iternext(mp_obj_t self_in) { STATIC mp_obj_t array_it_iternext(mp_obj_t self_in) {
mp_obj_array_it_t *self = self_in; mp_obj_array_it_t *self = self_in;
if (self->cur < self->array->len) { if (self->cur < self->array->len) {
return mp_binary_get_val(self->array->typecode, self->array->items, self->cur++); return mp_binary_get_val(self->array->typecode, self->array->items, self->cur++);
...@@ -222,7 +222,7 @@ STATIC const mp_obj_type_t array_it_type = { ...@@ -222,7 +222,7 @@ STATIC const mp_obj_type_t array_it_type = {
.iternext = array_it_iternext, .iternext = array_it_iternext,
}; };
mp_obj_t array_iterator_new(mp_obj_t array_in) { STATIC mp_obj_t array_iterator_new(mp_obj_t array_in) {
mp_obj_array_t *array = array_in; mp_obj_array_t *array = array_in;
mp_obj_array_it_t *o = m_new_obj(mp_obj_array_it_t); mp_obj_array_it_t *o = m_new_obj(mp_obj_array_it_t);
o->base.type = &array_it_type; o->base.type = &array_it_type;
......
...@@ -6,9 +6,12 @@ ...@@ -6,9 +6,12 @@
#include "mpconfig.h" #include "mpconfig.h"
#include "qstr.h" #include "qstr.h"
#include "obj.h" #include "obj.h"
#include "objmodule.h"
#include "runtime.h" #include "runtime.h"
#include "map.h" #include "map.h"
#include "builtin.h" #include "builtintables.h"
STATIC mp_map_t mp_loaded_modules_map; // TODO: expose as sys.modules
STATIC void module_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { STATIC void module_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
mp_obj_module_t *self = self_in; mp_obj_module_t *self = self_in;
...@@ -39,7 +42,7 @@ const mp_obj_type_t mp_type_module = { ...@@ -39,7 +42,7 @@ const mp_obj_type_t mp_type_module = {
}; };
mp_obj_t mp_obj_new_module(qstr module_name) { mp_obj_t mp_obj_new_module(qstr module_name) {
mp_map_elem_t *el = mp_map_lookup(rt_loaded_modules_get(), MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND); mp_map_elem_t *el = mp_map_lookup(&mp_loaded_modules_map, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
// We could error out if module already exists, but let C extensions // We could error out if module already exists, but let C extensions
// add new members to existing modules. // add new members to existing modules.
if (el->value != MP_OBJ_NULL) { if (el->value != MP_OBJ_NULL) {
...@@ -62,9 +65,27 @@ mp_obj_t mp_obj_new_module(qstr module_name) { ...@@ -62,9 +65,27 @@ mp_obj_t mp_obj_new_module(qstr module_name) {
return o; return o;
} }
mp_obj_t mp_obj_module_get(qstr module_name) { mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in) {
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_module));
mp_obj_module_t *self = self_in;
return self->globals;
}
/******************************************************************************/
// Global module table and related functions
void mp_module_init(void) {
mp_map_init(&mp_loaded_modules_map, 3);
}
void mp_module_deinit(void) {
mp_map_deinit(&mp_loaded_modules_map);
}
// returns MP_OBJ_NULL if not found
mp_obj_t mp_module_get(qstr module_name) {
// lookup module // lookup module
mp_map_elem_t *el = mp_map_lookup(rt_loaded_modules_get(), MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP); 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 // module found, return it
if (el != NULL) { if (el != NULL) {
...@@ -72,23 +93,10 @@ mp_obj_t mp_obj_module_get(qstr module_name) { ...@@ -72,23 +93,10 @@ mp_obj_t mp_obj_module_get(qstr module_name) {
} }
// module not found, look for builtin module names // module not found, look for builtin module names
#if MICROPY_ENABLE_FLOAT // it will return MP_OBJ_NULL if nothing found
if (module_name == MP_QSTR_math) { return mp_builtin_tables_lookup_module(module_name);
return (mp_obj_t)&mp_module_math;
}
#endif
// no module found, return NULL object
return MP_OBJ_NULL;
}
void mp_obj_module_register(qstr qstr, mp_obj_t module)
{
mp_map_lookup(rt_loaded_modules_get(), MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = module;
} }
mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in) { void mp_module_register(qstr qstr, mp_obj_t module) {
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_module)); mp_map_lookup(&mp_loaded_modules_map, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = module;
mp_obj_module_t *self = self_in;
return self->globals;
} }
void mp_module_init(void);
void mp_module_deinit(void);
mp_obj_t mp_module_get(qstr module_name);
void mp_module_register(qstr qstr, mp_obj_t module);
...@@ -74,8 +74,11 @@ PY_O_BASENAME = \ ...@@ -74,8 +74,11 @@ PY_O_BASENAME = \
builtin.o \ builtin.o \
builtinimport.o \ builtinimport.o \
builtinevex.o \ builtinevex.o \
builtinmp.o \ builtintables.o \
builtinmath.o \ modarray.o \
modcollections.o \
modmath.o \
modmicropython.o \
vm.o \ vm.o \
showbc.o \ showbc.o \
repl.o \ repl.o \
......
...@@ -12,12 +12,13 @@ ...@@ -12,12 +12,13 @@
#include "mpconfig.h" #include "mpconfig.h"
#include "qstr.h" #include "qstr.h"
#include "obj.h" #include "obj.h"
#include "objmodule.h"
#include "parsenum.h" #include "parsenum.h"
#include "runtime0.h" #include "runtime0.h"
#include "runtime.h" #include "runtime.h"
#include "map.h" #include "map.h"
#include "builtin.h" #include "builtin.h"
#include "objarray.h" #include "builtintables.h"
#include "bc.h" #include "bc.h"
#include "intdivmod.h" #include "intdivmod.h"
...@@ -35,7 +36,6 @@ ...@@ -35,7 +36,6 @@
STATIC mp_map_t *map_locals; STATIC mp_map_t *map_locals;
STATIC mp_map_t *map_globals; STATIC mp_map_t *map_globals;
STATIC mp_map_t map_builtins; STATIC mp_map_t map_builtins;
STATIC mp_map_t map_loaded_modules; // TODO: expose as sys.modules
typedef enum { typedef enum {
MP_CODE_NONE, MP_CODE_NONE,
...@@ -72,119 +72,6 @@ STATIC mp_code_t *unique_codes = NULL; ...@@ -72,119 +72,6 @@ STATIC mp_code_t *unique_codes = NULL;
FILE *fp_write_code = NULL; FILE *fp_write_code = NULL;
#endif #endif
// builtins
// we put this table in ROM because it's always needed and takes 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
// if we wanted to allow dynamic modification of the builtins, we could provide an mp_map_t object which is searched before this one
typedef struct _mp_builtin_elem_t {
qstr qstr;
mp_obj_t fun;
} mp_builtin_elem_t;
STATIC const mp_builtin_elem_t builtin_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 },
// built-in types
{ MP_QSTR_bool, (mp_obj_t)&bool_type },
{ MP_QSTR_bytes, (mp_obj_t)&bytes_type },
#if MICROPY_ENABLE_FLOAT
{ MP_QSTR_complex, (mp_obj_t)&mp_type_complex },
#endif
{ MP_QSTR_dict, (mp_obj_t)&dict_type },
{ MP_QSTR_enumerate, (mp_obj_t)&enumerate_type },
{ MP_QSTR_filter, (mp_obj_t)&filter_type },
#if MICROPY_ENABLE_FLOAT
{ MP_QSTR_float, (mp_obj_t)&mp_type_float },
#endif
{ MP_QSTR_int, (mp_obj_t)&int_type },
{ MP_QSTR_list, (mp_obj_t)&list_type },
{ MP_QSTR_map, (mp_obj_t)&map_type },
{ MP_QSTR_object, (mp_obj_t)&mp_type_object },
{ MP_QSTR_set, (mp_obj_t)&set_type },