Index: libcfa/src/concurrency/coroutine.cfa
===================================================================
--- libcfa/src/concurrency/coroutine.cfa	(revision b39e65663cd638f8ca22e419ae282b0b654db30e)
+++ libcfa/src/concurrency/coroutine.cfa	(revision 578c09abc3a6baa5d93897b74eadcba17d0dfe3f)
@@ -46,6 +46,4 @@
 
 //-----------------------------------------------------------------------------
-EHM_VIRTUAL_TABLE(SomeCoroutineCancelled, std_coroutine_cancelled);
-
 forall(T &)
 void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src) {
@@ -62,5 +60,6 @@
 // This code should not be inlined. It is the error path on resume.
 forall(T & | is_coroutine(T))
-void __cfaehm_cancelled_coroutine( T & cor, $coroutine * desc ) {
+void __cfaehm_cancelled_coroutine(
+		T & cor, $coroutine * desc, _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable ) {
 	verify( desc->cancellation );
 	desc->state = Cancelled;
@@ -68,10 +67,10 @@
 
 	// TODO: Remove explitate vtable set once trac#186 is fixed.
-	SomeCoroutineCancelled except;
-	except.virtual_table = &std_coroutine_cancelled;
+	CoroutineCancelled(T) except;
+	except.virtual_table = &_default_vtable;
 	except.the_coroutine = &cor;
 	except.the_exception = except;
 	// Why does this need a cast?
-	throwResume (SomeCoroutineCancelled &)except;
+	throwResume (CoroutineCancelled(T) &)except;
 
 	except->virtual_table->free( except );
@@ -146,5 +145,5 @@
 // Part of the Public API
 // Not inline since only ever called once per coroutine
-forall(T & | is_coroutine(T))
+forall(T & | is_coroutine(T) | { _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable; })
 void prime(T& cor) {
 	$coroutine* this = get_coroutine(cor);
Index: libcfa/src/concurrency/coroutine.hfa
===================================================================
--- libcfa/src/concurrency/coroutine.hfa	(revision b39e65663cd638f8ca22e419ae282b0b654db30e)
+++ libcfa/src/concurrency/coroutine.hfa	(revision 578c09abc3a6baa5d93897b74eadcba17d0dfe3f)
@@ -22,11 +22,4 @@
 //-----------------------------------------------------------------------------
 // Exception thrown from resume when a coroutine stack is cancelled.
-EHM_EXCEPTION(SomeCoroutineCancelled)(
-	void * the_coroutine;
-	exception_t * the_exception;
-);
-
-EHM_EXTERN_VTABLE(SomeCoroutineCancelled, std_coroutine_cancelled);
-
 EHM_FORALL_EXCEPTION(CoroutineCancelled, (coroutine_t &), (coroutine_t)) (
 	coroutine_t * the_coroutine;
@@ -44,5 +37,5 @@
 // Anything that implements this trait can be resumed.
 // Anything that is resumed is a coroutine.
-trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(SomeCoroutineCancelled)) {
+trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(CoroutineCancelled, (T))) {
 	void main(T & this);
 	$coroutine * get_coroutine(T & this);
@@ -67,5 +60,5 @@
 //-----------------------------------------------------------------------------
 // Public coroutine API
-forall(T & | is_coroutine(T))
+forall(T & | is_coroutine(T) | { _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable; })
 void prime(T & cor);
 
@@ -137,8 +130,9 @@
 
 forall(T & | is_coroutine(T))
-void __cfaehm_cancelled_coroutine( T & cor, $coroutine * desc );
+void __cfaehm_cancelled_coroutine(
+	T & cor, $coroutine * desc, _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable );
 
 // Resume implementation inlined for performance
-forall(T & | is_coroutine(T))
+forall(T & | is_coroutine(T) | { _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable; })
 static inline T & resume(T & cor) {
 	// optimization : read TLS once and reuse it
@@ -170,5 +164,5 @@
 	$ctx_switch( src, dst );
 	if ( unlikely(dst->cancellation) ) {
-		__cfaehm_cancelled_coroutine( cor, dst );
+		__cfaehm_cancelled_coroutine( cor, dst, _default_vtable );
 	}
 
Index: libcfa/src/exception.hfa
===================================================================
--- libcfa/src/exception.hfa	(revision b39e65663cd638f8ca22e419ae282b0b654db30e)
+++ libcfa/src/exception.hfa	(revision 578c09abc3a6baa5d93897b74eadcba17d0dfe3f)
@@ -142,8 +142,4 @@
 		_EHM_VTABLE_TYPE(exception_name) parameters const &) {} \
 
-#define _EHM_TRAIT_FUNCTION2(exception_name, forall_clause, parameters) \
-	forall_clause _EHM_VTABLE_TYPE(exception_name) parameters const & \
-			get_exception_vtable(exception_name parameters const & this)
-
 #define __EHM_TRAIT_FUNCTION(exception_name, forall_clause, parameters) \
 	forall_clause inline _EHM_VTABLE_TYPE(exception_name) parameters const & \
Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision b39e65663cd638f8ca22e419ae282b0b654db30e)
+++ src/Concurrency/Keywords.cc	(revision 578c09abc3a6baa5d93897b74eadcba17d0dfe3f)
@@ -414,7 +414,5 @@
 		if ( type_decl && isDestructorFor( decl, type_decl ) )
 			dtor_decl = decl;
-		else if ( vtable_name.empty() )
-			;
-		else if( !decl->has_body() )
+		else if ( vtable_name.empty() || !decl->has_body() )
 			;
 		else if ( auto param = isMainFor( decl, cast_target ) ) {
@@ -428,6 +426,17 @@
 			std::list< Expression * > poly_args = { new TypeExpr( struct_type->clone() ) };
 			ObjectDecl * vtable_object = Virtual::makeVtableInstance(
+				"_default_vtable_object_declaration",
 				vtable_decl->makeInst( poly_args ), struct_type, nullptr );
 			declsToAddAfter.push_back( vtable_object );
+			declsToAddAfter.push_back(
+				new ObjectDecl(
+					Virtual::concurrentDefaultVTableName(),
+					Type::Const,
+					LinkageSpec::Cforall,
+					/* bitfieldWidth */ nullptr,
+					new ReferenceType( Type::Const, vtable_object->type->clone() ),
+					new SingleInit( new VariableExpr( vtable_object ) )
+				)
+			);
 			declsToAddAfter.push_back( Virtual::makeGetExceptionFunction(
 				vtable_object, except_decl->makeInst( std::move( poly_args ) )
@@ -488,6 +497,18 @@
 			except_decl->makeInst( poly_args )
 		) );
-		declsToAddBefore.push_back( Virtual::makeVtableForward(
-			vtable_decl->makeInst( move( poly_args ) ) ) );
+		ObjectDecl * vtable_object = Virtual::makeVtableForward(
+			"_default_vtable_object_declaration",
+			vtable_decl->makeInst( move( poly_args ) ) );
+		declsToAddBefore.push_back( vtable_object );
+		declsToAddAfter.push_back(
+			new ObjectDecl(
+				Virtual::concurrentDefaultVTableName(),
+				Type::Const,
+				LinkageSpec::Cforall,
+				/* bitfieldWidth */ nullptr,
+				new ReferenceType( Type::Const, vtable_object->type->clone() ),
+				/* init */ nullptr
+			)
+		);
 	}
 
Index: src/Virtual/Tables.cc
===================================================================
--- src/Virtual/Tables.cc	(revision b39e65663cd638f8ca22e419ae282b0b654db30e)
+++ src/Virtual/Tables.cc	(revision 578c09abc3a6baa5d93897b74eadcba17d0dfe3f)
@@ -10,6 +10,6 @@
 // Created On       : Mon Aug 31 11:11:00 2020
 // Last Modified By : Andrew Beach
-// Last Modified On : Thr Apr  8 15:51:00 2021
-// Update Count     : 1
+// Last Modified On : Wed Apr 21 15:36:00 2021
+// Update Count     : 2
 //
 
@@ -50,4 +50,8 @@
 }
 
+std::string concurrentDefaultVTableName() {
+	return "_default_vtable";
+}
+
 bool isVTableInstanceName( std::string const & name ) {
 	// There are some delicate length calculations here.
@@ -57,6 +61,6 @@
 
 static ObjectDecl * makeVtableDeclaration(
+		std::string const & name,
 		StructInstType * type, Initializer * init ) {
-	std::string const & name = instanceName( type->name );
 	Type::StorageClasses storage = noStorageClasses;
 	if ( nullptr == init ) {
@@ -73,11 +77,12 @@
 }
 
-ObjectDecl * makeVtableForward( StructInstType * type ) {
+ObjectDecl * makeVtableForward( std::string const & name, StructInstType * type ) {
 	assert( type );
-	return makeVtableDeclaration( type, nullptr );
+	return makeVtableDeclaration( name, type, nullptr );
 }
 
 ObjectDecl * makeVtableInstance(
-		StructInstType * vtableType, Type * objectType, Initializer * init ) {
+		std::string const & name, StructInstType * vtableType,
+		Type * objectType, Initializer * init ) {
 	assert( vtableType );
 	assert( objectType );
@@ -115,5 +120,5 @@
 		assert(false);
 	}
-	return makeVtableDeclaration( vtableType, init );
+	return makeVtableDeclaration( name, vtableType, init );
 }
 
@@ -167,8 +172,4 @@
 }
 
-ObjectDecl * makeTypeIdForward() {
-	return nullptr;
-}
-
 Attribute * linkonce( const std::string & subsection ) {
 	const std::string section = ".gnu.linkonce." + subsection;
Index: src/Virtual/Tables.h
===================================================================
--- src/Virtual/Tables.h	(revision b39e65663cd638f8ca22e419ae282b0b654db30e)
+++ src/Virtual/Tables.h	(revision 578c09abc3a6baa5d93897b74eadcba17d0dfe3f)
@@ -10,6 +10,6 @@
 // Created On       : Mon Aug 31 11:07:00 2020
 // Last Modified By : Andrew Beach
-// Last Modified On : Thr Apr  8 15:55:00 2021
-// Update Count     : 1
+// Last Modified On : Wed Apr 21 10:30:00 2021
+// Update Count     : 2
 //
 
@@ -27,12 +27,16 @@
 std::string instanceName( std::string const & vtable_name );
 std::string vtableInstanceName( std::string const & type_name );
+std::string concurrentDefaultVTableName();
 bool isVTableInstanceName( std::string const & name );
 
-ObjectDecl * makeVtableForward( StructInstType * vtableType );
+ObjectDecl * makeVtableForward(
+	std::string const & name, StructInstType * vtableType );
 /* Create a forward declaration of a vtable of the given type.
  * vtableType node is consumed.
  */
 
-ObjectDecl * makeVtableInstance( StructInstType * vtableType, Type * objectType,
+ObjectDecl * makeVtableInstance(
+	std::string const & name,
+	StructInstType * vtableType, Type * objectType,
 	Initializer * init = nullptr );
 /* Create an initialized definition of a vtable.
Index: tests/exceptions/cancel/coroutine.cfa
===================================================================
--- tests/exceptions/cancel/coroutine.cfa	(revision b39e65663cd638f8ca22e419ae282b0b654db30e)
+++ tests/exceptions/cancel/coroutine.cfa	(revision 578c09abc3a6baa5d93897b74eadcba17d0dfe3f)
@@ -25,5 +25,5 @@
 		resume(cancel);
 		printf("4");
-	} catchResume (SomeCoroutineCancelled * error) {
+	} catchResume (CoroutineCancelled(WillCancel) * error) {
 		printf("2");
 		if ((virtual internal_error *)error->the_exception) {
