diff options
Diffstat (limited to 'py')
-rw-r--r-- | py/builtinimport.c | 7 | ||||
-rw-r--r-- | py/obj.h | 1 | ||||
-rw-r--r-- | py/objmodule.c | 22 |
3 files changed, 29 insertions, 1 deletions
diff --git a/py/builtinimport.c b/py/builtinimport.c index e3c630a0a4..92d5d5ac9f 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -28,8 +28,13 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) { } */ - // find the file to import qstr mod_name = mp_obj_get_qstr(args[0]); + mp_obj_t loaded = mp_obj_module_get(mod_name); + if (loaded != MP_OBJ_NULL) { + return loaded; + } + + // find the file to import mp_lexer_t *lex = mp_import_open_file(mod_name); if (lex == NULL) { // TODO handle lexer error correctly @@ -356,6 +356,7 @@ extern const mp_obj_type_t gen_instance_type; // module extern const mp_obj_type_t module_type; mp_obj_t mp_obj_new_module(qstr module_name); +mp_obj_t mp_obj_module_get(qstr module_name); 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 diff --git a/py/objmodule.c b/py/objmodule.c index e97e731929..fb7842e5af 100644 --- a/py/objmodule.c +++ b/py/objmodule.c @@ -17,6 +17,9 @@ typedef struct _mp_obj_module_t { mp_map_t *globals; } mp_obj_module_t; +// TODO: expose as sys.modules +static mp_map_t *loaded_modules; + 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; print(env, "<module '%s' from '-unknown-file-'>", qstr_str(self->name)); @@ -46,14 +49,33 @@ const mp_obj_type_t module_type = { }; mp_obj_t mp_obj_new_module(qstr module_name) { + if (loaded_modules == NULL) { + loaded_modules = mp_map_new(1); + } + mp_map_elem_t *el = mp_map_lookup(loaded_modules, 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 + // add new members to existing modules. + if (el->value != MP_OBJ_NULL) { + return el->value; + } + 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(1); + el->value = o; 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; } +mp_obj_t mp_obj_module_get(qstr module_name) { + mp_map_elem_t *el = mp_map_lookup(loaded_modules, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP); + if (el == NULL) { + return NULL; + } + return el->value; +} + mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in) { assert(MP_OBJ_IS_TYPE(self_in, &module_type)); mp_obj_module_t *self = self_in; |