Browse Source

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.
pull/1018/merge
Damien George 10 years ago
parent
commit
e37dcaafb4
  1. 14
      py/compile.c
  2. 2
      py/emit.h
  3. 4
      py/emitbc.c
  4. 4
      py/emitnative.c
  5. 2
      py/emitpass1.c
  6. 4
      py/grammar.h
  7. 4
      py/map.c
  8. 2
      py/modbuiltins.c
  9. 2
      py/vmentrytable.h
  10. 2
      unix/qstrdefsport.h

14
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 // first element sets whether it's a dict or set
bool is_dict; 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 // a dictionary
EMIT_ARG(build_map, 1 + n); EMIT_ARG(build_map, 1 + n);
compile_node(comp, pns->nodes[0]); 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 it's a set, build it
if (!is_dict) { if (!is_dict) {
EMIT_ARG(build_set, 1 + n); EMIT_ARG(build_set, 1 + n);
} }
#endif
} else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for) { } else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for) {
// dict/set comprehension // 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 // a dictionary comprehension
compile_comprehension(comp, pns, SCOPE_DICT_COMP); compile_comprehension(comp, pns, SCOPE_DICT_COMP);
} else { } else {
@ -2816,8 +2818,12 @@ STATIC void compile_atom_brace(compiler_t *comp, mp_parse_node_struct_t *pns) {
} else { } else {
// set with one element // set with one element
set_with_one_element: set_with_one_element:
#if MICROPY_PY_BUILTINS_SET
compile_node(comp, pn); compile_node(comp, pn);
EMIT_ARG(build_set, 1); 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); EMIT_ARG(list_append, for_depth + 2);
} else if (comp->scope_cur->kind == SCOPE_DICT_COMP) { } else if (comp->scope_cur->kind == SCOPE_DICT_COMP) {
EMIT_ARG(map_add, for_depth + 2); EMIT_ARG(map_add, for_depth + 2);
#if MICROPY_PY_BUILTINS_SET
} else if (comp->scope_cur->kind == SCOPE_SET_COMP) { } else if (comp->scope_cur->kind == SCOPE_SET_COMP) {
EMIT_ARG(set_add, for_depth + 2); EMIT_ARG(set_add, for_depth + 2);
#endif
} else { } else {
EMIT(yield_value); EMIT(yield_value);
EMIT(pop_top); 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); EMIT_ARG(build_list, 0);
} else if (scope->kind == SCOPE_DICT_COMP) { } else if (scope->kind == SCOPE_DICT_COMP) {
EMIT_ARG(build_map, 0); EMIT_ARG(build_map, 0);
#if MICROPY_PY_BUILTINS_SET
} else if (scope->kind == SCOPE_SET_COMP) { } else if (scope->kind == SCOPE_SET_COMP) {
EMIT_ARG(build_set, 0); EMIT_ARG(build_set, 0);
#endif
} }
uint l_end = comp_next_label(comp); uint l_end = comp_next_label(comp);

2
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 (*build_map)(emit_t *emit, mp_uint_t n_args);
void (*store_map)(emit_t *emit); void (*store_map)(emit_t *emit);
void (*map_add)(emit_t *emit, mp_uint_t map_stack_index); 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 (*build_set)(emit_t *emit, mp_uint_t n_args);
void (*set_add)(emit_t *emit, mp_uint_t set_stack_index); 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 (*build_slice)(emit_t *emit, mp_uint_t n_args);
void (*unpack_sequence)(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); void (*unpack_ex)(emit_t *emit, mp_uint_t n_left, mp_uint_t n_right);

