py/emit: Combine setup with/except/finally into one emit function.

This patch reduces code size by:

   bare-arm:   -16
minimal x86:  -156
   unix x64:  -288
unix nanbox:  -184
      stm32:   -48
     cc3200:   -16
    esp8266:   -96
      esp32:   -16

The last 10 patches combined reduce code size by:

   bare-arm:  -164
minimal x86: -1260
   unix x64: -3416
unix nanbox: -1616
      stm32:  -676
     cc3200:  -232
    esp8266: -1144
      esp32:  -268
This commit is contained in:
Damien George 2018-05-22 22:33:26 +10:00
parent 436e0d4c54
commit 18e6358480
4 changed files with 42 additions and 47 deletions

View File

@ -1516,7 +1516,7 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_
uint l1 = comp_next_label(comp);
uint success_label = comp_next_label(comp);
EMIT_ARG(setup_except, l1);
EMIT_ARG(setup_block, l1, MP_EMIT_SETUP_BLOCK_EXCEPT);
compile_increase_except_level(comp);
compile_node(comp, pn_body); // body
@ -1571,7 +1571,7 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_
uint l3 = 0;
if (qstr_exception_local != 0) {
l3 = comp_next_label(comp);
EMIT_ARG(setup_finally, l3);
EMIT_ARG(setup_block, l3, MP_EMIT_SETUP_BLOCK_FINALLY);
compile_increase_except_level(comp);
}
compile_node(comp, pns_except->nodes[1]);
@ -1606,7 +1606,7 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_
STATIC void compile_try_finally(compiler_t *comp, mp_parse_node_t pn_body, int n_except, mp_parse_node_t *pn_except, mp_parse_node_t pn_else, mp_parse_node_t pn_finally) {
uint l_finally_block = comp_next_label(comp);
EMIT_ARG(setup_finally, l_finally_block);
EMIT_ARG(setup_block, l_finally_block, MP_EMIT_SETUP_BLOCK_FINALLY);
compile_increase_except_level(comp);
if (n_except == 0) {
@ -1668,12 +1668,12 @@ STATIC void compile_with_stmt_helper(compiler_t *comp, int n, mp_parse_node_t *n
// this pre-bit is of the form "a as b"
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)nodes[0];
compile_node(comp, pns->nodes[0]);
EMIT_ARG(setup_with, l_end);
EMIT_ARG(setup_block, l_end, MP_EMIT_SETUP_BLOCK_WITH);
c_assign(comp, pns->nodes[1], ASSIGN_STORE);
} else {
// this pre-bit is just an expression
compile_node(comp, nodes[0]);
EMIT_ARG(setup_with, l_end);
EMIT_ARG(setup_block, l_end, MP_EMIT_SETUP_BLOCK_WITH);
EMIT(pop_top);
}
compile_increase_except_level(comp);
@ -1726,7 +1726,7 @@ STATIC void compile_async_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns
EMIT_ARG(label_assign, continue_label);
EMIT_ARG(setup_except, try_exception_label);
EMIT_ARG(setup_block, try_exception_label, MP_EMIT_SETUP_BLOCK_EXCEPT);
compile_increase_except_level(comp);
compile_load_id(comp, context);
@ -1797,7 +1797,7 @@ STATIC void compile_async_with_stmt_helper(compiler_t *comp, int n, mp_parse_nod
compile_load_id(comp, context);
EMIT_ARG(load_method, MP_QSTR___aexit__, false);
EMIT_ARG(setup_except, try_exception_label);
EMIT_ARG(setup_block, try_exception_label, MP_EMIT_SETUP_BLOCK_EXCEPT);
compile_increase_except_level(comp);
// compile additional pre-bits and the body
compile_async_with_stmt_helper(comp, n - 1, nodes + 1, body);

View File

@ -78,6 +78,11 @@ typedef enum {
#define MP_EMIT_ATTR_STORE (1)
#define MP_EMIT_ATTR_DELETE (2)
// Kind for emit->setup_block()
#define MP_EMIT_SETUP_BLOCK_WITH (0)
#define MP_EMIT_SETUP_BLOCK_EXCEPT (2)
#define MP_EMIT_SETUP_BLOCK_FINALLY (3)
// Kind for emit->build()
#define MP_EMIT_BUILD_TUPLE (0)
#define MP_EMIT_BUILD_LIST (1)
@ -128,10 +133,8 @@ typedef struct _emit_method_table_t {
void (*pop_jump_if)(emit_t *emit, bool cond, mp_uint_t label);
void (*jump_if_or_pop)(emit_t *emit, bool cond, mp_uint_t label);
void (*unwind_jump)(emit_t *emit, mp_uint_t label, mp_uint_t except_depth);
void (*setup_with)(emit_t *emit, mp_uint_t label);
void (*setup_block)(emit_t *emit, mp_uint_t label, int kind);
void (*with_cleanup)(emit_t *emit, mp_uint_t label);
void (*setup_except)(emit_t *emit, mp_uint_t label);
void (*setup_finally)(emit_t *emit, mp_uint_t label);
void (*end_finally)(emit_t *emit);
void (*get_iter)(emit_t *emit, bool use_stack);
void (*for_iter)(emit_t *emit, mp_uint_t label);
@ -223,10 +226,8 @@ void mp_emit_bc_jump(emit_t *emit, mp_uint_t label);
void mp_emit_bc_pop_jump_if(emit_t *emit, bool cond, mp_uint_t label);
void mp_emit_bc_jump_if_or_pop(emit_t *emit, bool cond, mp_uint_t label);
void mp_emit_bc_unwind_jump(emit_t *emit, mp_uint_t label, mp_uint_t except_depth);
void mp_emit_bc_setup_with(emit_t *emit, mp_uint_t label);
void mp_emit_bc_setup_block(emit_t *emit, mp_uint_t label, int kind);
void mp_emit_bc_with_cleanup(emit_t *emit, mp_uint_t label);
void mp_emit_bc_setup_except(emit_t *emit, mp_uint_t label);
void mp_emit_bc_setup_finally(emit_t *emit, mp_uint_t label);
void mp_emit_bc_end_finally(emit_t *emit);
void mp_emit_bc_get_iter(emit_t *emit, bool use_stack);
void mp_emit_bc_for_iter(emit_t *emit, mp_uint_t label);

View File

@ -719,11 +719,18 @@ void mp_emit_bc_unwind_jump(emit_t *emit, mp_uint_t label, mp_uint_t except_dept
}
}
void mp_emit_bc_setup_with(emit_t *emit, mp_uint_t label) {
void mp_emit_bc_setup_block(emit_t *emit, mp_uint_t label, int kind) {
MP_STATIC_ASSERT(MP_BC_SETUP_WITH + MP_EMIT_SETUP_BLOCK_WITH == MP_BC_SETUP_WITH);
MP_STATIC_ASSERT(MP_BC_SETUP_WITH + MP_EMIT_SETUP_BLOCK_EXCEPT == MP_BC_SETUP_EXCEPT);
MP_STATIC_ASSERT(MP_BC_SETUP_WITH + MP_EMIT_SETUP_BLOCK_FINALLY == MP_BC_SETUP_FINALLY);
if (kind == MP_EMIT_SETUP_BLOCK_WITH) {
// The SETUP_WITH opcode pops ctx_mgr from the top of the stack
// and then pushes 3 entries: __exit__, ctx_mgr, as_value.
emit_bc_pre(emit, 2);
emit_write_bytecode_byte_unsigned_label(emit, MP_BC_SETUP_WITH, label);
emit_bc_pre(emit, 2);
} else {
emit_bc_pre(emit, 0);
}
emit_write_bytecode_byte_unsigned_label(emit, MP_BC_SETUP_WITH + kind, label);
}
void mp_emit_bc_with_cleanup(emit_t *emit, mp_uint_t label) {
@ -732,17 +739,7 @@ void mp_emit_bc_with_cleanup(emit_t *emit, mp_uint_t label) {
mp_emit_bc_label_assign(emit, label);
emit_bc_pre(emit, 2); // ensure we have enough stack space to call the __exit__ method
emit_write_bytecode_byte(emit, MP_BC_WITH_CLEANUP);
emit_bc_pre(emit, -4); // cancel the 2 above, plus the 2 from mp_emit_bc_setup_with
}
void mp_emit_bc_setup_except(emit_t *emit, mp_uint_t label) {
emit_bc_pre(emit, 0);
emit_write_bytecode_byte_unsigned_label(emit, MP_BC_SETUP_EXCEPT, label);
}
void mp_emit_bc_setup_finally(emit_t *emit, mp_uint_t label) {
emit_bc_pre(emit, 0);
emit_write_bytecode_byte_unsigned_label(emit, MP_BC_SETUP_FINALLY, label);
emit_bc_pre(emit, -4); // cancel the 2 above, plus the 2 from mp_emit_bc_setup_block(MP_EMIT_SETUP_BLOCK_WITH)
}
void mp_emit_bc_end_finally(emit_t *emit) {
@ -953,10 +950,8 @@ const emit_method_table_t emit_bc_method_table = {
mp_emit_bc_pop_jump_if,
mp_emit_bc_jump_if_or_pop,
mp_emit_bc_unwind_jump,
mp_emit_bc_setup_with,
mp_emit_bc_setup_block,
mp_emit_bc_with_cleanup,
mp_emit_bc_setup_except,
mp_emit_bc_setup_finally,
mp_emit_bc_end_finally,
mp_emit_bc_get_iter,
mp_emit_bc_for_iter,

View File

@ -1617,6 +1617,21 @@ STATIC void emit_native_setup_with(emit_t *emit, mp_uint_t label) {
// stack: (..., __exit__, self, as_value, nlr_buf, as_value)
}
STATIC void emit_native_setup_block(emit_t *emit, mp_uint_t label, int kind) {
if (kind == MP_EMIT_SETUP_BLOCK_WITH) {
emit_native_setup_with(emit, label);
} else {
// Set up except and finally
emit_native_pre(emit);
// need to commit stack because we may jump elsewhere
need_stack_settled(emit);
emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_1, sizeof(nlr_buf_t) / sizeof(mp_uint_t)); // arg1 = pointer to nlr buf
emit_call(emit, MP_F_NLR_PUSH);
ASM_JUMP_IF_REG_NONZERO(emit->as, REG_RET, label);
emit_post(emit);
}
}
STATIC void emit_native_with_cleanup(emit_t *emit, mp_uint_t label) {
// note: label+1 is available as an auxiliary label
@ -1686,20 +1701,6 @@ STATIC void emit_native_with_cleanup(emit_t *emit, mp_uint_t label) {
emit_native_label_assign(emit, label + 1);
}
STATIC void emit_native_setup_except(emit_t *emit, mp_uint_t label) {
emit_native_pre(emit);
// need to commit stack because we may jump elsewhere
need_stack_settled(emit);
emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_1, sizeof(nlr_buf_t) / sizeof(mp_uint_t)); // arg1 = pointer to nlr buf
emit_call(emit, MP_F_NLR_PUSH);
ASM_JUMP_IF_REG_NONZERO(emit->as, REG_RET, label);
emit_post(emit);
}
STATIC void emit_native_setup_finally(emit_t *emit, mp_uint_t label) {
emit_native_setup_except(emit, label);
}
STATIC void emit_native_end_finally(emit_t *emit) {
// logic:
// exc = pop_stack
@ -2254,10 +2255,8 @@ const emit_method_table_t EXPORT_FUN(method_table) = {
emit_native_pop_jump_if,
emit_native_jump_if_or_pop,
emit_native_unwind_jump,
emit_native_setup_with,
emit_native_setup_block,
emit_native_with_cleanup,
emit_native_setup_except,
emit_native_setup_finally,
emit_native_end_finally,
emit_native_get_iter,
emit_native_for_iter,