1313#include "bc0.h"
1414#include "bc.h"
1515
16- // (value) stack grows down (to be compatible with native code when passing pointers to the stack), top element is pointed to
17- // exception stack grows up, top element is pointed to
16+ // Value stack grows up (this makes it incompatible with native C stack, but
17+ // makes sure that arguments to functions are in natural order arg1..argN
18+ // (Python semantics mandates left-to-right evaluation order, including for
19+ // function arguments). Stack pointer is pre-incremented and points at the
20+ // top element.
21+ // Exception stack also grows up, top element is also pointed at.
22+
23+ // Exception stack entry
24+ typedef struct _mp_exc_stack {
25+ const byte * handler ;
26+ // bit 0 is saved currently_in_except_block value
27+ machine_uint_t val_sp ;
28+ // We might only have 2 interesting cases here: SETUP_EXCEPT & SETUP_FINALLY,
29+ // consider storing it in bit 1 of val_sp. TODO: SETUP_WITH?
30+ byte opcode ;
31+ } mp_exc_stack ;
1832
1933#define DECODE_UINT do { unum = *ip++; if (unum > 127) { unum = ((unum & 0x3f) << 8) | (*ip++); } } while (0)
2034#define DECODE_ULABEL do { unum = (ip[0] | (ip[1] << 8)); ip += 2; } while (0)
@@ -83,8 +97,8 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
8397 nlr_buf_t nlr ;
8498
8599 volatile machine_uint_t currently_in_except_block = 0 ; // 0 or 1, to detect nested exceptions
86- machine_uint_t exc_stack [8 ]; // on the exception stack we store (ip, sp | X) for each block, X = previous value of currently_in_except_block
87- machine_uint_t * volatile exc_sp = & exc_stack [0 ] - 1 ; // stack grows up, exc_sp points to top of stack
100+ mp_exc_stack exc_stack [4 ];
101+ mp_exc_stack * volatile exc_sp = & exc_stack [0 ] - 1 ; // stack grows up, exc_sp points to top of stack
88102 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)
89103
90104 // outer exception handling loop
@@ -318,9 +332,12 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
318332
319333 // matched against: POP_BLOCK or POP_EXCEPT (anything else?)
320334 case MP_BC_SETUP_EXCEPT :
335+ case MP_BC_SETUP_FINALLY :
321336 DECODE_ULABEL ; // except labels are always forward
322- * ++ exc_sp = (machine_uint_t )ip + unum ;
323- * ++ exc_sp = (((machine_uint_t )sp ) | currently_in_except_block );
337+ ++ exc_sp ;
338+ exc_sp -> opcode = op ;
339+ exc_sp -> handler = ip + unum ;
340+ exc_sp -> val_sp = (((machine_uint_t )sp ) | currently_in_except_block );
324341 currently_in_except_block = 0 ; // in a try block now
325342 break ;
326343
@@ -359,8 +376,8 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
359376 case MP_BC_POP_BLOCK :
360377 // we are exiting an exception handler, so pop the last one of the exception-stack
361378 assert (exc_sp >= & exc_stack [0 ]);
362- currently_in_except_block = (exc_sp [ 0 ] & 1 ); // restore previous state
363- exc_sp -= 2 ; // pop back to previous exception handler
379+ currently_in_except_block = (exc_sp -> val_sp & 1 ); // restore previous state
380+ exc_sp -- ; // pop back to previous exception handler
364381 break ;
365382
366383 // matched against: SETUP_EXCEPT
@@ -371,8 +388,8 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
371388 assert (currently_in_except_block );
372389 //sp = (mp_obj_t*)(*exc_sp--);
373390 //exc_sp--; // discard ip
374- currently_in_except_block = (exc_sp [ 0 ] & 1 ); // restore previous state
375- exc_sp -= 2 ; // pop back to previous exception handler
391+ currently_in_except_block = (exc_sp -> val_sp & 1 ); // restore previous state
392+ exc_sp -- ; // pop back to previous exception handler
376393 //sp -= 3; // pop 3 exception values
377394 break ;
378395
@@ -550,17 +567,17 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
550567 // at the moment we are just raising the very last exception (the one that caused the nested exception)
551568
552569 // move up to previous exception handler
553- currently_in_except_block = (exc_sp [ 0 ] & 1 ); // restore previous state
554- exc_sp -= 2 ; // pop back to previous exception handler
570+ currently_in_except_block = (exc_sp -> val_sp & 1 ); // restore previous state
571+ exc_sp -- ; // pop back to previous exception handler
555572 }
556573
557574 if (exc_sp >= & exc_stack [0 ]) {
558575 // set flag to indicate that we are now handling an exception
559576 currently_in_except_block = 1 ;
560577
561578 // catch exception and pass to byte code
562- sp = (mp_obj_t * )(exc_sp [ 0 ] & (~((machine_uint_t )1 )));
563- ip = ( const byte * )( exc_sp [ -1 ]) ;
579+ sp = (mp_obj_t * )(exc_sp -> val_sp & (~((machine_uint_t )1 )));
580+ ip = exc_sp -> handler ;
564581 // push(traceback, exc-val, exc-type)
565582 PUSH (mp_const_none );
566583 PUSH (nlr .ret_val );
0 commit comments