1717
1818// args are in reverse order in array
1919py_obj_t py_execute_byte_code (const byte * code , uint len , const py_obj_t * args , uint n_args ) {
20+ // careful: be sure to declare volatile any variables read in the exception handler (written is ok, I think)
21+
2022 const byte * ip = code ;
2123 py_obj_t stack [10 ];
2224 py_obj_t * sp = & stack [10 ]; // stack grows down, sp points to top of stack
@@ -27,6 +29,10 @@ py_obj_t py_execute_byte_code(const byte *code, uint len, const py_obj_t *args,
2729 py_obj_t fast0 = NULL , fast1 = NULL , fast2 = NULL , fastn [4 ] = {NULL , NULL , NULL , NULL };
2830 nlr_buf_t nlr ;
2931
32+ // on the exception stack we store (ip, sp) for each block
33+ machine_uint_t exc_stack [8 ];
34+ machine_uint_t * volatile exc_sp = & exc_stack [-1 ]; // stack grows up, exc_sp points to top of stack
35+
3036 // init args
3137 for (int i = 0 ; i < n_args ; i ++ ) {
3238 if (i == 0 ) {
@@ -203,8 +209,9 @@ py_obj_t py_execute_byte_code(const byte *code, uint len, const py_obj_t *args,
203209 */
204210
205211 case PYBC_SETUP_EXCEPT :
206- // push_block(PYBC_SETUP_EXCEPT, code + unum, sp)
207- assert (0 );
212+ DECODE_UINT ;
213+ * ++ exc_sp = (machine_uint_t )code + unum ;
214+ * ++ exc_sp = (machine_uint_t )sp ;
208215 break ;
209216
210217 case PYBC_END_FINALLY :
@@ -237,8 +244,14 @@ py_obj_t py_execute_byte_code(const byte *code, uint len, const py_obj_t *args,
237244 break ;
238245
239246 case PYBC_POP_EXCEPT :
247+ // TODO need to work out how blocks work etc
240248 // pops block, checks it's an exception block, and restores the stack, saving the 3 exception values to local threadstate
241- assert (0 );
249+ assert (exc_sp >= & exc_stack [0 ]);
250+ //sp = (py_obj_t*)(*exc_sp--);
251+ //exc_sp--; // discard ip
252+ exc_sp -= 2 ;
253+ //sp += 3; // pop 3 exception values
254+ assert (sp <= & stack [10 ]);
242255 break ;
243256
244257 case PYBC_BINARY_OP :
@@ -303,6 +316,8 @@ py_obj_t py_execute_byte_code(const byte *code, uint len, const py_obj_t *args,
303316
304317 case PYBC_RETURN_VALUE :
305318 nlr_pop ();
319+ assert (sp == & stack [9 ]);
320+ assert (exc_sp == & exc_stack [-1 ]);
306321 return * sp ;
307322
308323 default :
@@ -316,11 +331,14 @@ py_obj_t py_execute_byte_code(const byte *code, uint len, const py_obj_t *args,
316331 } else {
317332 // exception occurred
318333
319- if (0 ) {
334+ if (exc_sp >= & exc_stack [ 0 ] ) {
320335 // catch exception and pass to byte code
321- //ip = pop
322- //sp = pop
323- //push(traceback, exc-val, exc-type)
336+ sp = (py_obj_t * )(exc_sp [0 ]);
337+ ip = (const byte * )(exc_sp [-1 ]);
338+ // push(traceback, exc-val, exc-type)
339+ PUSH (py_const_none );
340+ PUSH (nlr .ret_val );
341+ PUSH (py_const_none );
324342 } else {
325343 // re-raise exception
326344 nlr_jump (nlr .ret_val );
0 commit comments