Index: libcfa/src/concurrency/coroutine.cfa
===================================================================
--- libcfa/src/concurrency/coroutine.cfa	(revision fd4c009c9dfdc22d84d4bace73fa33c9d4937d90)
+++ libcfa/src/concurrency/coroutine.cfa	(revision 47e000c054a8dc58293a93fbc643e10735fd30f9)
@@ -46,8 +46,5 @@
 
 //-----------------------------------------------------------------------------
-FORALL_DATA_INSTANCE(CoroutineCancelled, (coroutine_t &), (coroutine_t))
-
-forall(T &)
-void mark_exception(CoroutineCancelled(T) *) {}
+EHM_VIRTUAL_TABLE(SomeCoroutineCancelled, std_coroutine_cancelled);
 
 forall(T &)
@@ -71,9 +68,10 @@
 
 	// TODO: Remove explitate vtable set once trac#186 is fixed.
-	CoroutineCancelled(T) except;
-	except.virtual_table = &get_exception_vtable(&except);
+	SomeCoroutineCancelled except;
+	except.virtual_table = &std_coroutine_cancelled;
 	except.the_coroutine = &cor;
 	except.the_exception = except;
-	throwResume except;
+	// Why does this need a cast?
+	throwResume (SomeCoroutineCancelled &)except;
 
 	except->virtual_table->free( except );
Index: libcfa/src/concurrency/coroutine.hfa
===================================================================
--- libcfa/src/concurrency/coroutine.hfa	(revision fd4c009c9dfdc22d84d4bace73fa33c9d4937d90)
+++ libcfa/src/concurrency/coroutine.hfa	(revision 47e000c054a8dc58293a93fbc643e10735fd30f9)
@@ -22,5 +22,12 @@
 //-----------------------------------------------------------------------------
 // Exception thrown from resume when a coroutine stack is cancelled.
-FORALL_DATA_EXCEPTION(CoroutineCancelled, (coroutine_t &), (coroutine_t)) (
+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;
 	exception_t * the_exception;
@@ -37,5 +44,5 @@
 // Anything that implements this trait can be resumed.
 // Anything that is resumed is a coroutine.
-trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(CoroutineCancelled, (T))) {
+trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(SomeCoroutineCancelled)) {
 	void main(T & this);
 	$coroutine * get_coroutine(T & this);
Index: libcfa/src/concurrency/kernel.cfa
===================================================================
--- libcfa/src/concurrency/kernel.cfa	(revision fd4c009c9dfdc22d84d4bace73fa33c9d4937d90)
+++ libcfa/src/concurrency/kernel.cfa	(revision 47e000c054a8dc58293a93fbc643e10735fd30f9)
@@ -359,4 +359,5 @@
 				#if !defined(__CFA_NO_STATISTICS__)
 					__tls_stats()->ready.threads.threads++;
+					__push_stat( __tls_stats(), __tls_stats()->ready.threads.threads, false, "Processor", this );
 				#endif
 				// This is case 2, the racy case, someone tried to run this thread before it finished blocking
@@ -376,4 +377,5 @@
 	#if !defined(__CFA_NO_STATISTICS__)
 		__tls_stats()->ready.threads.threads--;
+		__push_stat( __tls_stats(), __tls_stats()->ready.threads.threads, false, "Processor", this );
 	#endif
 
@@ -455,7 +457,9 @@
 		if( kernelTLS().this_stats ) {
 			__tls_stats()->ready.threads.threads++;
+			__push_stat( __tls_stats(), __tls_stats()->ready.threads.threads, false, "Processor", kernelTLS().this_processor );
 		}
 		else {
 			__atomic_fetch_add(&cl->stats->ready.threads.threads, 1, __ATOMIC_RELAXED);
+			__push_stat( cl->stats, cl->stats->ready.threads.threads, true, "Cluster", cl );
 		}
 	#endif
Index: libcfa/src/concurrency/kernel/startup.cfa
===================================================================
--- libcfa/src/concurrency/kernel/startup.cfa	(revision fd4c009c9dfdc22d84d4bace73fa33c9d4937d90)
+++ libcfa/src/concurrency/kernel/startup.cfa	(revision 47e000c054a8dc58293a93fbc643e10735fd30f9)
@@ -268,4 +268,7 @@
 			__print_stats( st, mainProcessor->print_stats, "Processor ", mainProcessor->name, (void*)mainProcessor );
 		}
+		#if defined(CFA_STATS_ARRAY)
+			__flush_stat( st, "Processor", mainProcessor );
+		#endif
 	#endif
 
@@ -348,4 +351,7 @@
 			__print_stats( &local_stats, proc->print_stats, "Processor ", proc->name, (void*)proc );
 		}
+		#if defined(CFA_STATS_ARRAY)
+			__flush_stat( &local_stats, "Processor", proc );
+		#endif
 	#endif
 
@@ -615,4 +621,7 @@
 			__print_stats( this.stats, this.print_stats, "Cluster", this.name, (void*)&this );
 		}
+		#if defined(CFA_STATS_ARRAY)
+			__flush_stat( this.stats, "Cluster", &this );
+		#endif
 		free( this.stats );
 	#endif
Index: libcfa/src/concurrency/stats.cfa
===================================================================
--- libcfa/src/concurrency/stats.cfa	(revision fd4c009c9dfdc22d84d4bace73fa33c9d4937d90)
+++ libcfa/src/concurrency/stats.cfa	(revision 47e000c054a8dc58293a93fbc643e10735fd30f9)
@@ -5,4 +5,5 @@
 #include <inttypes.h>
 #include "bits/debug.hfa"
+#include "bits/locks.hfa"
 #include "stats.hfa"
 
@@ -44,4 +45,9 @@
 			stats->io.calls.errors.busy = 0;
 			stats->io.poller.sleeps     = 0;
+		#endif
+
+		#if defined(CFA_STATS_ARRAY)
+			stats->array.values = alloc(CFA_STATS_ARRAY);
+			stats->array.cnt = 0;
 		#endif
 	}
@@ -151,3 +157,48 @@
 		#endif
 	}
+
+	#if defined(CFA_STATS_ARRAY)
+		extern "C" {
+			#include <stdio.h>
+			#include <errno.h>
+			#include <sys/stat.h>
+			#include <fcntl.h>
+		}
+
+		void __flush_stat( struct __stats_t * this, const char * name, void * handle) {
+			int ret = mkdir(".cfadata", 0755);
+			if(ret < 0 && errno != EEXIST) abort("Failed to create directory .cfadata: %d\n", errno);
+
+			char filename[100];
+			snprintf(filename, 100, ".cfadata/%s%p.data", name, handle);
+
+			int fd = open(filename, O_WRONLY | O_APPEND | O_CREAT, 0644);
+			if(fd < 0) abort("Failed to create file %s: %d\n", filename, errno);
+
+			for(i; this->array.cnt) {
+				char line[100];
+				size_t n = snprintf(line, 100, "%llu, %lld\n", this->array.values[i].ts, this->array.values[i].value);
+				write(fd, line, n);
+			}
+
+			this->array.cnt = 0;
+			close(fd);
+		}
+
+		static __spinlock_t stats_lock;
+
+		void __push_stat( struct __stats_t * this, int64_t value, bool external, const char * name, void * handle ) {
+			if(external) lock(stats_lock __cfaabi_dbg_ctx2);
+
+			if( this->array.cnt >= CFA_STATS_ARRAY ) __flush_stat( this, name, handle );
+
+			size_t idx = this->array.cnt;
+			this->array.cnt++;
+
+			if(external) unlock(stats_lock);
+
+			this->array.values[idx].ts = rdtscl();
+			this->array.values[idx].value = value;
+		}
+	#endif
 #endif
Index: libcfa/src/concurrency/stats.hfa
===================================================================
--- libcfa/src/concurrency/stats.hfa	(revision fd4c009c9dfdc22d84d4bace73fa33c9d4937d90)
+++ libcfa/src/concurrency/stats.hfa	(revision 47e000c054a8dc58293a93fbc643e10735fd30f9)
@@ -1,3 +1,5 @@
 #pragma once
+
+// #define CFA_STATS_ARRAY 10000
 
 #include <stdint.h>
@@ -109,4 +111,11 @@
 	#endif
 
+	#if defined(CFA_STATS_ARRAY)
+		struct __stats_elem_t {
+			long long int ts;
+			int64_t value;
+		};
+	#endif
+
 	struct __attribute__((aligned(128))) __stats_t {
 		__stats_readQ_t ready;
@@ -114,4 +123,12 @@
 			__stats_io_t    io;
 		#endif
+
+		#if defined(CFA_STATS_ARRAY)
+			struct {
+				__stats_elem_t * values;
+				volatile size_t cnt;
+			} array;
+		#endif
+
 	};
 
@@ -119,4 +136,11 @@
 	void __tally_stats( struct __stats_t *, struct __stats_t * );
 	void __print_stats( struct __stats_t *, int, const char *, const char *, void * );
+	#if defined(CFA_STATS_ARRAY)
+		void __push_stat ( struct __stats_t *, int64_t value, bool external, const char * name, void * handle);
+		void __flush_stat( struct __stats_t *, const char *, void * );
+	#else
+		static inline void __push_stat ( struct __stats_t *, int64_t, bool, const char *, void * ) {}
+		static inline void __flush_stat( struct __stats_t *, const char *, void * ) {}
+	#endif
 #endif
 
Index: libcfa/src/concurrency/thread.cfa
===================================================================
--- libcfa/src/concurrency/thread.cfa	(revision fd4c009c9dfdc22d84d4bace73fa33c9d4937d90)
+++ libcfa/src/concurrency/thread.cfa	(revision 47e000c054a8dc58293a93fbc643e10735fd30f9)
@@ -62,5 +62,5 @@
 }
 
-FORALL_DATA_INSTANCE(ThreadCancelled, (thread_t &), (thread_t))
+EHM_VIRTUAL_TABLE(SomeThreadCancelled, std_thread_cancelled);
 
 forall(T &)
@@ -73,21 +73,27 @@
 forall(T &)
 const char * msg(ThreadCancelled(T) *) {
-	return "ThreadCancelled";
+	return "ThreadCancelled(...)";
 }
 
 forall(T &)
 static void default_thread_cancel_handler(ThreadCancelled(T) & ) {
+	// Improve this error message, can I do formatting?
 	abort( "Unhandled thread cancellation.\n" );
 }
 
