From e37dcaafb43c1246ab55d79ebb8889a61f280533 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 27 Dec 2014 17:07:16 +0000 Subject: [PATCH] py: Allow to properly disable builtin "set" object. This patch makes MICROPY_PY_BUILTINS_SET compile-time option fully disable the builtin set object (when set to 0). This includes removing set constructor/comprehension from the grammar, the compiler and the emitters. Now, enabling set costs 8168 bytes on unix x64, and 3576 bytes on stmhal. --- py/compile.c | 14 ++++++++++++-- py/emit.h | 2 ++ py/emitbc.c | 4 ++++ py/emitnative.c | 4 ++++ py/emitpass1.c | 2 ++ py/grammar.h | 4 ++++ py/map.c | 4 ++++ py/modbuiltins.c | 2 +- py/vmentrytable.h | 2 ++ unix/qstrdefsport.h | 2 ++ 10 files changed, 37 insertions(+), 3 deletions(-) diff --git a/py/compile.c b/py/compile.c index 7cecf279b2..25bf64e3b9 100644 --- a/py/compile.c +++ b/py/compile.c @@ -2761,7 +2761,7 @@ STATIC void compile_atom_brace(compiler_t *comp, mp_parse_node_struct_t *pns) { // first element sets whether it's a dict or set bool is_dict; - if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) { + if (!MICROPY_PY_BUILTINS_SET || MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) { // a dictionary EMIT_ARG(build_map, 1 + n); compile_node(comp, pns->nodes[0]); @@ -2792,13 +2792,15 @@ STATIC void compile_atom_brace(compiler_t *comp, mp_parse_node_struct_t *pns) { } } + #if MICROPY_PY_BUILTINS_SET // if it's a set, build it if (!is_dict) { EMIT_ARG(build_set, 1 + n); } + #endif } else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for) { // dict/set comprehension - if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) { + if (!MICROPY_PY_BUILTINS_SET || MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_dictorsetmaker_item)) { // a dictionary comprehension compile_comprehension(comp, pns, SCOPE_DICT_COMP); } else { @@ -2816,8 +2818,12 @@ STATIC void compile_atom_brace(compiler_t *comp, mp_parse_node_struct_t *pns) { } else { // set with one element set_with_one_element: + #if MICROPY_PY_BUILTINS_SET compile_node(comp, pn); EMIT_ARG(build_set, 1); + #else + assert(0); + #endif } } @@ -3111,8 +3117,10 @@ STATIC void compile_scope_comp_iter(compiler_t *comp, mp_parse_node_t pn_iter, m EMIT_ARG(list_append, for_depth + 2); } else if (comp->scope_cur->kind == SCOPE_DICT_COMP) { EMIT_ARG(map_add, for_depth + 2); + #if MICROPY_PY_BUILTINS_SET } else if (comp->scope_cur->kind == SCOPE_SET_COMP) { EMIT_ARG(set_add, for_depth + 2); + #endif } else { EMIT(yield_value); EMIT(pop_top); @@ -3305,8 +3313,10 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { EMIT_ARG(build_list, 0); } else if (scope->kind == SCOPE_DICT_COMP) { EMIT_ARG(build_map, 0); + #if MICROPY_PY_BUILTINS_SET } else if (scope->kind == SCOPE_SET_COMP) { EMIT_ARG(build_set, 0); + #endif } uint l_end = comp_next_label(comp); diff --git a/py/emit.h b/py/emit.h index 8b9b368c2f..bc72b3cb3b 100644 --- a/py/emit.h +++ b/py/emit.h @@ -128,8 +128,10 @@ typedef struct _emit_method_table_t { void (*build_map)(emit_t *emit, mp_uint_t n_args); void (*store_map)(emit_t *emit); void (*map_add)(emit_t *emit, mp_uint_t map_stack_index); + #if MICROPY_PY_BUILTINS_SET void (*build_set)(emit_t *emit, mp_uint_t n_args); void (*set_add)(emit_t *emit, mp_uint_t set_stack_index); + #endif void (*build_slice)(emit_t *emit, mp_uint_t n_args); void (*unpack_sequence)(emit_t *emit, mp_uint_t n_args); void (*unpack_ex)(emit_t *emit, mp_uint_t n_left, mp_uint_t n_right); diff --git a/py/emitbc.c b/py/emitbc.c index 795c412830..723d5eda25 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -782,6 +782,7 @@ STATIC void emit_bc_map_add(emit_t *emit, mp_uint_t map_stack_index) { emit_write_bytecode_byte_uint(emit, MP_BC_MAP_ADD, map_stack_index); } +#if MICROPY_PY_BUILTINS_SET STATIC void emit_bc_build_set(emit_t *emit, mp_uint_t n_args) { emit_bc_pre(emit, 1 - n_args); emit_write_bytecode_byte_uint(emit, MP_BC_BUILD_SET, n_args); @@ -791,6 +792,7 @@ STATIC void emit_bc_set_add(emit_t *emit, mp_uint_t set_stack_index) { emit_bc_pre(emit, -1); emit_write_bytecode_byte_uint(emit, MP_BC_SET_ADD, set_stack_index); } +#endif STATIC void emit_bc_build_slice(emit_t *emit, mp_uint_t n_args) { emit_bc_pre(emit, 1 - n_args); @@ -960,8 +962,10 @@ const emit_method_table_t emit_bc_method_table = { emit_bc_build_map, emit_bc_store_map, emit_bc_map_add, + #if MICROPY_PY_BUILTINS_SET emit_bc_build_set, emit_bc_set_add, + #endif emit_bc_build_slice, emit_bc_unpack_sequence, emit_bc_unpack_ex, diff --git a/py/emitnative.c b/py/emitnative.c index 01e342d5a9..9f5733425c 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -2064,6 +2064,7 @@ STATIC void emit_native_map_add(emit_t *emit, mp_uint_t map_index) { emit_post(emit); } +#if MICROPY_PY_BUILTINS_SET STATIC void emit_native_build_set(emit_t *emit, mp_uint_t n_args) { emit_native_pre(emit); emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_2, n_args); // pointer to items @@ -2081,6 +2082,7 @@ STATIC void emit_native_set_add(emit_t *emit, mp_uint_t set_index) { emit_call(emit, MP_F_STORE_SET); emit_post(emit); } +#endif STATIC void emit_native_build_slice(emit_t *emit, mp_uint_t n_args) { DEBUG_printf("build_slice %d\n", n_args); @@ -2330,8 +2332,10 @@ const emit_method_table_t EXPORT_FUN(method_table) = { emit_native_build_map, emit_native_store_map, emit_native_map_add, + #if MICROPY_PY_BUILTINS_SET emit_native_build_set, emit_native_set_add, + #endif emit_native_build_slice, emit_native_unpack_sequence, emit_native_unpack_ex, diff --git a/py/emitpass1.c b/py/emitpass1.c index 601feb7fdf..fea3e7ff07 100644 --- a/py/emitpass1.c +++ b/py/emitpass1.c @@ -201,8 +201,10 @@ const emit_method_table_t emit_pass1_method_table = { (void*)emit_pass1_dummy, (void*)emit_pass1_dummy, (void*)emit_pass1_dummy, + #if MICROPY_PY_BUILTINS_SET (void*)emit_pass1_dummy, (void*)emit_pass1_dummy, + #endif (void*)emit_pass1_dummy, (void*)emit_pass1_dummy, (void*)emit_pass1_dummy, diff --git a/py/grammar.h b/py/grammar.h index 15c4e98109..1df0e938ec 100644 --- a/py/grammar.h +++ b/py/grammar.h @@ -287,8 +287,12 @@ DEF_RULE(exprlist_2, nc, or(2), rule(star_expr), rule(expr)) DEF_RULE(testlist, c(generic_tuple), list_with_end, rule(test), tok(DEL_COMMA)) // TODO dictorsetmaker lets through more than is allowed DEF_RULE(dictorsetmaker, nc, and(2), rule(dictorsetmaker_item), opt_rule(dictorsetmaker_tail)) +#if MICROPY_PY_BUILTINS_SET DEF_RULE(dictorsetmaker_item, c(dictorsetmaker_item), and(2), rule(test), opt_rule(dictorsetmaker_colon)) DEF_RULE(dictorsetmaker_colon, nc, ident | and(2), tok(DEL_COLON), rule(test)) +#else +DEF_RULE(dictorsetmaker_item, c(dictorsetmaker_item), and(3), rule(test), tok(DEL_COLON), rule(test)) +#endif DEF_RULE(dictorsetmaker_tail, nc, or(2), rule(comp_for), rule(dictorsetmaker_list)) DEF_RULE(dictorsetmaker_list, nc, and(2), tok(DEL_COMMA), opt_rule(dictorsetmaker_list2)) DEF_RULE(dictorsetmaker_list2, nc, list_with_end, rule(dictorsetmaker_item), tok(DEL_COMMA)) diff --git a/py/map.c b/py/map.c index a06325862e..22580de821 100644 --- a/py/map.c +++ b/py/map.c @@ -253,6 +253,8 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t /******************************************************************************/ /* set */ +#if MICROPY_PY_BUILTINS_SET + void mp_set_init(mp_set_t *set, mp_uint_t n) { set->alloc = n; set->used = 0; @@ -368,6 +370,8 @@ void mp_set_clear(mp_set_t *set) { set->table = NULL; } +#endif // MICROPY_PY_BUILTINS_SET + #if defined(DEBUG_PRINT) && DEBUG_PRINT void mp_map_dump(mp_map_t *map) { for (mp_uint_t i = 0; i < map->alloc; i++) { diff --git a/py/modbuiltins.c b/py/modbuiltins.c index c0b3b8a86b..7ac22fc49f 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -583,7 +583,7 @@ STATIC const mp_map_elem_t mp_module_builtins_globals_table[] = { #if MICROPY_PY_BUILTINS_FLOAT { MP_OBJ_NEW_QSTR(MP_QSTR_float), (mp_obj_t)&mp_type_float }, #endif -#if MICROPY_PY_BUILTINS_FROZENSET +#if MICROPY_PY_BUILTINS_SET && MICROPY_PY_BUILTINS_FROZENSET { MP_OBJ_NEW_QSTR(MP_QSTR_frozenset), (mp_obj_t)&mp_type_frozenset }, #endif { MP_OBJ_NEW_QSTR(MP_QSTR_int), (mp_obj_t)&mp_type_int }, diff --git a/py/vmentrytable.h b/py/vmentrytable.h index 29cfdce4e2..71d6f5b172 100644 --- a/py/vmentrytable.h +++ b/py/vmentrytable.h @@ -86,8 +86,10 @@ static void* entry_table[256] = { [MP_BC_BUILD_MAP] = &&entry_MP_BC_BUILD_MAP, [MP_BC_STORE_MAP] = &&entry_MP_BC_STORE_MAP, [MP_BC_MAP_ADD] = &&entry_MP_BC_MAP_ADD, + #if MICROPY_PY_BUILTINS_SET [MP_BC_BUILD_SET] = &&entry_MP_BC_BUILD_SET, [MP_BC_SET_ADD] = &&entry_MP_BC_SET_ADD, + #endif [MP_BC_BUILD_SLICE] = &&entry_MP_BC_BUILD_SLICE, [MP_BC_UNPACK_SEQUENCE] = &&entry_MP_BC_UNPACK_SEQUENCE, [MP_BC_UNPACK_EX] = &&entry_MP_BC_UNPACK_EX, diff --git a/unix/qstrdefsport.h b/unix/qstrdefsport.h index 7fd4e24f42..873d7d17ae 100644 --- a/unix/qstrdefsport.h +++ b/unix/qstrdefsport.h @@ -48,6 +48,8 @@ Q(as_bytearray) Q(callback) Q(func) Q(var) +Q(get) +Q(set) Q(input) Q(utime)