10000 Add code in VM to handle nested exceptions correctly. · jpralves/micropython@8f9e2ee · GitHub
[go: up one dir, main page]

Skip to content

Commit 8f9e2ee

Browse files
committed
Add code in VM to handle nested exceptions correctly.
1 parent dd12d13 commit 8f9e2ee

File tree

2 files changed

+35
-24
lines changed

2 files changed

+35
-24
lines changed

py/showbc.c

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,9 @@ void mp_show_byte_code(const byte *ip, int len) {
135135
printf("STORE_SUBSCR");
136136
break;
137137

138-
/*
139138
case MP_BC_DUP_TOP:
140-
obj1 = *sp;
141-
PUSH(obj1);
139+
printf("DUP_TOP");
142140
break;
143-
*/
144141

145142
case MP_BC_DUP_TOP_TWO:
146143
printf("DUP_TOP_TWO");
@@ -195,22 +192,20 @@ void mp_show_byte_code(const byte *ip, int len) {
195192
ip += unum;
196193
}
197194
break;
195+
*/
198196

199197
case MP_BC_SETUP_EXCEPT:
200198
DECODE_ULABEL; // except labels are always forward
201-
*++exc_sp = (machine_uint_t)ip + unum;
202-
*++exc_sp = (machine_uint_t)sp;
199+
printf("SETUP_EXCEPT %lu", ip + unum - ip_start);
203200
break;
204201

205202
case MP_BC_END_FINALLY:
206-
// not implemented
207203
// if TOS is an exception, reraises the exception (3 values on TOS)
208204
// if TOS is an integer, does something else
209205
// if TOS is None, just pops it and continues
210206
// else error
211-
assert(0);
207+
printf("END_FINALLY");
212208
break;
213-
*/
214209

215210
case MP_BC_GET_ITER:
216211
printf("GET_ITER");
@@ -221,22 +216,17 @@ void mp_show_byte_code(const byte *ip, int len) {
221216
printf("FOR_ITER %lu", ip + unum - ip_start);
222217
break;
223218

224-
/*
225219
case MP_BC_POP_BLOCK:
226220
// pops block and restores the stack
227-
assert(0);
221+
printf("POP_BLOCK");
228222
break;
229223

230224
case MP_BC_POP_EXCEPT:
231-
// TODO need to work out how blocks work etc
232225
// pops block, checks it's an exception block, and restores the stack, saving the 3 exception values to local threadstate
233-
assert(exc_sp >= &exc_stack[0]);
234-
//sp = (mp_obj_t*)(*exc_sp--);
235-
//exc_sp--; // discard ip
236-
exc_sp -= 2;
237-
//sp += 3; // pop 3 exception values
226+
printf("POP_EXCEPT");
238227
break;
239228

229+
/*
240230
case MP_BC_UNARY_OP:
241231
unum = *ip++;
242232
*sp = rt_unary_op(unum, *sp);
@@ -270,12 +260,14 @@ void mp_show_byte_code(const byte *ip, int len) {
270260
rt_list_append(sp[unum], sp[0]);
271261
sp++;
272262
break;
263+
*/
273264

274265
case MP_BC_BUILD_MAP:
275266
DECODE_UINT;
276-
PUSH(rt_build_map(unum));
267+
printf("BUILD_MAP %lu", unum);
277268
break;
278269

270+
/*
279271
case MP_BC_STORE_MAP:
280272
sp += 2;
281273
rt_store_map(sp[0], sp[-2], sp[-1]);

py/vm.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **
6161
mp_obj_t fast0 = fastn[0], fast1 = fastn[1], fast2 = fastn[2];
6262
nlr_buf_t nlr;
6363

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
6666
machine_uint_t *volatile exc_sp = &exc_stack[-1]; // stack grows up, exc_sp points to top of stack
6767

6868
// 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 **
275275
case MP_BC_SETUP_EXCEPT:
276276
DECODE_ULABEL; // except labels are always forward
277277
*++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
279280
break;
280281

281282
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 **
313314
assert(exc_sp >= &exc_stack[0]);
314315
//sp = (mp_obj_t*)(*exc_sp--);
315316
//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
317319
//sp += 3; // pop 3 exception values
318320
break;
319321

@@ -466,16 +468,33 @@ bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **
466468
} else {
467469
// exception occurred
468470

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+
469484
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+
470488
// 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)));
472490
ip = (const byte*)(exc_sp[-1]);
473491
// push(traceback, exc-val, exc-type)
474492
PUSH(mp_const_none);
475493
PUSH(nlr.ret_val);
476494
PUSH(mp_const_none);
495+
477496
} else {
478-
// re-raise exception
497+
// re-raise exception to higher level
479498
// TODO what to do if this is a generator??
480499
nlr_jump(nlr.ret_val);
481500
}

0 commit comments

Comments
 (0)
0