summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-03-29 21:58:36 +0000
committerDamien George <damien.p.george@gmail.com>2014-03-29 21:58:36 +0000
commitd40d8f1e168c5bc3cf52f51d9592425574e7e6a9 (patch)
tree2b225dbf54f5704f22b29b3fc6b1d131cafbeb2d
parent64563e39b3b6456a50b3ad04a61809ebb7b61b4b (diff)
parenta0ad77ba08e7bae8c71592565be9469aeff268ef (diff)
downloadmicropython-d40d8f1e168c5bc3cf52f51d9592425574e7e6a9.tar.gz
micropython-d40d8f1e168c5bc3cf52f51d9592425574e7e6a9.zip
Merge branch 'master' of github.com:micropython/micropython
-rw-r--r--py/vm.c22
-rw-r--r--tests/basics/try-reraise.py9
2 files changed, 21 insertions, 10 deletions
diff --git a/py/vm.c b/py/vm.c
index f340f52190..84bd4172dc 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -45,7 +45,7 @@ typedef enum {
#define TOP() (*sp)
#define SET_TOP(val) *sp = (val)
-#define SETUP_BLOCK() \
+#define PUSH_EXC_BLOCK() \
DECODE_ULABEL; /* except labels are always forward */ \
++exc_sp; \
exc_sp->opcode = op; \
@@ -53,6 +53,10 @@ typedef enum {
exc_sp->val_sp = MP_TAGPTR_MAKE(sp, currently_in_except_block); \
currently_in_except_block = 0; /* in a try block now */
+#define POP_EXC_BLOCK() \
+ currently_in_except_block = MP_TAGPTR_TAG(exc_sp->val_sp); /* restore previous state */ \
+ exc_sp--; /* pop back to previous exception handler */
+
mp_vm_return_kind_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, const mp_obj_t *args2, uint n_args2, mp_obj_t *ret) {
const byte *ip = code;
@@ -386,7 +390,7 @@ dispatch_loop:
SET_TOP(rt_load_attr(obj1, MP_QSTR___exit__));
rt_load_method(obj1, MP_QSTR___enter__, sp + 1);
obj2 = rt_call_method_n_kw(0, 0, sp + 1);
- SETUP_BLOCK();
+ PUSH_EXC_BLOCK();
PUSH(obj2);
break;
@@ -478,7 +482,7 @@ unwind_jump:
// matched against: POP_BLOCK or POP_EXCEPT (anything else?)
case MP_BC_SETUP_EXCEPT:
case MP_BC_SETUP_FINALLY:
- SETUP_BLOCK();
+ PUSH_EXC_BLOCK();
break;
case MP_BC_END_FINALLY:
@@ -527,8 +531,7 @@ unwind_jump:
case MP_BC_POP_BLOCK:
// we are exiting an exception handler, so pop the last one of the exception-stack
assert(exc_sp >= exc_stack);
- currently_in_except_block = MP_TAGPTR_TAG(exc_sp->val_sp); // restore previous state
- exc_sp--; // pop back to previous exception handler
+ POP_EXC_BLOCK();
break;
// matched against: SETUP_EXCEPT
@@ -539,8 +542,7 @@ unwind_jump:
assert(currently_in_except_block);
//sp = (mp_obj_t*)(*exc_sp--);
//exc_sp--; // discard ip
- currently_in_except_block = MP_TAGPTR_TAG(exc_sp->val_sp); // restore previous state
- exc_sp--; // pop back to previous exception handler
+ POP_EXC_BLOCK();
//sp -= 3; // pop 3 exception values
break;
@@ -697,6 +699,9 @@ unwind_return:
unum = *ip++;
assert(unum <= 1);
if (unum == 0) {
+ if (!currently_in_except_block) {
+ nlr_jump(mp_obj_new_exception_msg(&mp_type_RuntimeError, "No active exception to reraise"));
+ }
// This assumes that nlr.ret_val holds last raised
// exception and is not overwritten since then.
obj1 = nlr.ret_val;
@@ -827,8 +832,7 @@ yield:
// 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 = MP_TAGPTR_TAG(exc_sp->val_sp); // restore previous state
- exc_sp--; // pop back to previous exception handler
+ POP_EXC_BLOCK();
}
if (exc_sp >= exc_stack) {
diff --git a/tests/basics/try-reraise.py b/tests/basics/try-reraise.py
index bc817fc386..bf5e77c0b0 100644
--- a/tests/basics/try-reraise.py
+++ b/tests/basics/try-reraise.py
@@ -1,4 +1,4 @@
-# Re-reraising last exception with raise w/o args
+# Reraising last exception with raise w/o args
def f():
try:
@@ -10,3 +10,10 @@ try:
f()
except ValueError as e:
print(repr(e))
+
+
+# Can reraise only in except block
+try:
+ raise
+except RuntimeError:
+ print("RuntimeError")