From 19db4bb6b2b3f26adaff07eda2624b957c31dde3 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Sun, 2 Feb 2014 12:27:48 +0900 Subject: [PATCH] rest array got by pic_get_args has a dynamic extent; that is, we cannot store it to a heap object when we are going to rewind that stack and restore an old continuation. --- include/picrin/cont.h | 4 ++-- src/cont.c | 25 +++++++++++++++++++------ src/gc.c | 4 +--- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/include/picrin/cont.h b/include/picrin/cont.h index 6bb18623..c08a2830 100644 --- a/include/picrin/cont.h +++ b/include/picrin/cont.h @@ -30,8 +30,7 @@ struct pic_cont { struct pic_object *arena[PIC_ARENA_SIZE]; int arena_idx; - size_t argc; - pic_value *argv; + pic_value results; }; #define PIC_BLK_INCREF(pic,blk) do { \ @@ -54,6 +53,7 @@ struct pic_cont { pic_value pic_callcc(pic_state *, struct pic_proc *); pic_value pic_values(pic_state *, size_t, ...); pic_value pic_values_by_array(pic_state *, size_t, pic_value *); +pic_value pic_values_by_list(pic_state *, pic_value); #if defined(__cplusplus) } diff --git a/src/cont.c b/src/cont.c index 3164ee6d..2da3fd3d 100644 --- a/src/cont.c +++ b/src/cont.c @@ -9,6 +9,7 @@ #include "picrin.h" #include "picrin/proc.h" #include "picrin/cont.h" +#include "picrin/pair.h" static void save_cont(pic_state *, struct pic_cont **); static void restore_cont(pic_state *, struct pic_cont *); @@ -61,8 +62,7 @@ save_cont(pic_state *pic, struct pic_cont **c) cont->arena_idx = pic->arena_idx; memcpy(cont->arena, pic->arena, sizeof(struct pic_object *) * PIC_ARENA_SIZE); - cont->argc = 0; - cont->argv = NULL; + cont->results = pic_undef_value(); } static void @@ -142,8 +142,7 @@ cont_call(pic_state *pic) pic_get_args(pic, "*", &argc, &argv); cont = (struct pic_cont *)pic_ptr(proc->env->values[0]); - cont->argc = argc; - cont->argv = argv; + cont->results = pic_list_by_array(pic, argc, argv); /* execute guard handlers */ walk_to_block(pic, pic->blk, cont->blk); @@ -158,8 +157,7 @@ pic_callcc(pic_state *pic, struct pic_proc *proc) save_cont(pic, &cont); if (setjmp(cont->jmp)) { - printf("%d\n", cont->argc); - return pic_values_from_array(pic, cont->argc, cont->argv); + return pic_values_by_list(pic, cont->results); } else { struct pic_proc *c; @@ -205,6 +203,21 @@ pic_values_by_array(pic_state *pic, size_t argc, pic_value *argv) return argc == 0 ? pic_none_value() : pic->ci->fp[0]; } +pic_value +pic_values_by_list(pic_state *pic, pic_value list) +{ + pic_value v; + size_t i; + + i = 0; + pic_for_each (v, list) { + pic->ci->fp[i++] = v; + } + pic->ci->fp[i] = pic_undef_value(); + + return pic_nil_p(list) ? pic_none_value() : pic->ci->fp[0]; +} + static pic_value pic_cont_callcc(pic_state *pic) { diff --git a/src/gc.c b/src/gc.c index f37e045b..4099f42b 100644 --- a/src/gc.c +++ b/src/gc.c @@ -386,9 +386,7 @@ gc_mark_object(pic_state *pic, struct pic_object *obj) } /* result values */ - for (i = 0; i < cont->argc; ++i) { - gc_mark(pic, cont->argv[i]); - } + gc_mark(pic, cont->results); break; } case PIC_TT_SYNTAX: {