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
|
||||
|
||||
self.current_block = handler
|
||||
handlers.append(handler)
|
||||
|
||||
if handler_node.name is not None:
|
||||
exn = self.append(ir.Builtin("exncast", [landingpad], handler_node.name_type))
|
||||
self._set_local(handler_node.name, exn)
|
||||
|
||||
self.visit(handler_node.body)
|
||||
post_handler = self.current_block
|
||||
|
||||
handlers.append((handler, post_handler))
|
||||
|
||||
if any(node.finalbody):
|
||||
finalizer = self.add_block("finally")
|
||||
@ -580,12 +580,12 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
||||
# to execute.
|
||||
handler = self.add_block("handler.catchall")
|
||||
landingpad.add_clause(handler, None)
|
||||
handlers.append(handler)
|
||||
handlers.append((handler, handler))
|
||||
|
||||
for handler in handlers:
|
||||
if not handler.is_terminated():
|
||||
handler.append(ir.SetLocal(final_state, ".k", tail))
|
||||
handler.append(ir.Branch(tail))
|
||||
for handler, post_handler in handlers:
|
||||
if not post_handler.is_terminated():
|
||||
post_handler.append(ir.SetLocal(final_state, ".k", tail))
|
||||
post_handler.append(ir.Branch(tail))
|
||||
|
||||
if not post_finalizer.is_terminated():
|
||||
dest = post_finalizer.append(ir.GetLocal(final_state, ".k"))
|
||||
@ -594,9 +594,9 @@ class ARTIQIRGenerator(algorithm.Visitor):
|
||||
if not body.is_terminated():
|
||||
body.append(ir.Branch(tail))
|
||||
|
||||
for handler in handlers:
|
||||
if not handler.is_terminated():
|
||||
handler.append(ir.Branch(tail))
|
||||
for handler, post_handler in handlers:
|
||||
if not post_handler.is_terminated():
|
||||
post_handler.append(ir.Branch(tail))
|
||||
|
||||
# TODO: With
|
||||
|
||||
|
13
lit-test/test/exceptions/catch_all.py
Normal file
13
lit-test/test/exceptions/catch_all.py
Normal file
@ -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])
|
15
lit-test/test/exceptions/catch_multi.py
Normal file
15
lit-test/test/exceptions/catch_multi.py
Normal file
@ -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])
|
15
lit-test/test/exceptions/catch_outer.py
Normal file
15
lit-test/test/exceptions/catch_outer.py
Normal file
@ -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(
|
||||
int version, _Unwind_Action actions, uint64_t exceptionClass,
|
||||
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_CLEANUP_PHASE ? " cleanup" : ""),
|
||||
(actions & _UA_HANDLER_FRAME ? " handler" : ""),
|
||||
@ -240,7 +240,7 @@ _Unwind_Reason_Code __artiq_personality(
|
||||
|
||||
struct artiq_raised_exception *inflight =
|
||||
(struct artiq_raised_exception*)exceptionObject;
|
||||
EH_LOG("exception name=%s",
|
||||
EH_LOG("=> exception name=%s",
|
||||
inflight->artiq.name);
|
||||
|
||||
// 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 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.
|
||||
uint8_t lpStartEncoding = *lsda++;
|
||||
@ -286,7 +286,7 @@ _Unwind_Reason_Code __artiq_personality(
|
||||
const uint8_t *actionTableStart = callSiteTableEnd;
|
||||
const uint8_t *callSitePtr = callSiteTableStart;
|
||||
|
||||
while (callSitePtr < callSiteTableEnd) {
|
||||
while(callSitePtr < callSiteTableEnd) {
|
||||
uintptr_t start = readEncodedPointer(&callSitePtr,
|
||||
callSiteEncoding);
|
||||
uintptr_t length = readEncodedPointer(&callSitePtr,
|
||||
@ -303,8 +303,8 @@ _Unwind_Reason_Code __artiq_personality(
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((start <= pcOffset) && (pcOffset < (start + length))) {
|
||||
EH_LOG0("call site matches pc");
|
||||
if((start <= pcOffset) && (pcOffset < (start + length))) {
|
||||
EH_LOG0("=> call site matches pc");
|
||||
|
||||
int exceptionMatched = 0;
|
||||
if(actionValue) {
|
||||
@ -329,7 +329,7 @@ _Unwind_Reason_Code __artiq_personality(
|
||||
encodingSize, typeInfoPtrPtr, (void*)typeInfoPtr);
|
||||
EH_LOG("typeInfo=%s", (char*)typeInfoPtr);
|
||||
|
||||
if(inflight->artiq.typeinfo == typeInfoPtr) {
|
||||
if(typeInfoPtr == 0 || inflight->artiq.typeinfo == typeInfoPtr) {
|
||||
EH_LOG0("matching action found");
|
||||
exceptionMatched = 1;
|
||||
break;
|
||||
@ -342,8 +342,8 @@ _Unwind_Reason_Code __artiq_personality(
|
||||
}
|
||||
}
|
||||
|
||||
if (!(actions & _UA_SEARCH_PHASE)) {
|
||||
EH_LOG0("jumping to landing pad");
|
||||
if(!(actions & _UA_SEARCH_PHASE)) {
|
||||
EH_LOG0("=> jumping to landing pad");
|
||||
|
||||
_Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
|
||||
(uintptr_t)exceptionObject);
|
||||
@ -353,11 +353,11 @@ _Unwind_Reason_Code __artiq_personality(
|
||||
|
||||
return _URC_INSTALL_CONTEXT;
|
||||
} else if(exceptionMatched) {
|
||||
EH_LOG0("handler found");
|
||||
EH_LOG0("=> handler found");
|
||||
|
||||
return _URC_HANDLER_FOUND;
|
||||
} else {
|
||||
EH_LOG0("handler not found");
|
||||
EH_LOG0("=> handler not found");
|
||||
|
||||
return _URC_CONTINUE_UNWIND;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user