-forall(T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T)))
+static void default_thread_cancel_handler(SomeThreadCancelled & ) {
+	// Improve this error message, can I do formatting?
+	abort( "Unhandled thread cancellation.\n" );
+}
+
+forall(T & | is_thread(T) | IS_EXCEPTION(SomeThreadCancelled))
 void ?{}( thread_dtor_guard_t & this,
-		T & thrd, void(*cancelHandler)(ThreadCancelled(T) &)) {
- 	$monitor * m = get_monitor(thrd);
+		T & thrd, void(*cancelHandler)(SomeThreadCancelled &)) {
+	$monitor * m = get_monitor(thrd);
 	$thread * desc = get_thread(thrd);
 
 	// Setup the monitor guard
 	void (*dtor)(T& mutex this) = ^?{};
-	bool join = cancelHandler != (void(*)(ThreadCancelled(T)&))0;
+	bool join = cancelHandler != (void(*)(SomeThreadCancelled&))0;
 	(this.mg){&m, (void(*)())dtor, join};
 
@@ -103,13 +109,14 @@
 	}
 	desc->state = Cancelled;
-	void(*defaultResumptionHandler)(ThreadCancelled(T) &) = 
+	void(*defaultResumptionHandler)(SomeThreadCancelled &) =
 		join ? cancelHandler : default_thread_cancel_handler;
 
-	ThreadCancelled(T) except;
 	// TODO: Remove explitate vtable set once trac#186 is fixed.
-	except.virtual_table = &get_exception_vtable(&except);
+	SomeThreadCancelled except;
+	except.virtual_table = &std_thread_cancelled;
 	except.the_thread = &thrd;
 	except.the_exception = __cfaehm_cancellation_exception( cancellation );
-	throwResume except;
+	// Why is this cast required?
+	throwResume (SomeThreadCancelled &)except;
 
 	except.the_exception->virtual_table->free( except.the_exception );
@@ -158,5 +165,5 @@
 
 //-----------------------------------------------------------------------------
-forall(T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T)))
+forall(T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(SomeThreadCancelled))
 T & join( T & this ) {
 	thread_dtor_guard_t guard = { this, defaultResumptionHandler };
Index: libcfa/src/concurrency/thread.hfa
===================================================================
--- libcfa/src/concurrency/thread.hfa	(revision fd4c009c9dfdc22d84d4bace73fa33c9d4937d90)
+++ libcfa/src/concurrency/thread.hfa	(revision 47e000c054a8dc58293a93fbc643e10735fd30f9)
@@ -32,5 +32,12 @@
 };
 
-FORALL_DATA_EXCEPTION(ThreadCancelled, (thread_t &), (thread_t)) (
+EHM_EXCEPTION(SomeThreadCancelled) (
+	void * the_thread;
+	exception_t * the_exception;
+);
+
+EHM_EXTERN_VTABLE(SomeThreadCancelled, std_thread_cancelled);
+
+EHM_FORALL_EXCEPTION(ThreadCancelled, (thread_t &), (thread_t)) (
 	thread_t * the_thread;
 	exception_t * the_exception;
@@ -79,6 +86,6 @@
 };
 
-forall( T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T)) )
-void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)(ThreadCancelled(T) &) );
+forall( T & | is_thread(T) | IS_EXCEPTION(SomeThreadCancelled) )
+void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)(SomeThreadCancelled &) );
 void ^?{}( thread_dtor_guard_t & this );
 
@@ -125,5 +132,5 @@
 //----------
 // join
-forall( T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T)) )
+forall( T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(SomeThreadCancelled) )
 T & join( T & this );
 
Index: libcfa/src/exception.c
===================================================================
--- libcfa/src/exception.c	(revision fd4c009c9dfdc22d84d4bace73fa33c9d4937d90)
+++ libcfa/src/exception.c	(revision 47e000c054a8dc58293a93fbc643e10735fd30f9)
@@ -10,6 +10,6 @@
 // Created On       : Mon Jun 26 15:13:00 2017
 // Last Modified By : Andrew Beach
-// Last Modified On : Tue Oct 27 16:27:00 2020
-// Update Count     : 35
+// Last Modified On : Wed Feb 24 13:40:00 2021
+// Update Count     : 36
 //
 
@@ -26,4 +26,5 @@
 #include "concurrency/invoke.h"
 #include "stdhdr/assert.h"
+#include "virtual.h"
 
 #if defined( __ARM_ARCH )
@@ -46,12 +47,7 @@
 const _Unwind_Exception_Class __cfaehm_exception_class = 0x4c50575500414643;
 
-// Base exception vtable is abstract, you should not have base exceptions.
-struct __cfaehm_base_exception_t_vtable
-		___cfaehm_base_exception_t_vtable_instance = {
-	.parent = NULL,
-	.size = 0,
-	.copy = NULL,
-	.free = NULL,
-	.msg = NULL
+// Base Exception type id:
+struct __cfa__parent_vtable __cfatid_exception_t = {
+	NULL,
 };
 
Index: libcfa/src/exception.h
===================================================================
--- libcfa/src/exception.h	(revision fd4c009c9dfdc22d84d4bace73fa33c9d4937d90)
+++ libcfa/src/exception.h	(revision 47e000c054a8dc58293a93fbc643e10735fd30f9)
@@ -10,6 +10,6 @@
 // Created On       : Mon Jun 26 15:11:00 2017
 // Last Modified By : Andrew Beach
-// Last Modified On : Tue Oct 27 14:45:00 2020
-// Update Count     : 11
+// Last Modified On : Thr Apr  8 15:20:00 2021
+// Update Count     : 12
 //
 
@@ -29,6 +29,7 @@
 struct __cfaehm_base_exception_t;
 typedef struct __cfaehm_base_exception_t exception_t;
+struct __cfa__parent_vtable;
 struct __cfaehm_base_exception_t_vtable {
-	const struct __cfaehm_base_exception_t_vtable * parent;
+	const struct __cfa__parent_vtable * __cfavir_typeid;
 	size_t size;
 	void (*copy)(struct __cfaehm_base_exception_t *this,
@@ -40,6 +41,5 @@
 	struct __cfaehm_base_exception_t_vtable const * virtual_table;
 };
-extern struct __cfaehm_base_exception_t_vtable
-	___cfaehm_base_exception_t_vtable_instance;
+extern struct __cfa__parent_vtable __cfatid_exception_t;
 
 
@@ -104,7 +104,7 @@
 	/* The first field must be a pointer to a virtual table.
 	 * That virtual table must be a decendent of the base exception virtual table.
+	 * The virtual table must point at the prober type-id.
+	 * None of these can be enforced in an assertion.
 	 */
-	virtualT const & get_exception_vtable(exceptT *);
-	// Always returns the virtual table for this type (associated types hack).
 };
 
Index: libcfa/src/exception.hfa
===================================================================
--- libcfa/src/exception.hfa	(revision fd4c009c9dfdc22d84d4bace73fa33c9d4937d90)
+++ libcfa/src/exception.hfa	(revision 47e000c054a8dc58293a93fbc643e10735fd30f9)
@@ -10,6 +10,6 @@
 // Created On       : Thu Apr  7 10:25:00 2020
 // Last Modified By : Andrew Beach
-// Last Modified On : Tue Aug  4 16:22:00 2020
-// Update Count     : 3
+// Last Modified On : Thr Apr  8 15:16:00 2021
+// Update Count     : 4
 //
 
@@ -18,111 +18,53 @@
 // -----------------------------------------------------------------------------------------------
 
-// TRIVIAL_EXCEPTION_DECLARATION(exception_name);
-// Declare a trivial exception, one that adds no fields or features.
-// This will make the exception visible and may go in a .hfa or .cfa file.
-#define TRIVIAL_EXCEPTION_DECLARATION(...) \
-	_EXC_DISPATCH(_TRIVIAL_EXCEPTION_DECLARATION, __VA_ARGS__)
+// EHM_EXCEPTION(exception_name)(fields...);
+// Create an exception (a virtual structure that inherits from exception_t)
+// with the given name and fields.
+#define EHM_EXCEPTION(exception_name) \
+	_EHM_TYPE_ID_STRUCT(exception_name, ); \
+	_EHM_TYPE_ID_VALUE(exception_name, ); \
+	_EHM_VIRTUAL_TABLE_STRUCT(exception_name, , ); \
+	_EHM_EXCEPTION_STRUCT(exception_name, , )
 
-// TRIVIAL_EXCEPTION_INSTANCE(exception_name);
-// Create the trival exception. This must be used exactly once and should be used in a .cfa file,
-// as it creates the unique instance of the virtual table.
-#define TRIVIAL_EXCEPTION_INSTANCE(...) _EXC_DISPATCH(_TRIVIAL_EXCEPTION_INSTANCE, __VA_ARGS__)
+// EHM_EXTERN_VTABLE(exception_name, table_name);
+// Forward declare a virtual table called table_name for exception_name type.
+#define EHM_EXTERN_VTABLE(exception_name, table_name) \
+	_EHM_EXTERN_VTABLE(exception_name, , table_name)
 
-// TRIVIAL_EXCEPTION(exception_name[, parent_name]);
-// Does both of the above, a short hand if the exception is only used in one .cfa file.
-// For legacy reasons this is the only one that official supports having a parent other than the
-// base exception. This feature may be removed or changed.
-#define TRIVIAL_EXCEPTION(...) \
-	_EXC_DISPATCH(_TRIVIAL_EXCEPTION_DECLARATION, __VA_ARGS__); \
-	_EXC_DISPATCH(_TRIVIAL_EXCEPTION_INSTANCE, __VA_ARGS__)
+// EHM_VIRTUAL_TABLE(exception_name, table_name);
+// Define a virtual table called table_name for exception_name type.
+#define EHM_VIRTUAL_TABLE(exception_name, table_name) \
+	_EHM_DEFINE_COPY(exception_name, ) \
+	_EHM_DEFINE_MSG(exception_name, ) \
+	_EHM_VIRTUAL_TABLE(exception_name, , table_name)
 
-// FORALL_TRIVIAL_EXCEPTION(exception_name, (assertions...), (parameters...));
-// Forward declare a polymorphic but otherwise trivial exception type. You must provide the entire
-// assertion list (exactly what would go in the forall clause) and parameters list (only the
-// parameter names from the assertion list, same order and comma seperated). This should be
-// visible where ever use the exception. This just generates the polymorphic framework, see
-// POLY_VTABLE_DECLARATION to allow instantiations.
-#define FORALL_TRIVIAL_EXCEPTION(exception_name, assertions, parameters) \
-	_FORALL_TRIVIAL_EXCEPTION(exception_name, __cfaehm_base_exception_t, assertions, parameters, )
+// EHM_FORALL_EXCEPTION(exception_name, (assertions), (parameters))(fields...);
+// As EHM_EXCEPTION but for polymorphic types instead of monomorphic ones.
+// The assertions list should include all polymorphic parameters and
+// assertions inside a parentisized list. Parameters should include all the
+// polymorphic parameter names inside a parentisized list (same order).
+#define EHM_FORALL_EXCEPTION(exception_name, assertions, parameters) \
+	_EHM_TYPE_ID_STRUCT(exception_name, forall assertions); \
+	_EHM_VIRTUAL_TABLE_STRUCT(exception_name, forall assertions, parameters); \
+	_EHM_EXCEPTION_STRUCT(exception_name, forall assertions, parameters)
 
-// FORALL_TRIVIAL_INSTANCE(exception_name, (assertions...), (parameters...))
-// Create the forall trivial exception. The assertion list and parameters must match.
-// There must be exactly one use of this in a program for each exception type. This just
-// generates the polymorphic framework, see POLY_VTABLE_INSTANCE to allow instantiations.
-#define FORALL_TRIVIAL_INSTANCE(exception_name, assertions, parameters) \
-	_FORALL_CTOR0_INSTANCE(exception_name, assertions, parameters)
+// EHM_FORALL_EXTERN_VTABLE(exception_name, (arguments), table_name);
+// As EHM_EXTERN_VTABLE but for polymorphic types instead of monomorphic ones.
+// Arguments should be the parentisized list of polymorphic arguments.
+#define EHM_FORALL_EXTERN_VTABLE(exception_name, arguments, table_name) \
+	_EHM_EXTERN_VTABLE(exception_name, arguments, table_name)
 
-// DATA_EXCEPTION(exception_name)(fields...);
-// Forward declare an exception that adds fields but no features. The added fields go in the
-// second argument list. The virtual table instance must be provided later (see VTABLE_INSTANCE).
-#define DATA_EXCEPTION(...) _EXC_DISPATCH(_DATA_EXCEPTION, __VA_ARGS__)
+// EHM_FORALL_VIRTUAL_TABLE(exception_name, (arguments), table_name);
+// As EHM_VIRTUAL_TABLE but for polymorphic types instead of monomorphic ones.
+// Arguments should be the parentisized list of polymorphic arguments.
+#define EHM_FORALL_VIRTUAL_TABLE(exception_name, arguments, table_name) \
+	_EHM_TYPE_ID_VALUE(exception_name, arguments); \
+	_EHM_DEFINE_COPY(exception_name, arguments) \
+	_EHM_DEFINE_MSG(exception_name, arguments) \
+	_EHM_VIRTUAL_TABLE(exception_name, arguments, table_name)
 
-// FORALL_DATA_EXCEPTION(exception_name, (assertions...), (parameters...))(fields...);
-// Define a polymorphic exception that adds fields but no additional features. The assertion list
-// and matching parameters must match. Then you can give the list of fields. This should be
-// visible where ever you use the exception. This just generates the polymorphic framework, see
-// POLY_VTABLE_DECLARATION to allow instantiations.
-#define FORALL_DATA_EXCEPTION(exception_name, assertions, parameters) \
-	_FORALL_DATA_EXCEPTION(exception_name, __cfaehm_base_exception_t, assertions, parameters, )
+#define EHM_TYPE_ID(exception_name) _EHM_TYPE_ID_TYPE(exception_name)
 
-// FORALL_DATA_INSTANCE(exception_name, (assertions...), (parameters...))
-// Create a polymorphic data exception. The assertion list and parameters must match. This should
-// appear once in each program. This just generates the polymorphic framework, see
-// POLY_VTABLE_INSTANCE to allow instantiations.
-#define FORALL_DATA_INSTANCE(exception_name, assertions, parameters) \
-	_FORALL_CTOR0_INSTANCE(exception_name, assertions, parameters)
-
-// VTABLE_DECLARATION(exception_name)([new_features...]);
-// Declare a virtual table type for an exception with exception_name. You may also add features
-// (fields on the virtual table) by including them in the second list.
-#define VTABLE_DECLARATION(...) _EXC_DISPATCH(_VTABLE_DECLARATION, __VA_ARGS__)
-
-// VTABLE_INSTANCE(exception_name)(msg [, others...]);
-// Create the instance of the virtual table. There must be exactly one instance of a virtual table
-// for each exception type. This fills in most of the fields of the virtual table (uses ?=? and
-// ^?{}) but you must provide the message function and any other fields added in the declaration.
-#define VTABLE_INSTANCE(...) _EXC_DISPATCH(_VTABLE_INSTANCE, __VA_ARGS__)
-
-// FORALL_VTABLE_DECLARATION(exception_name, (assertions...), (parameters...))([new_features...]);
-// Declare a polymorphic virtual table type for an exception with exception_name, the given
-// assertions and parameters. You may also add features (fields on the virtual table). This just
-// generates the polymorphic framework, see POLY_VTABLE_DECLARATION to allow instantiations.
-#define FORALL_VTABLE_DECLARATION(exception_name, assertions, parameters) \
-	_FORALL_VTABLE_DECLARATION(exception_name, __cfaehm_base_exception_t, assertions, parameters, )
-
-// POLY_VTABLE_DECLARATION(exception_name, types...);
-// Declares that an instantiation for this exception exists for the given types. This should be
-// visible anywhere you use the instantiation of the exception is used.
-#define POLY_VTABLE_DECLARATION(exception_name, ...) \
-	VTABLE_TYPE(exception_name)(__VA_ARGS__) const & get_exception_vtable(exception_name(__VA_ARGS__) *); \
-	extern VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name)
-
-// POLY_VTABLE_INSTANCE(exception_name, types...)(msg [, others...]);
-// Creates an instantiation for the given exception for the given types. This should occur only
-// once in the entire program. You must fill in all features, message and any others given in the
-// initial declaration.
-#define POLY_VTABLE_INSTANCE(exception_name, ...) \
-	_POLY_VTABLE_INSTANCE(exception_name, __cfaehm_base_exception_t, __VA_ARGS__)
-
-// VTABLE_TYPE(exception_name) | VTABLE_NAME(exception_name)
-// Get the name of the vtable type or the name of the vtable instance for an exception type.
-#define VTABLE_TYPE(exception_name) struct _GLUE2(exception_name,_vtable)
-#define VTABLE_NAME(exception_name) _GLUE3(_,exception_name,_vtable_instance)
-
-// VTABLE_FIELD(exception_name);
-// FORALL_VTABLE_FIELD(exception_name, (parameters-or-types));
-// The declaration of the virtual table field. Should be the first declaration in a virtual type.
-#define VTABLE_FIELD(exception_name) VTABLE_TYPE(exception_name) const * virtual_table
-#define FORALL_VTABLE_FIELD(exception_name, parameters) \
-	VTABLE_TYPE(exception_name) parameters const * virtual_table
-
-// VTABLE_INIT(object_reference, exception_name);
-// Sets a virtual table field on an object to the virtual table instance for the type.
-#define VTABLE_INIT(this, exception_name) (this).virtual_table = &VTABLE_NAME(exception_name)
-
-// VTABLE_ASSERTION(exception_name, (parameters...))
-// The assertion that there is an instantiation of the vtable for the exception and types.
-#define VTABLE_ASSERTION(exception_name, parameters) \
-	{ VTABLE_TYPE(exception_name) parameters VTABLE_NAME(exception_name); }
+#define EHM_MATCH_ALL __cfa__parent_vtable
 
 // IS_EXCEPTION(exception_name [, (...parameters)])
