From c79e08632c9718f428dd3a59f0fc650f46b46d34 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Sun, 17 Nov 2013 15:58:53 +0900 Subject: [PATCH] when restoring continuation sp and ci must be re-allocated --- include/picrin/cont.h | 8 ++++---- src/cont.c | 12 ++++++++---- src/gc.c | 4 ++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/picrin/cont.h b/include/picrin/cont.h index 7864e320..d6b5b9dc 100644 --- a/include/picrin/cont.h +++ b/include/picrin/cont.h @@ -10,11 +10,11 @@ struct pic_cont { size_t stk_len; pic_value *stk_pos, *stk_ptr; - pic_value *sp, *st_ptr; - size_t st_len; + pic_value *st_ptr; + size_t sp_offset, st_len; - pic_callinfo *ci, *ci_ptr; - size_t ci_len; + pic_callinfo *ci_ptr; + size_t ci_offset, ci_len; struct pic_object *arena[PIC_ARENA_SIZE]; int arena_idx; diff --git a/src/cont.c b/src/cont.c index 387152c7..d1d48990 100644 --- a/src/cont.c +++ b/src/cont.c @@ -38,12 +38,12 @@ save_cont(pic_state *pic) cont->stk_ptr = pic_alloc(pic, sizeof(pic_value) * cont->stk_len); memcpy(cont->stk_ptr, cont->stk_pos, sizeof(pic_value) * cont->stk_len); - cont->sp = pic->sp; + cont->sp_offset = pic->sp - pic->stbase; cont->st_len = pic->stend - pic->stbase; cont->st_ptr = (pic_value *)pic_alloc(pic, sizeof(pic_value) * cont->st_len); memcpy(cont->st_ptr, pic->stbase, sizeof(pic_value) * cont->st_len); - cont->ci = pic->ci; + cont->ci_offset = pic->ci - pic->cibase; cont->ci_len = pic->ciend - pic->cibase; cont->ci_ptr = (pic_callinfo *)pic_alloc(pic, sizeof(pic_callinfo) * cont->ci_len); memcpy(cont->ci_ptr, pic->cibase, sizeof(pic_callinfo) * cont->ci_len); @@ -82,11 +82,15 @@ restore_cont(pic_state *pic, struct pic_cont *cont) PIC_BLK_INCREF(pic, cont->blk); pic->blk = cont->blk; - pic->sp = cont->sp; + pic->stbase = (pic_value *)pic_realloc(pic, pic->stbase, sizeof(pic_value) * cont->st_len); memcpy(pic->stbase, cont->st_ptr, sizeof(pic_value) * cont->st_len); + pic->sp = pic->stbase + cont->sp_offset; + pic->stend = pic->stbase + cont->st_len; - pic->ci = cont->ci; + pic->cibase = (pic_callinfo *)pic_realloc(pic, pic->cibase, sizeof(pic_callinfo) * cont->ci_len); memcpy(pic->cibase, cont->ci_ptr, sizeof(pic_callinfo) * cont->ci_len); + pic->ci = pic->cibase + cont->ci_offset; + pic->ciend = pic->cibase + cont->ci_len; memcpy(pic->arena, cont->arena, sizeof(struct pic_object *) * PIC_ARENA_SIZE); pic->arena_idx = cont->arena_idx; diff --git a/src/gc.c b/src/gc.c index 5ed70b44..9616296c 100644 --- a/src/gc.c +++ b/src/gc.c @@ -230,12 +230,12 @@ gc_mark_object(pic_state *pic, struct pic_object *obj) gc_mark_block(pic, cont->blk); /* stack */ - for (stack = cont->st_ptr; stack != cont->sp; ++stack) { + for (stack = cont->st_ptr; stack != cont->st_ptr + cont->sp_offset; ++stack) { gc_mark(pic, *stack); } /* callinfo */ - for (ci = cont->ci; ci != cont->ci_ptr; --ci) { + for (ci = cont->ci_ptr + cont->ci_offset; ci != cont->ci_ptr; --ci) { if (ci->env) { gc_mark_object(pic, (struct pic_object *)ci->env); }