@@ -129,9 +129,12 @@ mp_vm_return_kind_t mp_execute_bytecode(mp_code_state *code_state, volatile mp_o
129129 // loop and the exception handler, leading to very obscure bugs.
130130 #define RAISE (o ) do { nlr_pop(); nlr.ret_val = o; goto exception_handler; } while(0)
131131
132+ #if MICROPY_STACKLESS
133+ run_code_state : ;
134+ #endif
132135 // Pointers which are constant for particular invocation of mp_execute_bytecode()
133- mp_obj_t * const fastn = & code_state -> state [code_state -> n_state - 1 ];
134- mp_exc_stack_t * const exc_stack = (mp_exc_stack_t * )(code_state -> state + code_state -> n_state );
136+ mp_obj_t * /* const*/ fastn = & code_state -> state [code_state -> n_state - 1 ];
137+ mp_exc_stack_t * /* const*/ exc_stack = (mp_exc_stack_t * )(code_state -> state + code_state -> n_state );
135138
136139 // variables that are visible to the exception handler (declared volatile)
137140 volatile bool currently_in_except_block = MP_TAGPTR_TAG0 (code_state -> exc_sp ); // 0 or 1, to detect nested exceptions
@@ -865,6 +868,18 @@ unwind_jump:;
865868 // unum & 0xff == n_positional
866869 // (unum >> 8) & 0xff == n_keyword
867870 sp -= (unum & 0xff ) + ((unum >> 7 ) & 0x1fe );
871+ #if MICROPY_STACKLESS
872+ if (mp_obj_get_type (* sp ) == & mp_type_fun_bc ) {
873+ code_state -> ip = ip ;
874+ code_state -> sp = sp ;
875+ code_state -> exc_sp = MP_TAGPTR_MAKE (exc_sp , currently_in_except_block );
876+ mp_code_state * new_state = mp_obj_fun_bc_prepare_codestate (* sp , unum & 0xff , (unum >> 8 ) & 0xff , sp + 1 );
877+ new_state -> prev = code_state ;
878+ code_state = new_state ;
879+ nlr_pop ();
880+ goto run_code_state ;
881+ }
882+ #endif
868883 SET_TOP (mp_call_function_n_kw (* sp , unum & 0xff , (unum >> 8 ) & 0xff , sp + 1 ));
869884 DISPATCH ();
870885 }
@@ -925,6 +940,15 @@ unwind_jump:;
925940 nlr_pop ();
926941 code_state -> sp = sp ;
927942 assert (exc_sp == exc_stack - 1 );
943+ #if MICROPY_STACKLESS
944+ if (code_state -> prev != NULL ) {
945+ mp_obj_t res = * sp ;
946+ mp_globals_set (code_state -> old_globals );
947+ code_state = code_state -> prev ;
948+ * code_state -> sp = res ;
949+ goto run_code_state ;
950+ }
951+ #endif
928952 return MP_VM_RETURN_NORMAL ;
929953
930954 ENTRY (MP_BC_RAISE_VARARGS ): {
@@ -1122,6 +1146,9 @@ unwind_jump:;
11221146 goto outer_dispatch_loop ; // continue with dispatch loop
11231147 }
11241148
1149+ #if MICROPY_STACKLESS
1150+ unwind_loop :
1151+ #endif
11251152 // set file and line number that the exception occurred at
11261153 // TODO: don't set traceback for exceptions re-raised by END_FINALLY.
11271154 // But consider how to handle nested exceptions.
@@ -1185,6 +1212,18 @@ unwind_jump:;
11851212 PUSH (mp_obj_get_type (nlr .ret_val ));
11861213 code_state -> sp = sp ;
11871214
1215+ #if MICROPY_STACKLESS
1216+ } else if (code_state -> prev != NULL ) {
1217+ mp_globals_set (code_state -> old_globals );
1218+ code_state = code_state -> prev ;
1219+ fastn = & code_state -> state [code_state -> n_state - 1 ];
1220+ exc_stack = (mp_exc_stack_t * )(code_state -> state + code_state -> n_state );
1221+ // variables that are visible to the exception handler (declared volatile)
1222+ currently_in_except_block = MP_TAGPTR_TAG0 (code_state -> exc_sp ); // 0 or 1, to detect nested exceptions
1223+ exc_sp = MP_TAGPTR_PTR (code_state -> exc_sp ); // stack grows up, exc_sp points to top of stack
1224+ goto unwind_loop ;
1225+
1226+ #endif
11881227 } else {
11891228 // propagate exception to higher level
11901229 // TODO what to do about ip and sp? they don't really make sense at this point
0 commit comments