4
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); 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) { STATIC void emit_bc_build_set(emit_t *emit, mp_uint_t n_args) {
emit_bc_pre(emit, 1 - n_args); emit_bc_pre(emit, 1 - n_args);
emit_write_bytecode_byte_uint(emit, MP_BC_BUILD_SET, 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_bc_pre(emit, -1);
emit_write_bytecode_byte_uint(emit, MP_BC_SET_ADD, set_stack_index); 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) { STATIC void emit_bc_build_slice(emit_t *emit, mp_uint_t n_args) {
emit_bc_pre(emit, 1 - 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_build_map,
emit_bc_store_map, emit_bc_store_map,
emit_bc_map_add, emit_bc_map_add,
#if MICROPY_PY_BUILTINS_SET
emit_bc_build_set, emit_bc_build_set,
emit_bc_set_add, emit_bc_set_add,
#endif
emit_bc_build_slice, emit_bc_build_slice,
emit_bc_unpack_sequence, emit_bc_unpack_sequence,
emit_bc_unpack_ex, emit_bc_unpack_ex,

4
py/emitnative.c

@ -2064,6 +2064,7 @@ STATIC void emit_native_map_add(emit_t *emit, mp_uint_t map_index) {
emit_post(emit); emit_post(emit);
} }
#if MICROPY_PY_BUILTINS_SET
STATIC void emit_native_build_set(emit_t *emit, mp_uint_t n_args) { STATIC void emit_native_build_set(emit_t *emit, mp_uint_t n_args) {
emit_native_pre(emit); emit_native_pre(emit);
emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_2, n_args); // pointer to items 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_call(emit, MP_F_STORE_SET);
emit_post(emit); emit_post(emit);
} }
#endif
STATIC void emit_native_build_slice(emit_t *emit, mp_uint_t n_args) { STATIC void emit_native_build_slice(emit_t *emit, mp_uint_t n_args) {
DEBUG_printf("build_slice %d\n", 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_build_map,
emit_native_store_map, emit_native_store_map,
emit_native_map_add, emit_native_map_add,
#if MICROPY_PY_BUILTINS_SET
emit_native_build_set, emit_native_build_set,
emit_native_set_add, emit_native_set_add,
#endif
emit_native_build_slice, emit_native_build_slice,
emit_native_unpack_sequence, emit_native_unpack_sequence,
emit_native_unpack_ex, emit_native_unpack_ex,

2
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, (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,
(void*)emit_pass1_dummy, (void*)emit_pass1_dummy,
#endif
(void*)emit_pass1_dummy, (void*)emit_pass1_dummy,
(void*)emit_pass1_dummy, (void*)emit_pass1_dummy,
(void*)emit_pass1_dummy, (void*)emit_pass1_dummy,

4
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)) DEF_RULE(testlist, c(generic_tuple), list_with_end, rule(test), tok(DEL_COMMA))
// TODO dictorsetmaker lets through more than is allowed // TODO dictorsetmaker lets through more than is allowed
DEF_RULE(dictorsetmaker, nc, and(2), rule(dictorsetmaker_item), opt_rule(dictorsetmaker_tail)) 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_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)) 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_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_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)) DEF_RULE(dictorsetmaker_list2, nc, list_with_end, rule(dictorsetmaker_item), tok(DEL_COMMA))

4
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 */ /* set */
#if MICROPY_PY_BUILTINS_SET
void mp_set_init(mp_set_t *set, mp_uint_t n) { void mp_set_init(mp_set_t *set, mp_uint_t n) {
set->alloc = n; set->alloc = n;
set->used = 0; set->used = 0;
@ -368,6 +370,8 @@ void mp_set_clear(mp_set_t *set) {
set->table = NULL; set->table = NULL;
} }
#endif // MICROPY_PY_BUILTINS_SET
#if defined(DEBUG_PRINT) && DEBUG_PRINT #if defined(DEBUG_PRINT) && DEBUG_PRINT
void mp_map_dump(mp_map_t *map) { void mp_map_dump(mp_map_t *map) {
for (mp_uint_t i = 0; i < map->alloc; i++) { for (mp_uint_t i = 0; i < map->alloc; i++) {

2
py/modbuiltins.c

@ -583,7 +583,7 @@ STATIC const mp_map_elem_t mp_module_builtins_globals_table[] = {
#if MICROPY_PY_BUILTINS_FLOAT #if MICROPY_PY_BUILTINS_FLOAT
{ MP_OBJ_NEW_QSTR(MP_QSTR_float), (mp_obj_t)&mp_type_float }, { MP_OBJ_NEW_QSTR(MP_QSTR_float), (mp_obj_t)&mp_type_float },
#endif #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 }, { MP_OBJ_NEW_QSTR(MP_QSTR_frozenset), (mp_obj_t)&mp_type_frozenset },
#endif #endif
{ MP_OBJ_NEW_QSTR(MP_QSTR_int), (mp_obj_t)&mp_type_int }, { MP_OBJ_NEW_QSTR(MP_QSTR_int), (mp_obj_t)&mp_type_int },

2
py/vmentrytable.h

@ -86,8 +86,10 @@ static void* entry_table[256] = {
[MP_BC_BUILD_MAP] = &&entry_MP_BC_BUILD_MAP, [MP_BC_BUILD_MAP] = &&entry_MP_BC_BUILD_MAP,
[MP_BC_STORE_MAP] = &&entry_MP_BC_STORE_MAP, [MP_BC_STORE_MAP] = &&entry_MP_BC_STORE_MAP,
[MP_BC_MAP_ADD] = &&entry_MP_BC_MAP_ADD, [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_BUILD_SET] = &&entry_MP_BC_BUILD_SET,
[MP_BC_SET_ADD] = &&entry_MP_BC_SET_ADD, [MP_BC_SET_ADD] = &&entry_MP_BC_SET_ADD,
#endif
[MP_BC_BUILD_SLICE] = &&entry_MP_BC_BUILD_SLICE, [MP_BC_BUILD_SLICE] = &&entry_MP_BC_BUILD_SLICE,
[MP_BC_UNPACK_SEQUENCE] = &&entry_MP_BC_UNPACK_SEQUENCE, [MP_BC_UNPACK_SEQUENCE] = &&entry_MP_BC_UNPACK_SEQUENCE,
[MP_BC_UNPACK_EX] = &&entry_MP_BC_UNPACK_EX, [MP_BC_UNPACK_EX] = &&entry_MP_BC_UNPACK_EX,

2
unix/qstrdefsport.h

@ -48,6 +48,8 @@ Q(as_bytearray)
Q(callback) Q(callback)
Q(func) Q(func)
Q(var) Q(var)
Q(get)
Q(set)
Q(input) Q(input)
Q(utime) Q(utime)

Loading…
Cancel
Save