Index: libcfa/src/exception.c
===================================================================
--- libcfa/src/exception.c	(revision 6f121b8319d9f9ac95e57b58eb4e9e0faddb194e)
+++ libcfa/src/exception.c	(revision 99fea48f2387ef184355a08834361210b160f651)
@@ -10,6 +10,6 @@
 // Created On       : Mon Jun 26 15:13:00 2017
 // Last Modified By : Andrew Beach
-// Last Modified On : Tue Apr 14 12:01:00 2020
-// Update Count     : 18
+// Last Modified On : Thr May 21 12:18:00 2020
+// Update Count     : 20
 //
 
@@ -80,5 +80,5 @@
 }
 
-void __cfaehm_throw_resume(exception_t * except) {
+void __cfaehm_throw_resume(exception_t * except, void (*defaultHandler)(exception_t *)) {
 	struct exception_context_t * context = this_exception_context();
 
@@ -96,9 +96,7 @@
 	}
 
+	// No handler found, fall back to the default operation.
 	__cfadbg_print_safe(exception, "Unhandled exception\n");
-
-	// Fall back to termination:
-	__cfaehm_throw_terminate(except);
-	// TODO: Default handler for resumption.
+	defaultHandler(except);
 }
 
@@ -239,7 +237,14 @@
 }
 
+static void __cfaehm_cleanup_default( exception_t ** except ) {
+	__cfaehm_delete_exception( *except );
+	*except = NULL;
+}
+
 // The exception that is being thrown must already be stored.
