Changeset 79dbb79 for src/libcfa/exception.c
- Timestamp:
- Jul 28, 2017, 2:26:29 PM (7 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:
- 926341c, ea5023c
- Parents:
- 59310bf (diff), 86d5ba7c (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
r59310bf r79dbb79 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 Jul 28 12:41:00 2017 13 // Update Count : 3 14 14 // 15 15 … … 33 33 34 34 // Temperary global exception context. Does not work with concurency. 35 struct shared_stack_t {35 struct exception_context_t { 36 36 struct __cfaehm__try_resume_node * top_resume; 37 37 struct __cfaehm__try_resume_node * current_resume; 38 38 39 exception current_exception;39 exception * current_exception; 40 40 int current_handler_index; 41 } shared_stack = {NULL, NULL, 0, 0}; 42 41 42 // Storage to avoid using the heap for exceptions. 43 exception built_in_storage; 44 } shared_stack = {NULL, NULL, 0, 0, 0}; 45 46 // Get the current exception context. 47 // There can be a single global until multithreading occurs, then each stack 48 // needs its own. It will have to be updated to handle that. 49 struct exception_context_t * this_exception_context() { 50 return &shared_stack; 51 } 52 //#define SAVE_EXCEPTION_CONTEXT(to_name) 53 //struct exception_context_t * to_name = this_exception_context(); 54 //exception * this_exception() { 55 // return this_exception_context()->current_exception; 56 //} 43 57 44 58 … … 94 108 // TERMINATION =============================================================== 95 109 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) 110 // MEMORY MANAGEMENT (still for integers) 111 // May have to move to cfa for constructors and destructors. 112 113 // Creates a copy of the indicated exception and sets current_exception to it. 114 static void __cfaehm__allocate_exception( exception * except ) { 115 struct exception_context_t * context = this_exception_context(); 116 117 // Try to use the context's store, otherwise use the heap. 118 if ( 0 == context->built_in_storage ) { 119 context->current_exception = &context->built_in_storage; 120 } else { 121 exception * new_copy = malloc( sizeof( exception/*int*/ ) ); 122 if ( ! new_copy ) { 123 // Failure: cannot allocate exception. Terminate thread. 124 exit(1); // <- thread or program? 125 } 126 context->current_exception = new_copy; 127 } 128 129 // Copy the exception to storage. 130 *context->current_exception = *except; 131 } 132 133 // Delete the provided exception, unsetting current_exception if relivant. 134 static void __cfaehm__delete_exception( exception * except ) { 135 struct exception_context_t * context = this_exception_context(); 136 137 // DEBUG 138 printf( "Deleting Exception %d (%s)\n", *except, 139 (&context->built_in_storage == except) ? "builtin" : "dynamic" ); 140 141 if ( context->current_exception == except ) { 142 // TODO: This should restore it to the last exception. 143 context->current_exception = NULL; 144 } 145 if ( &context->built_in_storage == except ) { 146 // You can't throw the exception '0'. 147 context->built_in_storage = 0; 148 } else { 149 // Only secondary or too large exceptions are thrown. 150 free( except ); 151 } 152 } 153 154 // If this isn't a rethrow (*except==0), delete the provided exception. 155 void __cfaehm__cleanup_terminate( exception ** except ) { 156 if ( *except ) __cfaehm__delete_exception( *except ); 157 } 158 100 159 101 160 // We need a piece of storage to raise the exception … … 117 176 } 118 177 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); 178 // The exception that is being thrown must already be stored. 179 __attribute__((noreturn)) void __cfaehm__begin_unwind(void) { 180 if ( ! this_exception_context()->current_exception ) { 181 printf("UNWIND ERROR missing exception in begin unwind\n"); 182 abort(); 183 } 184 125 185 126 186 // Call stdlibc to raise the exception … … 148 208 } 149 209 150 // Nesting this the other way would probably be faster. 210 void __cfaehm__throw_terminate( exception * val ) { 211 // DEBUG 212 printf("Throwing termination exception\n"); 213 214 __cfaehm__allocate_exception( val ); 215 __cfaehm__begin_unwind(); 216 } 217 151 218 void __cfaehm__rethrow_terminate(void) { 152 219 // DEBUG 153 220 printf("Rethrowing termination exception\n"); 154 221 155 __cfaehm__ throw_terminate(&shared_stack.current_exception);222 __cfaehm__begin_unwind(); 156 223 } 157 224 … … 263 330 _Unwind_Reason_Code (*matcher)(exception *) = 264 331 MATCHER_FROM_CONTEXT(context); 265 int index = matcher( &shared_stack.current_exception);332 int index = matcher(shared_stack.current_exception); 266 333 _Unwind_Reason_Code ret = (0 == index) 267 334 ? _URC_CONTINUE_UNWIND : _URC_HANDLER_FOUND; … … 359 426 // Exception handler 360 427 catch_block( shared_stack.current_handler_index, 361 &shared_stack.current_exception );428 shared_stack.current_exception ); 362 429 } 363 430
Note: See TracChangeset
for help on using the changeset viewer.