@@ -135,113 +77,113 @@
 #define IS_TERMINATION_EXCEPTION(...) _IS_EXCEPTION(is_termination_exception, __VA_ARGS__, , ~)
 
-// All internal helper macros begin with an underscore.
-#define _CLOSE(...) __VA_ARGS__ }
-#define _GLUE2(left, right) left##right
-#define _GLUE3(left, middle, right) left##middle##right
-#define _EXC_DISPATCH(to, ...) to(__VA_ARGS__,__cfaehm_base_exception_t,)
-#define _UNPACK(...) __VA_ARGS__
+// Macros starting with a leading underscore are internal.
 
-#define _TRIVIAL_EXCEPTION_DECLARATION(exception_name, parent_name, ...) \
-	_VTABLE_DECLARATION(exception_name, parent_name)(); \
-	struct exception_name { \
-		VTABLE_FIELD(exception_name); \
-	}; \
-	void ?{}(exception_name & this); \
-	const char * _GLUE2(exception_name,_msg)(exception_name * this)
+// Create an exception type definition. must be tailing, can be polymorphic.
+#define _EHM_EXCEPTION_STRUCT(exception_name, forall_clause, parameters) \
+	forall_clause struct exception_name { \
+		_EHM_VTABLE_TYPE(exception_name) parameters const * virtual_table; \
+		_CLOSE
 
-#define _TRIVIAL_EXCEPTION_INSTANCE(exception_name, parent_name, ...) \
-	void ?{}(exception_name & this) { \
-		VTABLE_INIT(this, exception_name); \
-	} \
-	const char * _GLUE2(exception_name,_msg)(exception_name * this) { \
-		return #exception_name; \
-	} \
-	_VTABLE_INSTANCE(exception_name, parent_name,)(_GLUE2(exception_name,_msg))
+// Create a (possibly polymorphic) virtual table forward declaration.
+#define _EHM_EXTERN_VTABLE(exception_name, arguments, table_name) \
+	extern const _EHM_VTABLE_TYPE(exception_name) arguments table_name
 
-#define _FORALL_TRIVIAL_EXCEPTION(exception_name, parent_name, assertions, \
-		parameters, parent_parameters) \
-	_FORALL_VTABLE_DECLARATION(exception_name, parent_name, assertions, \
-		parameters, parent_parameters)(); \
-	forall assertions struct exception_name { \
-		FORALL_VTABLE_FIELD(exception_name, parameters); \
-	}; \
-	_FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters)
-
-#define _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters) \
-	forall(_UNPACK assertions | \
-		is_exception(exception_name parameters, VTABLE_TYPE(exception_name) parameters)) \
-	void ?{}(exception_name parameters & this)
-
-#define _FORALL_CTOR0_INSTANCE(exception_name, assertions, parameters) \
-	_FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters) { \
-		(this).virtual_table = &get_exception_vtable(&this); \
+// Create a (possibly polymorphic) virtual table definition.
+#define _EHM_VIRTUAL_TABLE(exception_type, arguments, table_name) \
+	const _EHM_VTABLE_TYPE(exception_type) arguments table_name @= { \
+		.__cfavir_typeid : &_EHM_TYPE_ID_NAME(exception_type), \
+		.size : sizeof(struct exception_type arguments), \
+		.copy : copy, \
+		.^?{} : ^?{}, \
+		.msg : msg, \
 	}
 
-#define _DATA_EXCEPTION(exception_name, parent_name, ...) \
-	_VTABLE_DECLARATION(exception_name, parent_name)(); \
-	struct exception_name { \
-		VTABLE_FIELD(exception_name); \
-		_CLOSE
+// Create a (possibly polymorphic) copy function from an assignment operator.
+#define _EHM_DEFINE_FORALL_COPY(exception_name, forall_clause, parameters) \
+	forall_clause void copy(exception_name parameters * this, \
+			exception_name parameters * that) { \
+		*this = *that; \
+	}
 
-#define _FORALL_DATA_EXCEPTION(exception_name, parent_name, \
-		assertions, parameters, parent_parameters) \
-	_FORALL_VTABLE_DECLARATION(exception_name, parent_name, \
-		assertions, parameters, parent_parameters)(); \
-	_FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters); \
-	forall assertions struct exception_name { \
-		FORALL_VTABLE_FIELD(exception_name, parameters); \
-		_CLOSE
+#define _EHM_DEFINE_COPY(exception_name, arguments) \
+	void copy(exception_name arguments * this, exception_name arguments * that) { \
+		*this = *that; \
+	}
 
-#define _VTABLE_DECLARATION(exception_name, parent_name, ...) \
-	struct exception_name; \
-	VTABLE_TYPE(exception_name); \
-	VTABLE_TYPE(exception_name) const & get_exception_vtable(exception_name *); \
-	extern VTABLE_TYPE(exception_name) VTABLE_NAME(exception_name); \
-	VTABLE_TYPE(exception_name) { \
-		VTABLE_TYPE(parent_name) const * parent; \
-		size_t size; \
-		void (*copy)(exception_name * this, exception_name * other); \
-		void (*^?{})(exception_name & this); \
-		const char * (*msg)(exception_name * this); \
-		_CLOSE
+// Create a (possibly polymorphic) msg function
+#define _EHM_DEFINE_FORALL_MSG(exception_name, forall_clause, parameters) \
+	forall_clause const char * msg(exception_name parameters * this) { \
+		return #exception_name #parameters; \
+	}
 
-#define _VTABLE_INSTANCE(exception_name, parent_name, ...) \
-	VTABLE_TYPE(exception_name) const & get_exception_vtable(exception_name *) { \
-		return VTABLE_NAME(exception_name); \
-	} \
-	void _GLUE2(exception_name,_copy)(exception_name * this, exception_name * other) { \
-		*this = *other; \
-	} \
-	VTABLE_TYPE(exception_name) VTABLE_NAME(exception_name) @= { \
-		&VTABLE_NAME(parent_name), sizeof(exception_name), \
-		_GLUE2(exception_name,_copy), ^?{}, \
-		_CLOSE
+#define _EHM_DEFINE_MSG(exception_name, arguments) \
+	const char * msg(exception_name arguments * this) { \
+		return #exception_name #arguments; \
+	}
 
-#define _FORALL_VTABLE_DECLARATION(exception_name, parent_name, assertions, \
-		parameters, parent_parameters) \
-	forall assertions struct exception_name; \
-	forall assertions VTABLE_TYPE(exception_name) { \
-		VTABLE_TYPE(parent_name) parent_parameters const * parent; \
+// Produces the C compatable name of the virtual table type for a virtual type.
+#define _EHM_VTABLE_TYPE(type_name) struct _GLUE2(type_name,_vtable)
+
+// Create the vtable type for exception name.
+#define _EHM_VIRTUAL_TABLE_STRUCT(exception_name, forall_clause, parameters) \
+	forall_clause struct exception_name; \
+	forall_clause _EHM_VTABLE_TYPE(exception_name) { \
+		_EHM_TYPE_ID_TYPE(exception_name) parameters const * __cfavir_typeid; \
 		size_t size; \
 		void (*copy)(exception_name parameters * this, exception_name parameters * other); \
 		void (*^?{})(exception_name parameters & this); \
 		const char * (*msg)(exception_name parameters * this); \
-		_CLOSE
+	}
 
-#define _POLY_VTABLE_INSTANCE(exception_name, parent_name, ...) \
-	extern VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name); \
-	VTABLE_TYPE(exception_name)(__VA_ARGS__) const & get_exception_vtable( \
-			exception_name(__VA_ARGS__) *) { \
-		return VTABLE_NAME(exception_name); \
-	} \
-	void _GLUE2(exception_name,_copy)( \
-			exception_name(__VA_ARGS__) * this, exception_name(__VA_ARGS__) * other) { \
-		*this = *other; \
-	} \
-	VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name) @= { \
-		&VTABLE_NAME(parent_name), sizeof(exception_name(__VA_ARGS__)), \
-		_GLUE2(exception_name,_copy), ^?{}, \
-		_CLOSE
+// Define the function required to satify the trait for exceptions.
+#define _EHM_TRAIT_FUNCTION(exception_name, forall_clause, parameters) \
+	forall_clause inline void mark_exception( \
+		exception_name parameters const &, \
+		_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 & \
+			get_exception_vtable(exception_name parameters const & this) { \
+		/* This comes before the structure definition, but we know the offset. */ \
+		/* return (_EHM_VTABLE_TYPE(exception_name) parameters const &)this; */ \
+		assert(false); \
+	}
+
+// Generates a new type-id structure. This is used to mangle the name of the
+// type-id instance so it also includes polymorphic information. Must be the
+// direct decendent of exception_t.
+// The second field is used to recover type information about the exception.
+#define _EHM_TYPE_ID_STRUCT(exception_name, forall_clause) \
+	forall_clause _EHM_TYPE_ID_TYPE(exception_name) { \
+		__cfa__parent_vtable const * parent; \
+	}
+
+// Generate a new type-id value.
+#define _EHM_TYPE_ID_VALUE(exception_name, arguments) \
+	__attribute__(( section(".gnu.linkonce." "__cfatid_" #exception_name) )) \
+	_EHM_TYPE_ID_TYPE(exception_name) arguments const \
+			_EHM_TYPE_ID_NAME(exception_name) = { \
+		&__cfatid_exception_t, \
+	}
+
+// _EHM_TYPE_ID_STRUCT and _EHM_TYPE_ID_VALUE are the two that would need to
+// be updated to extend the hierarchy if we are still using macros when that
+// is added.
+
+// Produce the C compatable name of the type-id type for an exception type.
+#define _EHM_TYPE_ID_TYPE(exception_name) \
+	struct _GLUE2(__cfatid_struct_, exception_name)
+
+// Produce the name of the instance of the type-id for an exception type.
+#define _EHM_TYPE_ID_NAME(exception_name) _GLUE2(__cfatid_,exception_name)
 
 #define _IS_EXCEPTION(kind, exception_name, parameters, ...) \
-	kind(exception_name parameters, VTABLE_TYPE(exception_name) parameters)
+	kind(exception_name parameters, _EHM_VTABLE_TYPE(exception_name) parameters)
+
+// Internal helper macros:
+#define _CLOSE(...) __VA_ARGS__ }
+#define _GLUE2(left, right) left##right
Index: libcfa/src/fstream.cfa
===================================================================
--- libcfa/src/fstream.cfa	(revision fd4c009c9dfdc22d84d4bace73fa33c9d4937d90)
+++ libcfa/src/fstream.cfa	(revision 47e000c054a8dc58293a93fbc643e10735fd30f9)
@@ -321,18 +321,15 @@
 
 
+EHM_VIRTUAL_TABLE(Open_Failure, Open_Failure_main_table);
 void ?{}( Open_Failure & this, ofstream & ostream ) {
-	VTABLE_INIT(this, Open_Failure);
+	this.virtual_table = &Open_Failure_main_table;
 	this.ostream = &ostream;
 	this.tag = 1;
 }
 void ?{}( Open_Failure & this, ifstream & istream ) {
-	VTABLE_INIT(this, Open_Failure);
+	this.virtual_table = &Open_Failure_main_table;
 	this.istream = &istream;
 	this.tag = 0;
 }
-const char * Open_Failure_msg(Open_Failure * this) {
-	return "Open_Failure";
-}
-VTABLE_INSTANCE(Open_Failure)(Open_Failure_msg);
 void throwOpen_Failure( ofstream & ostream ) {
 	Open_Failure exc = { ostream };
Index: libcfa/src/fstream.hfa
===================================================================
--- libcfa/src/fstream.hfa	(revision fd4c009c9dfdc22d84d4bace73fa33c9d4937d90)
+++ libcfa/src/fstream.hfa	(revision 47e000c054a8dc58293a93fbc643e10735fd30f9)
@@ -133,5 +133,5 @@
 
 
-DATA_EXCEPTION(Open_Failure)(
+EHM_EXCEPTION(Open_Failure)(
 	union {
 		ofstream * ostream;
Index: libcfa/src/virtual.c
===================================================================
--- libcfa/src/virtual.c	(revision fd4c009c9dfdc22d84d4bace73fa33c9d4937d90)
+++ libcfa/src/virtual.c	(revision 47e000c054a8dc58293a93fbc643e10735fd30f9)
@@ -15,7 +15,9 @@
 
 #include "virtual.h"
+#include "assert.h"
 
 int __cfa__is_parent( struct __cfa__parent_vtable const * parent,
     	struct __cfa__parent_vtable const * child ) {
+	assert( child );
 	do {
 		if ( parent == child )
@@ -28,4 +30,5 @@
 void * __cfa__virtual_cast( struct __cfa__parent_vtable const * parent,
     	struct __cfa__parent_vtable const * const * child ) {
+	assert( child );
 	return (__cfa__is_parent(parent, *child)) ? (void *)child : (void *)0;
 }
