Ignore:
Timestamp:
Aug 11, 2020, 4:40:15 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
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.
Message:

Merge branch 'master' into new-ast

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/exception.c

    r07d867b r22f94a4  
    1010// Created On       : Mon Jun 26 15:13:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Apr 14 12:01:00 2020
    13 // Update Count     : 18
     12// Last Modified On : Thr May 21 12:18:00 2020
     13// Update Count     : 20
    1414//
    1515
     
    8080}
    8181
    82 void __cfaehm_throw_resume(exception_t * except) {
     82void __cfaehm_throw_resume(exception_t * except, void (*defaultHandler)(exception_t *)) {
    8383        struct exception_context_t * context = this_exception_context();
    8484
    8585        __cfadbg_print_safe(exception, "Throwing resumption exception\n");
    8686
    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                        }
    9597                }
    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.
    98101        __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);
    103103}
    104104
     
    121121
    122122
    123 // TERMINATION ===============================================================
    124 
    125 // MEMORY MANAGEMENT (still for integers)
    126 // May have to move to cfa for constructors and destructors (references).
     123// MEMORY MANAGEMENT =========================================================
    127124
    128125// How to clean up an exception in various situations.
     
    203200}
    204201
    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 ==============================================================
    209203
    210204// Function needed by force unwind
     
    228222}
    229223
     224// Cancel the current stack, prefroming approprate clean-up and messaging.
     225void __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.
     237void __cfaehm_cleanup_terminate( void * except ) {
     238        if ( *(void**)except ) __cfaehm_delete_exception( *(exception_t **)except );
     239}
     240
     241static void __cfaehm_cleanup_default( exception_t ** except ) {
     242        __cfaehm_delete_exception( *except );
     243        *except = NULL;
     244}
     245
    230246// 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 ) {
     247static 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 ) {
    233251                printf("UNWIND ERROR missing exception in begin unwind\n");
    234252                abort();
     
    236254
    237255        // 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 );
    239258
    240259        // If we reach here it means something happened. For resumption to work we need to find a way
     
    245264        // the whole stack.
    246265
    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);
    254269                abort();
    255270        }
    256271
    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
     280void __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
     287static __attribute__((noreturn)) void __cfaehm_rethrow_adapter( exception_t * except ) {
     288        // TODO: Print some error message.
     289        (void)except;
    259290        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();
    267291}
    268292
     
    270294        __cfadbg_print_safe(exception, "Rethrowing termination exception\n");
    271295
    272         __cfaehm_begin_unwind();
     296        __cfaehm_begin_unwind( __cfaehm_rethrow_adapter );
     297        abort();
    273298}
    274299
Note: See TracChangeset for help on using the changeset viewer.