summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-03-30 00:09:35 +0000
committerDamien George <damien.p.george@gmail.com>2014-03-30 00:09:35 +0000
commitf8ff700de8af43413a59cad2a0c197678a05fdd5 (patch)
tree5f29a55fb7a10f7c6ab39b325145212f842b72ca
parentd54b8a4789bb8ec8b9be0b8d62486cc7de11540c (diff)
parent0c904df8e6c4cf9123a837861b97585a61b3d8df (diff)
downloadmicropython-f8ff700de8af43413a59cad2a0c197678a05fdd5.tar.gz
micropython-f8ff700de8af43413a59cad2a0c197678a05fdd5.zip
Merge pull request #390 from pfalcon/reraise-recursive
vm: Save current active exception on opening new try block.
-rw-r--r--py/bc.h2
-rw-r--r--py/vm.c2
-rw-r--r--tests/basics/try-reraise2.py23
3 files changed, 27 insertions, 0 deletions
diff --git a/py/bc.h b/py/bc.h
index 065daece47..d7e6aa70eb 100644
--- a/py/bc.h
+++ b/py/bc.h
@@ -9,6 +9,8 @@ typedef struct _mp_exc_stack {
const byte *handler;
// bit 0 is saved currently_in_except_block value
mp_obj_t *val_sp;
+ // Saved exception, valid if currently_in_except_block bit is 1
+ mp_obj_t prev_exc;
// We might only have 2 interesting cases here: SETUP_EXCEPT & SETUP_FINALLY,
// consider storing it in bit 1 of val_sp. TODO: SETUP_WITH?
byte opcode;
diff --git a/py/vm.c b/py/vm.c
index 7316742665..b96cca1425 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -51,10 +51,12 @@ typedef enum {
exc_sp->opcode = op; \
exc_sp->handler = ip + unum; \
exc_sp->val_sp = MP_TAGPTR_MAKE(sp, currently_in_except_block); \
+ exc_sp->prev_exc = nlr.ret_val; \
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 */ \
+ if (currently_in_except_block) { nlr.ret_val = exc_sp->prev_exc; } \
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) {
diff --git a/tests/basics/try-reraise2.py b/tests/basics/try-reraise2.py
new file mode 100644
index 0000000000..9ab8d9c099
--- /dev/null
+++ b/tests/basics/try-reraise2.py
@@ -0,0 +1,23 @@
+# Reraise not the latest occured exception
+def f():
+ try:
+ raise ValueError("val", 3)
+ except:
+ try:
+ raise TypeError
+ except:
+ try:
+ try:
+ raise AttributeError
+ except:
+ pass
+ raise
+ except TypeError:
+ pass
+ # This should raise original ValueError, not the most recently occurred AttributeError
+ raise
+
+try:
+ f()
+except ValueError as e:
+ print(repr(e))