diff --git a/extlib/benz/cont.c b/extlib/benz/cont.c index 698ae234..132ed018 100644 --- a/extlib/benz/cont.c +++ b/extlib/benz/cont.c @@ -61,6 +61,7 @@ pic_save_point(pic_state *pic, struct pic_cont *cont) cont->ptable = pic->ptable; cont->prev = pic->cc; cont->results = pic_undef_value(); + cont->id = pic->ccnt++; pic->cc = cont; } @@ -68,17 +69,6 @@ pic_save_point(pic_state *pic, struct pic_cont *cont) void pic_load_point(pic_state *pic, struct pic_cont *cont) { - struct pic_cont *cc; - - for (cc = pic->cc; cc != NULL; cc = cc->prev) { - if (cc == cont) { - break; - } - } - if (cc == NULL) { - pic_errorf(pic, "calling dead escape continuation"); - } - pic_wind(pic, pic->cp, cont->cp); /* load runtime context */ @@ -94,18 +84,32 @@ pic_load_point(pic_state *pic, struct pic_cont *cont) static pic_value cont_call(pic_state *pic) { + struct pic_proc *self = pic_get_proc(pic); size_t argc; pic_value *argv; - struct pic_data *e; + int id; + struct pic_cont *cc, *cont; pic_get_args(pic, "*", &argc, &argv); - e = pic_data_ptr(pic_proc_env_ref(pic, pic_get_proc(pic), "escape")); - ((struct pic_cont *)e->data)->results = pic_list_by_array(pic, argc, argv); + id = pic_int(pic_proc_env_ref(pic, self, "id")); - pic_load_point(pic, e->data); + /* check if continuation is alive */ + for (cc = pic->cc; cc != NULL; cc = cc->prev) { + if (cc->id == id) { + break; + } + } + if (cc == NULL) { + pic_errorf(pic, "calling dead escape continuation"); + } - PIC_LONGJMP(pic, ((struct pic_cont *)e->data)->jmp, 1); + cont = pic_data_ptr(pic_proc_env_ref(pic, self, "escape"))->data; + cont->results = pic_list_by_array(pic, argc, argv); + + pic_load_point(pic, cont); + + PIC_LONGJMP(pic, cont->jmp, 1); PIC_UNREACHABLE(); } @@ -123,6 +127,7 @@ pic_make_cont(pic_state *pic, struct pic_cont *cont) /* save the escape continuation in proc */ pic_proc_env_set(pic, c, "escape", pic_obj_value(e)); + pic_proc_env_set(pic, c, "id", pic_int_value(cont->id)); return c; } diff --git a/extlib/benz/include/picrin.h b/extlib/benz/include/picrin.h index b28d286a..e5419c24 100644 --- a/extlib/benz/include/picrin.h +++ b/extlib/benz/include/picrin.h @@ -73,8 +73,9 @@ struct pic_state { pic_allocf allocf; - struct pic_cont *cc; pic_checkpoint *cp; + struct pic_cont *cc; + int ccnt; pic_value *sp; pic_value *stbase, *stend; diff --git a/extlib/benz/include/picrin/cont.h b/extlib/benz/include/picrin/cont.h index 10c394d4..439f6aeb 100644 --- a/extlib/benz/include/picrin/cont.h +++ b/extlib/benz/include/picrin/cont.h @@ -12,14 +12,14 @@ extern "C" { struct pic_cont { PIC_JMPBUF jmp; - pic_checkpoint *cp; + int id; + pic_checkpoint *cp; ptrdiff_t sp_offset; ptrdiff_t ci_offset; ptrdiff_t xp_offset; size_t arena_idx; pic_value ptable; - pic_code *ip; pic_value results; diff --git a/extlib/benz/state.c b/extlib/benz/state.c index 61dd2ae0..141f76ec 100644 --- a/extlib/benz/state.c +++ b/extlib/benz/state.c @@ -174,6 +174,7 @@ pic_open(int argc, char *argv[], char **envp, pic_allocf allocf) /* continuation chain */ pic->cc = NULL; + pic->ccnt = 0; /* root block */ pic->cp = NULL;