1717// top element.
1818// Exception stack also grows up, top element is also pointed at.
1919
20- // Exception stack entry
21- typedef struct _mp_exc_stack {
22- const byte * handler ;
23- // bit 0 is saved currently_in_except_block value
24- machine_uint_t val_sp ;
25- // We might only have 2 interesting cases here: SETUP_EXCEPT & SETUP_FINALLY,
26- // consider storing it in bit 1 of val_sp. TODO: SETUP_WITH?
27- byte opcode ;
28- } mp_exc_stack ;
29-
3020// Exception stack unwind reasons (WHY_* in CPython-speak)
3121// TODO perhaps compress this to RETURN=0, JUMP>0, with number of unwinds
3222// left to do encoded in the JUMP number
@@ -89,8 +79,10 @@ mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args,
8979 }
9080 }
9181
82+ mp_exc_stack exc_stack [4 ];
83+ mp_exc_stack * exc_sp = & exc_stack [0 ] - 1 ;
9284 // execute the byte code
93- mp_vm_return_kind_t vm_return_kind = mp_execute_byte_code_2 (code , & ip , & state [n_state - 1 ], & sp );
85+ mp_vm_return_kind_t vm_return_kind = mp_execute_byte_code_2 (code , & ip , & state [n_state - 1 ], & sp , exc_stack , & exc_sp );
9486
9587 switch (vm_return_kind ) {
9688 case MP_VM_RETURN_NORMAL :
@@ -113,7 +105,10 @@ mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args,
113105// MP_VM_RETURN_NORMAL, sp valid, return value in *sp
114106// MP_VM_RETURN_YIELD, ip, sp valid, yielded value in *sp
115107// MP_VM_RETURN_EXCEPTION, exception in fastn[0]
116- 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 ) {
108+ mp_vm_return_kind_t mp_execute_byte_code_2 (const byte * code_info , const byte * * ip_in_out ,
109+ mp_obj_t * fastn , mp_obj_t * * sp_in_out ,
110+ mp_exc_stack * exc_stack ,
111+ mp_exc_stack * * exc_sp_in_out ) {
117112 // careful: be sure to declare volatile any variables read in the exception handler (written is ok, I think)
118113
119114 const byte * ip = * ip_in_out ;
@@ -124,8 +119,7 @@ mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **i
124119 nlr_buf_t nlr ;
125120
126121 volatile machine_uint_t currently_in_except_block = 0 ; // 0 or 1, to detect nested exceptions
127- mp_exc_stack exc_stack [4 ];
128- mp_exc_stack * volatile exc_sp = & exc_stack [0 ] - 1 ; // stack grows up, exc_sp points to top of stack
122+ mp_exc_stack * volatile exc_sp = * exc_sp_in_out ; // stack grows up, exc_sp points to top of stack
129123 const byte * volatile save_ip = ip ; // this is so we can access ip in the exception handler without making ip volatile (which means the compiler can't keep it in a register in the main loop)
130124
131125 // outer exception handling loop
@@ -434,7 +428,7 @@ mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **i
434428 // matched against: SETUP_EXCEPT, SETUP_FINALLY, SETUP_WITH
435429 case MP_BC_POP_BLOCK :
436430 // we are exiting an exception handler, so pop the last one of the exception-stack
437- assert (exc_sp >= & exc_stack [ 0 ] );
431+ assert (exc_sp >= exc_stack );
438432 currently_in_except_block = (exc_sp -> val_sp & 1 ); // restore previous state
439433 exc_sp -- ; // pop back to previous exception handler
440434 break ;
@@ -443,7 +437,7 @@ mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **i
443437 case MP_BC_POP_EXCEPT :
444438 // TODO need to work out how blocks work etc
445439 // pops block, checks it's an exception block, and restores the stack, saving the 3 exception values to local threadstate
446- assert (exc_sp >= & exc_stack [ 0 ] );
440+ assert (exc_sp >= exc_stack );
447441 assert (currently_in_except_block );
448442 //sp = (mp_obj_t*)(*exc_sp--);
449443 //exc_sp--; // discard ip
@@ -592,7 +586,7 @@ mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **i
592586 }
593587 nlr_pop ();
594588 * sp_in_out = sp ;
595- assert (exc_sp == & exc_stack [ 0 ] - 1 );
589+ assert (exc_sp == exc_stack - 1 );
596590 return MP_VM_RETURN_NORMAL ;
597591
598592 case MP_BC_RAISE_VARARGS :
@@ -605,6 +599,7 @@ mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **i
605599 nlr_pop ();
606600 * ip_in_out = ip ;
607601 * sp_in_out = sp ;
602+ * exc_sp_in_out = exc_sp ;
608603 return MP_VM_RETURN_YIELD ;
609604
610605 case MP_BC_IMPORT_NAME :
@@ -654,7 +649,7 @@ mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **i
654649 while (currently_in_except_block ) {
655650 // nested exception
656651
657- assert (exc_sp >= & exc_stack [ 0 ] );
652+ assert (exc_sp >= exc_stack );
658653
659654 // TODO make a proper message for nested exception
660655 // at the moment we are just raising the very last exception (the one that caused the nested exception)
@@ -664,7 +659,7 @@ mp_vm_return_kind_t mp_execute_byte_code_2(const byte *code_info, const byte **i
664659 exc_sp -- ; // pop back to previous exception handler
665660 }
666661
667- if (exc_sp >= & exc_stack [ 0 ] ) {
662+ if (exc_sp >= exc_stack ) {
668663 // set flag to indicate that we are now handling an exception
669664 currently_in_except_block = 1 ;
670665
0 commit comments