void pic_wind(pic_state *pic, pic_checkpoint *here, pic_checkpoint *there) { if (here == there) return; if (here->depth < there->depth) { pic_wind(pic, here, there->prev); pic_apply0(pic, there->in); } else { pic_apply0(pic, there->out); pic_wind(pic, here->prev, there); } }
void pic_load_point(pic_state *pic, struct pic_cont *cont) { pic_jmpbuf *jmp; for (jmp = pic->jmp; jmp != NULL; jmp = jmp->prev) { if (jmp == &cont->jmp) { break; } } if (jmp == NULL) { pic_errorf(pic, "calling dead escape continuation"); } pic_wind(pic, pic->cp, cont->cp); /* load runtime context */ pic->cp = cont->cp; pic->sp = pic->stbase + cont->sp_offset; pic->ci = pic->cibase + cont->ci_offset; pic->xp = pic->xpbase + cont->xp_offset; pic->arena_idx = cont->arena_idx; pic->ip = cont->ip; pic->ptable = cont->ptable; }
void pic_load_point(pic_state *pic, struct pic_cont *cont) { pic_wind(pic, pic->cp, cont->cp); /* load runtime context */ pic->cp = cont->cp; pic->sp = pic->stbase + cont->sp_offset; pic->ci = pic->cibase + cont->ci_offset; pic->xp = pic->xpbase + cont->xp_offset; pic->arena_idx = cont->arena_idx; pic->ip = cont->ip; pic->ptable = cont->ptable; pic->cc = cont->prev; }
PIC_NORETURN static pic_value cont_call(pic_state *pic) { int argc, i; pic_value *argv, *retv; struct fullcont *cont; pic_get_args(pic, "*", &argc, &argv); retv = pic_alloca(pic, sizeof(pic_value) * argc); for (i = 0; i < argc; ++i) { retv[i] = argv[i]; } cont = pic_data(pic, pic_closure_ref(pic, 0)); cont->retc = argc; cont->retv = retv; /* execute guard handlers */ pic_wind(pic, pic->cp, cont->cp); restore_cont(pic, cont); }