Changeset 4c925cd for libcfa/src/exception.c
- Timestamp:
- Aug 14, 2020, 11:40:04 AM (3 years ago)
- Branches:
- ADT, arm-eh, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 5715d43, fa5e011
- Parents:
- 309d814 (diff), badd22f (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
-
libcfa/src/exception.c
r309d814 r4c925cd 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 … … 28 28 #include <unwind.h> 29 29 #include <bits/debug.hfa> 30 #include "concurrency/invoke.h" 30 31 #include "stdhdr/assert.h" 31 32 … … 59 60 60 61 // Temperary global exception context. Does not work with concurency. 61 struct exception_context_t { 62 struct __cfaehm_try_resume_node * top_resume; 63 64 exception_t * current_exception; 65 int current_handler_index; 66 } static shared_stack = {NULL, NULL, 0}; 62 static struct exception_context_t shared_stack = {NULL, NULL}; 67 63 68 64 // Get the current exception context. … … 122 118 123 119 // MEMORY MANAGEMENT ========================================================= 120 121 struct __cfaehm_node { 122 struct _Unwind_Exception unwind_exception; 123 struct __cfaehm_node * next; 124 int handler_index; 125 }; 126 127 #define NODE_TO_EXCEPT(node) ((exception_t *)(1 + (node))) 128 #define EXCEPT_TO_NODE(except) ((struct __cfaehm_node *)(except) - 1) 129 #define UNWIND_TO_NODE(unwind) ((struct __cfaehm_node *)(unwind)) 130 #define NULL_MAP(map, ptr) ((ptr) ? (map(ptr)) : NULL) 124 131 125 132 // How to clean up an exception in various situations. … … 137 144 } 138 145 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 146 // Creates a copy of the indicated exception and sets current_exception to it. 151 147 static void __cfaehm_allocate_exception( exception_t * except ) { … … 161 157 } 162 158 159 // Initialize the node: 160 exception_t * except_store = NODE_TO_EXCEPT(store); 161 store->unwind_exception.exception_class = __cfaehm_exception_class; 162 store->unwind_exception.exception_cleanup = __cfaehm_exception_cleanup; 163 store->handler_index = 0; 164 except->virtual_table->copy( except_store, except ); 165 163 166 // 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; 167 store->next = NULL_MAP(EXCEPT_TO_NODE, context->current_exception); 168 context->current_exception = except_store; 173 169 } 174 170 … … 185 181 if ( context->current_exception == except ) { 186 182 node = to_free->next; 187 context->current_exception = (node) ? NODE_TO_EXCEPT(node) : 0;183 context->current_exception = NULL_MAP(NODE_TO_EXCEPT, node); 188 184 } else { 189 185 node = EXCEPT_TO_NODE(context->current_exception); … … 213 209 // Verify actions follow the rules we expect. 214 210 verify((actions & _UA_CLEANUP_PHASE) && (actions & _UA_FORCE_UNWIND)); 215 verify(!(actions & (_UA_SEARCH_PHASE | _UA_HAND ER_FRAME)));211 verify(!(actions & (_UA_SEARCH_PHASE | _UA_HANDLER_FRAME))); 216 212 217 213 if ( actions & _UA_END_OF_STACK ) { … … 222 218 } 223 219 220 static struct _Unwind_Exception cancel_exception_storage; 221 224 222 // Cancel the current stack, prefroming approprate clean-up and messaging. 225 223 void __cfaehm_cancel_stack( exception_t * exception ) { 226 224 // TODO: Detect current stack and pick a particular stop-function. 227 225 _Unwind_Reason_Code ret; 228 ret = _Unwind_ForcedUnwind( & this_exception_storage, _Stop_Fn, (void*)0x22 );226 ret = _Unwind_ForcedUnwind( &cancel_exception_storage, _Stop_Fn, (void*)0x22 ); 229 227 printf("UNWIND ERROR %d after force unwind\n", ret); 230 228 abort(); … … 247 245 static void __cfaehm_begin_unwind(void(*defaultHandler)(exception_t *)) { 248 246 struct exception_context_t * context = this_exception_context(); 249 struct _Unwind_Exception * storage = &this_exception_storage;250 247 if ( NULL == context->current_exception ) { 251 248 printf("UNWIND ERROR missing exception in begin unwind\n"); 252 249 abort(); 253 250 } 251 struct _Unwind_Exception * storage = 252 &EXCEPT_TO_NODE(context->current_exception)->unwind_exception; 254 253 255 254 // Call stdlibc to raise the exception … … 419 418 _Unwind_Reason_Code ret = (0 == index) 420 419 ? _URC_CONTINUE_UNWIND : _URC_HANDLER_FOUND; 421 context->current_handler_index = index;420 UNWIND_TO_NODE(unwind_exception)->handler_index = index; 422 421 423 422 // Based on the return value, check if we matched the exception … … 425 424 __cfadbg_print_safe(exception, " handler found\n"); 426 425 } else { 426 // TODO: Continue the search if there is more in the table. 427 427 __cfadbg_print_safe(exception, " no handler\n"); 428 428 } … … 516 516 // Exception handler 517 517 // Note: Saving the exception context on the stack breaks termination exceptions. 518 catch_block( this_exception_context()->current_handler_index,518 catch_block( EXCEPT_TO_NODE( this_exception_context()->current_exception )->handler_index, 519 519 this_exception_context()->current_exception ); 520 520 }
Note: See TracChangeset
for help on using the changeset viewer.