forked from M-Labs/artiq
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))
|
handlers.append((handler, post_handler))
|
||||||
|
|
||||||
if any(node.finalbody):
|
if any(node.finalbody):
|
||||||
|
# Finalize and continue after try statement.
|
||||||
self.final_branch = old_final_branch
|
self.final_branch = old_final_branch
|
||||||
|
|
||||||
finalizer = self.add_block("finally")
|
finalizer = self.add_block("finally")
|
||||||
@ -698,13 +699,17 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||||||
self.visit(node.finalbody)
|
self.visit(node.finalbody)
|
||||||
post_finalizer = self.current_block
|
post_finalizer = self.current_block
|
||||||
|
|
||||||
reraise = self.add_block('try.reraise')
|
# Finalize and reraise. Separate from previous case to expose flow
|
||||||
reraise.append(ir.Reraise(self.unwind_target))
|
# 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")
|
self.current_block = tail = self.add_block("try.tail")
|
||||||
if any(node.finalbody):
|
if any(node.finalbody):
|
||||||
final_targets.append(tail)
|
final_targets.append(tail)
|
||||||
final_targets.append(reraise)
|
|
||||||
|
|
||||||
for block in final_paths:
|
for block in final_paths:
|
||||||
block.append(ir.Branch(finalizer))
|
block.append(ir.Branch(finalizer))
|
||||||
@ -713,8 +718,7 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
|||||||
body.append(ir.SetLocal(final_state, "$cont", tail))
|
body.append(ir.SetLocal(final_state, "$cont", tail))
|
||||||
body.append(ir.Branch(finalizer))
|
body.append(ir.Branch(finalizer))
|
||||||
|
|
||||||
cleanup.append(ir.SetLocal(final_state, "$cont", reraise))
|
cleanup.append(ir.Branch(finalizer_reraise))
|
||||||
cleanup.append(ir.Branch(finalizer))
|
|
||||||
|
|
||||||
for handler, post_handler in handlers:
|
for handler, post_handler in handlers:
|
||||||
if not post_handler.is_terminated():
|
if not post_handler.is_terminated():
|
||||||
|
22
artiq/test/lit/exceptions/finally_reraise.py
Normal file
22
artiq/test/lit/exceptions/finally_reraise.py
Normal file
@ -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
Block a user