Changes in src/libcfa/exception.c [cbce272:b947fb2]
- File:
-
- 1 edited
-
src/libcfa/exception.c (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/exception.c
rcbce272 rb947fb2 9 9 // Author : Andrew Beach 10 10 // Created On : Mon Jun 26 15:13:00 2017 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Aug 4 15:20:00 2017 13 // Update Count : 6 14 // 15 16 #include <stddef.h> // for size_t 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jul 26 10:37:51 2017 13 // Update Count : 2 14 // 17 15 18 16 #include "exception.h" … … 34 32 #include "lsda.h" 35 33 36 37 // Base exception vtable is abstract, you should not have base exceptions.38 struct __cfaehm__base_exception_t_vtable39 ___cfaehm__base_exception_t_vtable_instance = {40 .parent = NULL,41 .size = 0,42 .copy = NULL,43 .free = NULL,44 .msg = NULL45 };46 47 48 34 // Temperary global exception context. Does not work with concurency. 49 struct exception_context_t {35 struct shared_stack_t { 50 36 struct __cfaehm__try_resume_node * top_resume; 51 37 struct __cfaehm__try_resume_node * current_resume; 52 38 53 exception *current_exception;39 exception current_exception; 54 40 int current_handler_index; 55 41 } shared_stack = {NULL, NULL, 0, 0}; 56 42 57 // Get the current exception context.58 // There can be a single global until multithreading occurs, then each stack59 // 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 //}68 43 69 44 … … 80 55 81 56 // DEBUG 82 printf("Throwing resumption exception \n");57 printf("Throwing resumption exception %d\n", *except); 83 58 84 59 struct __cfaehm__try_resume_node * original_head = shared_stack.current_resume; … … 94 69 } 95 70 96 printf("Unhandled exception \n");71 printf("Unhandled exception %d\n", *except); 97 72 shared_stack.current_resume = original_head; 98 73 … … 119 94 // TERMINATION =============================================================== 120 95 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 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) 185 100 186 101 // We need a piece of storage to raise the exception … … 202 117 } 203 118 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 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); 211 125 212 126 // Call stdlibc to raise the exception … … 234 148 } 235 149 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 150 // Nesting this the other way would probably be faster. 244 151 void __cfaehm__rethrow_terminate(void) { 245 152 // DEBUG 246 153 printf("Rethrowing termination exception\n"); 247 154 248 __cfaehm__ begin_unwind();155 __cfaehm__throw_terminate(&shared_stack.current_exception); 249 156 } 250 157 … … 356 263 _Unwind_Reason_Code (*matcher)(exception *) = 357 264 MATCHER_FROM_CONTEXT(context); 358 int index = matcher( shared_stack.current_exception);265 int index = matcher(&shared_stack.current_exception); 359 266 _Unwind_Reason_Code ret = (0 == index) 360 267 ? _URC_CONTINUE_UNWIND : _URC_HANDLER_FOUND; … … 452 359 // Exception handler 453 360 catch_block( shared_stack.current_handler_index, 454 shared_stack.current_exception );361 &shared_stack.current_exception ); 455 362 } 456 363
Note:
See TracChangeset
for help on using the changeset viewer.