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:
parent
436e0d4c54
commit
18e6358480
14
py/compile.c
14
py/compile.c
|
@ -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);
|
||||
|
|
13
py/emit.h
13
py/emit.h
|
@ -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);
|
||||
|
|
29
py/emitbc.c
29
py/emitbc.c
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue