Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
8f9e2ee1
Commit
8f9e2ee1
authored
Dec 29, 2013
by
Damien
Browse files
Add code in VM to handle nested exceptions correctly.
parent
dd12d137
Changes
2
Hide whitespace changes
Inline
Side-by-side
py/showbc.c
View file @
8f9e2ee1
...
...
@@ -135,12 +135,9 @@ void mp_show_byte_code(const byte *ip, int len) {
printf
(
"STORE_SUBSCR"
);
break
;
/*
case
MP_BC_DUP_TOP
:
obj1 = *sp;
PUSH(obj1);
printf
(
"DUP_TOP"
);
break
;
*/
case
MP_BC_DUP_TOP_TWO
:
printf
(
"DUP_TOP_TWO"
);
...
...
@@ -195,22 +192,20 @@ void mp_show_byte_code(const byte *ip, int len) {
ip += unum;
}
break;
*/
case
MP_BC_SETUP_EXCEPT
:
DECODE_ULABEL
;
// except labels are always forward
*++exc_sp = (machine_uint_t)ip + unum;
*++exc_sp = (machine_uint_t)sp;
printf
(
"SETUP_EXCEPT %lu"
,
ip
+
unum
-
ip_start
);
break
;
case
MP_BC_END_FINALLY
:
// not implemented
// 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
// else error
assert(0
);
printf
(
"END_FINALLY"
);
break
;
*/
case
MP_BC_GET_ITER
:
printf
(
"GET_ITER"
);
...
...
@@ -221,22 +216,17 @@ void mp_show_byte_code(const byte *ip, int len) {
printf
(
"FOR_ITER %lu"
,
ip
+
unum
-
ip_start
);
break
;
/*
case
MP_BC_POP_BLOCK
:
// pops block and restores the stack
assert(0
);
printf
(
"POP_BLOCK"
);
break
;
case
MP_BC_POP_EXCEPT
:
// 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
assert(exc_sp >= &exc_stack[0]);
//sp = (mp_obj_t*)(*exc_sp--);
//exc_sp--; // discard ip
exc_sp -= 2;
//sp += 3; // pop 3 exception values
printf
(
"POP_EXCEPT"
);
break
;
/*
case MP_BC_UNARY_OP:
unum = *ip++;
*sp = rt_unary_op(unum, *sp);
...
...
@@ -270,12 +260,14 @@ void mp_show_byte_code(const byte *ip, int len) {
rt_list_append(sp[unum], sp[0]);
sp++;
break;
*/
case
MP_BC_BUILD_MAP
:
DECODE_UINT
;
PUSH(rt_build_map(
unum)
)
;
printf
(
"BUILD_MAP %lu"
,
unum
);
break
;
/*
case MP_BC_STORE_MAP:
sp += 2;
rt_store_map(sp[0], sp[-2], sp[-1]);
...
...
py/vm.c
View file @
8f9e2ee1
...
...
@@ -61,8 +61,8 @@ bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **
mp_obj_t
fast0
=
fastn
[
0
],
fast1
=
fastn
[
1
],
fast2
=
fastn
[
2
];
nlr_buf_t
nlr
;
// on the exception stack we store (ip, sp) for each block
machine_uint_t
exc_stack
[
8
];
volatile
machine_uint_t
currently_in_except_block
=
0
;
// 0 or 1, to detect nested exceptions
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
machine_uint_t
*
volatile
exc_sp
=
&
exc_stack
[
-
1
];
// stack grows up, exc_sp points to top of stack
// 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 **
case
MP_BC_SETUP_EXCEPT
:
DECODE_ULABEL
;
// except labels are always forward
*++
exc_sp
=
(
machine_uint_t
)
ip
+
unum
;
*++
exc_sp
=
(
machine_uint_t
)
sp
;
*++
exc_sp
=
(((
machine_uint_t
)
sp
)
|
currently_in_except_block
);
currently_in_except_block
=
0
;
// in a try block now
break
;
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 **
assert
(
exc_sp
>=
&
exc_stack
[
0
]);
//sp = (mp_obj_t*)(*exc_sp--);
//exc_sp--; // discard ip
exc_sp
-=
2
;
currently_in_except_block
=
(
exc_sp
[
0
]
&
1
);
// restore previous state
exc_sp
-=
2
;
// pop back to previous exception handler
//sp += 3; // pop 3 exception values
break
;
...
...
@@ -466,16 +468,33 @@ bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **
}
else
{
// exception occurred
while
(
currently_in_except_block
)
{
// nested exception
assert
(
exc_sp
>=
&
exc_stack
[
0
]);
// TODO make a proper message for nested exception
// at the moment we are just raising the very last exception (the one that caused the nested exception)
// move up to previous exception handler
currently_in_except_block
=
(
exc_sp
[
0
]
&
1
);
// restore previous state
exc_sp
-=
2
;
// pop back to previous exception handler
}
if
(
exc_sp
>=
&
exc_stack
[
0
])
{
// set flag to indicate that we are now handling an exception
currently_in_except_block
=
1
;
// catch exception and pass to byte code
sp
=
(
mp_obj_t
*
)(
exc_sp
[
0
]);
sp
=
(
mp_obj_t
*
)(
exc_sp
[
0
]
&
(
~
((
machine_uint_t
)
1
))
);
ip
=
(
const
byte
*
)(
exc_sp
[
-
1
]);
// push(traceback, exc-val, exc-type)
PUSH
(
mp_const_none
);
PUSH
(
nlr
.
ret_val
);
PUSH
(
mp_const_none
);
}
else
{
// re-raise exception
// re-raise exception
to higher level
// TODO what to do if this is a generator??
nlr_jump
(
nlr
.
ret_val
);
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment