diff options
author | Damien George <damien.p.george@gmail.com> | 2014-02-06 22:57:51 +0000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-02-06 22:57:51 +0000 |
commit | aea532ece182b0eb234144612f3083e2da0b5943 (patch) | |
tree | 1d70481d89a1416a6354f7c458f3f658a19a1a9f | |
parent | 354d15a964474b0ced060abfbb8f889be8ce8efd (diff) | |
download | micropython-aea532ece182b0eb234144612f3083e2da0b5943.tar.gz micropython-aea532ece182b0eb234144612f3083e2da0b5943.zip |
py: Put builtins into ROM table.
Linear table at the moment, to eventually be replaced with a hash table
generated by a preprocessor.
Dynamic table is retained so that builtins can be overridden.
-rw-r--r-- | py/runtime.c | 156 |
1 files changed, 86 insertions, 70 deletions
diff --git a/py/runtime.c b/py/runtime.c index 6790da4e59..2f65186a0d 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -74,6 +74,79 @@ static mp_code_t *unique_codes = NULL; FILE *fp_write_code = NULL; #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 }, +#if MICROPY_ENABLE_FLOAT + { MP_QSTR_complex, (mp_obj_t)&complex_type }, +#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)&float_type }, +#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_set, (mp_obj_t)&set_type }, + { MP_QSTR_super, (mp_obj_t)&super_type }, + { MP_QSTR_tuple, (mp_obj_t)&tuple_type }, + { MP_QSTR_type, (mp_obj_t)&mp_const_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_bytes, (mp_obj_t)&mp_builtin_bytes_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_str, (mp_obj_t)&mp_builtin_str_obj }, + { MP_QSTR_bytearray, (mp_obj_t)&mp_builtin_bytearray_obj }, + + { MP_QSTR_, MP_OBJ_NULL }, // end of list sentinel +}; + // a good optimising compiler will inline this if necessary static void mp_map_add_qstr(mp_map_t *map, qstr qstr, mp_obj_t value) { mp_map_lookup(map, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; @@ -109,67 +182,9 @@ void rt_init(void) { // built-in objects mp_map_add_qstr(&map_builtins, MP_QSTR_Ellipsis, mp_const_ellipsis); - // built-in core functions - mp_map_add_qstr(&map_builtins, MP_QSTR___build_class__, (mp_obj_t)&mp_builtin___build_class___obj); - mp_map_add_qstr(&map_builtins, MP_QSTR___import__, (mp_obj_t)&mp_builtin___import___obj); - mp_map_add_qstr(&map_builtins, MP_QSTR___repl_print__, (mp_obj_t)&mp_builtin___repl_print___obj); - - // built-in types - mp_map_add_qstr(&map_builtins, MP_QSTR_bool, (mp_obj_t)&bool_type); -#if MICROPY_ENABLE_FLOAT - mp_map_add_qstr(&map_builtins, MP_QSTR_complex, (mp_obj_t)&complex_type); -#endif - mp_map_add_qstr(&map_builtins, MP_QSTR_dict, (mp_obj_t)&dict_type); - mp_map_add_qstr(&map_builtins, MP_QSTR_enumerate, (mp_obj_t)&enumerate_type); - mp_map_add_qstr(&map_builtins, MP_QSTR_filter, (mp_obj_t)&filter_type); -#if MICROPY_ENABLE_FLOAT - mp_map_add_qstr(&map_builtins, MP_QSTR_float, (mp_obj_t)&float_type); -#endif - mp_map_add_qstr(&map_builtins, MP_QSTR_int, (mp_obj_t)&int_type); - mp_map_add_qstr(&map_builtins, MP_QSTR_list, (mp_obj_t)&list_type); - mp_map_add_qstr(&map_builtins, MP_QSTR_map, (mp_obj_t)&map_type); - mp_map_add_qstr(&map_builtins, MP_QSTR_set, (mp_obj_t)&set_type); - mp_map_add_qstr(&map_builtins, MP_QSTR_super, (mp_obj_t)&super_type); - mp_map_add_qstr(&map_builtins, MP_QSTR_tuple, (mp_obj_t)&tuple_type); - mp_map_add_qstr(&map_builtins, MP_QSTR_type, (mp_obj_t)&mp_const_type); - mp_map_add_qstr(&map_builtins, MP_QSTR_zip, (mp_obj_t)&zip_type); - - mp_map_add_qstr(&map_builtins, MP_QSTR_classmethod, (mp_obj_t)&mp_type_classmethod); - mp_map_add_qstr(&map_builtins, MP_QSTR_staticmethod, (mp_obj_t)&mp_type_staticmethod); - mp_obj_t m_array = mp_obj_new_module(MP_QSTR_array); rt_store_attr(m_array, MP_QSTR_array, (mp_obj_t)&array_type); - // built-in user functions - mp_map_add_qstr(&map_builtins, MP_QSTR_abs, (mp_obj_t)&mp_builtin_abs_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_all, (mp_obj_t)&mp_builtin_all_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_any, (mp_obj_t)&mp_builtin_any_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_bytes, (mp_obj_t)&mp_builtin_bytes_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_callable, (mp_obj_t)&mp_builtin_callable_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_chr, (mp_obj_t)&mp_builtin_chr_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_dir, (mp_obj_t)&mp_builtin_dir_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_divmod, (mp_obj_t)&mp_builtin_divmod_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_eval, (mp_obj_t)&mp_builtin_eval_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_exec, (mp_obj_t)&mp_builtin_exec_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_hash, (mp_obj_t)&mp_builtin_hash_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_id, (mp_obj_t)&mp_builtin_id_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_isinstance, (mp_obj_t)&mp_builtin_isinstance_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_issubclass, (mp_obj_t)&mp_builtin_issubclass_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_iter, (mp_obj_t)&mp_builtin_iter_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_len, (mp_obj_t)&mp_builtin_len_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_max, (mp_obj_t)&mp_builtin_max_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_min, (mp_obj_t)&mp_builtin_min_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_next, (mp_obj_t)&mp_builtin_next_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_ord, (mp_obj_t)&mp_builtin_ord_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_pow, (mp_obj_t)&mp_builtin_pow_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_print, (mp_obj_t)&mp_builtin_print_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_range, (mp_obj_t)&mp_builtin_range_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_repr, (mp_obj_t)&mp_builtin_repr_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_sorted, (mp_obj_t)&mp_builtin_sorted_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_sum, (mp_obj_t)&mp_builtin_sum_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_str, (mp_obj_t)&mp_builtin_str_obj); - mp_map_add_qstr(&map_builtins, MP_QSTR_bytearray, (mp_obj_t)&mp_builtin_bytearray_obj); - #if MICROPY_CPYTHON_COMPAT // Precreate sys module, so "import sys" didn't throw exceptions. mp_obj_t m_sys = mp_obj_new_module(MP_QSTR_sys); @@ -432,16 +447,11 @@ mp_obj_t rt_load_name(qstr qstr) { // logic: search locals, globals, builtins DEBUG_OP_printf("load name %s\n", qstr_str(qstr)); mp_map_elem_t *elem = mp_map_lookup(map_locals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP); - if (elem == NULL) { - elem = mp_map_lookup(map_globals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP); - if (elem == NULL) { - elem = mp_map_lookup(&map_builtins, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP); - if (elem == NULL) { - nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_NameError, "name '%s' is not defined", qstr_str(qstr))); - } - } + if (elem != NULL) { + return elem->value; + } else { + return rt_load_global(qstr); } - return elem->value; } mp_obj_t rt_load_global(qstr qstr) { @@ -451,6 +461,11 @@ mp_obj_t rt_load_global(qstr qstr) { if (elem == NULL) { elem = mp_map_lookup(&map_builtins, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP); if (elem == NULL) { + for (const mp_builtin_elem_t *e = &builtin_table[0]; e->qstr != MP_QSTR_; e++) { + if (e->qstr == qstr) { + return e->fun; + } + } nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_NameError, "name '%s' is not defined", qstr_str(qstr))); } } @@ -460,10 +475,11 @@ mp_obj_t rt_load_global(qstr qstr) { mp_obj_t rt_load_build_class(void) { DEBUG_OP_printf("load_build_class\n"); mp_map_elem_t *elem = mp_map_lookup(&map_builtins, MP_OBJ_NEW_QSTR(MP_QSTR___build_class__), MP_MAP_LOOKUP); - if (elem == NULL) { - nlr_jump(mp_obj_new_exception_msg(MP_QSTR_NameError, "name '__build_class__' is not defined")); + if (elem != NULL) { + return elem->value; + } else { + return (mp_obj_t)&mp_builtin___build_class___obj; } - return elem->value; } mp_obj_t rt_get_cell(mp_obj_t cell) { |