Ignore:
Timestamp:
Jul 28, 2017, 2:06:10 PM (4 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
03eedd5, 79dbb79
Parents:
a2e0687
Message:

Added the memory management calls to the exception control flow.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/exception.c

    ra2e0687 r86d5ba7c  
    99// Author           : Andrew Beach
    1010// Created On       : Mon Jun 26 15:13:00 2017
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 26 10:37:51 2017
    13 // Update Count     : 2
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Fri Jul 28 12:41:00 2017
     13// Update Count     : 3
    1414//
    1515
     
    3333
    3434// Temperary global exception context. Does not work with concurency.
    35 struct shared_stack_t {
     35struct exception_context_t {
    3636    struct __cfaehm__try_resume_node * top_resume;
    3737    struct __cfaehm__try_resume_node * current_resume;
    3838
    39     exception current_exception;
     39    exception * current_exception;
    4040    int current_handler_index;
    41 } shared_stack = {NULL, NULL, 0, 0};
    42 
     41
     42        // Storage to avoid using the heap for exceptions.
     43        exception built_in_storage;
     44} shared_stack = {NULL, NULL, 0, 0, 0};
     45
     46// Get the current exception context.
     47// There can be a single global until multithreading occurs, then each stack
     48// needs its own. It will have to be updated to handle that.
     49struct exception_context_t * this_exception_context() {
     50        return &shared_stack;
     51}
     52//#define SAVE_EXCEPTION_CONTEXT(to_name)
     53//struct exception_context_t * to_name = this_exception_context();
     54//exception * this_exception() {
     55//    return this_exception_context()->current_exception;
     56//}
    4357
    4458
     
    94108// TERMINATION ===============================================================
    95109
    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)
     110// MEMORY MANAGEMENT (still for integers)
     111// May have to move to cfa for constructors and destructors.
     112
     113// Creates a copy of the indicated exception and sets current_exception to it.
     114static void __cfaehm__allocate_exception( exception * except ) {
     115        struct exception_context_t * context = this_exception_context();
     116
     117        // Try to use the context's store, otherwise use the heap.
     118        if ( 0 == context->built_in_storage ) {
     119                context->current_exception = &context->built_in_storage;
     120        } else {
     121                exception * new_copy = malloc( sizeof( exception/*int*/ ) );
     122                if ( ! new_copy ) {
     123                        // Failure: cannot allocate exception. Terminate thread.
     124                        exit(1); // <- thread or program?
     125                }
     126                context->current_exception = new_copy;
     127        }
     128
     129        // Copy the exception to storage.
     130        *context->current_exception = *except;
     131}
     132
     133// Delete the provided exception, unsetting current_exception if relivant.
     134static void __cfaehm__delete_exception( exception * except ) {
     135        struct exception_context_t * context = this_exception_context();
     136
     137        // DEBUG
     138        printf( "Deleting Exception %d (%s)\n", *except,
     139                (&context->built_in_storage == except) ? "builtin" : "dynamic" );
     140
     141        if ( context->current_exception == except ) {
     142                // TODO: This should restore it to the last exception.
     143                context->current_exception = NULL;
     144        }
     145        if ( &context->built_in_storage == except ) {
     146                // You can't throw the exception '0'.
     147                context->built_in_storage = 0;
     148        } else {
     149                // Only secondary or too large exceptions are thrown.
     150                free( except );
     151        }
     152}
     153
     154// If this isn't a rethrow (*except==0), delete the provided exception.
     155void __cfaehm__cleanup_terminate( exception ** except ) {
     156        if ( *except ) __cfaehm__delete_exception( *except );
     157}
     158
    100159
    101160// We need a piece of storage to raise the exception
     
    117176}
    118177
    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);
     178// The exception that is being thrown must already be stored.
     179__attribute__((noreturn)) void __cfaehm__begin_unwind(void) {
     180        if ( ! this_exception_context()->current_exception ) {
     181                printf("UNWIND ERROR missing exception in begin unwind\n");
     182                abort();
     183        }
     184
    125185
    126186        // Call stdlibc to raise the exception
     
    148208}
    149209
    150 // Nesting this the other way would probably be faster.
     210void __cfaehm__throw_terminate( exception * val ) {
     211        // DEBUG
     212        printf("Throwing termination exception\n");
     213
     214        __cfaehm__allocate_exception( val );
     215        __cfaehm__begin_unwind();
     216}
     217
    151218void __cfaehm__rethrow_terminate(void) {
    152219        // DEBUG
    153220        printf("Rethrowing termination exception\n");
    154221
    155         __cfaehm__throw_terminate(&shared_stack.current_exception);
     222        __cfaehm__begin_unwind();
    156223}
    157224
     
    263330                                        _Unwind_Reason_Code (*matcher)(exception *) =
    264331                                                MATCHER_FROM_CONTEXT(context);
    265                                         int index = matcher(&shared_stack.current_exception);
     332                                        int index = matcher(shared_stack.current_exception);
    266333                                        _Unwind_Reason_Code ret = (0 == index)
    267334                                                ? _URC_CONTINUE_UNWIND : _URC_HANDLER_FOUND;
     
    359426        // Exception handler
    360427        catch_block( shared_stack.current_handler_index,
    361                     &shared_stack.current_exception );
     428                     shared_stack.current_exception );
    362429}
    363430
Note: See TracChangeset for help on using the changeset viewer.