From 77d47c2fdd7ab348407795dc24dd05aabc615ec9 Mon Sep 17 00:00:00 2001 From: whitequark Date: Wed, 22 Jun 2016 00:56:39 +0000 Subject: [PATCH] =?UTF-8?q?transforms.artiq=5Fir=5Fgenerator:=20split=20ou?= =?UTF-8?q?t=20finally=E2=86=92reraise=20control=20flow.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes it accessible to introspect by local access validator, making some previously rejected code valid. Fixes #331. --- .../compiler/transforms/artiq_ir_generator.py | 14 +++++++----- artiq/test/lit/exceptions/finally_reraise.py | 22 +++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 artiq/test/lit/exceptions/finally_reraise.py diff --git a/artiq/compiler/transforms/artiq_ir_generator.py b/artiq/compiler/transforms/artiq_ir_generator.py index 9d432acd6..35aa25616 100644 --- a/artiq/compiler/transforms/artiq_ir_generator.py +++ b/artiq/compiler/transforms/artiq_ir_generator.py @@ -690,6 +690,7 @@ class ARTIQIRGenerator(algorithm.Visitor): handlers.append((handler, post_handler)) if any(node.finalbody): + # Finalize and continue after try statement. self.final_branch = old_final_branch finalizer = self.add_block("finally") @@ -698,13 +699,17 @@ class ARTIQIRGenerator(algorithm.Visitor): self.visit(node.finalbody) post_finalizer = self.current_block - reraise = self.add_block('try.reraise') - reraise.append(ir.Reraise(self.unwind_target)) + # Finalize and reraise. Separate from previous case to expose flow + # to LocalAccessValidator. + finalizer_reraise = self.add_block("finally.reraise") + self.current_block = finalizer_reraise + + self.visit(node.finalbody) + self.terminate(ir.Reraise(self.unwind_target)) self.current_block = tail = self.add_block("try.tail") if any(node.finalbody): final_targets.append(tail) - final_targets.append(reraise) for block in final_paths: block.append(ir.Branch(finalizer)) @@ -713,8 +718,7 @@ class ARTIQIRGenerator(algorithm.Visitor): body.append(ir.SetLocal(final_state, "$cont", tail)) body.append(ir.Branch(finalizer)) - cleanup.append(ir.SetLocal(final_state, "$cont", reraise)) - cleanup.append(ir.Branch(finalizer)) + cleanup.append(ir.Branch(finalizer_reraise)) for handler, post_handler in handlers: if not post_handler.is_terminated(): diff --git a/artiq/test/lit/exceptions/finally_reraise.py b/artiq/test/lit/exceptions/finally_reraise.py new file mode 100644 index 000000000..ef4da2af9 --- /dev/null +++ b/artiq/test/lit/exceptions/finally_reraise.py @@ -0,0 +1,22 @@ +# RUN: %python -m artiq.compiler.testbench.jit %s >%t +# RUN: OutputCheck %s --file-to-check=%t +# REQUIRES: exceptions + +x = 1 + +def doit(): + try: + if x > 0: + raise ZeroDivisionError + r = 0 + finally: + print('final') + return r + +try: + doit() +except ZeroDivisionError: + print('caught') + +# CHECK-L: final +# CHECK-L: caught