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
This commit is contained in:
Damien George 2018-05-19 00:30:42 +10:00
parent 0a25fff956
commit e686c94052
5 changed files with 19 additions and 28 deletions

View File

@ -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) { STATIC void compile_yield_from(compiler_t *comp) {
EMIT_ARG(get_iter, false); EMIT_ARG(get_iter, false);
EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
EMIT(yield_from); EMIT_ARG(yield, MP_EMIT_YIELD_FROM);
} }
#if MICROPY_PY_ASYNC_AWAIT #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])) { if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) {
EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); 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)) { } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_yield_arg_from)) {
pns = (mp_parse_node_struct_t*)pns->nodes[0]; pns = (mp_parse_node_struct_t*)pns->nodes[0];
compile_node(comp, pns->nodes[0]); compile_node(comp, pns->nodes[0]);
compile_yield_from(comp); compile_yield_from(comp);
} else { } else {
compile_node(comp, pns->nodes[0]); 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 // no more nested if/for; compile inner expression
compile_node(comp, pn_inner_expr); compile_node(comp, pn_inner_expr);
if (comp->scope_cur->kind == SCOPE_GEN_EXPR) { if (comp->scope_cur->kind == SCOPE_GEN_EXPR) {
EMIT(yield_value); EMIT_ARG(yield, MP_EMIT_YIELD_VALUE);
EMIT(pop_top); EMIT(pop_top);
} else { } else {
EMIT_ARG(store_comp, comp->scope_cur->kind, 4 * for_depth + 5); EMIT_ARG(store_comp, comp->scope_cur->kind, 4 * for_depth + 5);

View File

@ -59,6 +59,10 @@ typedef enum {
#define MP_EMIT_IDOP_LOCAL_FAST (0) #define MP_EMIT_IDOP_LOCAL_FAST (0)
#define MP_EMIT_IDOP_LOCAL_DEREF (1) #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 _emit_t emit_t;
typedef struct _mp_emit_method_table_id_ops_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 (*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 (*return_value)(emit_t *emit);
void (*raise_varargs)(emit_t *emit, mp_uint_t n_args); void (*raise_varargs)(emit_t *emit, mp_uint_t n_args);
void (*yield_value)(emit_t *emit); void (*yield)(emit_t *emit, int kind);
void (*yield_from)(emit_t *emit);
// these methods are used to control entry to/exit from an exception handler // these methods are used to control entry to/exit from an exception handler
// they may or may not emit code // 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_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_return_value(emit_t *emit);
void mp_emit_bc_raise_varargs(emit_t *emit, mp_uint_t n_args); 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(emit_t *emit, int kind);
void mp_emit_bc_yield_from(emit_t *emit);
void mp_emit_bc_start_except_handler(emit_t *emit); void mp_emit_bc_start_except_handler(emit_t *emit);
void mp_emit_bc_end_except_handler(emit_t *emit); void mp_emit_bc_end_except_handler(emit_t *emit);

View File

@ -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); emit_write_bytecode_byte_byte(emit, MP_BC_RAISE_VARARGS, n_args);
} }
void mp_emit_bc_yield_value(emit_t *emit) { void mp_emit_bc_yield(emit_t *emit, int kind) {
emit_bc_pre(emit, 0); 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->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
emit_write_bytecode_byte(emit, MP_BC_YIELD_VALUE); emit_write_bytecode_byte(emit, MP_BC_YIELD_VALUE + kind);
}
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);
} }
void mp_emit_bc_start_except_handler(emit_t *emit) { 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_call_method,
mp_emit_bc_return_value, mp_emit_bc_return_value,
mp_emit_bc_raise_varargs, mp_emit_bc_raise_varargs,
mp_emit_bc_yield_value, mp_emit_bc_yield,
mp_emit_bc_yield_from,
mp_emit_bc_start_except_handler, mp_emit_bc_start_except_handler,
mp_emit_bc_end_except_handler, mp_emit_bc_end_except_handler,

View File

@ -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); 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) // not supported (for now)
(void)emit; (void)emit;
(void)kind;
mp_raise_NotImplementedError("native yield"); 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) { 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 // 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_call_method,
emit_native_return_value, emit_native_return_value,
emit_native_raise_varargs, emit_native_raise_varargs,
emit_native_yield_value, emit_native_yield,
emit_native_yield_from,
emit_native_start_except_handler, emit_native_start_except_handler,
emit_native_end_except_handler, emit_native_end_except_handler,

View File

@ -20,6 +20,6 @@ ViperTypeError('unary op __neg__ not implemented',)
ViperTypeError('unary op __invert__ not implemented',) ViperTypeError('unary op __invert__ not implemented',)
ViperTypeError('binary op not implemented',) ViperTypeError('binary op not implemented',)
NotImplementedError('native yield',) NotImplementedError('native yield',)
NotImplementedError('native yield from',) NotImplementedError('native yield',)
NotImplementedError('conversion to object',) NotImplementedError('conversion to object',)
NotImplementedError('casting',) NotImplementedError('casting',)