mirror of https://github.com/m-labs/artiq.git
transforms.artiq_ir_generator: split out finally→reraise control flow.
This makes it accessible to introspect by local access validator, making some previously rejected code valid. Fixes #331.
This commit is contained in:
parent
f2ae24da39
commit
77d47c2fdd
|
@ -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():
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue