Index: doc/working/exception/README
===================================================================
--- doc/working/exception/README	(revision ae6f1ec1d85524657b3516f4d6718b46777f8d37)
+++ 	(revision )
@@ -1,9 +1,0 @@
-This folder contains a working prototype of how to implement exceptions in C.
-
-main.cfa	: Example user code
-main.c	: Example generated code
-except.c	: Implementation of the unwinding logic
-except.h	: header for except
-lsda.h	: stolen code from gcc that handles reading the exception table language specifica data
-
-to compile run : "gcc -fexceptions -Wall -Werror -g main.c except.c"
Index: doc/working/exception/design.txt
===================================================================
--- doc/working/exception/design.txt	(revision daf9671439895f6d3bdd15ca16d77fa736b00a4c)
+++ doc/working/exception/design.txt	(revision daf9671439895f6d3bdd15ca16d77fa736b00a4c)
@@ -0,0 +1,140 @@
+Design of Exceptions and EHM in Cforall:
+
+Currently this is a combination of ideas and big questions that still have to
+be addressed. It also includes some other error handling options, how they
+interact and compare to exceptions.
+
+
+What is an Exception:
+
+In other words what do we throw? What is matched against, how does it carry
+data with it? A very important question that has not been answered.
+
+Option 1: Strutures
+
+Considering the current state of Cforall the most natural form of the
+exception would likely be a struture, implementing a trait repersenting the
+minimum features of an exception. This has many advantages, including arbitray
+fields, some polymorphism and it matches exceptations of many current systems.
+
+The main issue with this is matching, without OOP inheritance there is no
+exception hierarchy. Meaning all handling has to happen on the exact exception
+without the ease of grouping parents. There are several ways to attempt to
+recover this.
+
+The first is with conditional matching (a check after the type has been
+matched) which allows for matching particular values of a known type. However
+this does not dynamically expand and requires an extra step (as opposed to
+mearly allowing one). I would not recomend this as the primary method.
+
+Second is to try and use type casts/conversions to create an implicate
+hierachy, so that a catch clause catches anything of the given type or
+anything that converts to the given type.
+
+Plan9 (from what I know of it) would be a powerful tool here. Even with it,
+creating a hierarchy of types at runtime might be too expencive. Esecially
+since they are less likely to be tree like at that point.
+
+Option 2: Tags
+
+The other option is to introduce a new construct into the language. A tag
+repersents a type of exception, it is not a structure or variable (or even
+a normal type). It may be usable in some of those contexts.
+
+Tags can declare an existing tag as its parent. Tags can be caught by handlers
+that catch their parents. (There is a single base_exception that all other
+exceptions are children of eventually.) This allows for grouping of exceptions
+that repersent similar errors.
+
+Tags should also have some assotiated data, where and on what did the error
+occur. Keeping with the otherness of exception tags and allowing them to be
+expanded, using a parameter list. Each exception can have a list of paramters
+given to it on a throw. Each tag would have a declared list of parameters
+(which could be treated more like a set of fields as well). Child tags must
+use their parent's list as a prefix to their own, so that the parameters can
+be accessed when the child tag is matched against the parent.
+
+Option N: ...
+
+This list is not complete.
+
+
+Seperating Termination and Resumption:
+
+Differentating the types of exceptions based on exception would be hard with
+exceptions as structures. It is possible with exceptions as tags by having
+two base exceptions, one for each type of throw. However recompining them
+to dual types would be harder.
+
+Reguardless, using different keywords would also be useful for clarity, even
+if it does not add functality. Using the C++ like keywords would be a good
+base. Resumption exceptions could use a different set (ex. raise->handle) or
+use resume as a qualifier on the existing statements.
+
+
+Conditional Matching:
+
+A possible useful feature, it allows for arbitrary checks on a catch block
+instead of merely matching a type. However there are few use cases that
+cannot be avoided with proper use of a type hierarchy, and this shrinks even
+further with a good use of re-throws.
+
+Also it assumes one sweep, that might also be a problem. But might also give
+it an advantage over re-throws.
+
+
+Alternatives: Implicate Handlers & Return Unions
+
+Both act as a kind of local version of an exception. Implicate handlers act as
+resumption exceptions and return unions like termination exceptions. By local
+I mean they work well at one or two levels of calls, but do not cover N levels
+as cleanly.
+
+Implicate handles require a growing number of function pointers (which should
+not be used very often) to be passed to functions, creating and additional
+preformance cost. Return unions have to be checked and handled at every level,
+which has some preformance cost, but also can significantly clutter code.
+Proper tools can help with the latter.
+
+However, they may work better at that local level as they do not require stack
+walking or unwinding. In addition they are closer to regular control flow and
+are easier to staticly check. So even if they can't replace exceptions
+(directly) they may still be worth using together.
+
+For instance, consider the Python iterator interface. It uses a single
+function, __next__, to access the next value and to signal the end of the
+sequence. If a value is returned, it is the next value, if the StopIteration
+exception is thrown the sequence has finished.
+
+However almost every use of an iterator will add a try-except block around the
+call site (possibly through for or next) to catch and handle the exception
+immediately, ignoring the advantages of more distant exception handling.
+
+In this case it may be cleaner to use a Maybe for both cases (as in Rust)
+which gives similar results without having to jump to the exception handler.
+This will likely handle the error case more efficiently and the success case a
+bit less so.
+
+It also mixes the error and regular control flow, which can hurt readablity,
+but very little if the handling is simple, for instance providing a default
+value. Similarly, if the error (or alternate outcome) is common enough
+encoding it in the function signature may be good commuication.
+
+In short, these errors seem to be more effective when errors are likely and
+immediate. High failure operations, especially ones with failures that can
+be handled locally, might be better off using these instead of exceptions.
+
+Also the implicate handlers and return unions could use exceptions as well.
+For instance, a useful default might handler might be to throw an exception,
+seaching up the stack for a solution if one is not locally provided.
+
+Or here is a possible helper for unpacking a Result value:
+		forall(otype T, otype E | exception(E))
+		T get_or_throw (Result(T, E) * this) {
+			if (is_success(this)) {
+				return get_success(this);
+			} else {
+				throw get_failure(this);
+			}
+		}
+So they can feed off of each other.
Index: doc/working/exception/except.c
===================================================================
--- doc/working/exception/except.c	(revision ae6f1ec1d85524657b3516f4d6718b46777f8d37)
+++ 	(revision )
@@ -1,217 +1,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <unwind.h>
-
-#include "lsda.h"
-
-//Global which defines the current exception
-//Currently an int just to make matching easier
-int this_exception;
-
-//This is our personality routine
-//For every stack frame anotated with ".cfi_personality 0x3,__gcfa_personality_v0"
-//This function will be called twice when unwinding
-//Once in the search phased and once in the cleanup phase
-_Unwind_Reason_Code __gcfa_personality_v0 (
-                     int version, _Unwind_Action actions, unsigned long long exceptionClass,
-                     struct _Unwind_Exception* unwind_exception, struct _Unwind_Context* context)
-{
-	//DEBUG
-	printf("Personality function (%d, %x, %llu, %p, %p):", version, actions, exceptionClass, unwind_exception, context);
-
-	//If we've reached the end of the stack then there is nothing much we can do...
-	if( actions & _UA_END_OF_STACK ) return _URC_END_OF_STACK;
-	
-	//DEBUG
-	if (actions & _UA_SEARCH_PHASE) {
-		printf(" lookup phase");
-	} 
-	//DEBUG
-	else if (actions & _UA_CLEANUP_PHASE) {
-		printf(" cleanup phase");
-	}
-	//Just in case, probably can't actually happen
-	else {
-		printf(" error\n");
-		return _URC_FATAL_PHASE1_ERROR;
-	}
-	
-	//Get a pointer to the language specific data from which we will read what we need
-	const unsigned char * lsd = (const unsigned char*) _Unwind_GetLanguageSpecificData( context );
-
-	if( !lsd ) {	//Nothing to do, keep unwinding
-		printf(" no LSD");
-		goto UNWIND;
-	}
-
-	//Get the instuction pointer and a reading pointer into the exception table
-	lsda_header_info lsd_info;
-	const unsigned char * cur_ptr = parse_lsda_header( context, lsd, &lsd_info);
-	_Unwind_Ptr instruction_ptr = _Unwind_GetIP( context );
-
-	//Linearly search the table for stuff to do
-	while( cur_ptr < lsd_info.action_table ) {
-		_Unwind_Ptr callsite_start;
-		_Unwind_Ptr callsite_len;
-		_Unwind_Ptr callsite_landing_pad;
-		_uleb128_t  callsite_action;
-
-		//Decode the common stuff we have in here
-		cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_start);
-		cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_len);
-		cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_landing_pad);
-		cur_ptr = read_uleb128 (cur_ptr, &callsite_action);
-
-		//Have we reach the correct frame info yet?
-		if( lsd_info.Start + callsite_start + callsite_len < instruction_ptr ) {
-			//DEBUG BEGIN
-			void * ls = (void*)lsd_info.Start;
-			void * cs = (void*)callsite_start;
-			void * cl = (void*)callsite_len;
-			void * bp = (void*)lsd_info.Start + callsite_start;
-			void * ep = (void*)lsd_info.Start + callsite_start + callsite_len;
-			void * ip = (void*)instruction_ptr;
-			printf("\nfound %p - %p (%p, %p, %p), looking for %p\n", bp, ep, ls, cs, cl, ip);
-			//DEBUG END
-			continue;
-		}
-		
-		//Have we gone too far
-		if( lsd_info.Start + callsite_start > instruction_ptr ) {
-			printf(" gone too far");
-			break;
-		}
-
-		//Something to do?
-		if( callsite_landing_pad ) {
-			//Which phase are we in
-			if (actions & _UA_SEARCH_PHASE) {
-				//Search phase, this means we probably found a potential handler and must check if it is a match
-
-				//If we have arbitrarily decided that 0 means nothing to do and 1 means there is a potential handler
-				//This doesn't seem to conflict the gcc default behavior
-				if (callsite_action != 0) {
-					//Now we want to run some code to see if the handler matches
-					//This is the tricky part where we want to the power to run arbitrary code
-					//However, generating a new exception table entry and try routine every time 
-					//is way more expansive than we might like
-					//The information we have is :
-					//  - The GR (???)
-					//  - The instruction pointer
-					//  - The instruction pointer info (???)
-					//  - The CFA (???)
-					//  - The BSP (Probably the base stack pointer)
-
-
-					//The current apprach uses one exception table entry per try block
-					_uleb128_t imatcher;
-					//Get the relative offset to the 
-					cur_ptr = read_uleb128 (cur_ptr, &imatcher);
-
-					//Get a function pointer from the relative offset and call it
-					_Unwind_Reason_Code (*matcher)() = (_Unwind_Reason_Code (*)())lsd_info.LPStart + imatcher;					
-					_Unwind_Reason_Code ret = matcher();
-
-					//Based on the return value, check if we matched the exception
-					if( ret == _URC_HANDLER_FOUND) printf(" handler found\n");
-					else printf(" no handler\n");
-					return ret;
-				}
-
-				//This is only a cleanup handler, ignore it
-				printf(" no action");
-			} 
-			else if (actions & _UA_CLEANUP_PHASE) {
-
-				if( (callsite_action != 0) && !(actions & _UA_HANDLER_FRAME) ){
-					//If this is a potential exception handler 
-					//but not the one that matched the exception in the seach phase,
-					//just ignore it
-					goto UNWIND;
-				}
-
-				//We need to run some clean-up or a handler
-				//These statment do the right thing but I don't know any specifics at all
-				_Unwind_SetGR( context, __builtin_eh_return_data_regno(0), (_Unwind_Ptr) unwind_exception );
-				_Unwind_SetGR( context, __builtin_eh_return_data_regno(1), 0 );
-
-				//I assume this sets the instruction pointer to the adress of the landing pad
-				//It doesn't actually set it, it only state the value that needs to be set once we return _URC_INSTALL_CONTEXT
-				_Unwind_SetIP( context, lsd_info.LPStart + callsite_landing_pad );
-
-				//DEBUG
-				printf(" action\n");
-
-				//Return have some action to run
-				return _URC_INSTALL_CONTEXT;
-			}
-		}
-
-		//Nothing to do, move along
-		printf(" no landing pad");
-	}
-	//No handling found
-	printf(" table end reached\n");
-
-	//DEBUG
-	UNWIND:
-	printf(" unwind\n");
-
-	//Keep unwinding the stack
-	return _URC_CONTINUE_UNWIND;
-}
-
-//We need a piece of storage to raise the exception
-struct _Unwind_Exception this_exception_storage;
-
-//Function needed by force unwind
-//It basically says to unwind the whole stack and then exit when we reach the end of the stack
-static _Unwind_Reason_Code _Stop_Fn(	
-	int version, 
-	_Unwind_Action actions, 
-	_Unwind_Exception_Class exceptionClass, 
-	struct _Unwind_Exception * unwind_exception, 
-	struct _Unwind_Context * context, 
-	void * some_param
-) {
-	if( actions & _UA_END_OF_STACK  ) exit(1);
-	if( actions & _UA_CLEANUP_PHASE ) return _URC_NO_REASON;
-
-	return _URC_FATAL_PHASE2_ERROR;
-}
-
-//Example throw routine
-void throw( int val ) {
-	//Store the current exception
-	this_exception = val;
-
-	//DEBUG
-	printf("Throwing exception %d\n", this_exception);
-
-	//Call stdlibc to raise the exception
-	_Unwind_Reason_Code ret = _Unwind_RaiseException( &this_exception_storage );
-
-	//If we reach here it means something happened
-	//For resumption to work we need to find a way to return back to here
-	//Most of them will probably boil down to setting a global flag and making the phase 1 either stop or fail.
-	//Causing an error on purpose may help avoiding unnecessary work but it might have some weird side effects.
-	//If we just pretend no handler was found that would work but may be expensive for no reason since we will always
-	//search the whole stack
-
-	if( ret == _URC_END_OF_STACK ) {
-		//No proper handler was found
-		//This can be handled in several way
-		//C++ calls std::terminate
-		//Here we force unwind the stack, basically raising a cancellation
-		printf("Uncaught exception %p\n", &this_exception_storage);
-		
-		ret = _Unwind_ForcedUnwind( &this_exception_storage, _Stop_Fn, (void*)0x22 );
-		printf("UNWIND ERROR %d after force unwind\n", ret);
-		abort();
-	}
-
-	//We did not simply reach the end of the stack without finding a handler,
-	//Something wen't wrong
-	printf("UNWIND ERROR %d after raise exception\n", ret);
-	abort();
-}
Index: doc/working/exception/except.h
===================================================================
--- doc/working/exception/except.h	(revision ae6f1ec1d85524657b3516f4d6718b46777f8d37)
+++ 	(revision )
@@ -1,3 +1,0 @@
-#include <unwind.h>
-
-void throw( int val );
Index: doc/working/exception/impl/README
===================================================================
--- doc/working/exception/impl/README	(revision daf9671439895f6d3bdd15ca16d77fa736b00a4c)
+++ doc/working/exception/impl/README	(revision daf9671439895f6d3bdd15ca16d77fa736b00a4c)
@@ -0,0 +1,9 @@
+This folder contains a working prototype of how to implement exceptions in C.
+
+main.cfa	: Example user code
+main.c	: Example generated code
+except.c	: Implementation of the unwinding logic
+except.h	: header for except
+lsda.h	: stolen code from gcc that handles reading the exception table language specifica data
+
+to compile run : "gcc -fexceptions -Wall -Werror -g main.c except.c"
Index: doc/working/exception/impl/except.c
===================================================================
--- doc/working/exception/impl/except.c	(revision daf9671439895f6d3bdd15ca16d77fa736b00a4c)
+++ doc/working/exception/impl/except.c	(revision daf9671439895f6d3bdd15ca16d77fa736b00a4c)
@@ -0,0 +1,217 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <unwind.h>
+
+#include "lsda.h"
+
+//Global which defines the current exception
+//Currently an int just to make matching easier
+int this_exception;
+
+//This is our personality routine
+//For every stack frame anotated with ".cfi_personality 0x3,__gcfa_personality_v0"
+//This function will be called twice when unwinding
+//Once in the search phased and once in the cleanup phase
+_Unwind_Reason_Code __gcfa_personality_v0 (
+                     int version, _Unwind_Action actions, unsigned long long exceptionClass,
+                     struct _Unwind_Exception* unwind_exception, struct _Unwind_Context* context)
+{
+	//DEBUG
+	printf("Personality function (%d, %x, %llu, %p, %p):", version, actions, exceptionClass, unwind_exception, context);
+
+	//If we've reached the end of the stack then there is nothing much we can do...
+	if( actions & _UA_END_OF_STACK ) return _URC_END_OF_STACK;
+	
+	//DEBUG
+	if (actions & _UA_SEARCH_PHASE) {
+		printf(" lookup phase");
+	} 
+	//DEBUG
+	else if (actions & _UA_CLEANUP_PHASE) {
+		printf(" cleanup phase");
+	}
+	//Just in case, probably can't actually happen
+	else {
+		printf(" error\n");
+		return _URC_FATAL_PHASE1_ERROR;
+	}
+	
+	//Get a pointer to the language specific data from which we will read what we need
+	const unsigned char * lsd = (const unsigned char*) _Unwind_GetLanguageSpecificData( context );
+
+	if( !lsd ) {	//Nothing to do, keep unwinding
+		printf(" no LSD");
+		goto UNWIND;
+	}
+
+	//Get the instuction pointer and a reading pointer into the exception table
+	lsda_header_info lsd_info;
+	const unsigned char * cur_ptr = parse_lsda_header( context, lsd, &lsd_info);
+	_Unwind_Ptr instruction_ptr = _Unwind_GetIP( context );
+
+	//Linearly search the table for stuff to do
+	while( cur_ptr < lsd_info.action_table ) {
+		_Unwind_Ptr callsite_start;
+		_Unwind_Ptr callsite_len;
+		_Unwind_Ptr callsite_landing_pad;
+		_uleb128_t  callsite_action;
+
+		//Decode the common stuff we have in here
+		cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_start);
+		cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_len);
+		cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_landing_pad);
+		cur_ptr = read_uleb128 (cur_ptr, &callsite_action);
+
+		//Have we reach the correct frame info yet?
+		if( lsd_info.Start + callsite_start + callsite_len < instruction_ptr ) {
+			//DEBUG BEGIN
+			void * ls = (void*)lsd_info.Start;
+			void * cs = (void*)callsite_start;
+			void * cl = (void*)callsite_len;
+			void * bp = (void*)lsd_info.Start + callsite_start;
+			void * ep = (void*)lsd_info.Start + callsite_start + callsite_len;
+			void * ip = (void*)instruction_ptr;
+			printf("\nfound %p - %p (%p, %p, %p), looking for %p\n", bp, ep, ls, cs, cl, ip);
+			//DEBUG END
+			continue;
+		}
+		
+		//Have we gone too far
+		if( lsd_info.Start + callsite_start > instruction_ptr ) {
+			printf(" gone too far");
+			break;
+		}
+
+		//Something to do?
+		if( callsite_landing_pad ) {
+			//Which phase are we in
+			if (actions & _UA_SEARCH_PHASE) {
+				//Search phase, this means we probably found a potential handler and must check if it is a match
+
+				//If we have arbitrarily decided that 0 means nothing to do and 1 means there is a potential handler
+				//This doesn't seem to conflict the gcc default behavior
+				if (callsite_action != 0) {
+					//Now we want to run some code to see if the handler matches
+					//This is the tricky part where we want to the power to run arbitrary code
+					//However, generating a new exception table entry and try routine every time 
+					//is way more expansive than we might like
+					//The information we have is :
+					//  - The GR (???)
+					//  - The instruction pointer
+					//  - The instruction pointer info (???)
+					//  - The CFA (???)
+					//  - The BSP (Probably the base stack pointer)
+
+
+					//The current apprach uses one exception table entry per try block
+					_uleb128_t imatcher;
+					//Get the relative offset to the 
+					cur_ptr = read_uleb128 (cur_ptr, &imatcher);
+
+					//Get a function pointer from the relative offset and call it
+					_Unwind_Reason_Code (*matcher)() = (_Unwind_Reason_Code (*)())lsd_info.LPStart + imatcher;					
+					_Unwind_Reason_Code ret = matcher();
+
+					//Based on the return value, check if we matched the exception
+					if( ret == _URC_HANDLER_FOUND) printf(" handler found\n");
+					else printf(" no handler\n");
+					return ret;
+				}
+
+				//This is only a cleanup handler, ignore it
+				printf(" no action");
+			} 
+			else if (actions & _UA_CLEANUP_PHASE) {
+
+				if( (callsite_action != 0) && !(actions & _UA_HANDLER_FRAME) ){
+					//If this is a potential exception handler 
+					//but not the one that matched the exception in the seach phase,
+					//just ignore it
+					goto UNWIND;
+				}
+
+				//We need to run some clean-up or a handler
+				//These statment do the right thing but I don't know any specifics at all
+				_Unwind_SetGR( context, __builtin_eh_return_data_regno(0), (_Unwind_Ptr) unwind_exception );
+				_Unwind_SetGR( context, __builtin_eh_return_data_regno(1), 0 );
+
+				//I assume this sets the instruction pointer to the adress of the landing pad
+				//It doesn't actually set it, it only state the value that needs to be set once we return _URC_INSTALL_CONTEXT
+				_Unwind_SetIP( context, lsd_info.LPStart + callsite_landing_pad );
+
+				//DEBUG
+				printf(" action\n");
+
+				//Return have some action to run
+				return _URC_INSTALL_CONTEXT;
+			}
+		}
+
+		//Nothing to do, move along
+		printf(" no landing pad");
+	}
+	//No handling found
+	printf(" table end reached\n");
+
+	//DEBUG
+	UNWIND:
+	printf(" unwind\n");
+
+	//Keep unwinding the stack
+	return _URC_CONTINUE_UNWIND;
+}
+
+//We need a piece of storage to raise the exception
+struct _Unwind_Exception this_exception_storage;
+
+//Function needed by force unwind
+//It basically says to unwind the whole stack and then exit when we reach the end of the stack
+static _Unwind_Reason_Code _Stop_Fn(	
+	int version, 
+	_Unwind_Action actions, 
+	_Unwind_Exception_Class exceptionClass, 
+	struct _Unwind_Exception * unwind_exception, 
+	struct _Unwind_Context * context, 
+	void * some_param
+) {
+	if( actions & _UA_END_OF_STACK  ) exit(1);
+	if( actions & _UA_CLEANUP_PHASE ) return _URC_NO_REASON;
+
+	return _URC_FATAL_PHASE2_ERROR;
+}
+
+//Example throw routine
+void throw( int val ) {
+	//Store the current exception
+	this_exception = val;
+
+	//DEBUG
+	printf("Throwing exception %d\n", this_exception);
+
+	//Call stdlibc to raise the exception
+	_Unwind_Reason_Code ret = _Unwind_RaiseException( &this_exception_storage );
+
+	//If we reach here it means something happened
+	//For resumption to work we need to find a way to return back to here
+	//Most of them will probably boil down to setting a global flag and making the phase 1 either stop or fail.
+	//Causing an error on purpose may help avoiding unnecessary work but it might have some weird side effects.
+	//If we just pretend no handler was found that would work but may be expensive for no reason since we will always
+	//search the whole stack
+
+	if( ret == _URC_END_OF_STACK ) {
+		//No proper handler was found
+		//This can be handled in several way
+		//C++ calls std::terminate
+		//Here we force unwind the stack, basically raising a cancellation
+		printf("Uncaught exception %p\n", &this_exception_storage);
+		
+		ret = _Unwind_ForcedUnwind( &this_exception_storage, _Stop_Fn, (void*)0x22 );
+		printf("UNWIND ERROR %d after force unwind\n", ret);
+		abort();
+	}
+
+	//We did not simply reach the end of the stack without finding a handler,
+	//Something wen't wrong
+	printf("UNWIND ERROR %d after raise exception\n", ret);
+	abort();
+}
Index: doc/working/exception/impl/except.h
===================================================================
--- doc/working/exception/impl/except.h	(revision daf9671439895f6d3bdd15ca16d77fa736b00a4c)
+++ doc/working/exception/impl/except.h	(revision daf9671439895f6d3bdd15ca16d77fa736b00a4c)
@@ -0,0 +1,3 @@
+#include <unwind.h>
+
+void throw( int val );
Index: doc/working/exception/impl/lsda.h
===================================================================
--- doc/working/exception/impl/lsda.h	(revision daf9671439895f6d3bdd15ca16d77fa736b00a4c)
+++ doc/working/exception/impl/lsda.h	(revision daf9671439895f6d3bdd15ca16d77fa736b00a4c)
@@ -0,0 +1,262 @@
+//This code was stolen from gcc to read exception tables
+
+
+/* If using C++, references to abort have to be qualified with std::.  */
+#if __cplusplus
+#define __gxx_abort std::abort
+#else
+#define __gxx_abort abort
+#endif
+
+/* Pointer encodings, from dwarf2.h.  */
+#define DW_EH_PE_absptr         0x00
+#define DW_EH_PE_omit           0xff
+
+#define DW_EH_PE_uleb128        0x01
+#define DW_EH_PE_udata2         0x02
+#define DW_EH_PE_udata4         0x03
+#define DW_EH_PE_udata8         0x04
+#define DW_EH_PE_sleb128        0x09
+#define DW_EH_PE_sdata2         0x0A
+#define DW_EH_PE_sdata4         0x0B
+#define DW_EH_PE_sdata8         0x0C
+#define DW_EH_PE_signed         0x08
+
+#define DW_EH_PE_pcrel          0x10
+#define DW_EH_PE_textrel        0x20
+#define DW_EH_PE_datarel        0x30
+#define DW_EH_PE_funcrel        0x40
+#define DW_EH_PE_aligned        0x50
+
+#define DW_EH_PE_indirect	0x80
+
+
+
+int handler_found = 0;
+
+/* Given an encoding, return the number of bytes the format occupies.
+This is only defined for fixed-size encodings, and so does not
+include leb128.  */
+static unsigned int size_of_encoded_value (unsigned char encoding) __attribute__ ((unused));
+
+static unsigned int size_of_encoded_value (unsigned char encoding)
+{
+	if (encoding == DW_EH_PE_omit) return 0;
+
+	switch (encoding & 0x07) {
+		case DW_EH_PE_absptr: return sizeof (void *);
+		case DW_EH_PE_udata2: return 2;
+		case DW_EH_PE_udata4: return 4;
+		case DW_EH_PE_udata8: return 8;
+	}
+	__gxx_abort ();
+}
+
+/* Given an encoding and an _Unwind_Context, return the base to which
+the encoding is relative.  This base may then be passed to
+read_encoded_value_with_base for use when the _Unwind_Context is
+not available.  */
+static _Unwind_Ptr base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context)
+{
+	if (encoding == DW_EH_PE_omit) return 0;
+
+	switch (encoding & 0x70) {
+		case DW_EH_PE_absptr:
+		case DW_EH_PE_pcrel:
+		case DW_EH_PE_aligned:
+			return 0;
+		case DW_EH_PE_textrel:
+			return _Unwind_GetTextRelBase (context);
+		case DW_EH_PE_datarel:
+			return _Unwind_GetDataRelBase (context);
+		case DW_EH_PE_funcrel:
+			return _Unwind_GetRegionStart (context);
+	}
+	__gxx_abort ();
+}
+
+/* Read an unsigned leb128 value from P, store the value in VAL, return
+P incremented past the value.  We assume that a word is large enough to
+hold any value so encoded; if it is smaller than a pointer on some target,
+pointers should not be leb128 encoded on that target.  */
+static const unsigned char * read_uleb128 (const unsigned char *p, _uleb128_t *val)
+{
+	unsigned int shift = 0;
+	unsigned char byte;
+	_uleb128_t result;
+
+	result = 0;
+	do
+	{
+		byte = *p++;
+		result |= ((_uleb128_t)byte & 0x7f) << shift;
+		shift += 7;
+	}
+	while (byte & 0x80);
+
+	*val = result;
+	return p;
+}
+
+/* Similar, but read a signed leb128 value.  */
+static const unsigned char * read_sleb128 (const unsigned char *p, _sleb128_t *val)
+{
+	unsigned int shift = 0;
+	unsigned char byte;
+	_uleb128_t result;
+
+	result = 0;
+	do
+	{
+		byte = *p++;
+		result |= ((_uleb128_t)byte & 0x7f) << shift;
+		shift += 7;
+	}
+	while (byte & 0x80);
+
+	/* Sign-extend a negative value.  */
+	if (shift < 8 * sizeof(result) && (byte & 0x40) != 0) result |= -(((_uleb128_t)1L) << shift);
+
+	*val = (_sleb128_t) result;
+	return p;
+}
+
+/* Load an encoded value from memory at P.  The value is returned in VAL;
+The function returns P incremented past the value.  BASE is as given
+by base_of_encoded_value for this encoding in the appropriate context.  */
+
+static const unsigned char * read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base, const unsigned char *p, _Unwind_Ptr *val)
+{
+	union unaligned
+	{
+		void *ptr;
+		unsigned u2 __attribute__ ((mode (HI)));
+		unsigned u4 __attribute__ ((mode (SI)));
+		unsigned u8 __attribute__ ((mode (DI)));
+		signed s2 __attribute__ ((mode (HI)));
+		signed s4 __attribute__ ((mode (SI)));
+		signed s8 __attribute__ ((mode (DI)));
+	} __attribute__((__packed__));
+
+	const union unaligned *u = (const union unaligned *) p;
+	_Unwind_Internal_Ptr result;
+
+	if (encoding == DW_EH_PE_aligned)
+	{
+		_Unwind_Internal_Ptr a = (_Unwind_Internal_Ptr) p;
+		a = (a + sizeof (void *) - 1) & - sizeof(void *);
+		result = *(_Unwind_Internal_Ptr *) a;
+		p = (const unsigned char *) (_Unwind_Internal_Ptr) (a + sizeof (void *));
+	}
+	else
+	{
+		switch (encoding & 0x0f)
+		{
+			case DW_EH_PE_absptr:
+				result = (_Unwind_Internal_Ptr) u->ptr;
+				p += sizeof (void *);
+				break;
+			case DW_EH_PE_uleb128:
+			{
+				_uleb128_t tmp;
+				p = read_uleb128 (p, &tmp);
+				result = (_Unwind_Internal_Ptr) tmp;
+			}
+			break;
+
+			case DW_EH_PE_sleb128:
+			{
+				_sleb128_t tmp;
+				p = read_sleb128 (p, &tmp);
+				result = (_Unwind_Internal_Ptr) tmp;
+			}
+			break;
+
+			case DW_EH_PE_udata2:
+				result = u->u2;
+				p += 2;
+				break;
+			case DW_EH_PE_udata4:
+				result = u->u4;
+				p += 4;
+				break;
+			case DW_EH_PE_udata8:
+				result = u->u8;
+				p += 8;
+				break;
+			case DW_EH_PE_sdata2:
+				result = u->s2;
+				p += 2;
+				break;
+			case DW_EH_PE_sdata4:
+				result = u->s4;
+				p += 4;
+				break;
+			case DW_EH_PE_sdata8:
+				result = u->s8;
+				p += 8;
+				break;
+			default:
+				__gxx_abort();
+		}
+
+		if (result != 0)
+		{
+			result += ((encoding & 0x70) == DW_EH_PE_pcrel ? (_Unwind_Internal_Ptr) u : base);
+			
+			if (encoding & DW_EH_PE_indirect) result = *(_Unwind_Internal_Ptr *) result;
+		}
+	}
+
+	*val = result;
+	return p;
+}
+
+/* Like read_encoded_value_with_base, but get the base from the context
+rather than providing it directly.  */
+static inline const unsigned char * read_encoded_value (struct _Unwind_Context *context, unsigned char encoding, const unsigned char *p, _Unwind_Ptr *val)
+{
+	return read_encoded_value_with_base (encoding, base_of_encoded_value (encoding, context), p, val);
+}
+
+typedef struct
+{
+	_Unwind_Ptr Start;
+	_Unwind_Ptr LPStart;
+	_Unwind_Ptr ttype_base;
+	const unsigned char *TType;
+	const unsigned char *action_table;
+	unsigned char ttype_encoding;
+	unsigned char call_site_encoding;
+} lsda_header_info;
+
+static const unsigned char * parse_lsda_header (struct _Unwind_Context *context, const unsigned char *p, lsda_header_info *info)
+{
+	_uleb128_t tmp;
+	unsigned char lpstart_encoding;
+
+	info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
+
+	/* Find @LPStart, the base to which landing pad offsets are relative.  */
+	lpstart_encoding = *p++;
+	if (lpstart_encoding != DW_EH_PE_omit) p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart);
+
+	else info->LPStart = info->Start;
+
+	/* Find @TType, the base of the handler and exception spec type data.  */
+	info->ttype_encoding = *p++;
+	if (info->ttype_encoding != DW_EH_PE_omit)
+	{
+		p = read_uleb128 (p, &tmp);
+		info->TType = p + tmp;
+	}
+	else info->TType = 0;
+
+	/* The encoding and length of the call-site table; the action table
+	immediately follows.  */
+	info->call_site_encoding = *p++;
+	p = read_uleb128 (p, &tmp);
+	info->action_table = p + tmp;
+
+	return p;
+}
Index: doc/working/exception/impl/main.c
===================================================================
--- doc/working/exception/impl/main.c	(revision daf9671439895f6d3bdd15ca16d77fa736b00a4c)
+++ doc/working/exception/impl/main.c	(revision daf9671439895f6d3bdd15ca16d77fa736b00a4c)
@@ -0,0 +1,134 @@
+#include <stdio.h>
+#include "except.h"
+
+#define EXCEPTION 2
+
+struct type_raii_t {
+	char * msg;
+};
+
+//Dtor function to test clean up routines
+void dtor( struct type_raii_t * this ) {
+	printf("%s\n", this->msg);
+}
+
+//Type macro use to make scope unwinding easier to see.
+#define raii_t __attribute__(( cleanup(dtor) )) struct type_raii_t
+
+//Leaf functions that raises exception
+void bar() {
+	raii_t a = { "Bar dtor" };
+
+	throw( EXCEPTION );
+}
+
+//Matcher function which will check if the exception was correctly caught
+extern int this_exception;
+_Unwind_Reason_Code foo_try_match() {
+	return this_exception == 3 ? _URC_HANDLER_FOUND : _URC_CONTINUE_UNWIND;
+}
+
+//Try statements are hoisted out see comments for details
+//With this could probably be unique and simply linked from
+//libcfa but there is one problem left, see the exception table 
+//for details
+void try( void (*try_block)(), void (*catch_block)() )
+{
+	//Setup statments
+	//These 2 statments won't actually result in any code,
+	//they only setup global tables.
+	//However, they clobber gcc cancellation support from gcc.
+	//We can replace the personality routine but replacing the exception
+	//table gcc generates is not really doable, it generates labels based
+	//on how the assembly works.
+	//Setup the personality routine
+	asm volatile (".cfi_personality 0x3,__gcfa_personality_v0");
+	//Setup the exception table
+	asm volatile (".cfi_lsda 0x3, .LLSDACFA2");
+
+	//Label which defines the start of the area for which the handler is setup
+	asm volatile (".TRYSTART:");
+
+	//The actual statements of the try blocks
+	try_block();
+
+	//asm statement to prevent deadcode removal
+	asm volatile goto ("" : : : : CATCH );
+
+	//Normal return
+	return;
+
+	//Exceptionnal path
+	CATCH : __attribute__(( unused ));
+	//Label which defines the end of the area for which the handler is setup
+	asm volatile (".TRYEND:");
+	//Label which defines the start of the exception landing pad
+	//basically what will be called when the exception is caught
+	//Note, if multiple handlers are given, the multiplexing should be done
+	//by the generated code, not the exception runtime
+	asm volatile (".CATCH:");
+
+	//Exception handler
+	catch_block();
+}
+
+//Exception table data we need to generate
+//While this is almost generic, the custom data refers to
+//foo_try_match try match, which is no way generic
+//Some more works need to be done if we want to have a single 
+//call to the try routine
+asm (
+	//HEADER
+	".LFECFA1:\n"
+	"	.globl	__gcfa_personality_v0\n"
+	"	.section	.gcc_except_table,\"a\",@progbits\n"
+	".LLSDACFA2:\n"							//TABLE header
+	"	.byte	0xff\n"
+	"	.byte	0xff\n"
+	"	.byte	0x1\n"
+	"	.uleb128 .LLSDACSECFA2-.LLSDACSBCFA2\n"		//BODY length
+	//Body uses language specific data and therefore could be modified arbitrarily
+	".LLSDACSBCFA2:\n"						//BODY start
+	"	.uleb128 .TRYSTART-try\n"				//Handled area start  (relative to start of function)
+	"	.uleb128 .TRYEND-.TRYSTART\n"				//Handled area length
+	"	.uleb128 .CATCH-try\n"				//Hanlder landing pad adress  (relative to start of function)
+	"	.uleb128 1\n"						//Action code, gcc seems to use always 0
+	//Beyond this point we don't match gcc data'
+	"	.uleb128 foo_try_match-try\n"			//Handler routine to check if the exception is matched
+	".LLSDACSECFA2:\n"						//BODY end
+	"	.text\n"							//TABLE footer
+	"	.size	try, .-try\n"
+	"	.ident	\"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n"
+	"	.section	.note.GNU-stack,\"x\",@progbits\n"
+);
+
+void foo() {
+	raii_t a = { "Foo dtor" };
+
+	//Since try will clobber the gcc exception table assembly,
+	//We need to nest this to have gcc regenerate the data
+	void foo_try_block() {
+		raii_t b = { "Foo try dtor" };
+
+		bar();
+
+		printf("Called bar successfully\n");
+	}
+
+	void foo_catch_block() {
+		printf("Exception caught\n");
+	}
+
+	//Actual call to the try block
+	try( foo_try_block, foo_catch_block );
+
+	printf( "Foo exited normally\n" );
+}
+
+int main() {
+	raii_t a = { "Main dtor" };
+
+	foo();
+
+	printf("End of program reached\n");
+}
Index: doc/working/exception/impl/main.cfa
===================================================================
--- doc/working/exception/impl/main.cfa	(revision daf9671439895f6d3bdd15ca16d77fa736b00a4c)
+++ doc/working/exception/impl/main.cfa	(revision daf9671439895f6d3bdd15ca16d77fa736b00a4c)
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include "except.h"
+
+struct raii_t {
+	char * msg;
+};
+
+void ^?{}( type_raii_t * this ) {
+	printf("%s\n", this->msg);
+}
+
+void bar() {
+	raii_t a = { "Bar dtor" };
+
+	throw( 3 );
+}
+
+void foo() {
+	raii_t a = { "Foo dtor" };
+
+	try {
+		raii_t b = { "Foo try dtor" };
+
+		bar();
+
+		printf("Called bar successfully\n");
+	}
+	catch( 2 ) {
+		printf("Exception caught\n");
+	}
+
+	printf( "Foo exited normally\n" );
+}
+
+int main() {
+	raii_t a = { "Main dtor" };
+
+	foo();
+
+	printf("End of program reached\n");
+}
Index: doc/working/exception/lsda.h
===================================================================
--- doc/working/exception/lsda.h	(revision ae6f1ec1d85524657b3516f4d6718b46777f8d37)
+++ 	(revision )
@@ -1,262 +1,0 @@
-//This code was stolen from gcc to read exception tables
-
-
-/* If using C++, references to abort have to be qualified with std::.  */
-#if __cplusplus
-#define __gxx_abort std::abort
-#else
-#define __gxx_abort abort
-#endif
-
-/* Pointer encodings, from dwarf2.h.  */
-#define DW_EH_PE_absptr         0x00
-#define DW_EH_PE_omit           0xff
-
-#define DW_EH_PE_uleb128        0x01
-#define DW_EH_PE_udata2         0x02
-#define DW_EH_PE_udata4         0x03
-#define DW_EH_PE_udata8         0x04
-#define DW_EH_PE_sleb128        0x09
-#define DW_EH_PE_sdata2         0x0A
-#define DW_EH_PE_sdata4         0x0B
-#define DW_EH_PE_sdata8         0x0C
-#define DW_EH_PE_signed         0x08
-
-#define DW_EH_PE_pcrel          0x10
-#define DW_EH_PE_textrel        0x20
-#define DW_EH_PE_datarel        0x30
-#define DW_EH_PE_funcrel        0x40
-#define DW_EH_PE_aligned        0x50
-
-#define DW_EH_PE_indirect	0x80
-
-
-
-int handler_found = 0;
-
-/* Given an encoding, return the number of bytes the format occupies.
-This is only defined for fixed-size encodings, and so does not
-include leb128.  */
-static unsigned int size_of_encoded_value (unsigned char encoding) __attribute__ ((unused));
-
-static unsigned int size_of_encoded_value (unsigned char encoding)
-{
-	if (encoding == DW_EH_PE_omit) return 0;
-
-	switch (encoding & 0x07) {
-		case DW_EH_PE_absptr: return sizeof (void *);
-		case DW_EH_PE_udata2: return 2;
-		case DW_EH_PE_udata4: return 4;
-		case DW_EH_PE_udata8: return 8;
-	}
-	__gxx_abort ();
-}
-
-/* Given an encoding and an _Unwind_Context, return the base to which
-the encoding is relative.  This base may then be passed to
-read_encoded_value_with_base for use when the _Unwind_Context is
-not available.  */
-static _Unwind_Ptr base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context)
-{
-	if (encoding == DW_EH_PE_omit) return 0;
-
-	switch (encoding & 0x70) {
-		case DW_EH_PE_absptr:
-		case DW_EH_PE_pcrel:
-		case DW_EH_PE_aligned:
-			return 0;
-		case DW_EH_PE_textrel:
-			return _Unwind_GetTextRelBase (context);
-		case DW_EH_PE_datarel:
-			return _Unwind_GetDataRelBase (context);
-		case DW_EH_PE_funcrel:
-			return _Unwind_GetRegionStart (context);
-	}
-	__gxx_abort ();
-}
-
-/* Read an unsigned leb128 value from P, store the value in VAL, return
-P incremented past the value.  We assume that a word is large enough to
-hold any value so encoded; if it is smaller than a pointer on some target,
-pointers should not be leb128 encoded on that target.  */
-static const unsigned char * read_uleb128 (const unsigned char *p, _uleb128_t *val)
-{
-	unsigned int shift = 0;
-	unsigned char byte;
-	_uleb128_t result;
-
-	result = 0;
-	do
-	{
-		byte = *p++;
-		result |= ((_uleb128_t)byte & 0x7f) << shift;
-		shift += 7;
-	}
-	while (byte & 0x80);
-
-	*val = result;
-	return p;
-}
-
-/* Similar, but read a signed leb128 value.  */
-static const unsigned char * read_sleb128 (const unsigned char *p, _sleb128_t *val)
-{
-	unsigned int shift = 0;
-	unsigned char byte;
-	_uleb128_t result;
-
-	result = 0;
-	do
-	{
-		byte = *p++;
-		result |= ((_uleb128_t)byte & 0x7f) << shift;
-		shift += 7;
-	}
-	while (byte & 0x80);
-
-	/* Sign-extend a negative value.  */
-	if (shift < 8 * sizeof(result) && (byte & 0x40) != 0) result |= -(((_uleb128_t)1L) << shift);
-
-	*val = (_sleb128_t) result;
-	return p;
-}
-
-/* Load an encoded value from memory at P.  The value is returned in VAL;
-The function returns P incremented past the value.  BASE is as given
-by base_of_encoded_value for this encoding in the appropriate context.  */
-
-static const unsigned char * read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base, const unsigned char *p, _Unwind_Ptr *val)
-{
-	union unaligned
-	{
-		void *ptr;
-		unsigned u2 __attribute__ ((mode (HI)));
-		unsigned u4 __attribute__ ((mode (SI)));
-		unsigned u8 __attribute__ ((mode (DI)));
-		signed s2 __attribute__ ((mode (HI)));
-		signed s4 __attribute__ ((mode (SI)));
-		signed s8 __attribute__ ((mode (DI)));
-	} __attribute__((__packed__));
-
-	const union unaligned *u = (const union unaligned *) p;
-	_Unwind_Internal_Ptr result;
-
-	if (encoding == DW_EH_PE_aligned)
-	{
-		_Unwind_Internal_Ptr a = (_Unwind_Internal_Ptr) p;
-		a = (a + sizeof (void *) - 1) & - sizeof(void *);
-		result = *(_Unwind_Internal_Ptr *) a;
-		p = (const unsigned char *) (_Unwind_Internal_Ptr) (a + sizeof (void *));
-	}
-	else
-	{
-		switch (encoding & 0x0f)
-		{
-			case DW_EH_PE_absptr:
-				result = (_Unwind_Internal_Ptr) u->ptr;
-				p += sizeof (void *);
-				break;
-			case DW_EH_PE_uleb128:
-			{
-				_uleb128_t tmp;
-				p = read_uleb128 (p, &tmp);
-				result = (_Unwind_Internal_Ptr) tmp;
-			}
-			break;
-
-			case DW_EH_PE_sleb128:
-			{
-				_sleb128_t tmp;
-				p = read_sleb128 (p, &tmp);
-				result = (_Unwind_Internal_Ptr) tmp;
-			}
-			break;
-
-			case DW_EH_PE_udata2:
-				result = u->u2;
-				p += 2;
-				break;
-			case DW_EH_PE_udata4:
-				result = u->u4;
-				p += 4;
-				break;
-			case DW_EH_PE_udata8:
-				result = u->u8;
-				p += 8;
-				break;
-			case DW_EH_PE_sdata2:
-				result = u->s2;
-				p += 2;
-				break;
-			case DW_EH_PE_sdata4:
-				result = u->s4;
-				p += 4;
-				break;
-			case DW_EH_PE_sdata8:
-				result = u->s8;
-				p += 8;
-				break;
-			default:
-				__gxx_abort();
-		}
-
-		if (result != 0)
-		{
-			result += ((encoding & 0x70) == DW_EH_PE_pcrel ? (_Unwind_Internal_Ptr) u : base);
-			
-			if (encoding & DW_EH_PE_indirect) result = *(_Unwind_Internal_Ptr *) result;
-		}
-	}
-
-	*val = result;
-	return p;
-}
-
-/* Like read_encoded_value_with_base, but get the base from the context
-rather than providing it directly.  */
-static inline const unsigned char * read_encoded_value (struct _Unwind_Context *context, unsigned char encoding, const unsigned char *p, _Unwind_Ptr *val)
-{
-	return read_encoded_value_with_base (encoding, base_of_encoded_value (encoding, context), p, val);
-}
-
-typedef struct
-{
-	_Unwind_Ptr Start;
-	_Unwind_Ptr LPStart;
-	_Unwind_Ptr ttype_base;
-	const unsigned char *TType;
-	const unsigned char *action_table;
-	unsigned char ttype_encoding;
-	unsigned char call_site_encoding;
-} lsda_header_info;
-
-static const unsigned char * parse_lsda_header (struct _Unwind_Context *context, const unsigned char *p, lsda_header_info *info)
-{
-	_uleb128_t tmp;
-	unsigned char lpstart_encoding;
-
-	info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
-
-	/* Find @LPStart, the base to which landing pad offsets are relative.  */
-	lpstart_encoding = *p++;
-	if (lpstart_encoding != DW_EH_PE_omit) p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart);
-
-	else info->LPStart = info->Start;
-
-	/* Find @TType, the base of the handler and exception spec type data.  */
-	info->ttype_encoding = *p++;
-	if (info->ttype_encoding != DW_EH_PE_omit)
-	{
-		p = read_uleb128 (p, &tmp);
-		info->TType = p + tmp;
-	}
-	else info->TType = 0;
-
-	/* The encoding and length of the call-site table; the action table
-	immediately follows.  */
-	info->call_site_encoding = *p++;
-	p = read_uleb128 (p, &tmp);
-	info->action_table = p + tmp;
-
-	return p;
-}
Index: doc/working/exception/main.c
===================================================================
--- doc/working/exception/main.c	(revision ae6f1ec1d85524657b3516f4d6718b46777f8d37)
+++ 	(revision )
@@ -1,134 +1,0 @@
-#include <stdio.h>
-#include "except.h"
-
-#define EXCEPTION 2
-
-struct type_raii_t {
-	char * msg;
-};
-
-//Dtor function to test clean up routines
-void dtor( struct type_raii_t * this ) {
-	printf("%s\n", this->msg);
-}
-
-//Type macro use to make scope unwinding easier to see.
-#define raii_t __attribute__(( cleanup(dtor) )) struct type_raii_t
-
-//Leaf functions that raises exception
-void bar() {
-	raii_t a = { "Bar dtor" };
-
-	throw( EXCEPTION );
-}
-
-//Matcher function which will check if the exception was correctly caught
-extern int this_exception;
-_Unwind_Reason_Code foo_try_match() {
-	return this_exception == 2 ? _URC_HANDLER_FOUND : _URC_CONTINUE_UNWIND;
-}
-
-//Try statements are hoisted out see comments for details
-//With this could probably be unique and simply linked from
-//libcfa but there is one problem left, see the exception table 
-//for details
-void try( void (*try_block)(), void (*catch_block)() )
-{
-	//Setup statments
-	//These 2 statments won't actually result in any code,
-	//they only setup global tables.
-	//However, they clobber gcc cancellation support from gcc.
-	//We can replace the personality routine but replacing the exception
-	//table gcc generates is not really doable, it generates labels based
-	//on how the assembly works.
-	//Setup the personality routine
-	asm volatile (".cfi_personality 0x3,__gcfa_personality_v0");
-	//Setup the exception table
-	asm volatile (".cfi_lsda 0x3, .LLSDACFA2");
-
-	//Label which defines the start of the area for which the handler is setup
-	asm volatile (".TRYSTART:");
-
-	//The actual statements of the try blocks
-	try_block();
-
-	//asm statement to prevent deadcode removal
-	asm volatile goto ("" : : : : CATCH );
-
-	//Normal return
-	return;
-
-	//Exceptionnal path
-	CATCH : __attribute__(( unused ));
-	//Label which defines the end of the area for which the handler is setup
-	asm volatile (".TRYEND:");
-	//Label which defines the start of the exception landing pad
-	//basically what will be called when the exception is caught
-	//Note, if multiple handlers are given, the multiplexing should be done
-	//by the generated code, not the exception runtime
-	asm volatile (".CATCH:");
-
-	//Exception handler
-	catch_block();
-}
-
-//Exception table data we need to generate
-//While this is almost generic, the custom data refers to
-//foo_try_match try match, which is no way generic
-//Some more works need to be done if we want to have a single 
-//call to the try routine
-asm (
-	//HEADER
-	".LFECFA1:\n"
-	"	.globl	__gcfa_personality_v0\n"
-	"	.section	.gcc_except_table,\"a\",@progbits\n"
-	".LLSDACFA2:\n"							//TABLE header
-	"	.byte	0xff\n"
-	"	.byte	0xff\n"
-	"	.byte	0x1\n"
-	"	.uleb128 .LLSDACSECFA2-.LLSDACSBCFA2\n"		//BODY length
-	//Body uses language specific data and therefore could be modified arbitrarily
-	".LLSDACSBCFA2:\n"						//BODY start
-	"	.uleb128 .TRYSTART-try\n"				//Handled area start  (relative to start of function)
-	"	.uleb128 .TRYEND-.TRYSTART\n"				//Handled area length
-	"	.uleb128 .CATCH-try\n"				//Hanlder landing pad adress  (relative to start of function)
-	"	.uleb128 1\n"						//Action code, gcc seems to use always 0
-	//Beyond this point we don't match gcc data'
-	"	.uleb128 foo_try_match-try\n"			//Handler routine to check if the exception is matched
-	".LLSDACSECFA2:\n"						//BODY end
-	"	.text\n"							//TABLE footer
-	"	.size	try, .-try\n"
-	"	.ident	\"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n"
-	"	.section	.note.GNU-stack,\"x\",@progbits\n"
-);
-
-void foo() {
-	raii_t a = { "Foo dtor" };
-
-	//Since try will clobber the gcc exception table assembly,
-	//We need to nest this to have gcc regenerate the data
-	void foo_try_block() {
-		raii_t b = { "Foo try dtor" };
-
-		bar();
-
-		printf("Called bar successfully\n");
-	}
-
-	void foo_catch_block() {
-		printf("Exception caught\n");
-	}
-
-	//Actual call to the try block
-	try( foo_try_block, foo_catch_block );
-
-	printf( "Foo exited normally\n" );
-}
-
-int main() {
-	raii_t a = { "Main dtor" };
-
-	foo();
-
-	printf("End of program reached\n");
-}
Index: doc/working/exception/main.cfa
===================================================================
--- doc/working/exception/main.cfa	(revision ae6f1ec1d85524657b3516f4d6718b46777f8d37)
+++ 	(revision )
@@ -1,41 +1,0 @@
-#include <stdio.h>
-#include "except.h"
-
-struct raii_t {
-	char * msg;
-};
-
-void ^?{}( type_raii_t * this ) {
-	printf("%s\n", this->msg);
-}
-
-void bar() {
-	raii_t a = { "Bar dtor" };
-
-	throw( 3 );
-}
-
-void foo() {
-	raii_t a = { "Foo dtor" };
-
-	try {
-		raii_t b = { "Foo try dtor" };
-
-		bar();
-
-		printf("Called bar successfully\n");
-	}
-	catch( 2 ) {
-		printf("Exception caught\n");
-	}
-
-	printf( "Foo exited normally\n" );
-}
-
-int main() {
-	raii_t a = { "Main dtor" };
-
-	foo();
-
-	printf("End of program reached\n");
-}
