py/emit: Combine load/store/delete attr into one emit function.

Reduces code size by:

   bare-arm:   -20
minimal x86:  -140
   unix x64:  -408
unix nanbox:  -140
      stm32:   -68
     cc3200:   -16
    esp8266:   -80
      esp32:   -32
This commit is contained in:
Damien George 2018-05-22 21:43:41 +10:00
parent a4941a8ba4
commit 6211d979ee
4 changed files with 43 additions and 41 deletions

View File

@ -381,12 +381,12 @@ STATIC void c_assign_atom_expr(compiler_t *comp, mp_parse_node_struct_t *pns, as
assert(MP_PARSE_NODE_IS_ID(pns1->nodes[0])); assert(MP_PARSE_NODE_IS_ID(pns1->nodes[0]));
if (assign_kind == ASSIGN_AUG_LOAD) { if (assign_kind == ASSIGN_AUG_LOAD) {
EMIT(dup_top); EMIT(dup_top);
EMIT_ARG(load_attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0])); EMIT_ARG(attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0]), MP_EMIT_ATTR_LOAD);
} else { } else {
if (assign_kind == ASSIGN_AUG_STORE) { if (assign_kind == ASSIGN_AUG_STORE) {
EMIT(rot_two); EMIT(rot_two);
} }
EMIT_ARG(store_attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0])); EMIT_ARG(attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0]), MP_EMIT_ATTR_STORE);
} }
return; return;
} }
@ -820,7 +820,7 @@ STATIC void compile_decorated(compiler_t *comp, mp_parse_node_struct_t *pns) {
compile_node(comp, name_nodes[0]); compile_node(comp, name_nodes[0]);
for (int j = 1; j < name_len; j++) { for (int j = 1; j < name_len; j++) {
assert(MP_PARSE_NODE_IS_ID(name_nodes[j])); // should be assert(MP_PARSE_NODE_IS_ID(name_nodes[j])); // should be
EMIT_ARG(load_attr, MP_PARSE_NODE_LEAF_ARG(name_nodes[j])); EMIT_ARG(attr, MP_PARSE_NODE_LEAF_ARG(name_nodes[j]), MP_EMIT_ATTR_LOAD);
} }
// nodes[1] contains arguments to the decorator function, if any // nodes[1] contains arguments to the decorator function, if any
@ -887,7 +887,7 @@ STATIC void c_del_stmt(compiler_t *comp, mp_parse_node_t pn) {
EMIT_ARG(subscr, MP_EMIT_SUBSCR_DELETE); EMIT_ARG(subscr, MP_EMIT_SUBSCR_DELETE);
} else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) { } else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_trailer_period) {
assert(MP_PARSE_NODE_IS_ID(pns1->nodes[0])); assert(MP_PARSE_NODE_IS_ID(pns1->nodes[0]));
EMIT_ARG(delete_attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0])); EMIT_ARG(attr, MP_PARSE_NODE_LEAF_ARG(pns1->nodes[0]), MP_EMIT_ATTR_DELETE);
} else { } else {
goto cannot_delete; goto cannot_delete;
} }
@ -1061,7 +1061,7 @@ STATIC void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q_base) {
EMIT_ARG(import_name, q_full); EMIT_ARG(import_name, q_full);
if (is_as) { if (is_as) {
for (int i = 1; i < n; i++) { for (int i = 1; i < n; i++) {
EMIT_ARG(load_attr, MP_PARSE_NODE_LEAF_ARG(pns->nodes[i])); EMIT_ARG(attr, MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]), MP_EMIT_ATTR_LOAD);
} }
} }
} }
@ -1811,7 +1811,7 @@ STATIC void compile_async_with_stmt_helper(compiler_t *comp, int n, mp_parse_nod
// at this point the stack contains: ..., __aexit__, self, exc // at this point the stack contains: ..., __aexit__, self, exc
EMIT(dup_top); EMIT(dup_top);
#if MICROPY_CPYTHON_COMPAT #if MICROPY_CPYTHON_COMPAT
EMIT_ARG(load_attr, MP_QSTR___class__); // get type(exc) EMIT_ARG(attr, MP_QSTR___class__, MP_EMIT_ATTR_LOAD); // get type(exc)
#else #else
compile_load_id(comp, MP_QSTR_type); compile_load_id(comp, MP_QSTR_type);
EMIT(rot_two); EMIT(rot_two);
@ -2541,7 +2541,7 @@ STATIC void compile_trailer_bracket(compiler_t *comp, mp_parse_node_struct_t *pn
STATIC void compile_trailer_period(compiler_t *comp, mp_parse_node_struct_t *pns) { STATIC void compile_trailer_period(compiler_t *comp, mp_parse_node_struct_t *pns) {
// object who's attribute we want is on top of stack // object who's attribute we want is on top of stack
EMIT_ARG(load_attr, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0])); // attribute to get EMIT_ARG(attr, MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]), MP_EMIT_ATTR_LOAD); // attribute to get
} }
#if MICROPY_PY_BUILTINS_SLICE #if MICROPY_PY_BUILTINS_SLICE

