forked from M-Labs/artiq
Add tests for exceptional control flow.
This commit is contained in:
parent
90be44c596
commit
a83e7e2248
|
@ -546,13 +546,13 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
||||||
has_catchall = True
|
has_catchall = True
|
||||||
|
|
||||||
self.current_block = handler
|
self.current_block = handler
|
||||||
handlers.append(handler)
|
|
||||||
|
|
||||||
if handler_node.name is not None:
|
if handler_node.name is not None:
|
||||||
exn = self.append(ir.Builtin("exncast", [landingpad], handler_node.name_type))
|
exn = self.append(ir.Builtin("exncast", [landingpad], handler_node.name_type))
|
||||||
self._set_local(handler_node.name, exn)
|
self._set_local(handler_node.name, exn)
|
||||||
|
|
||||||
self.visit(handler_node.body)
|
self.visit(handler_node.body)
|
||||||
|
post_handler = self.current_block
|
||||||
|
|
||||||
|
handlers.append((handler, post_handler))
|
||||||
|
|
||||||
if any(node.finalbody):
|
if any(node.finalbody):
|
||||||
finalizer = self.add_block("finally")
|
finalizer = self.add_block("finally")
|
||||||
|
@ -580,12 +580,12 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
||||||
# to execute.
|
# to execute.
|
||||||
handler = self.add_block("handler.catchall")
|
handler = self.add_block("handler.catchall")
|
||||||
landingpad.add_clause(handler, None)
|
landingpad.add_clause(handler, None)
|
||||||
handlers.append(handler)
|
handlers.append((handler, handler))
|
||||||
|
|
||||||
for handler in handlers:
|
for handler, post_handler in handlers:
|
||||||
if not handler.is_terminated():
|
if not post_handler.is_terminated():
|
||||||
handler.append(ir.SetLocal(final_state, ".k", tail))
|
post_handler.append(ir.SetLocal(final_state, ".k", tail))
|
||||||
handler.append(ir.Branch(tail))
|
post_handler.append(ir.Branch(tail))
|
||||||
|
|
||||||
if not post_finalizer.is_terminated():
|
if not post_finalizer.is_terminated():
|
||||||
dest = post_finalizer.append(ir.GetLocal(final_state, ".k"))
|
dest = post_finalizer.append(ir.GetLocal(final_state, ".k"))
|
||||||
|
@ -594,9 +594,9 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
||||||
if not body.is_terminated():
|
if not body.is_terminated():
|
||||||
body.append(ir.Branch(tail))
|
body.append(ir.Branch(tail))
|
||||||
|
|
||||||
for handler in handlers:
|
for handler, post_handler in handlers:
|
||||||
if not handler.is_terminated():
|
if not post_handler.is_terminated():
|
||||||
handler.append(ir.Branch(tail))
|
post_handler.append(ir.Branch(tail))
|
||||||
|
|
||||||
# TODO: With
|
# TODO: With
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
# RUN: %python -m artiq.compiler.testbench.jit %s
|
||||||
|
# REQUIRES: exceptions
|
||||||
|
|
||||||
|
def catch(f):
|
||||||
|
try:
|
||||||
|
f()
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
# CHECK-L: ZeroDivisionError
|
||||||
|
catch(lambda: 1/0)
|
||||||
|
# CHECK-L: IndexError
|
||||||
|
catch(lambda: [1.0][10])
|
|
@ -0,0 +1,15 @@
|
||||||
|
# RUN: %python -m artiq.compiler.testbench.jit %s
|
||||||
|
# REQUIRES: exceptions
|
||||||
|
|
||||||
|
def catch(f):
|
||||||
|
try:
|
||||||
|
f()
|
||||||
|
except ZeroDivisionError as zde:
|
||||||
|
print(zde)
|
||||||
|
except IndexError as ie:
|
||||||
|
print(ie)
|
||||||
|
|
||||||
|
# CHECK-L: ZeroDivisionError
|
||||||
|
catch(lambda: 1/0)
|
||||||
|
# CHECK-L: IndexError
|
||||||
|
catch(lambda: [1.0][10])
|
|
@ -0,0 +1,15 @@
|
||||||
|
# RUN: %python -m artiq.compiler.testbench.jit %s
|
||||||
|
# REQUIRES: exceptions
|
||||||
|
|
||||||
|
def f():
|
||||||
|
try:
|
||||||
|
1/0
|
||||||
|
except ValueError:
|
||||||
|
# CHECK-NOT-L: FAIL
|
||||||
|
print("FAIL")
|
||||||
|
|
||||||
|
try:
|
||||||
|
f()
|
||||||
|
except ZeroDivisionError:
|
||||||
|
# CHECK-L: OK
|
||||||
|
print("OK")
|
|
@ -229,7 +229,7 @@ void __artiq_raise(struct artiq_exception *artiq_exn) {
|
||||||
_Unwind_Reason_Code __artiq_personality(
|
_Unwind_Reason_Code __artiq_personality(
|
||||||
int version, _Unwind_Action actions, uint64_t exceptionClass,
|
int version, _Unwind_Action actions, uint64_t exceptionClass,
|
||||||
struct _Unwind_Exception *exceptionObject, struct _Unwind_Context *context) {
|
struct _Unwind_Exception *exceptionObject, struct _Unwind_Context *context) {
|
||||||
EH_LOG("entry (actions =%s%s%s%s; class=%08lx; object=%p, context=%p)",
|
EH_LOG("===> entry (actions =%s%s%s%s; class=%08lx; object=%p, context=%p)",
|
||||||
(actions & _UA_SEARCH_PHASE ? " search" : ""),
|
(actions & _UA_SEARCH_PHASE ? " search" : ""),
|
||||||
(actions & _UA_CLEANUP_PHASE ? " cleanup" : ""),
|
(actions & _UA_CLEANUP_PHASE ? " cleanup" : ""),
|
||||||
(actions & _UA_HANDLER_FRAME ? " handler" : ""),
|
(actions & _UA_HANDLER_FRAME ? " handler" : ""),
|
||||||
|
@ -240,7 +240,7 @@ _Unwind_Reason_Code __artiq_personality(
|
||||||
|
|
||||||
struct artiq_raised_exception *inflight =
|
struct artiq_raised_exception *inflight =
|
||||||
(struct artiq_raised_exception*)exceptionObject;
|
(struct artiq_raised_exception*)exceptionObject;
|
||||||
EH_LOG("exception name=%s",
|
EH_LOG("=> exception name=%s",
|
||||||
inflight->artiq.name);
|
inflight->artiq.name);
|
||||||
|
|
||||||
// Get a pointer to LSDA. If there's no LSDA, this function doesn't
|
// Get a pointer to LSDA. If there's no LSDA, this function doesn't
|
||||||
|
@ -259,7 +259,7 @@ _Unwind_Reason_Code __artiq_personality(
|
||||||
uintptr_t funcStart = _Unwind_GetRegionStart(context);
|
uintptr_t funcStart = _Unwind_GetRegionStart(context);
|
||||||
uintptr_t pcOffset = pc - funcStart;
|
uintptr_t pcOffset = pc - funcStart;
|
||||||
|
|
||||||
EH_LOG("pc=%p (%p+%p)", (void*)pc, (void*)funcStart, (void*)pcOffset);
|
EH_LOG("=> pc=%p (%p+%p)", (void*)pc, (void*)funcStart, (void*)pcOffset);
|
||||||
|
|
||||||
// Parse LSDA header.
|
// Parse LSDA header.
|
||||||
uint8_t lpStartEncoding = *lsda++;
|
uint8_t lpStartEncoding = *lsda++;
|
||||||
|
@ -304,7 +304,7 @@ _Unwind_Reason_Code __artiq_personality(
|
||||||
}
|
}
|
||||||
|
|
||||||
if((start <= pcOffset) && (pcOffset < (start + length))) {
|
if((start <= pcOffset) && (pcOffset < (start + length))) {
|
||||||
EH_LOG0("call site matches pc");
|
EH_LOG0("=> call site matches pc");
|
||||||
|
|
||||||
int exceptionMatched = 0;
|
int exceptionMatched = 0;
|
||||||
if(actionValue) {
|
if(actionValue) {
|
||||||
|
@ -329,7 +329,7 @@ _Unwind_Reason_Code __artiq_personality(
|
||||||
encodingSize, typeInfoPtrPtr, (void*)typeInfoPtr);
|
encodingSize, typeInfoPtrPtr, (void*)typeInfoPtr);
|
||||||
EH_LOG("typeInfo=%s", (char*)typeInfoPtr);
|
EH_LOG("typeInfo=%s", (char*)typeInfoPtr);
|
||||||
|
|
||||||
if(inflight->artiq.typeinfo == typeInfoPtr) {
|
if(typeInfoPtr == 0 || inflight->artiq.typeinfo == typeInfoPtr) {
|
||||||
EH_LOG0("matching action found");
|
EH_LOG0("matching action found");
|
||||||
exceptionMatched = 1;
|
exceptionMatched = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -343,7 +343,7 @@ _Unwind_Reason_Code __artiq_personality(
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(actions & _UA_SEARCH_PHASE)) {
|
if(!(actions & _UA_SEARCH_PHASE)) {
|
||||||
EH_LOG0("jumping to landing pad");
|
EH_LOG0("=> jumping to landing pad");
|
||||||
|
|
||||||
_Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
|
_Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
|
||||||
(uintptr_t)exceptionObject);
|
(uintptr_t)exceptionObject);
|
||||||
|
@ -353,11 +353,11 @@ _Unwind_Reason_Code __artiq_personality(
|
||||||
|
|
||||||
return _URC_INSTALL_CONTEXT;
|
return _URC_INSTALL_CONTEXT;
|
||||||
} else if(exceptionMatched) {
|
} else if(exceptionMatched) {
|
||||||
EH_LOG0("handler found");
|
EH_LOG0("=> handler found");
|
||||||
|
|
||||||
return _URC_HANDLER_FOUND;
|
return _URC_HANDLER_FOUND;
|
||||||
} else {
|
} else {
|
||||||
EH_LOG0("handler not found");
|
EH_LOG0("=> handler not found");
|
||||||
|
|
||||||
return _URC_CONTINUE_UNWIND;
|
return _URC_CONTINUE_UNWIND;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue