diff --git a/ports/unix/coverage.c b/ports/unix/coverage.c index f545674ceeb80..64701e4e7000c 100644 --- a/ports/unix/coverage.c +++ b/ports/unix/coverage.c @@ -552,7 +552,9 @@ STATIC mp_obj_t extra_coverage(void) { code_state->exc_sp_idx = 0; code_state->old_globals = NULL; mp_vm_return_kind_t ret = mp_execute_bytecode(code_state, MP_OBJ_NULL); - mp_printf(&mp_plat_print, "%d %d\n", ret, mp_obj_get_type(code_state->state[0]) == &mp_type_NotImplementedError); + mp_printf(&mp_plat_print, "%d %d\n", + ret == MP_VM_RETURN_EXCEPTION, + mp_obj_get_type(code_state->state[0]) == &mp_type_NotImplementedError); } // scheduler diff --git a/py/compile.c b/py/compile.c index 76d4c1bf5aa0a..5d384a4fb9828 100644 --- a/py/compile.c +++ b/py/compile.c @@ -938,7 +938,7 @@ STATIC void compile_decorated(compiler_t *comp, mp_parse_node_struct_t *pns) { mp_parse_node_struct_t *pns0 = (mp_parse_node_struct_t *)pns_body->nodes[0]; body_name = compile_funcdef_helper(comp, pns0, emit_options); scope_t *fscope = (scope_t *)pns0->nodes[4]; - fscope->scope_flags |= MP_SCOPE_FLAG_GENERATOR; + fscope->scope_flags |= MP_SCOPE_FLAG_GENERATOR | MP_SCOPE_FLAG_ASYNCDEF; #endif } else { assert(MP_PARSE_NODE_STRUCT_KIND(pns_body) == PN_classdef); // should be @@ -1041,6 +1041,12 @@ STATIC void compile_return_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { return; } #endif + #if MICROPY_PY_ASYNC_AWAIT + if ((comp->scope_cur->scope_flags & MP_SCOPE_FLAG_ASYNCGENERATOR) + && !MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { + compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("'return' with value in async generator")); + } + #endif if (MP_PARSE_NODE_IS_NULL(pns->nodes[0])) { // no argument to 'return', so return None EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); @@ -1765,6 +1771,7 @@ STATIC void compile_with_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { } STATIC void compile_yield_from(compiler_t *comp) { + comp->scope_cur->scope_flags |= MP_SCOPE_FLAG_GENERATOR; EMIT_ARG(get_iter, false); EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); EMIT_ARG(yield, MP_EMIT_YIELD_FROM); @@ -1959,7 +1966,7 @@ STATIC void compile_async_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { // async def compile_funcdef(comp, pns0); scope_t *fscope = (scope_t *)pns0->nodes[4]; - fscope->scope_flags |= MP_SCOPE_FLAG_GENERATOR; + fscope->scope_flags |= MP_SCOPE_FLAG_GENERATOR | MP_SCOPE_FLAG_ASYNCDEF; } else { // async for/with; first verify the scope is a generator int scope_flags = comp->scope_cur->scope_flags; @@ -2711,6 +2718,12 @@ STATIC void compile_yield_expr(compiler_t *comp, mp_parse_node_struct_t *pns) { compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("'yield' outside function")); return; } + comp->scope_cur->scope_flags |= MP_SCOPE_FLAG_GENERATOR; + #if MICROPY_PY_ASYNC_AWAIT + if (comp->scope_cur->scope_flags & MP_SCOPE_FLAG_ASYNCDEF) { + comp->scope_cur->scope_flags |= MP_SCOPE_FLAG_ASYNCGENERATOR; + } + #endif 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); @@ -2719,6 +2732,11 @@ STATIC void compile_yield_expr(compiler_t *comp, mp_parse_node_struct_t *pns) { pns = (mp_parse_node_struct_t *)pns->nodes[0]; compile_node(comp, pns->nodes[0]); compile_yield_from(comp); + #if MICROPY_PY_ASYNC_AWAIT + if (comp->scope_cur->scope_flags & MP_SCOPE_FLAG_ASYNCDEF) { + compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("'yield from' in async function")); + } + #endif } else { compile_node(comp, pns->nodes[0]); EMIT_ARG(yield, MP_EMIT_YIELD_VALUE); @@ -2920,6 +2938,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) { + comp->scope_cur->scope_flags |= MP_SCOPE_FLAG_GENERATOR; EMIT_ARG(yield, MP_EMIT_YIELD_VALUE); reserve_labels_for_native(comp, 1); EMIT(pop_top); diff --git a/py/emitbc.c b/py/emitbc.c index 70a4d8b12e18a..374feb2e93a12 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -800,7 +800,6 @@ void mp_emit_bc_raise_varargs(emit_t *emit, mp_uint_t n_args) { void mp_emit_bc_yield(emit_t *emit, int kind) { MP_STATIC_ASSERT(MP_BC_YIELD_VALUE + 1 == MP_BC_YIELD_FROM); emit_write_bytecode_byte(emit, -kind, MP_BC_YIELD_VALUE + kind); - emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR; } void mp_emit_bc_start_except_handler(emit_t *emit) { diff --git a/py/emitnative.c b/py/emitnative.c index 2d694983bd2ab..48e4e73a1b44b 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -2831,7 +2831,6 @@ STATIC void emit_native_yield(emit_t *emit, int kind) { if (emit->do_viper_types) { mp_raise_NotImplementedError(MP_ERROR_TEXT("native yield")); } - emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR; need_stack_settled(emit); @@ -2853,7 +2852,13 @@ STATIC void emit_native_yield(emit_t *emit, int kind) { emit_native_mov_state_reg(emit, OFFSETOF_CODE_STATE_SP, REG_TEMP0); // Put return type in return value slot - ASM_MOV_REG_IMM(emit->as, REG_TEMP0, MP_VM_RETURN_YIELD); + mp_vm_return_kind_t ret_kind = MP_VM_RETURN_YIELD; + #if MICROPY_PY_ASYNC_AWAIT + if ((emit->scope->scope_flags & MP_SCOPE_FLAG_ASYNCGENERATOR) && kind == MP_EMIT_YIELD_FROM) { + ret_kind = MP_VM_RETURN_YIELD_FROM; + } + #endif + ASM_MOV_REG_IMM(emit->as, REG_TEMP0, ret_kind); ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_RET_VAL(emit), REG_TEMP0); // Save re-entry PC diff --git a/py/obj.h b/py/obj.h index b5b855bad395c..3b6408ce7df22 100644 --- a/py/obj.h +++ b/py/obj.h @@ -813,6 +813,7 @@ extern const mp_obj_type_t mp_type_super; extern const mp_obj_type_t mp_type_gen_wrap; extern const mp_obj_type_t mp_type_native_gen_wrap; extern const mp_obj_type_t mp_type_gen_instance; +extern const mp_obj_type_t mp_type_agen_instance; extern const mp_obj_type_t mp_type_fun_builtin_0; extern const mp_obj_type_t mp_type_fun_builtin_1; extern const mp_obj_type_t mp_type_fun_builtin_2; diff --git a/py/objgenerator.c b/py/objgenerator.c index 8175dbd683db0..c9639143ddf82 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2013-2019 Damien P. George + * Copyright (c) 2013-2020 Damien P. George * Copyright (c) 2014-2017 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -29,6 +29,7 @@ #include #include "py/runtime.h" +#include "py/bc0.h" #include "py/bc.h" #include "py/objstr.h" #include "py/objgenerator.h" @@ -63,6 +64,12 @@ STATIC mp_obj_t gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t), &mp_type_gen_instance); + #if MICROPY_PY_ASYNC_AWAIT + if (scope_flags & MP_SCOPE_FLAG_ASYNCGENERATOR) { + o->base.type = &mp_type_agen_instance; + } + #endif + o->pend_exc = mp_const_none; o->code_state.fun_bc = self_fun; o->code_state.n_state = n_state; @@ -116,6 +123,11 @@ STATIC mp_obj_t native_gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_k // Allocate the generator object, with room for local stack (exception stack not needed). mp_obj_gen_instance_native_t *o = mp_obj_malloc_var(mp_obj_gen_instance_native_t, byte, n_state * sizeof(mp_obj_t), &mp_type_gen_instance); + #if MICROPY_PY_ASYNC_AWAIT + if (scope_flags & MP_SCOPE_FLAG_ASYNCGENERATOR) { + o->base.type = &mp_type_agen_instance; + } + #endif // Parse the input arguments and set up the code state o->pend_exc = mp_const_none; @@ -167,6 +179,13 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_ mp_obj_gen_instance_t *self = MP_OBJ_TO_PTR(self_in); if (self->code_state.ip == 0) { // Trying to resume an already stopped generator. + #if MICROPY_PY_ASYNC_AWAIT + if (self->base.type == &mp_type_agen_instance) { + // Do a "raise StopAsyncIteration()". + *ret_val = mp_obj_new_exception(&mp_type_StopAsyncIteration); + return MP_VM_RETURN_EXCEPTION; + } + #endif // This is an optimised "raise StopIteration(None)". *ret_val = mp_const_none; return MP_VM_RETURN_NORMAL; @@ -235,13 +254,42 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_ self->code_state.ip = 0; // This is an optimised "raise StopIteration(*ret_val)". *ret_val = *self->code_state.sp; + #if MICROPY_PY_ASYNC_AWAIT + if (self->base.type == &mp_type_agen_instance) { + // Reached the end of the async generator, do "raise StopAsyncIteration()". + assert(*ret_val == mp_const_none); // enforced by the compiler + *ret_val = mp_obj_new_exception(&mp_type_StopAsyncIteration); + ret_kind = MP_VM_RETURN_EXCEPTION; + } + #endif break; case MP_VM_RETURN_YIELD: + case MP_VM_RETURN_YIELD_FROM: *ret_val = *self->code_state.sp; #if MICROPY_PY_GENERATOR_PEND_THROW *self->code_state.sp = mp_const_none; #endif + #if MICROPY_PY_ASYNC_AWAIT + if (self->base.type == &mp_type_agen_instance) { + #if MICROPY_EMIT_NATIVE + if (self->code_state.exc_sp_idx == MP_CODE_STATE_EXC_SP_IDX_SENTINEL) { + // A native generator. + if (ret_kind == MP_VM_RETURN_YIELD) { + // "yield" in native async generator. + ret_kind = MP_VM_RETURN_NORMAL; + } else { + // "yield from" in native async generator. + ret_kind = MP_VM_RETURN_YIELD; + } + } else + #endif + if (*self->code_state.ip != MP_BC_YIELD_FROM) { + // "yield" in async generator. + ret_kind = MP_VM_RETURN_NORMAL; + } + } + #endif break; case MP_VM_RETURN_EXCEPTION: { @@ -374,3 +422,25 @@ MP_DEFINE_CONST_OBJ_TYPE( iter, gen_instance_iternext, locals_dict, &gen_instance_locals_dict ); + +/******************************************************************************/ +// async generator instance + +#if MICROPY_PY_ASYNC_AWAIT + +STATIC const mp_rom_map_elem_t agen_instance_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___aiter__), MP_ROM_PTR(&mp_identity_obj) }, + { MP_ROM_QSTR(MP_QSTR___anext__), MP_ROM_PTR(&mp_identity_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(agen_instance_locals_dict, agen_instance_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_agen_instance, + MP_QSTR_async_generator, + MP_TYPE_FLAG_ITER_IS_ITERNEXT, + unary_op, mp_generic_unary_op, + iter, gen_instance_iternext, + locals_dict, &agen_instance_locals_dict + ); + +#endif // MICROPY_PY_ASYNC_AWAIT diff --git a/py/runtime.c b/py/runtime.c index 23fae6041dd0f..3e1f3986be8c1 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1387,7 +1387,11 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th assert((send_value != MP_OBJ_NULL) ^ (throw_value != MP_OBJ_NULL)); const mp_obj_type_t *type = mp_obj_get_type(self_in); - if (type == &mp_type_gen_instance) { + if (type == &mp_type_gen_instance + #if MICROPY_PY_ASYNC_AWAIT + || type == &mp_type_agen_instance + #endif + ) { return mp_obj_gen_resume(self_in, send_value, throw_value, ret_val); } diff --git a/py/runtime.h b/py/runtime.h index 36b3caa6c73e6..965051a68b177 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -32,6 +32,7 @@ typedef enum { MP_VM_RETURN_NORMAL, MP_VM_RETURN_YIELD, + MP_VM_RETURN_YIELD_FROM, // used only by the native emitter MP_VM_RETURN_EXCEPTION, } mp_vm_return_kind_t; diff --git a/py/runtime0.h b/py/runtime0.h index c82a4717f4516..88e792ecbee2b 100644 --- a/py/runtime0.h +++ b/py/runtime0.h @@ -26,19 +26,23 @@ #ifndef MICROPY_INCLUDED_PY_RUNTIME0_H #define MICROPY_INCLUDED_PY_RUNTIME0_H -// The first four must fit in 8 bits, see emitbc.c -// The remaining must fit in 16 bits, see scope.h -#define MP_SCOPE_FLAG_ALL_SIG (0x0f) +// The first five must fit in 7 bits, see mp_raw_code_t.scope_flags. +// The remaining must fit in 16 bits, see scope_t.scope_flags. +#define MP_SCOPE_FLAG_ALL_SIG (0x1f) + #define MP_SCOPE_FLAG_GENERATOR (0x01) #define MP_SCOPE_FLAG_VARKEYWORDS (0x02) #define MP_SCOPE_FLAG_VARARGS (0x04) #define MP_SCOPE_FLAG_DEFKWARGS (0x08) -#define MP_SCOPE_FLAG_REFGLOBALS (0x10) // used only if native emitter enabled -#define MP_SCOPE_FLAG_HASCONSTS (0x20) // used only if native emitter enabled -#define MP_SCOPE_FLAG_VIPERRET_POS (6) // 3 bits used for viper return type, to pass from compiler to native emitter -#define MP_SCOPE_FLAG_VIPERRELOC (0x10) // used only when loading viper from .mpy -#define MP_SCOPE_FLAG_VIPERRODATA (0x20) // used only when loading viper from .mpy -#define MP_SCOPE_FLAG_VIPERBSS (0x40) // used only when loading viper from .mpy +#define MP_SCOPE_FLAG_ASYNCGENERATOR (0x10) + +#define MP_SCOPE_FLAG_REFGLOBALS (0x20) // used only if native emitter enabled +#define MP_SCOPE_FLAG_HASCONSTS (0x40) // used only if native emitter enabled +#define MP_SCOPE_FLAG_VIPERRET_POS (7) // 3 bits used for viper return type, to pass from compiler to native emitter +#define MP_SCOPE_FLAG_VIPERRELOC (0x20) // used only when loading viper from .mpy +#define MP_SCOPE_FLAG_VIPERRODATA (0x40) // used only when loading viper from .mpy +#define MP_SCOPE_FLAG_VIPERBSS (0x80) // used only when loading viper from .mpy +#define MP_SCOPE_FLAG_ASYNCDEF (0x8000) // used ony by the compiler // types for native (viper) function signature #define MP_NATIVE_TYPE_OBJ (0x00) diff --git a/tests/basics/async_agen.py b/tests/basics/async_agen.py new file mode 100644 index 0000000000000..7e0d1e0efdcb4 --- /dev/null +++ b/tests/basics/async_agen.py @@ -0,0 +1,79 @@ +# Test async generators + +# helper +def run_task(t): + while True: + try: + t.send(None) + except Exception as er: + print('run_task finished with', repr(er)) + break + +# Test SyntaxError + +try: + exec('async def f(): yield from y') +except Exception as er: + print(type(er)) + +try: + exec('async def f(): yield; return 1') +except Exception as er: + print(type(er)) + +try: + exec('async def f(): return 2; yield') +except Exception as er: + print(type(er)) + +# Test core behaviour + +async def genfunc(): + yield 1 + yield 2 + +async def main(): + gen = genfunc() + + print(gen.__aiter__() is gen) + + print(repr(await gen.__anext__())) # should be 1 + print(repr(await gen.__anext__())) # should be 2 + + try: + await gen.__anext__() + except Exception as er: + print(type(er)) + + try: + await gen.__anext__() + except Exception as er: + print(type(er)) + +run_task(main()) + +# Test async-for iterating over an async generator + +class Wait: + def __init__(self, n): + self.n = n + def __await__(self): + return self + __iter__ = __await__ # needed for uPy + def __next__(self): + if self.n == 0: + raise StopIteration + print('wait', self.n) + self.n -= 1 + +async def gen(): + for i in range(4): + yield i + await Wait(2) + +async def main(): + g = gen() + async for a in g: + print('got', a) + +run_task(main()) diff --git a/tests/basics/async_agen.py.exp b/tests/basics/async_agen.py.exp new file mode 100644 index 0000000000000..acb0c0f598730 --- /dev/null +++ b/tests/basics/async_agen.py.exp @@ -0,0 +1,22 @@ + + + +True +1 +2 + + +run_task finished with StopIteration() +got 0 +wait 2 +wait 1 +got 1 +wait 2 +wait 1 +got 2 +wait 2 +wait 1 +got 3 +wait 2 +wait 1 +run_task finished with StopIteration() diff --git a/tests/micropython/import_mpy_native.py b/tests/micropython/import_mpy_native.py index 73e20694cc27e..f83dac048d600 100644 --- a/tests/micropython/import_mpy_native.py +++ b/tests/micropython/import_mpy_native.py @@ -101,7 +101,7 @@ def open(self, path, mode): b'\x22' # 4 bytes, no children, viper code b'\x00\x00\x00\x00' # dummy machine code - b'\x70' # scope_flags: VIPERBSS | VIPERRODATA | VIPERRELOC + b'\xe0' # scope_flags: VIPERBSS | VIPERRODATA | VIPERRELOC b'\x06\x04' # rodata=6 bytes, bss=4 bytes b'rodata' # rodata content b'\x03\x01\x00' # dummy relocation of rodata diff --git a/tests/micropython/import_mpy_native_gc.py b/tests/micropython/import_mpy_native_gc.py index e18720fb31473..247665f530ce3 100644 --- a/tests/micropython/import_mpy_native_gc.py +++ b/tests/micropython/import_mpy_native_gc.py @@ -49,9 +49,9 @@ def open(self, path, mode): # by the required value of sys.implementation._mpy (without sub-version). features0_file_contents = { # -march=x64 - 0x806: b'M\x06\x09\x1f\x02\x004build/features0.native.mpy\x00\x12factorial\x00\x8a\x02\xe9/\x00\x00\x00SH\x8b\x1d\x83\x00\x00\x00\xbe\x02\x00\x00\x00\xffS\x18\xbf\x01\x00\x00\x00H\x85\xc0u\x0cH\x8bC \xbe\x02\x00\x00\x00[\xff\xe0H\x0f\xaf\xf8H\xff\xc8\xeb\xe6ATUSH\x8b\x1dQ\x00\x00\x00H\x8bG\x08L\x8bc(H\x8bx\x08A\xff\xd4H\x8d5+\x00\x00\x00H\x89\xc5H\x8b\x059\x00\x00\x00\x0f\xb7x\x02\xffShH\x89\xefA\xff\xd4H\x8b\x03[]A\\\xc3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x11$\r&\xa3 \x01"\xff', + 0x806: b'M\x06\t\x1f\x02\x004build/features0.native.mpy\x00\x12factorial\x00\x8a\x02\xe9/\x00\x00\x00SH\x8b\x1d\x83\x00\x00\x00\xbe\x02\x00\x00\x00\xffS\x18\xbf\x01\x00\x00\x00H\x85\xc0u\x0cH\x8bC \xbe\x02\x00\x00\x00[\xff\xe0H\x0f\xaf\xf8H\xff\xc8\xeb\xe6ATUSH\x8b\x1dQ\x00\x00\x00H\x8bG\x08L\x8bc(H\x8bx\x08A\xff\xd4H\x8d5+\x00\x00\x00H\x89\xc5H\x8b\x059\x00\x00\x00\x0f\xb7x\x02\xffShH\x89\xefA\xff\xd4H\x8b\x03[]A\\\xc3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x11$\r&\xa3 \x01"\xff', # -march=armv6m - 0x1006: b"M\x06\x11\x1f\x02\x004build/features0.native.mpy\x00\x12factorial\x00\x88\x02\x18\xe0\x00\x00\x10\xb5\tK\tJ{D\x9cX\x02!\xe3h\x98G\x03\x00\x01 \x00+\x02\xd0XC\x01;\xfa\xe7\x02!#i\x98G\x10\xbd\xc0Fj\x00\x00\x00\x00\x00\x00\x00\xf8\xb5\nN\nK~D\xf4XChgiXh\xb8G\x05\x00\x07K\x08I\xf3XyDX\x88ck\x98G(\x00\xb8G h\xf8\xbd\xc0F:\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x11<\r>\xa38\x01:\xff", + 0x1006: b"M\x06\x11\x1f\x02\x004build/features0.native.mpy\x00\x12factorial\x00\x88\x02\x18\xe0\x00\x00\x10\xb5\tK\tJ{D\x9cX\x02!\xe3h\x98G\x03\x00\x01 \x00+\x02\xd0XC\x01;\xfa\xe7\x02!#i\x98G\x10\xbd\xc0Fj\x00\x00\x00\x00\x00\x00\x00\xf8\xb5\nN\nK~D\xf4XChgiXh\xb8G\x05\x00\x07K\x08I\xf3XyDX\x88ck\x98G(\x00\xb8G h\xf8\xbd\xc0F:\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x11<\r>\xa38\x01:\xff", } # Populate armv7m-derived archs based on armv6m. diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp index ab6d497723012..61a53b72f7b4a 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -104,7 +104,7 @@ Warning: test 123 456 # VM -2 1 +1 1 # scheduler sched(0)=1 sched(1)=1 diff --git a/tools/mpy_ld.py b/tools/mpy_ld.py index 05e70709ad8a4..59a2da623e30b 100755 --- a/tools/mpy_ld.py +++ b/tools/mpy_ld.py @@ -48,9 +48,9 @@ MP_NATIVE_ARCH_XTENSA = 9 MP_NATIVE_ARCH_XTENSAWIN = 10 MP_PERSISTENT_OBJ_STR = 5 -MP_SCOPE_FLAG_VIPERRELOC = 0x10 -MP_SCOPE_FLAG_VIPERRODATA = 0x20 -MP_SCOPE_FLAG_VIPERBSS = 0x40 +MP_SCOPE_FLAG_VIPERRELOC = 0x20 +MP_SCOPE_FLAG_VIPERRODATA = 0x40 +MP_SCOPE_FLAG_VIPERBSS = 0x80 MP_SMALL_INT_BITS = 31 # ELF constants pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy