diff options
author | Damien George <damien.p.george@gmail.com> | 2014-12-09 16:19:48 +0000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-12-09 16:19:48 +0000 |
commit | 78d702c300ae9f175e6f47f805a37cdfe5b81898 (patch) | |
tree | 034b42ea789dc38c629a2f0dd8a48001a32cd838 /py/objmodule.c | |
parent | e6e8ad8ab238cd596a3eedf8f4dd635e2e84f46e (diff) | |
download | micropython-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.c | 86 |
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; } |