Browse Source

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
pull/3814/head
Damien George 7 years ago
parent
commit
e686c94052
  1. 8
      py/compile.c
  2. 10
      py/emit.h
  3. 16
      py/emitbc.c
  4. 11
      py/emitnative.c
  5. 2
      tests/micropython/viper_error.py.exp

8
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) { 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);

10
py/emit.h

@ -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);

16
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); 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->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR; emit_bc_pre(emit, -kind);
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->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) { 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,

11
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); 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,

2
tests/micropython/viper_error.py.exp

@ -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',)

Loading…
Cancel
Save