@@ -61,8 +61,8 @@ bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **
61
61
mp_obj_t fast0 = fastn [0 ], fast1 = fastn [1 ], fast2 = fastn [2 ];
62
62
nlr_buf_t nlr ;
63
63
64
- // on the exception stack we store (ip, sp) for each block
65
- machine_uint_t exc_stack [8 ];
64
+ volatile machine_uint_t currently_in_except_block = 0 ; // 0 or 1, to detect nested exceptions
65
+ 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
66
66
machine_uint_t * volatile exc_sp = & exc_stack [-1 ]; // stack grows up, exc_sp points to top of stack
67
67
68
68
// outer exception handling loop
@@ -275,7 +275,8 @@ bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **
275
275
case MP_BC_SETUP_EXCEPT :
276
276
DECODE_ULABEL ; // except labels are always forward
277
277
* ++ exc_sp = (machine_uint_t )ip + unum ;
278
- * ++ exc_sp = (machine_uint_t )sp ;
278
+ * ++ exc_sp = (((machine_uint_t )sp ) | currently_in_except_block );
279
+ currently_in_except_block = 0 ; // in a try block now
279
280
break ;
280
281
281
282
case MP_BC_END_FINALLY :
@@ -313,7 +314,8 @@ bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **
313
314
assert (exc_sp >= & exc_stack [0 ]);
314
315
//sp = (mp_obj_t*)(*exc_sp--);
315
316
//exc_sp--; // discard ip
316
- exc_sp -= 2 ;
317
+ currently_in_except_block = (exc_sp [0 ] & 1 ); // restore previous state
318
+ exc_sp -= 2 ; // pop back to previous exception handler
317
319
//sp += 3; // pop 3 exception values
318
320
break ;
319
321
@@ -466,16 +468,33 @@ bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **
466
468
} else {
467
469
// exception occurred
468
470
471
+ while (currently_in_except_block ) {
472
+ // nested exception
473
+
474
+ assert (exc_sp >= & exc_stack [0 ]);
475
+
476
+ // TODO make a proper message for nested exception
477
+ // at the moment we are just raising the very last exception (the one that caused the nested exception)
478
+
479
+ // move up to previous exception handler
480
+ currently_in_except_block = (exc_sp [0 ] & 1 ); // restore previous state
481
+ exc_sp -= 2 ; // pop back to previous exception handler
482
+ }
483
+
469
484
if (exc_sp >= & exc_stack [0 ]) {
485
+ // set flag to indicate that we are now handling an exception
486
+ currently_in_except_block = 1 ;
487
+
470
488
// catch exception and pass to byte code
471
- sp = (mp_obj_t * )(exc_sp [0 ]);
489
+ sp = (mp_obj_t * )(exc_sp [0 ] & (~(( machine_uint_t ) 1 )) );
472
490
ip = (const byte * )(exc_sp [-1 ]);
473
491
// push(traceback, exc-val, exc-type)
474
492
PUSH (mp_const_none );
475
493
PUSH (nlr .ret_val );
476
494
PUSH (mp_const_none );
495
+
477
496
} else {
478
- // re-raise exception
497
+ // re-raise exception to higher level
479
498
// TODO what to do if this is a generator??
480
499
nlr_jump (nlr .ret_val );
481
500
}
0 commit comments