vm: Add basic implementation of END_FINALLY opcode.
Allows to have nested try blocks with except filters. TODO: Don't add END_FINALLY's exception re-raise points to traceback.
This commit is contained in:
parent
09a0c64bce
commit
382e8eeea2
14
py/vm.c
14
py/vm.c
|
@ -325,12 +325,19 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_BC_END_FINALLY:
|
case MP_BC_END_FINALLY:
|
||||||
// not implemented
|
// not fully implemented
|
||||||
// if TOS is an exception, reraises the exception (3 values on TOS)
|
// if TOS is an exception, reraises the exception (3 values on TOS)
|
||||||
// if TOS is an integer, does something else
|
|
||||||
// if TOS is None, just pops it and continues
|
// if TOS is None, just pops it and continues
|
||||||
|
// if TOS is an integer, does something else
|
||||||
// else error
|
// else error
|
||||||
|
if (MP_OBJ_IS_TYPE(TOP(), &exception_type)) {
|
||||||
|
nlr_jump(TOP());
|
||||||
|
}
|
||||||
|
if (TOP() == mp_const_none) {
|
||||||
|
sp--;
|
||||||
|
} else {
|
||||||
assert(0);
|
assert(0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_BC_GET_ITER:
|
case MP_BC_GET_ITER:
|
||||||
|
@ -361,6 +368,7 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
|
||||||
// TODO need to work out how blocks work etc
|
// TODO need to work out how blocks work etc
|
||||||
// pops block, checks it's an exception block, and restores the stack, saving the 3 exception values to local threadstate
|
// pops block, checks it's an exception block, and restores the stack, saving the 3 exception values to local threadstate
|
||||||
assert(exc_sp >= &exc_stack[0]);
|
assert(exc_sp >= &exc_stack[0]);
|
||||||
|
assert(currently_in_except_block);
|
||||||
//sp = (mp_obj_t*)(*exc_sp--);
|
//sp = (mp_obj_t*)(*exc_sp--);
|
||||||
//exc_sp--; // discard ip
|
//exc_sp--; // discard ip
|
||||||
currently_in_except_block = (exc_sp[0] & 1); // restore previous state
|
currently_in_except_block = (exc_sp[0] & 1); // restore previous state
|
||||||
|
@ -517,6 +525,8 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
|
||||||
// exception occurred
|
// exception occurred
|
||||||
|
|
||||||
// set file and line number that the exception occurred at
|
// set file and line number that the exception occurred at
|
||||||
|
// TODO: don't set traceback for exceptions re-raised by END_FINALLY.
|
||||||
|
// But consider how to handle nested exceptions.
|
||||||
if (MP_OBJ_IS_TYPE(nlr.ret_val, &exception_type)) {
|
if (MP_OBJ_IS_TYPE(nlr.ret_val, &exception_type)) {
|
||||||
machine_uint_t code_info_size = code_info[0] | (code_info[1] << 8) | (code_info[2] << 16) | (code_info[3] << 24);
|
machine_uint_t code_info_size = code_info[0] | (code_info[1] << 8) | (code_info[2] << 16) | (code_info[3] << 24);
|
||||||
qstr source_file = code_info[4] | (code_info[5] << 8) | (code_info[6] << 16) | (code_info[7] << 24);
|
qstr source_file = code_info[4] | (code_info[5] << 8) | (code_info[6] << 16) | (code_info[7] << 24);
|
||||||
|
|
|
@ -10,3 +10,14 @@ try:
|
||||||
bar()
|
bar()
|
||||||
except:
|
except:
|
||||||
print("except 1")
|
print("except 1")
|
||||||
|
|
||||||
|
try:
|
||||||
|
print("try 1")
|
||||||
|
try:
|
||||||
|
print("try 2")
|
||||||
|
foo()
|
||||||
|
except TypeError:
|
||||||
|
print("except 2")
|
||||||
|
bar()
|
||||||
|
except NameError:
|
||||||
|
print("except 1")
|
||||||
|
|
Loading…
Reference in New Issue