Changeset 980fb4e


Ignore:
Timestamp:
Aug 12, 2020, 2:49:19 PM (4 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
80ec409
Parents:
fb0ae06
Message:

Added a test for exceptions and made a patch to allow it to pass.

Files:
2 added
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/exception.c

    rfb0ae06 r980fb4e  
    1010// Created On       : Mon Jun 26 15:13:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thr May 21 12:18:00 2020
    13 // Update Count     : 20
     12// Last Modified On : Wed Aug 12 13:55:00 2020
     13// Update Count     : 21
    1414//
    1515
     
    6363
    6464        exception_t * current_exception;
    65         int current_handler_index;
    66 } static shared_stack = {NULL, NULL, 0};
     65} static shared_stack = {NULL, NULL};
    6766
    6867// Get the current exception context.
     
    122121
    123122// MEMORY MANAGEMENT =========================================================
     123
     124struct __cfaehm_node {
     125        struct _Unwind_Exception unwind_exception;
     126        struct __cfaehm_node * next;
     127        int handler_index;
     128};
     129
     130#define NODE_TO_EXCEPT(node) ((exception_t *)(1 + (node)))
     131#define EXCEPT_TO_NODE(except) ((struct __cfaehm_node *)(except) - 1)
     132#define UNWIND_TO_NODE(unwind) ((struct __cfaehm_node *)(unwind))
     133#define NULL_MAP(map, ptr) ((ptr) ? (map(ptr)) : NULL)
    124134
    125135// How to clean up an exception in various situations.
     
    137147}
    138148
    139 // We need a piece of storage to raise the exception, for now its a single
    140 // 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 
    150149// Creates a copy of the indicated exception and sets current_exception to it.
    151150static void __cfaehm_allocate_exception( exception_t * except ) {
     
    161160        }
    162161
     162        // Initialize the node:
     163        exception_t * except_store = NODE_TO_EXCEPT(store);
     164        store->unwind_exception.exception_class = __cfaehm_exception_class;
     165        store->unwind_exception.exception_cleanup = __cfaehm_exception_cleanup;
     166        store->handler_index = 0;
     167        except->virtual_table->copy( except_store, except );
     168
    163169        // 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;
     170        store->next = NULL_MAP(EXCEPT_TO_NODE, context->current_exception);
     171        context->current_exception = except_store;
    173172}
    174173
     
    185184        if ( context->current_exception == except ) {
    186185                node = to_free->next;
    187                 context->current_exception = (node) ? NODE_TO_EXCEPT(node) : 0;
     186                context->current_exception = NULL_MAP(NODE_TO_EXCEPT, node);
    188187        } else {
    189188                node = EXCEPT_TO_NODE(context->current_exception);
     
    213212        // Verify actions follow the rules we expect.
    214213        verify((actions & _UA_CLEANUP_PHASE) && (actions & _UA_FORCE_UNWIND));
    215         verify(!(actions & (_UA_SEARCH_PHASE | _UA_HANDER_FRAME)));
     214        verify(!(actions & (_UA_SEARCH_PHASE | _UA_HANDLER_FRAME)));
    216215
    217216        if ( actions & _UA_END_OF_STACK ) {
     
    222221}
    223222
     223static struct _Unwind_Exception cancel_exception_storage;
     224
    224225// Cancel the current stack, prefroming approprate clean-up and messaging.
    225226void __cfaehm_cancel_stack( exception_t * exception ) {
    226227        // TODO: Detect current stack and pick a particular stop-function.
    227228        _Unwind_Reason_Code ret;
    228         ret = _Unwind_ForcedUnwind( &this_exception_storage, _Stop_Fn, (void*)0x22 );
     229        ret = _Unwind_ForcedUnwind( &cancel_exception_storage, _Stop_Fn, (void*)0x22 );
    229230        printf("UNWIND ERROR %d after force unwind\n", ret);
    230231        abort();
     
    247248static void __cfaehm_begin_unwind(void(*defaultHandler)(exception_t *)) {
    248249        struct exception_context_t * context = this_exception_context();
    249         struct _Unwind_Exception * storage = &this_exception_storage;
    250250        if ( NULL == context->current_exception ) {
    251251                printf("UNWIND ERROR missing exception in begin unwind\n");
    252252                abort();
    253253        }
     254        struct _Unwind_Exception * storage =
     255                &EXCEPT_TO_NODE(context->current_exception)->unwind_exception;
    254256
    255257        // Call stdlibc to raise the exception
     
    419421                                _Unwind_Reason_Code ret = (0 == index)
    420422                                        ? _URC_CONTINUE_UNWIND : _URC_HANDLER_FOUND;
    421                                 context->current_handler_index = index;
     423                                UNWIND_TO_NODE(unwind_exception)->handler_index = index;
    422424
    423425                                // Based on the return value, check if we matched the exception
     
    425427                                        __cfadbg_print_safe(exception, " handler found\n");
    426428                                } else {
     429                                        // TODO: Continue the search if there is more in the table.
    427430                                        __cfadbg_print_safe(exception, " no handler\n");
    428431                                }
     
    516519        // Exception handler
    517520        // Note: Saving the exception context on the stack breaks termination exceptions.
    518         catch_block( this_exception_context()->current_handler_index,
     521        catch_block( EXCEPT_TO_NODE( this_exception_context()->current_exception )->handler_index,
    519522                     this_exception_context()->current_exception );
    520523}
Note: See TracChangeset for help on using the changeset viewer.