Changeset ff7ff14a for src


Ignore:
Timestamp:
Jul 31, 2017, 1:58:26 PM (7 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
5c80197
Parents:
61e2761
Message:

Discovered a case where the memory management didn't work, stricter tracking of the current exception fixes the issue.

Location:
src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/exception.c

    r61e2761 rff7ff14a  
    1010// Created On       : Mon Jun 26 15:13:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Jul 28 12:41:00 2017
    13 // Update Count     : 3
     12// Last Modified On : Mon Jul 31 13:51:00 2017
     13// Update Count     : 4
    1414//
    1515
     
    109109
    110110// MEMORY MANAGEMENT (still for integers)
    111 // May have to move to cfa for constructors and destructors.
     111// May have to move to cfa for constructors and destructors (references).
     112
     113struct __cfaehm__node {
     114        struct __cfaehm__node * next;
     115};
     116
     117#define NODE_TO_EXCEPT(node) ((exception *)(1 + (node)))
     118#define EXCEPT_TO_NODE(except) ((struct __cfaehm__node *)(except) - 1)
    112119
    113120// Creates a copy of the indicated exception and sets current_exception to it.
     
    115122        struct exception_context_t * context = this_exception_context();
    116123
    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         }
     124        // Allocate memory for the exception.
     125        struct __cfaehm__node * store = malloc(
     126                sizeof( except ) + sizeof( struct __cfaehm__node ) );
     127
     128        if ( ! store ) {
     129                // Failure: cannot allocate exception. Terminate thread.
     130                abort(); // <- Although I think it might be the process.
     131        }
     132
     133        // Add the node to the list:
     134        store->next = EXCEPT_TO_NODE(context->current_exception);
     135        context->current_exception = NODE_TO_EXCEPT(store);
    128136
    129137        // Copy the exception to storage.
     
    136144
    137145        // DEBUG
    138         printf( "Deleting Exception %d (%s)\n", *except,
    139                 (&context->built_in_storage == except) ? "builtin" : "dynamic" );
     146        printf( "Deleting Exception %d\n", *except);
     147
     148        // Remove the exception from the list.
     149        struct __cfaehm__node * to_free = EXCEPT_TO_NODE(except);
     150        struct __cfaehm__node * node;
    140151
    141152        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;
     153                node = to_free->next;
     154                context->current_exception = (node) ? NODE_TO_EXCEPT(node) : 0;
    148155        } else {
    149                 // Only secondary or too large exceptions are thrown.
    150                 free( except );
    151         }
     156                node = EXCEPT_TO_NODE(context->current_exception);
     157                // It may always be in the first or second position.
     158                while( to_free != node->next ) {
     159                        node = node->next;
     160                }
     161                node->next = to_free->next;
     162        }
     163
     164        // Free the old exception node.
     165        free( to_free );
    152166}
    153167
  • src/tests/except-1.c

    r61e2761 rff7ff14a  
    4646        }
    4747        printf("Part C Complete\n");
     48
     49        try {
     50                try {
     51                        throw 7;
     52                }
     53                catch( 7 ) {
     54                        printf("Caught initial throw.\n");
     55                        try {
     56                                throw 8;
     57                        }
     58                        catch( 8 ) {
     59                                printf("Caught intermediate throw.\n");
     60                        }
     61                        throw;
     62                }
     63        }
     64        catch( 7 ) {
     65                printf("Caught final throw.\n");
     66        }
     67        printf("Part D Complete\n");
    4868}
Note: See TracChangeset for help on using the changeset viewer.