13
13
#include "bc0.h"
14
14
#include "bc.h"
15
15
16
+ // Exception stack entry
17
+ typedef struct _mp_exc_stack {
18
+ const byte * handler ;
19
+ // bit 0 is saved currently_in_except_block value
20
+ machine_uint_t val_sp ;
21
+ // We might only have 2 interesting cases here: SETUP_EXCEPT & SETUP_FINALLY,
22
+ // consider storing it in bit 1 of val_sp. TODO: SETUP_WITH?
23
+ byte opcode ;
24
+ } mp_exc_stack ;
25
+
16
26
// (value) stack grows down (to be compatible with native code when passing pointers to the stack), top element is pointed to
17
27
// exception stack grows up, top element is pointed to
18
28
@@ -83,8 +93,8 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
83
93
nlr_buf_t nlr ;
84
94
85
95
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
96
+ mp_exc_stack exc_stack [4 ];
97
+ mp_exc_stack * volatile exc_sp = & exc_stack [0 ] - 1 ; // stack grows up, exc_sp points to top of stack
88
98
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)
89
99
90
100
// outer exception handling loop
@@ -318,9 +328,12 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
318
328
319
329
// matched against: POP_BLOCK or POP_EXCEPT (anything else?)
320
330
case MP_BC_SETUP_EXCEPT :
331
+ case MP_BC_SETUP_FINALLY :
321
332
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 );
333
+ ++ exc_sp ;
334
+ exc_sp -> opcode = op ;
335
+ exc_sp -> handler = ip + unum ;
336
+ exc_sp -> val_sp = (((machine_uint_t )sp ) | currently_in_except_block );
324
337
currently_in_except_block = 0 ; // in a try block now
325
338
break ;
326
339
@@ -359,8 +372,8 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
359
372
case MP_BC_POP_BLOCK :
360
373
// we are exiting an exception handler, so pop the last one of the exception-stack
361
374
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
375
+ currently_in_except_block = (exc_sp -> val_sp & 1 ); // restore previous state
376
+ exc_sp -- ; // pop back to previous exception handler
364
377
break ;
365
378
366
379
// matched against: SETUP_EXCEPT
@@ -371,8 +384,8 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
371
384
assert (currently_in_except_block );
372
385
//sp = (mp_obj_t*)(*exc_sp--);
373
386
//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
387
+ currently_in_except_block = (exc_sp -> val_sp & 1 ); // restore previous state
388
+ exc_sp -- ; // pop back to previous exception handler
376
389
//sp -= 3; // pop 3 exception values
377
390
break ;
378
391
@@ -550,17 +563,17 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
550
563
// at the moment we are just raising the very last exception (the one that caused the nested exception)
551
564
552
565
// 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
566
+ currently_in_except_block = (exc_sp -> val_sp & 1 ); // restore previous state
567
+ exc_sp -- ; // pop back to previous exception handler
555
568
}
556
569
557
570
if (exc_sp >= & exc_stack [0 ]) {
558
571
// set flag to indicate that we are now handling an exception
559
572
currently_in_except_block = 1 ;
560
573
561
574
// 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 ]) ;
575
+ sp = (mp_obj_t * )(exc_sp -> val_sp & (~((machine_uint_t )1 )));
576
+ ip = exc_sp -> handler ;
564
577
// push(traceback, exc-val, exc-type)
565
578
PUSH (mp_const_none );
566
579
PUSH (nlr .ret_val );
0 commit comments