Changeset 980fb4e
- Timestamp:
- Aug 12, 2020, 2:49:19 PM (4 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 80ec409
- Parents:
- fb0ae06
- Files:
-
- 2 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/exception.c
rfb0ae06 r980fb4e 10 10 // Created On : Mon Jun 26 15:13:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr May 21 12:18:00 202013 // Update Count : 2 012 // Last Modified On : Wed Aug 12 13:55:00 2020 13 // Update Count : 21 14 14 // 15 15 … … 63 63 64 64 exception_t * current_exception; 65 int current_handler_index; 66 } static shared_stack = {NULL, NULL, 0}; 65 } static shared_stack = {NULL, NULL}; 67 66 68 67 // Get the current exception context. … … 122 121 123 122 // MEMORY MANAGEMENT ========================================================= 123 124 struct __cfaehm_node { 125 struct _Unwind_Exception unwind_exception; 126 struct __cfaehm_node * next; 127 int handler_index; 128 }; 129 130 #define NODE_TO_EXCEPT(node) ((exception_t *)(1 + (node))) 131 #define EXCEPT_TO_NODE(except) ((struct __cfaehm_node *)(except) - 1) 132 #define UNWIND_TO_NODE(unwind) ((struct __cfaehm_node *)(unwind)) 133 #define NULL_MAP(map, ptr) ((ptr) ? (map(ptr)) : NULL) 124 134 125 135 // How to clean up an exception in various situations. … … 137 147 } 138 148 139 // We need a piece of storage to raise the exception, for now its a single140 // piece.141 static struct _Unwind_Exception this_exception_storage;142 143 struct __cfaehm_node {144 struct __cfaehm_node * next;145 };146 147 #define NODE_TO_EXCEPT(node) ((exception_t *)(1 + (node)))148 #define EXCEPT_TO_NODE(except) ((struct __cfaehm_node *)(except) - 1)149 150 149 // Creates a copy of the indicated exception and sets current_exception to it. 151 150 static void __cfaehm_allocate_exception( exception_t * except ) { … … 161 160 } 162 161 162 // Initialize the node: 163 exception_t * except_store = NODE_TO_EXCEPT(store); 164 store->unwind_exception.exception_class = __cfaehm_exception_class; 165 store->unwind_exception.exception_cleanup = __cfaehm_exception_cleanup; 166 store->handler_index = 0; 167 except->virtual_table->copy( except_store, except ); 168 163 169 // Add the node to the list: 164 store->next = EXCEPT_TO_NODE(context->current_exception); 165 context->current_exception = NODE_TO_EXCEPT(store); 166 167 // Copy the exception to storage. 168 except->virtual_table->copy( context->current_exception, except ); 169 170 // Set up the exception storage. 171 this_exception_storage.exception_class = __cfaehm_exception_class; 172 this_exception_storage.exception_cleanup = __cfaehm_exception_cleanup; 170 store->next = NULL_MAP(EXCEPT_TO_NODE, context->current_exception); 171 context->current_exception = except_store; 173 172 } 174 173 … … 185 184 if ( context->current_exception == except ) { 186 185 node = to_free->next; 187 context->current_exception = (node) ? NODE_TO_EXCEPT(node) : 0;186 context->current_exception = NULL_MAP(NODE_TO_EXCEPT, node); 188 187 } else { 189 188 node = EXCEPT_TO_NODE(context->current_exception); … … 213 212 // Verify actions follow the rules we expect. 214 213 verify((actions & _UA_CLEANUP_PHASE) && (actions & _UA_FORCE_UNWIND)); 215 verify(!(actions & (_UA_SEARCH_PHASE | _UA_HAND ER_FRAME)));214 verify(!(actions & (_UA_SEARCH_PHASE | _UA_HANDLER_FRAME))); 216 215 217 216 if ( actions & _UA_END_OF_STACK ) { … … 222 221 } 223 222 223 static struct _Unwind_Exception cancel_exception_storage; 224 224 225 // Cancel the current stack, prefroming approprate clean-up and messaging. 225 226 void __cfaehm_cancel_stack( exception_t * exception ) { 226 227 // TODO: Detect current stack and pick a particular stop-function. 227 228 _Unwind_Reason_Code ret; 228 ret = _Unwind_ForcedUnwind( & this_exception_storage, _Stop_Fn, (void*)0x22 );229 ret = _Unwind_ForcedUnwind( &cancel_exception_storage, _Stop_Fn, (void*)0x22 ); 229 230 printf("UNWIND ERROR %d after force unwind\n", ret); 230 231 abort(); … … 247 248 static void __cfaehm_begin_unwind(void(*defaultHandler)(exception_t *)) { 248 249 struct exception_context_t * context = this_exception_context(); 249 struct _Unwind_Exception * storage = &this_exception_storage;250 250 if ( NULL == context->current_exception ) { 251 251 printf("UNWIND ERROR missing exception in begin unwind\n"); 252 252 abort(); 253 253 } 254 struct _Unwind_Exception * storage = 255 &EXCEPT_TO_NODE(context->current_exception)->unwind_exception; 254 256 255 257 // Call stdlibc to raise the exception … … 419 421 _Unwind_Reason_Code ret = (0 == index) 420 422 ? _URC_CONTINUE_UNWIND : _URC_HANDLER_FOUND; 421 context->current_handler_index = index;423 UNWIND_TO_NODE(unwind_exception)->handler_index = index; 422 424 423 425 // Based on the return value, check if we matched the exception … … 425 427 __cfadbg_print_safe(exception, " handler found\n"); 426 428 } else { 429 // TODO: Continue the search if there is more in the table. 427 430 __cfadbg_print_safe(exception, " no handler\n"); 428 431 } … … 516 519 // Exception handler 517 520 // Note: Saving the exception context on the stack breaks termination exceptions. 518 catch_block( this_exception_context()->current_handler_index,521 catch_block( EXCEPT_TO_NODE( this_exception_context()->current_exception )->handler_index, 519 522 this_exception_context()->current_exception ); 520 523 }
Note: See TracChangeset
for help on using the changeset viewer.