Index: src/pmc/exceptionhandler.pmc =================================================================== --- src/pmc/exceptionhandler.pmc (revision 46593) +++ src/pmc/exceptionhandler.pmc (working copy) @@ -32,6 +32,7 @@ ATTR PMC *handled_types_except; ATTR INTVAL min_severity; ATTR INTVAL max_severity; + ATTR void *runloop_from; /* @@ -112,6 +113,11 @@ return PARROT_CONTINUATION(SELF)->invoked; } + VTABLE void set_pointer(void *value) { + SUPER(value); + SET_ATTR_runloop_from(INTERP, SELF, INTERP->current_runloop); + } + /* =item C @@ -300,6 +306,24 @@ : PMCNULL; } + + METHOD rewind(INTVAL pos) { + INTVAL cid = INTERP->current_runloop_id; + INTVAL rid; + GET_ATTR_runloop_id(INTERP, SELF, rid); + if (rid != cid) { + void *vrl; + Parrot_runloop *rl, *cur, *old; + Parrot_eprintf(INTERP, "rid: %d cid: %d\n", rid, cid); + GET_ATTR_runloop_from(INTERP, SELF, vrl); + rl = (Parrot_runloop *)vrl; + while (INTERP->current_runloop != rl) + free_runloop_jump_point(INTERP); + rl->handler_start = (opcode_t *)pos; + longjmp(rl->resume, 3); + } + } + } /* Index: src/call/ops.c =================================================================== --- src/call/ops.c (revision 46593) +++ src/call/ops.c (working copy) @@ -105,6 +105,12 @@ offset = interp->current_runloop->handler_start - interp->code->base.data; /* Prevent incorrect reuse */ goto reenter; + case 3: + /* runloop rewind from exception handling */ + offset = interp->current_runloop->handler_start - interp->code->base.data; + interp->current_runloop_level = our_runloop_level; + interp->current_runloop_id = our_runloop_id; + goto reenter; default: break; }