View File

@ -68,6 +68,11 @@ typedef enum {
#define MP_EMIT_SUBSCR_STORE (1) #define MP_EMIT_SUBSCR_STORE (1)
#define MP_EMIT_SUBSCR_DELETE (2) #define MP_EMIT_SUBSCR_DELETE (2)
// Kind for emit->attr()
#define MP_EMIT_ATTR_LOAD (0)
#define MP_EMIT_ATTR_STORE (1)
#define MP_EMIT_ATTR_DELETE (2)
// Kind for emit->build() // Kind for emit->build()
#define MP_EMIT_BUILD_TUPLE (0) #define MP_EMIT_BUILD_TUPLE (0)
#define MP_EMIT_BUILD_LIST (1) #define MP_EMIT_BUILD_LIST (1)
@ -105,12 +110,10 @@ typedef struct _emit_method_table_t {
void (*load_const_str)(emit_t *emit, qstr qst); void (*load_const_str)(emit_t *emit, qstr qst);
void (*load_const_obj)(emit_t *emit, mp_obj_t obj); void (*load_const_obj)(emit_t *emit, mp_obj_t obj);
void (*load_null)(emit_t *emit); void (*load_null)(emit_t *emit);
void (*load_attr)(emit_t *emit, qstr qst);
void (*load_method)(emit_t *emit, qstr qst, bool is_super); void (*load_method)(emit_t *emit, qstr qst, bool is_super);
void (*load_build_class)(emit_t *emit); void (*load_build_class)(emit_t *emit);
void (*subscr)(emit_t *emit, int kind); void (*subscr)(emit_t *emit, int kind);
void (*store_attr)(emit_t *emit, qstr qst); void (*attr)(emit_t *emit, qstr qst, int kind);
void (*delete_attr)(emit_t *emit, qstr qst);
void (*dup_top)(emit_t *emit); void (*dup_top)(emit_t *emit);
void (*dup_top_two)(emit_t *emit); void (*dup_top_two)(emit_t *emit);
void (*pop_top)(emit_t *emit); void (*pop_top)(emit_t *emit);
@ -211,12 +214,10 @@ void mp_emit_bc_load_const_small_int(emit_t *emit, mp_int_t arg);
void mp_emit_bc_load_const_str(emit_t *emit, qstr qst); void mp_emit_bc_load_const_str(emit_t *emit, qstr qst);
void mp_emit_bc_load_const_obj(emit_t *emit, mp_obj_t obj); void mp_emit_bc_load_const_obj(emit_t *emit, mp_obj_t obj);
void mp_emit_bc_load_null(emit_t *emit); void mp_emit_bc_load_null(emit_t *emit);
void mp_emit_bc_load_attr(emit_t *emit, qstr qst);
void mp_emit_bc_load_method(emit_t *emit, qstr qst, bool is_super); void mp_emit_bc_load_method(emit_t *emit, qstr qst, bool is_super);
void mp_emit_bc_load_build_class(emit_t *emit); void mp_emit_bc_load_build_class(emit_t *emit);
void mp_emit_bc_subscr(emit_t *emit, int kind); void mp_emit_bc_subscr(emit_t *emit, int kind);
void mp_emit_bc_store_attr(emit_t *emit, qstr qst); void mp_emit_bc_attr(emit_t *emit, qstr qst, int kind);
void mp_emit_bc_delete_attr(emit_t *emit, qstr qst);
void mp_emit_bc_dup_top(emit_t *emit); void mp_emit_bc_dup_top(emit_t *emit);
void mp_emit_bc_dup_top_two(emit_t *emit); void mp_emit_bc_dup_top_two(emit_t *emit);
void mp_emit_bc_pop_top(emit_t *emit); void mp_emit_bc_pop_top(emit_t *emit);

View File

@ -579,14 +579,6 @@ void mp_emit_bc_load_global(emit_t *emit, qstr qst, int kind) {
} }
} }
void mp_emit_bc_load_attr(emit_t *emit, qstr qst) {
emit_bc_pre(emit, 0);
emit_write_bytecode_byte_qstr(emit, MP_BC_LOAD_ATTR, qst);
if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE_DYNAMIC) {
emit_write_bytecode_byte(emit, 0);
}
}
void mp_emit_bc_load_method(emit_t *emit, qstr qst, bool is_super) { void mp_emit_bc_load_method(emit_t *emit, qstr qst, bool is_super) {
emit_bc_pre(emit, 1 - 2 * is_super); emit_bc_pre(emit, 1 - 2 * is_super);
emit_write_bytecode_byte_qstr(emit, is_super ? MP_BC_LOAD_SUPER_METHOD : MP_BC_LOAD_METHOD, qst); emit_write_bytecode_byte_qstr(emit, is_super ? MP_BC_LOAD_SUPER_METHOD : MP_BC_LOAD_METHOD, qst);
@ -611,6 +603,23 @@ void mp_emit_bc_subscr(emit_t *emit, int kind) {
} }
} }
void mp_emit_bc_attr(emit_t *emit, qstr qst, int kind) {
if (kind == MP_EMIT_ATTR_LOAD) {
emit_bc_pre(emit, 0);
emit_write_bytecode_byte_qstr(emit, MP_BC_LOAD_ATTR, qst);
} else {
if (kind == MP_EMIT_ATTR_DELETE) {
mp_emit_bc_load_null(emit);
mp_emit_bc_rot_two(emit);
}
emit_bc_pre(emit, -2);
emit_write_bytecode_byte_qstr(emit, MP_BC_STORE_ATTR, qst);
}
if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE_DYNAMIC) {
emit_write_bytecode_byte(emit, 0);
}
}
void mp_emit_bc_store_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind) { void mp_emit_bc_store_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind) {
MP_STATIC_ASSERT(MP_BC_STORE_FAST_N + MP_EMIT_IDOP_LOCAL_FAST == MP_BC_STORE_FAST_N); MP_STATIC_ASSERT(MP_BC_STORE_FAST_N + MP_EMIT_IDOP_LOCAL_FAST == MP_BC_STORE_FAST_N);
MP_STATIC_ASSERT(MP_BC_STORE_FAST_N + MP_EMIT_IDOP_LOCAL_DEREF == MP_BC_STORE_DEREF); MP_STATIC_ASSERT(MP_BC_STORE_FAST_N + MP_EMIT_IDOP_LOCAL_DEREF == MP_BC_STORE_DEREF);
@ -630,14 +639,6 @@ void mp_emit_bc_store_global(emit_t *emit, qstr qst, int kind) {
emit_write_bytecode_byte_qstr(emit, MP_BC_STORE_NAME + kind, qst); emit_write_bytecode_byte_qstr(emit, MP_BC_STORE_NAME + kind, qst);
} }
void mp_emit_bc_store_attr(emit_t *emit, qstr qst) {
emit_bc_pre(emit, -2);
emit_write_bytecode_byte_qstr(emit, MP_BC_STORE_ATTR, qst);
if (MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE_DYNAMIC) {
emit_write_bytecode_byte(emit, 0);
}
}
void mp_emit_bc_delete_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind) { void mp_emit_bc_delete_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind) {
MP_STATIC_ASSERT(MP_BC_DELETE_FAST + MP_EMIT_IDOP_LOCAL_FAST == MP_BC_DELETE_FAST); MP_STATIC_ASSERT(MP_BC_DELETE_FAST + MP_EMIT_IDOP_LOCAL_FAST == MP_BC_DELETE_FAST);
MP_STATIC_ASSERT(MP_BC_DELETE_FAST + MP_EMIT_IDOP_LOCAL_DEREF == MP_BC_DELETE_DEREF); MP_STATIC_ASSERT(MP_BC_DELETE_FAST + MP_EMIT_IDOP_LOCAL_DEREF == MP_BC_DELETE_DEREF);
@ -652,12 +653,6 @@ void mp_emit_bc_delete_global(emit_t *emit, qstr qst, int kind) {
emit_write_bytecode_byte_qstr(emit, MP_BC_DELETE_NAME + kind, qst); emit_write_bytecode_byte_qstr(emit, MP_BC_DELETE_NAME + kind, qst);
} }
void mp_emit_bc_delete_attr(emit_t *emit, qstr qst) {
mp_emit_bc_load_null(emit);
mp_emit_bc_rot_two(emit);
mp_emit_bc_store_attr(emit, qst);
}
void mp_emit_bc_dup_top(emit_t *emit) { void mp_emit_bc_dup_top(emit_t *emit) {
emit_bc_pre(emit, 1); emit_bc_pre(emit, 1);
emit_write_bytecode_byte(emit, MP_BC_DUP_TOP); emit_write_bytecode_byte(emit, MP_BC_DUP_TOP);
@ -959,12 +954,10 @@ const emit_method_table_t emit_bc_method_table = {
mp_emit_bc_load_const_str, mp_emit_bc_load_const_str,
mp_emit_bc_load_const_obj, mp_emit_bc_load_const_obj,
mp_emit_bc_load_null, mp_emit_bc_load_null,
mp_emit_bc_load_attr,
mp_emit_bc_load_method, mp_emit_bc_load_method,
mp_emit_bc_load_build_class, mp_emit_bc_load_build_class,
mp_emit_bc_subscr, mp_emit_bc_subscr,
mp_emit_bc_store_attr, mp_emit_bc_attr,
mp_emit_bc_delete_attr,
mp_emit_bc_dup_top, mp_emit_bc_dup_top,
mp_emit_bc_dup_top_two, mp_emit_bc_dup_top_two,
mp_emit_bc_pop_top, mp_emit_bc_pop_top,

View File

@ -1457,6 +1457,16 @@ STATIC void emit_native_subscr(emit_t *emit, int kind) {
} }
} }
STATIC void emit_native_attr(emit_t *emit, qstr qst, int kind) {
if (kind == MP_EMIT_ATTR_LOAD) {
emit_native_load_attr(emit, qst);
} else if (kind == MP_EMIT_ATTR_STORE) {
emit_native_store_attr(emit, qst);
} else {
emit_native_delete_attr(emit, qst);
}
}
STATIC void emit_native_dup_top(emit_t *emit) { STATIC void emit_native_dup_top(emit_t *emit) {
DEBUG_printf("dup_top\n"); DEBUG_printf("dup_top\n");
vtype_kind_t vtype; vtype_kind_t vtype;
@ -2226,12 +2236,10 @@ const emit_method_table_t EXPORT_FUN(method_table) = {
emit_native_load_const_str, emit_native_load_const_str,
emit_native_load_const_obj, emit_native_load_const_obj,
emit_native_load_null, emit_native_load_null,
emit_native_load_attr,
emit_native_load_method, emit_native_load_method,
emit_native_load_build_class, emit_native_load_build_class,
emit_native_subscr, emit_native_subscr,
emit_native_store_attr, emit_native_attr,
emit_native_delete_attr,
emit_native_dup_top, emit_native_dup_top,
emit_native_dup_top_two, emit_native_dup_top_two,
emit_native_pop_top, emit_native_pop_top,