From 5270da39344cddcf5ace17b3e8c6c5646e4bc435 Mon Sep 17 00:00:00 2001 From: Aviv Palivoda Date: Sat, 4 May 2019 12:25:17 +0300 Subject: [PATCH 1/4] Add ExceptHandler block --- tests/snippets/try_exceptions.py | 13 +++++++++++++ vm/src/frame.rs | 16 ++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/tests/snippets/try_exceptions.py b/tests/snippets/try_exceptions.py index c6a148e78..5c90a502e 100644 --- a/tests/snippets/try_exceptions.py +++ b/tests/snippets/try_exceptions.py @@ -193,3 +193,16 @@ for _ in [1, 2]: raise ArithmeticError() except ArithmeticError as e: continue + + +def g(): + try: + 1/0 + except ArithmeticError: + return 5 + +try: + g() + raise NameError +except NameError as ex: + assert ex.__context__ == None diff --git a/vm/src/frame.rs b/vm/src/frame.rs index a9e155969..23c9b8e2b 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -203,6 +203,7 @@ enum BlockType { end: bytecode::Label, context_manager: PyObjectRef, }, + ExceptHandler {}, } pub type FrameRef = PyRef; @@ -862,6 +863,12 @@ impl Frame { } bytecode::Instruction::PopException {} => { assert!(vm.pop_exception().is_some()); + let block = self.pop_block(); + assert!(block.is_some()); + match block.unwrap().typ { + BlockType::ExceptHandler {} => (), + _ => assert!(false), + }; Ok(None) } } @@ -937,6 +944,9 @@ impl Frame { } } } + BlockType::ExceptHandler { .. } => { + vm.pop_exception(); + } } } @@ -959,6 +969,9 @@ impl Frame { panic!("Exception in with __exit__ {:?}", exc); } }, + BlockType::ExceptHandler { .. } => { + vm.pop_exception(); + } } self.pop_block(); @@ -970,6 +983,7 @@ impl Frame { while let Some(block) = self.pop_block() { match block.typ { BlockType::TryExcept { handler } => { + self.push_block(BlockType::ExceptHandler {}); self.push_value(exc.clone()); vm.push_exception(exc); self.jump(handler); @@ -1004,6 +1018,8 @@ impl Frame { } } BlockType::Loop { .. } => {} + // Exception was already poped on Raised. + BlockType::ExceptHandler { .. } => {} } } Some(exc) From d803acfdc5e3493471c18e95bb503e52d8541421 Mon Sep 17 00:00:00 2001 From: Aviv Palivoda Date: Sat, 4 May 2019 12:28:19 +0300 Subject: [PATCH 2/4] Add yield in except test --- tests/snippets/try_exceptions.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/snippets/try_exceptions.py b/tests/snippets/try_exceptions.py index 5c90a502e..f37101b61 100644 --- a/tests/snippets/try_exceptions.py +++ b/tests/snippets/try_exceptions.py @@ -206,3 +206,17 @@ try: raise NameError except NameError as ex: assert ex.__context__ == None + + +def y(): + try: + 1/0 + except ArithmeticError: + yield 5 + + +try: + y() + raise NameError +except NameError as ex: + assert ex.__context__ == None From 32714f889e968a49afdcf29b556a1bf7db5c0493 Mon Sep 17 00:00:00 2001 From: Aviv Palivoda Date: Sat, 4 May 2019 17:18:04 +0300 Subject: [PATCH 3/4] Remove empty params from ExceptHandler --- vm/src/frame.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vm/src/frame.rs b/vm/src/frame.rs index 23c9b8e2b..c22ad8897 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -203,7 +203,7 @@ enum BlockType { end: bytecode::Label, context_manager: PyObjectRef, }, - ExceptHandler {}, + ExceptHandler, } pub type FrameRef = PyRef; @@ -866,7 +866,7 @@ impl Frame { let block = self.pop_block(); assert!(block.is_some()); match block.unwrap().typ { - BlockType::ExceptHandler {} => (), + BlockType::ExceptHandler => (), _ => assert!(false), }; Ok(None) @@ -944,7 +944,7 @@ impl Frame { } } } - BlockType::ExceptHandler { .. } => { + BlockType::ExceptHandler => { vm.pop_exception(); } } @@ -969,7 +969,7 @@ impl Frame { panic!("Exception in with __exit__ {:?}", exc); } }, - BlockType::ExceptHandler { .. } => { + BlockType::ExceptHandler => { vm.pop_exception(); } } @@ -1019,7 +1019,7 @@ impl Frame { } BlockType::Loop { .. } => {} // Exception was already poped on Raised. - BlockType::ExceptHandler { .. } => {} + BlockType::ExceptHandler => {} } } Some(exc) From 810b8ee4d0d8a1fa4be05f1fc92b04c717c16235 Mon Sep 17 00:00:00 2001 From: Aviv Palivoda Date: Sat, 4 May 2019 17:19:59 +0300 Subject: [PATCH 4/4] Simplify PopException --- vm/src/frame.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/vm/src/frame.rs b/vm/src/frame.rs index c22ad8897..ddddad91e 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -862,14 +862,13 @@ impl Frame { Ok(None) } bytecode::Instruction::PopException {} => { - assert!(vm.pop_exception().is_some()); - let block = self.pop_block(); - assert!(block.is_some()); - match block.unwrap().typ { - BlockType::ExceptHandler => (), - _ => assert!(false), - }; - Ok(None) + let block = self.pop_block().unwrap(); // this asserts that the block is_some. + if let BlockType::ExceptHandler = block.typ { + assert!(vm.pop_exception().is_some()); + Ok(None) + } else { + panic!("Block type must be ExceptHandler here.") + } } } }