Index: src/exceptions.c =================================================================== --- src/exceptions.c (revision 39868) +++ src/exceptions.c (working copy) @@ -343,6 +343,7 @@ Parrot_runloop *return_point = interp->current_runloop; RunProfile * const profile = interp->profile; + opcode_t *address; PMC * const handler = Parrot_cx_find_handler_local(interp, exception); @@ -384,12 +385,12 @@ } /* Run the handler. */ - Parrot_runops_fromc_args(interp, handler, "vP", exception); - - /* After handling a C exception, you don't want to resume at the point - * where the C exception was thrown. You want to resume the next outer - * runloop. */ - longjmp(return_point->resume, 1); + address = VTABLE_invoke(interp, handler, NULL); + if (PMC_cont(handler)->current_results) + address = pass_exception_args(interp, "P", address, + CONTEXT(interp), exception); + return_point->newoffset = address; + longjmp(return_point->resume, 2); } /* Index: src/call/ops.c =================================================================== --- src/call/ops.c (revision 39868) +++ src/call/ops.c (working copy) @@ -88,19 +88,28 @@ #endif { new_runloop_jump_point(interp); - if (setjmp(interp->current_runloop->resume)) { - /* an exception was handled */ - if (STACKED_EXCEPTIONS) - free_runloop_jump_point(interp); + reenter: + switch (setjmp(interp->current_runloop->resume)) { + case 1: + /* an exception was handled */ + if (STACKED_EXCEPTIONS) + free_runloop_jump_point(interp); - interp->current_runloop_level = our_runloop_level - 1; - interp->current_runloop_id = old_runloop_id; + interp->current_runloop_level = our_runloop_level - 1; + interp->current_runloop_id = old_runloop_id; #if RUNLOOP_TRACE - fprintf(stderr, "[handled exception; back to loop %d, level %d]\n", - interp->current_runloop_id, interp->current_runloop_level); + fprintf(stderr, "[handled exception; back to loop %d, level %d]\n", + interp->current_runloop_id, interp->current_runloop_level); #endif - return; + return; + case 2: + /* Reenter the runloop from a exception thrown from C + * with a pir handler */ + offset = interp->current_runloop->newoffset - interp->code->base.data; + goto reenter; + default: + break; } } Index: include/parrot/interpreter.h =================================================================== --- include/parrot/interpreter.h (revision 39868) +++ include/parrot/interpreter.h (working copy) @@ -292,6 +292,7 @@ typedef struct parrot_runloop_t { Parrot_jump_buff resume; /* jmp_buf */ struct parrot_runloop_t *prev; /* interpreter's runloop jump buffer stack */ + opcode_t *newoffset; /* Used in exception handling */ } parrot_runloop_t; typedef parrot_runloop_t Parrot_runloop;