Changeset cd7ef0b for src/libcfa/exception.c
- Timestamp:
- Aug 10, 2017, 3:39:11 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 38d70ab
- Parents:
- 275f4b4 (diff), e1780a2 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/exception.c
r275f4b4 rcd7ef0b 9 9 // Author : Andrew Beach 10 10 // Created On : Mon Jun 26 15:13:00 2017 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Jul 26 10:37:51201713 // Update Count : 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Aug 4 15:20:00 2017 13 // Update Count : 6 14 14 // 15 16 #include <stddef.h> // for size_t 15 17 16 18 #include "exception.h" … … 32 34 #include "lsda.h" 33 35 36 37 // Base exception vtable is abstract, you should not have base exceptions. 38 struct __cfaehm__base_exception_t_vtable 39 ___cfaehm__base_exception_t_vtable_instance = { 40 .parent = NULL, 41 .size = 0, 42 .copy = NULL, 43 .free = NULL, 44 .msg = NULL 45 }; 46 47 34 48 // Temperary global exception context. Does not work with concurency. 35 struct shared_stack_t {49 struct exception_context_t { 36 50 struct __cfaehm__try_resume_node * top_resume; 37 51 struct __cfaehm__try_resume_node * current_resume; 38 52 39 exception current_exception;53 exception * current_exception; 40 54 int current_handler_index; 41 55 } shared_stack = {NULL, NULL, 0, 0}; 42 56 57 // Get the current exception context. 58 // There can be a single global until multithreading occurs, then each stack 59 // needs its own. It will have to be updated to handle that. 60 struct exception_context_t * this_exception_context() { 61 return &shared_stack; 62 } 63 //#define SAVE_EXCEPTION_CONTEXT(to_name) 64 //struct exception_context_t * to_name = this_exception_context(); 65 //exception * this_exception() { 66 // return this_exception_context()->current_exception; 67 //} 43 68 44 69 … … 55 80 56 81 // DEBUG 57 printf("Throwing resumption exception %d\n", *except);82 printf("Throwing resumption exception\n"); 58 83 59 84 struct __cfaehm__try_resume_node * original_head = shared_stack.current_resume; … … 69 94 } 70 95 71 printf("Unhandled exception %d\n", *except);96 printf("Unhandled exception\n"); 72 97 shared_stack.current_resume = original_head; 73 98 … … 94 119 // TERMINATION =============================================================== 95 120 96 // Requires -fexceptions to work. 97 98 // Global which defines the current exception. Currently an int just to make matching easier. 99 //int this_exception; (became shared_stack.current_exception) 121 // MEMORY MANAGEMENT (still for integers) 122 // May have to move to cfa for constructors and destructors (references). 123 124 struct __cfaehm__node { 125 struct __cfaehm__node * next; 126 }; 127 128 #define NODE_TO_EXCEPT(node) ((exception *)(1 + (node))) 129 #define EXCEPT_TO_NODE(except) ((struct __cfaehm__node *)(except) - 1) 130 131 // Creates a copy of the indicated exception and sets current_exception to it. 132 static void __cfaehm__allocate_exception( exception * except ) { 133 struct exception_context_t * context = this_exception_context(); 134 135 // Allocate memory for the exception. 136 struct __cfaehm__node * store = malloc( 137 sizeof( struct __cfaehm__node ) + except->virtual_table->size ); 138 139 if ( ! store ) { 140 // Failure: cannot allocate exception. Terminate thread. 141 abort(); // <- Although I think it might be the process. 142 } 143 144 // Add the node to the list: 145 store->next = EXCEPT_TO_NODE(context->current_exception); 146 context->current_exception = NODE_TO_EXCEPT(store); 147 148 // Copy the exception to storage. 149 except->virtual_table->copy( context->current_exception, except ); 150 } 151 152 // Delete the provided exception, unsetting current_exception if relivant. 153 static void __cfaehm__delete_exception( exception * except ) { 154 struct exception_context_t * context = this_exception_context(); 155 156 // DEBUG 157 printf( "Deleting Exception\n"); 158 159 // Remove the exception from the list. 160 struct __cfaehm__node * to_free = EXCEPT_TO_NODE(except); 161 struct __cfaehm__node * node; 162 163 if ( context->current_exception == except ) { 164 node = to_free->next; 165 context->current_exception = (node) ? NODE_TO_EXCEPT(node) : 0; 166 } else { 167 node = EXCEPT_TO_NODE(context->current_exception); 168 // It may always be in the first or second position. 169 while( to_free != node->next ) { 170 node = node->next; 171 } 172 node->next = to_free->next; 173 } 174 175 // Free the old exception node. 176 except->virtual_table->free( except ); 177 free( to_free ); 178 } 179 180 // If this isn't a rethrow (*except==0), delete the provided exception. 181 void __cfaehm__cleanup_terminate( void * except ) { 182 if ( *(void**)except ) __cfaehm__delete_exception( *(exception**)except ); 183 } 184 100 185 101 186 // We need a piece of storage to raise the exception … … 117 202 } 118 203 119 void __cfaehm__throw_terminate( exception * val ) { 120 // Store the current exception 121 shared_stack.current_exception = *val; 122 123 // DEBUG 124 printf("Throwing termination exception %d\n", *val); 204 // The exception that is being thrown must already be stored. 205 __attribute__((noreturn)) void __cfaehm__begin_unwind(void) { 206 if ( ! this_exception_context()->current_exception ) { 207 printf("UNWIND ERROR missing exception in begin unwind\n"); 208 abort(); 209 } 210 125 211 126 212 // Call stdlibc to raise the exception … … 148 234 } 149 235 150 // Nesting this the other way would probably be faster. 236 void __cfaehm__throw_terminate( exception * val ) { 237 // DEBUG 238 printf("Throwing termination exception\n"); 239 240 __cfaehm__allocate_exception( val ); 241 __cfaehm__begin_unwind(); 242 } 243 151 244 void __cfaehm__rethrow_terminate(void) { 152 245 // DEBUG 153 246 printf("Rethrowing termination exception\n"); 154 247 155 __cfaehm__ throw_terminate(&shared_stack.current_exception);248 __cfaehm__begin_unwind(); 156 249 } 157 250 … … 263 356 _Unwind_Reason_Code (*matcher)(exception *) = 264 357 MATCHER_FROM_CONTEXT(context); 265 int index = matcher( &shared_stack.current_exception);358 int index = matcher(shared_stack.current_exception); 266 359 _Unwind_Reason_Code ret = (0 == index) 267 360 ? _URC_CONTINUE_UNWIND : _URC_HANDLER_FOUND; … … 359 452 // Exception handler 360 453 catch_block( shared_stack.current_handler_index, 361 &shared_stack.current_exception );454 shared_stack.current_exception ); 362 455 } 363 456
Note:
See TracChangeset
for help on using the changeset viewer.