@@ -30,6 +30,13 @@ typedef struct _mp_exc_stack {
3030 byte opcode ;
3131} mp_exc_stack ;
3232
33+ // Exception stack unwind reasons (WHY_* in CPython-speak)
34+ typedef enum {
35+ UNWIND_RETURN = 1 ,
36+ UNWIND_BREAK ,
37+ UNWIND_CONTINUE ,
38+ } mp_unwind_reason_t ;
39+
3340#define DECODE_UINT do { unum = *ip++; if (unum > 127) { unum = ((unum & 0x3f) << 8) | (*ip++); } } while (0)
3441#define DECODE_ULABEL do { unum = (ip[0] | (ip[1] << 8)); ip += 2; } while (0)
3542#define DECODE_SLABEL do { unum = (ip[0] | (ip[1] << 8)) - 0x8000; ip += 2; } while (0)
@@ -106,6 +113,7 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
106113 if (nlr_push (& nlr ) == 0 ) {
107114 // loop to execute byte code
108115 for (;;) {
116+ dispatch_loop :
109117 save_ip = ip ;
110118 int op = * ip ++ ;
111119 switch (op ) {
@@ -352,6 +360,19 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
352360 }
353361 if (TOP () == mp_const_none ) {
354362 sp -- ;
363+ } else if (MP_OBJ_IS_SMALL_INT (TOP ())) {
364+ // We finished "finally" coroutine and now dispatch back
365+ // to our caller, based on TOS value
366+ mp_unwind_reason_t reason = MP_OBJ_SMALL_INT_VALUE (POP ());
367+ switch (reason ) {
368+ case UNWIND_RETURN :
369+ goto unwind_return ;
370+ // TODO
371+ case UNWIND_BREAK :
372+ case UNWIND_CONTINUE :
373+ ;
374+ }
375+ assert (0 );
355376 } else {
356377 assert (0 );
357378 }
@@ -501,6 +522,23 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
501522 break ;
502523
503524 case MP_BC_RETURN_VALUE :
525+ unwind_return :
526+ while (exc_sp >= exc_stack ) {
527+ if (exc_sp -> opcode == MP_BC_SETUP_FINALLY ) {
528+ // We're going to run "finally" code as a coroutine
529+ // (not calling it recursively). Set up a sentinel
530+ // on a stack so it can return back to us when it is
531+ // done (when END_FINALLY reached).
532+ PUSH (MP_OBJ_NEW_SMALL_INT (UNWIND_RETURN ));
533+ ip = exc_sp -> handler ;
534+ // We don't need to do anything with sp, finally is just
535+ // syntactic sugar for sequential execution??
536+ // sp =
537+ exc_sp -- ;
538+ goto dispatch_loop ;
539+ }
540+ exc_sp -- ;
541+ }
504542 nlr_pop ();
505543 * sp_in_out = sp ;
506544 assert (exc_sp == & exc_stack [0 ] - 1 );
0 commit comments