[bugfix] don't compare continuation objects by pointers. They may be
reused when it reenters the same stack position.
This commit is contained in:
parent
aae1b8792a
commit
777ba0ff6a
|
@ -61,6 +61,7 @@ pic_save_point(pic_state *pic, struct pic_cont *cont)
|
||||||
cont->ptable = pic->ptable;
|
cont->ptable = pic->ptable;
|
||||||
cont->prev = pic->cc;
|
cont->prev = pic->cc;
|
||||||
cont->results = pic_undef_value();
|
cont->results = pic_undef_value();
|
||||||
|
cont->id = pic->ccnt++;
|
||||||
|
|
||||||
pic->cc = cont;
|
pic->cc = cont;
|
||||||
}
|
}
|
||||||
|
@ -68,17 +69,6 @@ pic_save_point(pic_state *pic, struct pic_cont *cont)
|
||||||
void
|
void
|
||||||
pic_load_point(pic_state *pic, struct pic_cont *cont)
|
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);
|
pic_wind(pic, pic->cp, cont->cp);
|
||||||
|
|
||||||
/* load runtime context */
|
/* load runtime context */
|
||||||
|
@ -94,18 +84,32 @@ pic_load_point(pic_state *pic, struct pic_cont *cont)
|
||||||
static pic_value
|
static pic_value
|
||||||
cont_call(pic_state *pic)
|
cont_call(pic_state *pic)
|
||||||
{
|
{
|
||||||
|
struct pic_proc *self = pic_get_proc(pic);
|
||||||
size_t argc;
|
size_t argc;
|
||||||
pic_value *argv;
|
pic_value *argv;
|
||||||
struct pic_data *e;
|
int id;
|
||||||
|
struct pic_cont *cc, *cont;
|
||||||
|
|
||||||
pic_get_args(pic, "*", &argc, &argv);
|
pic_get_args(pic, "*", &argc, &argv);
|
||||||
|
|
||||||
e = pic_data_ptr(pic_proc_env_ref(pic, pic_get_proc(pic), "escape"));
|
id = pic_int(pic_proc_env_ref(pic, self, "id"));
|
||||||
((struct pic_cont *)e->data)->results = pic_list_by_array(pic, argc, argv);
|
|
||||||
|
|
||||||
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();
|
PIC_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -123,6 +127,7 @@ pic_make_cont(pic_state *pic, struct pic_cont *cont)
|
||||||
|
|
||||||
/* save the escape continuation in proc */
|
/* save the escape continuation in proc */
|
||||||
pic_proc_env_set(pic, c, "escape", pic_obj_value(e));
|
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;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,8 +73,9 @@ struct pic_state {
|
||||||
|
|
||||||
pic_allocf allocf;
|
pic_allocf allocf;
|
||||||
|
|
||||||
struct pic_cont *cc;
|
|
||||||
pic_checkpoint *cp;
|
pic_checkpoint *cp;
|
||||||
|
struct pic_cont *cc;
|
||||||
|
int ccnt;
|
||||||
|
|
||||||
pic_value *sp;
|
pic_value *sp;
|
||||||
pic_value *stbase, *stend;
|
pic_value *stbase, *stend;
|
||||||
|
|
|
@ -12,14 +12,14 @@ extern "C" {
|
||||||
struct pic_cont {
|
struct pic_cont {
|
||||||
PIC_JMPBUF jmp;
|
PIC_JMPBUF jmp;
|
||||||
|
|
||||||
pic_checkpoint *cp;
|
int id;
|
||||||
|
|
||||||
|
pic_checkpoint *cp;
|
||||||
ptrdiff_t sp_offset;
|
ptrdiff_t sp_offset;
|
||||||
ptrdiff_t ci_offset;
|
ptrdiff_t ci_offset;
|
||||||
ptrdiff_t xp_offset;
|
ptrdiff_t xp_offset;
|
||||||
size_t arena_idx;
|
size_t arena_idx;
|
||||||
pic_value ptable;
|
pic_value ptable;
|
||||||
|
|
||||||
pic_code *ip;
|
pic_code *ip;
|
||||||
|
|
||||||
pic_value results;
|
pic_value results;
|
||||||
|
|
|
@ -174,6 +174,7 @@ pic_open(int argc, char *argv[], char **envp, pic_allocf allocf)
|
||||||
|
|
||||||
/* continuation chain */
|
/* continuation chain */
|
||||||
pic->cc = NULL;
|
pic->cc = NULL;
|
||||||
|
pic->ccnt = 0;
|
||||||
|
|
||||||
/* root block */
|
/* root block */
|
||||||
pic->cp = NULL;
|
pic->cp = NULL;
|
||||||
|
|
Loading…
Reference in New Issue