@@ -47,7 +47,7 @@ typedef enum {
4747#define TOP () (*sp)
4848#define SET_TOP (val ) *sp = (val)
4949
50- mp_obj_t mp_execute_byte_code (const byte * code , const mp_obj_t * args , uint n_args , const mp_obj_t * args2 , uint n_args2 , uint n_state ) {
50+ mp_vm_return_kind_t mp_execute_byte_code (const byte * code , const mp_obj_t * args , uint n_args , const mp_obj_t * args2 , uint n_args2 , uint n_state , mp_obj_t * ret ) {
5151 // allocate state for locals and stack
5252 mp_obj_t temp_state [10 ];
5353 mp_obj_t * state = & temp_state [0 ];
@@ -83,20 +83,30 @@ mp_obj_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_arg
8383 }
8484
8585 // execute the byte code
86- if (mp_execute_byte_code_2 (code , & ip , & state [n_state - 1 ], & sp )) {
87- // it shouldn't yield
88- assert (0 );
86+ mp_vm_return_kind_t vm_return_kind = mp_execute_byte_code_2 (code , & ip , & state [n_state - 1 ], & sp );
87+
88+ switch (vm_return_kind ) {
89+ case MP_VM_RETURN_NORMAL :
90+ * ret = * sp ;
91+ return MP_VM_RETURN_NORMAL ;
92+ case MP_VM_RETURN_EXCEPTION :
93+ * ret = state [n_state - 1 ];
94+ return MP_VM_RETURN_EXCEPTION ;
95+ case MP_VM_RETURN_YIELD : // byte-code shouldn't yield
96+ default :
97+ assert (0 );
98+ * ret = mp_const_none ;
99+ return MP_VM_RETURN_NORMAL ;
89100 }
90-
91- // TODO check fails if, eg, return from within for loop
92- //assert(sp == &state[17]);
93- return * sp ;
94101}
95102
96103// fastn has items in reverse order (fastn[0] is local[0], fastn[-1] is local[1], etc)
97104// sp points to bottom of stack which grows up
98- // returns true if bytecode yielded
99- bool mp_execute_byte_code_2 (const byte * code_info , const byte * * ip_in_out , mp_obj_t * fastn , mp_obj_t * * sp_in_out ) {
105+ // returns:
106+ // MP_VM_RETURN_NORMAL, sp valid, return value in *sp
107+ // MP_VM_RETURN_YIELD, ip, sp valid, yielded value in *sp
108+ // MP_VM_RETURN_EXCEPTION, exception in fastn[0]
109+ mp_vm_return_kind_t mp_execute_byte_code_2 (const byte * code_info , const byte * * ip_in_out , mp_obj_t * fastn , mp_obj_t * * sp_in_out ) {
100110 // careful: be sure to declare volatile any variables read in the exception handler (written is ok, I think)
101111
102112 const byte * ip = * ip_in_out ;
@@ -569,7 +579,7 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
569579 nlr_pop ();
570580 * sp_in_out = sp ;
571581 assert (exc_sp == & exc_stack [0 ] - 1 );
572- return false ;
582+ return MP_VM_RETURN_NORMAL ;
573583
574584 case MP_BC_RAISE_VARARGS :
575585 unum = * ip ++ ;
@@ -581,7 +591,7 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
581591 nlr_pop ();
582592 * ip_in_out = ip ;
583593 * sp_in_out = sp ;
584- return true ;
594+ return MP_VM_RETURN_YIELD ;
585595
586596 case MP_BC_IMPORT_NAME :
587597 DECODE_QSTR ;
@@ -603,7 +613,7 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
603613 printf ("code %p, byte code 0x%02x not implemented\n" , ip , op );
604614 assert (0 );
605615 nlr_pop ();
606- return false ;
616+ return MP_VM_RETURN_NORMAL ;
607617 }
608618 }
609619
@@ -653,9 +663,10 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
653663 PUSH (nlr .ret_val ); // TODO should be type(nlr.ret_val), I think...
654664
655665 } else {
656- // re-raise exception to higher level
657- // TODO what to do if this is a generator??
658- nlr_jump (nlr .ret_val );
666+ // propagate exception to higher level
667+ // TODO what to do about ip and sp? they don't really make sense at this point
668+ fastn [0 ] = nlr .ret_val ; // must put exception here because sp is invalid
669+ return MP_VM_RETURN_EXCEPTION ;
659670 }
660671 }
661672 }
0 commit comments