From e686c940525c5b87d02e3dd7bfcdec23cfa996dd Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 19 May 2018 00:30:42 +1000 Subject: [PATCH] py/emit: Combine yield value and yield-from emit funcs into one. Reduces code size by: bare-arm: -24 minimal x86: -72 unix x64: -200 unix nanbox: -72 stm32: -52 cc3200: -32 esp8266: -84 esp32: -24 --- py/compile.c | 8 ++++---- py/emit.h | 10 ++++++---- py/emitbc.c | 16 +++++----------- py/emitnative.c | 11 +++-------- tests/micropython/viper_error.py.exp | 2 +- 5 files changed, 19 insertions(+), 28 deletions(-) diff --git a/py/compile.c b/py/compile.c index 4d985a07fc..743034e57c 100644 --- a/py/compile.c +++ b/py/compile.c @@ -1699,7 +1699,7 @@ STATIC void compile_with_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { STATIC void compile_yield_from(compiler_t *comp) { EMIT_ARG(get_iter, false); EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); - EMIT(yield_from); + EMIT_ARG(yield, MP_EMIT_YIELD_FROM); } #if MICROPY_PY_ASYNC_AWAIT @@ -2621,14 +2621,14 @@ STATIC void compile_yield_expr(compiler_t *comp, mp_parse_node_struct_t *pns) { } if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); - EMIT(yield_value); + EMIT_ARG(yield, MP_EMIT_YIELD_VALUE); } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_yield_arg_from)) { pns = (mp_parse_node_struct_t*)pns->nodes[0]; compile_node(comp, pns->nodes[0]); compile_yield_from(comp); } else { compile_node(comp, pns->nodes[0]); - EMIT(yield_value); + EMIT_ARG(yield, MP_EMIT_YIELD_VALUE); } } @@ -2862,7 +2862,7 @@ STATIC void compile_scope_comp_iter(compiler_t *comp, mp_parse_node_struct_t *pn // no more nested if/for; compile inner expression compile_node(comp, pn_inner_expr); if (comp->scope_cur->kind == SCOPE_GEN_EXPR) { - EMIT(yield_value); + EMIT_ARG(yield, MP_EMIT_YIELD_VALUE); EMIT(pop_top); } else { EMIT_ARG(store_comp, comp->scope_cur->kind, 4 * for_depth + 5); diff --git a/py/emit.h b/py/emit.h index 5fe3c3d1f6..c85df0a675 100644 --- a/py/emit.h +++ b/py/emit.h @@ -59,6 +59,10 @@ typedef enum { #define MP_EMIT_IDOP_LOCAL_FAST (0) #define MP_EMIT_IDOP_LOCAL_DEREF (1) +// Kind for emit->yield() +#define MP_EMIT_YIELD_VALUE (0) +#define MP_EMIT_YIELD_FROM (1) + typedef struct _emit_t emit_t; typedef struct _mp_emit_method_table_id_ops_t { @@ -137,8 +141,7 @@ typedef struct _emit_method_table_t { void (*call_method)(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags); void (*return_value)(emit_t *emit); void (*raise_varargs)(emit_t *emit, mp_uint_t n_args); - void (*yield_value)(emit_t *emit); - void (*yield_from)(emit_t *emit); + void (*yield)(emit_t *emit, int kind); // these methods are used to control entry to/exit from an exception handler // they may or may not emit code @@ -252,8 +255,7 @@ void mp_emit_bc_call_function(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_ void mp_emit_bc_call_method(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags); void mp_emit_bc_return_value(emit_t *emit); void mp_emit_bc_raise_varargs(emit_t *emit, mp_uint_t n_args); -void mp_emit_bc_yield_value(emit_t *emit); -void mp_emit_bc_yield_from(emit_t *emit); +void mp_emit_bc_yield(emit_t *emit, int kind); void mp_emit_bc_start_except_handler(emit_t *emit); void mp_emit_bc_end_except_handler(emit_t *emit); diff --git a/py/emitbc.c b/py/emitbc.c index 28d32d4ea8..bff2c5a4c5 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -931,16 +931,11 @@ void mp_emit_bc_raise_varargs(emit_t *emit, mp_uint_t n_args) { emit_write_bytecode_byte_byte(emit, MP_BC_RAISE_VARARGS, n_args); } -void mp_emit_bc_yield_value(emit_t *emit) { - emit_bc_pre(emit, 0); +void mp_emit_bc_yield(emit_t *emit, int kind) { + MP_STATIC_ASSERT(MP_BC_YIELD_VALUE + 1 == MP_BC_YIELD_FROM); + emit_bc_pre(emit, -kind); emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR; - emit_write_bytecode_byte(emit, MP_BC_YIELD_VALUE); -} - -void mp_emit_bc_yield_from(emit_t *emit) { - emit_bc_pre(emit, -1); - emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR; - emit_write_bytecode_byte(emit, MP_BC_YIELD_FROM); + emit_write_bytecode_byte(emit, MP_BC_YIELD_VALUE + kind); } void mp_emit_bc_start_except_handler(emit_t *emit) { @@ -1034,8 +1029,7 @@ const emit_method_table_t emit_bc_method_table = { mp_emit_bc_call_method, mp_emit_bc_return_value, mp_emit_bc_raise_varargs, - mp_emit_bc_yield_value, - mp_emit_bc_yield_from, + mp_emit_bc_yield, mp_emit_bc_start_except_handler, mp_emit_bc_end_except_handler, diff --git a/py/emitnative.c b/py/emitnative.c index 9e16ef4bd9..26bcebfcbb 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -2170,16 +2170,12 @@ STATIC void emit_native_raise_varargs(emit_t *emit, mp_uint_t n_args) { emit_call(emit, MP_F_NATIVE_RAISE); } -STATIC void emit_native_yield_value(emit_t *emit) { +STATIC void emit_native_yield(emit_t *emit, int kind) { // not supported (for now) (void)emit; + (void)kind; mp_raise_NotImplementedError("native yield"); } -STATIC void emit_native_yield_from(emit_t *emit) { - // not supported (for now) - (void)emit; - mp_raise_NotImplementedError("native yield from"); -} STATIC void emit_native_start_except_handler(emit_t *emit) { // This instruction follows an nlr_pop, so the stack counter is back to zero, when really @@ -2278,8 +2274,7 @@ const emit_method_table_t EXPORT_FUN(method_table) = { emit_native_call_method, emit_native_return_value, emit_native_raise_varargs, - emit_native_yield_value, - emit_native_yield_from, + emit_native_yield, emit_native_start_except_handler, emit_native_end_except_handler, diff --git a/tests/micropython/viper_error.py.exp b/tests/micropython/viper_error.py.exp index a44fb3ff0a..3a8cb02994 100644 --- a/tests/micropython/viper_error.py.exp +++ b/tests/micropython/viper_error.py.exp @@ -20,6 +20,6 @@ ViperTypeError('unary op __neg__ not implemented',) ViperTypeError('unary op __invert__ not implemented',) ViperTypeError('binary op not implemented',) NotImplementedError('native yield',) -NotImplementedError('native yield from',) +NotImplementedError('native yield',) NotImplementedError('conversion to object',) NotImplementedError('casting',)