-static __attribute__((noreturn)) void __cfaehm_begin_unwind(void) {
-	if ( ! this_exception_context()->current_exception ) {
+static void __cfaehm_begin_unwind(void(*defaultHandler)(exception_t *)) {
+	struct exception_context_t * context = this_exception_context();
+	struct _Unwind_Exception * storage = &this_exception_storage;
+	if ( NULL == context->current_exception ) {
 		printf("UNWIND ERROR missing exception in begin unwind\n");
 		abort();
@@ -247,5 +252,6 @@
 
 	// Call stdlibc to raise the exception
-	_Unwind_Reason_Code ret = _Unwind_RaiseException( &this_exception_storage );
+	__cfadbg_print_safe(exception, "Begin unwinding (storage &p, context %p)\n", storage, context);
+	_Unwind_Reason_Code ret = _Unwind_RaiseException( storage );
 
 	// If we reach here it means something happened. For resumption to work we need to find a way
@@ -256,22 +262,29 @@
 	// the whole stack.
 
+	// We did not simply reach the end of the stack without finding a handler. This is an error.
+	if ( ret != _URC_END_OF_STACK ) {
+		printf("UNWIND ERROR %d after raise exception\n", ret);
+		abort();
+	}
+
 	// No handler found, go to the default operation.
-	// Currently this will always be a cancellation.
-	if ( ret == _URC_END_OF_STACK ) {
-		__cfadbg_print_safe(exception, "Uncaught exception %p\n", &this_exception_storage);
-
-		__cfaehm_cancel_stack(this_exception_context()->current_exception);
-	}
-
-	// We did not simply reach the end of the stack without finding a handler. This is an error.
-	printf("UNWIND ERROR %d after raise exception\n", ret);
+	__cfadbg_print_safe(exception, "Uncaught exception %p\n", storage);
+
+	__attribute__((cleanup(__cfaehm_cleanup_default)))
+	exception_t * exception = context->current_exception;
+	defaultHandler( exception );
+}
+
+void __cfaehm_throw_terminate( exception_t * val, void (*defaultHandler)(exception_t *) ) {
+	__cfadbg_print_safe(exception, "Throwing termination exception\n");
+
+	__cfaehm_allocate_exception( val );
+	__cfaehm_begin_unwind( defaultHandler );
+}
+
+static __attribute__((noreturn)) void __cfaehm_rethrow_adapter( exception_t * except ) {
+	// TODO: Print some error message.
+	(void)except;
 	abort();
-}
-
-void __cfaehm_throw_terminate( exception_t * val ) {
-	__cfadbg_print_safe(exception, "Throwing termination exception\n");
-
-	__cfaehm_allocate_exception( val );
-	__cfaehm_begin_unwind();
 }
 
@@ -279,5 +292,6 @@
 	__cfadbg_print_safe(exception, "Rethrowing termination exception\n");
 
-	__cfaehm_begin_unwind();
+	__cfaehm_begin_unwind( __cfaehm_rethrow_adapter );
+	abort();
 }
 
Index: libcfa/src/exception.h
===================================================================
--- libcfa/src/exception.h	(revision 6f121b8319d9f9ac95e57b58eb4e9e0faddb194e)
+++ libcfa/src/exception.h	(revision 99fea48f2387ef184355a08834361210b160f651)
@@ -10,6 +10,6 @@
 // Created On       : Mon Jun 26 15:11:00 2017
 // Last Modified By : Andrew Beach
-// Last Modified On : Fri Mar 27 10:16:00 2020
-// Update Count     : 9
+// Last Modified On : Tue May 19 14:17:00 2020
+// Update Count     : 10
 //
 
@@ -41,7 +41,7 @@
 
 // Used in throw statement translation.
-void __cfaehm_throw_terminate(exception_t * except) __attribute__((noreturn));
+void __cfaehm_throw_terminate(exception_t * except, void (*)(exception_t *));
 void __cfaehm_rethrow_terminate() __attribute__((noreturn));
-void __cfaehm_throw_resume(exception_t * except);
+void __cfaehm_throw_resume(exception_t * except, void (*)(exception_t *));
 
 // Function catches termination exceptions.
@@ -72,3 +72,54 @@
 #ifdef __cforall
 }
+
+// Not all the built-ins can be expressed in C. These can't be
+// implemented in the .c file either so they all have to be inline.
+
+trait is_exception(dtype T) {
+	/* The first field must be a pointer to a virtual table.
+	 * That virtual table must be a decendent of the base exception virtual tab$
+	 */
+	void mark_exception(T *);
+	// This is never used and should be a no-op.
+};
+
+trait is_termination_exception(dtype T | is_exception(T)) {
+	void defaultTerminationHandler(T &);
+};
+
+trait is_resumption_exception(dtype T | is_exception(T)) {
+	void defaultResumptionHandler(T &);
+};
+
+forall(dtype T | is_termination_exception(T))
+static inline void $throw(T & except) {
+	__cfaehm_throw_terminate(
+		(exception_t *)&except,
+		(void(*)(exception_t *))defaultTerminationHandler
+	);
+}
+
+forall(dtype T | is_resumption_exception(T))
+static inline void $throwResume(T & except) {
+	__cfaehm_throw_resume(
+		(exception_t *)&except,
+		(void(*)(exception_t *))defaultResumptionHandler
+	);
+}
+
+forall(dtype T | is_exception(T))
+static inline void cancel_stack(T & except) __attribute__((noreturn)) {
+	__cfaehm_cancel_stack( (exception_t *)&except );
+}
+
+forall(dtype T | is_exception(T))
+static inline void defaultTerminationHandler(T & except) {
+	return cancel_stack( except );
+}
+
+forall(dtype T | is_exception(T))
+static inline void defaultResumptionHandler(T & except) {
+	throw except;
+}
+
 #endif
Index: libcfa/src/exception.hfa
===================================================================
--- libcfa/src/exception.hfa	(revision 6f121b8319d9f9ac95e57b58eb4e9e0faddb194e)
+++ libcfa/src/exception.hfa	(revision 99fea48f2387ef184355a08834361210b160f651)
@@ -10,18 +10,7 @@
 // Created On       : Thu Apr  7 10:25:00 2020
 // Last Modified By : Andrew Beach
-// Last Modified On : Wed Apr 13 15:42:00 2020
-// Update Count     : 1
+// Last Modified On : Tue May 19 14:17:00 2020
+// Update Count     : 2
 //
-
-trait is_exception(dtype T) {
-	// The trait system can't describe the actual constrants.
-	// Unused, should always be a no-op.
-	void mark_exception(T *);
-};
-
-forall(dtype T | is_exception(T))
-inline void cancel_stack(T & except) __attribute__((noreturn)) {
-	__cfaehm_cancel_stack( (exception_t *)&except );
-}
 
 // Everything below this line should be considered a patch while the exception
