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/runtime.c | |
parent | e6e8ad8ab238cd596a3eedf8f4dd635e2e84f46e (diff) |
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/runtime.c')
-rw-r--r-- | py/runtime.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/py/runtime.c b/py/runtime.c index 463e325d2..0690bd8b0 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -42,7 +42,6 @@ #include "runtime.h" #include "emitglue.h" #include "builtin.h" -#include "builtintables.h" #include "bc.h" #include "smallint.h" #include "objgenerator.h" @@ -78,6 +77,10 @@ const mp_obj_module_t mp_module___main__ = { .globals = (mp_obj_dict_t*)&dict_main, }; +#if MICROPY_CAN_OVERRIDE_BUILTINS +mp_obj_dict_t *mp_module_builtins_override_dict; +#endif + void mp_init(void) { qstr_init(); mp_stack_ctrl_init(); @@ -106,6 +109,11 @@ void mp_init(void) { // locals = globals for outer module (see Objects/frameobject.c/PyFrame_New()) dict_locals = dict_globals = &dict_main; + + #if MICROPY_CAN_OVERRIDE_BUILTINS + // start with no extensions to builtins + mp_module_builtins_override_dict = NULL; + #endif } void mp_deinit(void) { @@ -162,8 +170,16 @@ mp_obj_t mp_load_global(qstr qstr) { DEBUG_OP_printf("load global %s\n", qstr_str(qstr)); mp_map_elem_t *elem = mp_map_lookup(&dict_globals->map, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP); if (elem == NULL) { - // 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 MICROPY_CAN_OVERRIDE_BUILTINS + if (mp_module_builtins_override_dict != NULL) { + // lookup in additional dynamic table of builtins first + elem = mp_map_lookup(&mp_module_builtins_override_dict->map, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP); + if (elem != NULL) { + return elem->value; + } + } + #endif + elem = mp_map_lookup((mp_map_t*)&mp_module_builtins_globals.map, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP); if (elem == NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { nlr_raise(mp_obj_new_exception_msg(&mp_type_NameError, @@ -179,8 +195,15 @@ mp_obj_t mp_load_global(qstr qstr) { mp_obj_t mp_load_build_class(void) { DEBUG_OP_printf("load_build_class\n"); - // TODO lookup __build_class__ in dynamic table of builtins first - // ... else no user-defined __build_class__, return builtin one + #if MICROPY_CAN_OVERRIDE_BUILTINS + if (mp_module_builtins_override_dict != NULL) { + // lookup in additional dynamic table of builtins first + mp_map_elem_t *elem = mp_map_lookup(&mp_module_builtins_override_dict->map, MP_OBJ_NEW_QSTR(MP_QSTR___build_class__), MP_MAP_LOOKUP); + if (elem != NULL) { + return elem->value; + } + } + #endif return (mp_obj_t)&mp_builtin___build_class___obj; } |