summaryrefslogtreecommitdiffstatshomepage
path: root/py/objmodule.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-12-09 16:19:48 +0000
committerDamien George <damien.p.george@gmail.com>2014-12-09 16:19:48 +0000
commit78d702c300ae9f175e6f47f805a37cdfe5b81898 (patch)
tree034b42ea789dc38c629a2f0dd8a48001a32cd838 /py/objmodule.c
parente6e8ad8ab238cd596a3eedf8f4dd635e2e84f46e (diff)
downloadmicropython-78d702c300ae9f175e6f47f805a37cdfe5b81898.tar.gz
micropython-78d702c300ae9f175e6f47f805a37cdfe5b81898.zip
py: Allow builtins to be overridden.
This patch adds a configuration option (MICROPY_CAN_OVERRIDE_BUILTINS) which, when enabled, allows to override all names within the builtins module. A builtins override dict is created the first time the user assigns to a name in the builtins model, and then that dict is searched first on subsequent lookups. Note that this implementation doesn't allow deleting of names. This patch also does some refactoring of builtins code, creating the modbuiltins.c file. Addresses issue #959.
Diffstat (limited to 'py/objmodule.c')
-rw-r--r--py/objmodule.c86
1 files changed, 82 insertions, 4 deletions
diff --git a/py/objmodule.c b/py/objmodule.c
index 7f765ff95c..5ffb368bf5 100644
--- a/py/objmodule.c
+++ b/py/objmodule.c
@@ -34,7 +34,7 @@
#include "obj.h"
#include "objmodule.h"
#include "runtime.h"
-#include "builtintables.h"
+#include "builtin.h"
STATIC mp_map_t mp_loaded_modules_map; // TODO: expose as sys.modules
@@ -65,13 +65,28 @@ STATIC void module_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
STATIC bool module_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) {
mp_obj_module_t *self = self_in;
+ mp_obj_dict_t *dict = self->globals;
+ if (dict->map.table_is_fixed_array) {
+ #if MICROPY_CAN_OVERRIDE_BUILTINS
+ if (dict == &mp_module_builtins_globals) {
+ if (mp_module_builtins_override_dict == NULL) {
+ mp_module_builtins_override_dict = mp_obj_new_dict(1);
+ }
+ dict = mp_module_builtins_override_dict;
+ } else
+ #endif
+ {
+ // can't delete or store to fixed map
+ return false;
+ }
+ }
if (value == MP_OBJ_NULL) {
// delete attribute
- mp_obj_dict_delete(self->globals, MP_OBJ_NEW_QSTR(attr));
+ mp_obj_dict_delete(dict, MP_OBJ_NEW_QSTR(attr));
} else {
// store attribute
// TODO CPython allows STORE_ATTR to a module, but is this the correct implementation?
- mp_obj_dict_store(self->globals, MP_OBJ_NEW_QSTR(attr), value);
+ mp_obj_dict_store(dict, MP_OBJ_NEW_QSTR(attr), value);
}
return true;
}
@@ -117,6 +132,69 @@ mp_obj_dict_t *mp_obj_module_get_globals(mp_obj_t self_in) {
/******************************************************************************/
// Global module table and related functions
+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_builtins), (mp_obj_t)&mp_module_builtins },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_micropython), (mp_obj_t)&mp_module_micropython },
+
+#if MICROPY_PY_ARRAY
+ { MP_OBJ_NEW_QSTR(MP_QSTR_array), (mp_obj_t)&mp_module_array },
+#endif
+#if MICROPY_PY_IO
+ { MP_OBJ_NEW_QSTR(MP_QSTR__io), (mp_obj_t)&mp_module_io },
+#endif
+#if MICROPY_PY_COLLECTIONS
+ { MP_OBJ_NEW_QSTR(MP_QSTR__collections), (mp_obj_t)&mp_module_collections },
+#endif
+#if MICROPY_PY_STRUCT
+ { MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&mp_module_struct },
+#endif
+
+#if MICROPY_PY_BUILTINS_FLOAT
+#if MICROPY_PY_MATH
+ { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&mp_module_math },
+#endif
+#if MICROPY_PY_CMATH
+ { MP_OBJ_NEW_QSTR(MP_QSTR_cmath), (mp_obj_t)&mp_module_cmath },
+#endif
+#endif
+#if MICROPY_PY_SYS
+ { MP_OBJ_NEW_QSTR(MP_QSTR_sys), (mp_obj_t)&mp_module_sys },
+#endif
+#if MICROPY_PY_GC && MICROPY_ENABLE_GC
+ { MP_OBJ_NEW_QSTR(MP_QSTR_gc), (mp_obj_t)&mp_module_gc },
+#endif
+
+ // extmod modules
+
+#if MICROPY_PY_UCTYPES
+ { MP_OBJ_NEW_QSTR(MP_QSTR_uctypes), (mp_obj_t)&mp_module_uctypes },
+#endif
+#if MICROPY_PY_UZLIB
+ { MP_OBJ_NEW_QSTR(MP_QSTR_uzlib), (mp_obj_t)&mp_module_uzlib },
+#endif
+#if MICROPY_PY_UJSON
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ujson), (mp_obj_t)&mp_module_ujson },
+#endif
+#if MICROPY_PY_URE
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ure), (mp_obj_t)&mp_module_ure },
+#endif
+#if MICROPY_PY_UHEAPQ
+ { MP_OBJ_NEW_QSTR(MP_QSTR_uheapq), (mp_obj_t)&mp_module_uheapq },
+#endif
+#if MICROPY_PY_UHASHLIB
+ { MP_OBJ_NEW_QSTR(MP_QSTR_uhashlib), (mp_obj_t)&mp_module_uhashlib },
+#endif
+#if MICROPY_PY_UBINASCII
+ { MP_OBJ_NEW_QSTR(MP_QSTR_ubinascii), (mp_obj_t)&mp_module_ubinascii },
+#endif
+
+ // extra builtin modules as defined by a port
+ MICROPY_PORT_BUILTIN_MODULES
+};
+
+STATIC MP_DEFINE_CONST_MAP(mp_builtin_module_map, mp_builtin_module_table);
+
void mp_module_init(void) {
mp_map_init(&mp_loaded_modules_map, 3);
}
@@ -132,7 +210,7 @@ mp_obj_t mp_module_get(qstr module_name) {
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);
+ el = mp_map_lookup((mp_map_t*)&mp_builtin_module_map, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP);
if (el == NULL) {
return MP_OBJ_NULL;
}