py/emitnative: Implement yield and yield-from in native emitter.

This commit adds first class support for yield and yield-from in the native
emitter, including send and throw support, and yields enclosed in exception
handlers (which requires pulling down the NLR stack before yielding, then
rebuilding it when resuming).

This has been fully tested and is working on unix x86 and x86-64, and
stm32.  Also basic tests have been done with the esp8266 port.  Performance
of existing native code is unchanged.
This commit is contained in:
Damien George
2018-10-01 13:07:04 +10:00
parent 8fec6f5434
commit cc2bd63c57
9 changed files with 377 additions and 84 deletions

View File

@@ -1703,6 +1703,7 @@ STATIC void compile_yield_from(compiler_t *comp) {
EMIT_ARG(get_iter, false);
EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
EMIT_ARG(yield, MP_EMIT_YIELD_FROM);
reserve_labels_for_native(comp, 3);
}
#if MICROPY_PY_ASYNC_AWAIT
@@ -2634,6 +2635,7 @@ 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_ARG(yield, MP_EMIT_YIELD_VALUE);
reserve_labels_for_native(comp, 1);
} 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]);
@@ -2641,6 +2643,7 @@ STATIC void compile_yield_expr(compiler_t *comp, mp_parse_node_struct_t *pns) {
} else {
compile_node(comp, pns->nodes[0]);
EMIT_ARG(yield, MP_EMIT_YIELD_VALUE);
reserve_labels_for_native(comp, 1);
}
}
@@ -2873,6 +2876,7 @@ STATIC void compile_scope_comp_iter(compiler_t *comp, mp_parse_node_struct_t *pn
compile_node(comp, pn_inner_expr);
if (comp->scope_cur->kind == SCOPE_GEN_EXPR) {
EMIT_ARG(yield, MP_EMIT_YIELD_VALUE);
reserve_labels_for_native(comp, 1);
EMIT(pop_top);
} else {
EMIT_ARG(store_comp, comp->scope_cur->kind, 4 * for_depth + 5);