Changeset 22f94a4 for libcfa/src/exception.c
- Timestamp:
- Aug 11, 2020, 4:40:15 PM (5 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:
- 0d070ca
- Parents:
- 07d867b (diff), 129674b (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
-
libcfa/src/exception.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/exception.c
r07d867b r22f94a4 10 10 // Created On : Mon Jun 26 15:13:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T ue Apr 14 12:01:00 202013 // Update Count : 1812 // Last Modified On : Thr May 21 12:18:00 2020 13 // Update Count : 20 14 14 // 15 15 … … 80 80 } 81 81 82 void __cfaehm_throw_resume(exception_t * except ) {82 void __cfaehm_throw_resume(exception_t * except, void (*defaultHandler)(exception_t *)) { 83 83 struct exception_context_t * context = this_exception_context(); 84 84 85 85 __cfadbg_print_safe(exception, "Throwing resumption exception\n"); 86 86 87 __attribute__((cleanup(reset_top_resume))) 88 struct __cfaehm_try_resume_node * original_head = context->top_resume; 89 struct __cfaehm_try_resume_node * current = context->top_resume; 90 91 for ( ; current ; current = current->next) { 92 context->top_resume = current->next; 93 if (current->handler(except)) { 94 return; 87 { 88 __attribute__((cleanup(reset_top_resume))) 89 struct __cfaehm_try_resume_node * original_head = context->top_resume; 90 struct __cfaehm_try_resume_node * current = context->top_resume; 91 92 for ( ; current ; current = current->next) { 93 context->top_resume = current->next; 94 if (current->handler(except)) { 95 return; 96 } 95 97 } 96 } 97 98 } // End the search and return to the top of the stack. 99 100 // No handler found, fall back to the default operation. 98 101 __cfadbg_print_safe(exception, "Unhandled exception\n"); 99 100 // Fall back to termination: 101 __cfaehm_throw_terminate(except); 102 // TODO: Default handler for resumption. 102 defaultHandler(except); 103 103 } 104 104 … … 121 121 122 122 123 // TERMINATION =============================================================== 124 125 // MEMORY MANAGEMENT (still for integers) 126 // May have to move to cfa for constructors and destructors (references). 123 // MEMORY MANAGEMENT ========================================================= 127 124 128 125 // How to clean up an exception in various situations. … … 203 200 } 204 201 205 // If this isn't a rethrow (*except==0), delete the provided exception. 206 void __cfaehm_cleanup_terminate( void * except ) { 207 if ( *(void**)except ) __cfaehm_delete_exception( *(exception_t **)except ); 208 } 202 // CANCELLATION ============================================================== 209 203 210 204 // Function needed by force unwind … … 228 222 } 229 223 224 // Cancel the current stack, prefroming approprate clean-up and messaging. 225 void __cfaehm_cancel_stack( exception_t * exception ) { 226 // TODO: Detect current stack and pick a particular stop-function. 227 _Unwind_Reason_Code ret; 228 ret = _Unwind_ForcedUnwind( &this_exception_storage, _Stop_Fn, (void*)0x22 ); 229 printf("UNWIND ERROR %d after force unwind\n", ret); 230 abort(); 231 } 232 233 234 // TERMINATION =============================================================== 235 236 // If this isn't a rethrow (*except==0), delete the provided exception. 237 void __cfaehm_cleanup_terminate( void * except ) { 238 if ( *(void**)except ) __cfaehm_delete_exception( *(exception_t **)except ); 239 } 240 241 static void __cfaehm_cleanup_default( exception_t ** except ) { 242 __cfaehm_delete_exception( *except ); 243 *except = NULL; 244 } 245 230 246 // The exception that is being thrown must already be stored. 231 static __attribute__((noreturn)) void __cfaehm_begin_unwind(void) { 232 if ( ! this_exception_context()->current_exception ) { 247 static void __cfaehm_begin_unwind(void(*defaultHandler)(exception_t *)) { 248 struct exception_context_t * context = this_exception_context(); 249 struct _Unwind_Exception * storage = &this_exception_storage; 250 if ( NULL == context->current_exception ) { 233 251 printf("UNWIND ERROR missing exception in begin unwind\n"); 234 252 abort(); … … 236 254 237 255 // Call stdlibc to raise the exception 238 _Unwind_Reason_Code ret = _Unwind_RaiseException( &this_exception_storage ); 256 __cfadbg_print_safe(exception, "Begin unwinding (storage &p, context %p)\n", storage, context); 257 _Unwind_Reason_Code ret = _Unwind_RaiseException( storage ); 239 258 240 259 // If we reach here it means something happened. For resumption to work we need to find a way … … 245 264 // the whole stack. 246 265 247 if ( ret == _URC_END_OF_STACK ) { 248 // No proper handler was found. This can be handled in many ways, C++ calls std::terminate. 249 // Here we force unwind the stack, basically raising a cancellation. 250 printf("Uncaught exception %p\n", &this_exception_storage); 251 252 ret = _Unwind_ForcedUnwind( &this_exception_storage, _Stop_Fn, (void*)0x22 ); 253 printf("UNWIND ERROR %d after force unwind\n", ret); 266 // We did not simply reach the end of the stack without finding a handler. This is an error. 267 if ( ret != _URC_END_OF_STACK ) { 268 printf("UNWIND ERROR %d after raise exception\n", ret); 254 269 abort(); 255 270 } 256 271 257 // We did not simply reach the end of the stack without finding a handler. This is an error. 258 printf("UNWIND ERROR %d after raise exception\n", ret); 272 // No handler found, go to the default operation. 273 __cfadbg_print_safe(exception, "Uncaught exception %p\n", storage); 274 275 __attribute__((cleanup(__cfaehm_cleanup_default))) 276 exception_t * exception = context->current_exception; 277 defaultHandler( exception ); 278 } 279 280 void __cfaehm_throw_terminate( exception_t * val, void (*defaultHandler)(exception_t *) ) { 281 __cfadbg_print_safe(exception, "Throwing termination exception\n"); 282 283 __cfaehm_allocate_exception( val ); 284 __cfaehm_begin_unwind( defaultHandler ); 285 } 286 287 static __attribute__((noreturn)) void __cfaehm_rethrow_adapter( exception_t * except ) { 288 // TODO: Print some error message. 289 (void)except; 259 290 abort(); 260 }261 262 void __cfaehm_throw_terminate( exception_t * val ) {263 __cfadbg_print_safe(exception, "Throwing termination exception\n");264 265 __cfaehm_allocate_exception( val );266 __cfaehm_begin_unwind();267 291 } 268 292 … … 270 294 __cfadbg_print_safe(exception, "Rethrowing termination exception\n"); 271 295 272 __cfaehm_begin_unwind(); 296 __cfaehm_begin_unwind( __cfaehm_rethrow_adapter ); 297 abort(); 273 298 } 274 299
Note:
See TracChangeset
for help on using the changeset viewer.