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
382b3d00
Commit
382b3d00
authored
Feb 01, 2014
by
Damien George
Browse files
Merge pull request #251 from pfalcon/return_unwind
Add exception stack unwind support for RETURN_VALUE.
parents
d71cd86d
6472dea1
Changes
2
Hide whitespace changes
Inline
Side-by-side
py/vm.c
View file @
382b3d00
...
...
@@ -30,6 +30,13 @@ typedef struct _mp_exc_stack {
byte
opcode
;
}
mp_exc_stack
;
// Exception stack unwind reasons (WHY_* in CPython-speak)
typedef
enum
{
UNWIND_RETURN
=
1
,
UNWIND_BREAK
,
UNWIND_CONTINUE
,
}
mp_unwind_reason_t
;
#define DECODE_UINT do { unum = *ip++; if (unum > 127) { unum = ((unum & 0x3f) << 8) | (*ip++); } } while (0)
#define DECODE_ULABEL do { unum = (ip[0] | (ip[1] << 8)); ip += 2; } while (0)
#define DECODE_SLABEL do { unum = (ip[0] | (ip[1] << 8)) - 0x8000; ip += 2; } while (0)
...
...
@@ -106,6 +113,7 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
if
(
nlr_push
(
&
nlr
)
==
0
)
{
// loop to execute byte code
for
(;;)
{
dispatch_loop:
save_ip
=
ip
;
int
op
=
*
ip
++
;
switch
(
op
)
{
...
...
@@ -352,6 +360,19 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
}
if
(
TOP
()
==
mp_const_none
)
{
sp
--
;
}
else
if
(
MP_OBJ_IS_SMALL_INT
(
TOP
()))
{
// We finished "finally" coroutine and now dispatch back
// to our caller, based on TOS value
mp_unwind_reason_t
reason
=
MP_OBJ_SMALL_INT_VALUE
(
POP
());
switch
(
reason
)
{
case
UNWIND_RETURN
:
goto
unwind_return
;
// TODO
case
UNWIND_BREAK
:
case
UNWIND_CONTINUE
:
;
}
assert
(
0
);
}
else
{
assert
(
0
);
}
...
...
@@ -501,6 +522,23 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
break
;
case
MP_BC_RETURN_VALUE
:
unwind_return:
while
(
exc_sp
>=
exc_stack
)
{
if
(
exc_sp
->
opcode
==
MP_BC_SETUP_FINALLY
)
{
// We're going to run "finally" code as a coroutine
// (not calling it recursively). Set up a sentinel
// on a stack so it can return back to us when it is
// done (when END_FINALLY reached).
PUSH
(
MP_OBJ_NEW_SMALL_INT
(
UNWIND_RETURN
));
ip
=
exc_sp
->
handler
;
// We don't need to do anything with sp, finally is just
// syntactic sugar for sequential execution??
// sp =
exc_sp
--
;
goto
dispatch_loop
;
}
exc_sp
--
;
}
nlr_pop
();
*
sp_in_out
=
sp
;
assert
(
exc_sp
==
&
exc_stack
[
0
]
-
1
);
...
...
tests/basics/try-finally-return.py
0 → 100644
View file @
382b3d00
def
func1
():
try
:
return
"it worked"
finally
:
print
(
"finally 1"
)
print
(
func1
())
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