Ticket #804: RT_63592.patch

File RT_63592.patch, 3.2 KB (added by NotFound, 5 years ago)
  • src/exceptions.c

     
    343343 
    344344    Parrot_runloop    *return_point = interp->current_runloop; 
    345345    RunProfile * const profile      = interp->profile; 
     346    opcode_t *address; 
    346347    PMC        * const handler      = 
    347348                             Parrot_cx_find_handler_local(interp, exception); 
    348349 
     
    384385    } 
    385386 
    386387    /* Run the handler. */ 
    387     Parrot_runops_fromc_args(interp, handler, "vP", exception); 
    388  
    389     /* After handling a C exception, you don't want to resume at the point 
    390      * where the C exception was thrown.  You want to resume the next outer 
    391      * runloop.  */ 
    392     longjmp(return_point->resume, 1); 
     388    address = VTABLE_invoke(interp, handler, NULL); 
     389    if (PMC_cont(handler)->current_results) 
     390        address = pass_exception_args(interp, "P", address, 
     391                CONTEXT(interp), exception); 
     392    return_point->newoffset = address; 
     393    longjmp(return_point->resume, 2); 
    393394} 
    394395 
    395396/* 
  • src/call/ops.c

     
    8888#endif 
    8989    { 
    9090        new_runloop_jump_point(interp); 
    91         if (setjmp(interp->current_runloop->resume)) { 
    92             /* an exception was handled */ 
    93             if (STACKED_EXCEPTIONS) 
    94                 free_runloop_jump_point(interp); 
     91    reenter: 
     92        switch (setjmp(interp->current_runloop->resume)) { 
     93            case 1: 
     94                /* an exception was handled */ 
     95                if (STACKED_EXCEPTIONS) 
     96                    free_runloop_jump_point(interp); 
    9597 
    96             interp->current_runloop_level = our_runloop_level - 1; 
    97             interp->current_runloop_id    = old_runloop_id; 
     98                interp->current_runloop_level = our_runloop_level - 1; 
     99                interp->current_runloop_id    = old_runloop_id; 
    98100 
    99101#if RUNLOOP_TRACE 
    100             fprintf(stderr, "[handled exception; back to loop %d, level %d]\n", 
    101                     interp->current_runloop_id, interp->current_runloop_level); 
     102                fprintf(stderr, "[handled exception; back to loop %d, level %d]\n", 
     103                        interp->current_runloop_id, interp->current_runloop_level); 
    102104#endif 
    103             return; 
     105                return; 
     106            case 2: 
     107                /* Reenter the runloop from a exception thrown from C 
     108                 * with a pir handler */ 
     109                offset = interp->current_runloop->newoffset - interp->code->base.data; 
     110                goto reenter; 
     111            default: 
     112                break; 
    104113        } 
    105114    } 
    106115 
  • include/parrot/interpreter.h

     
    292292typedef struct parrot_runloop_t { 
    293293    Parrot_jump_buff resume;     /* jmp_buf */ 
    294294    struct parrot_runloop_t *prev; /* interpreter's runloop jump buffer stack */ 
     295    opcode_t *newoffset; /* Used in exception handling */ 
    295296} parrot_runloop_t; 
    296297 
    297298typedef parrot_runloop_t Parrot_runloop;