diff --git a/extlib/benz/cont.c b/extlib/benz/cont.c index 79fc747d..df1beedb 100644 --- a/extlib/benz/cont.c +++ b/extlib/benz/cont.c @@ -31,7 +31,7 @@ pic_dynamic_wind(pic_state *pic, struct pic_proc *in, struct pic_proc *thunk, st } here = pic->cp; - pic->cp = pic_malloc(pic, sizeof(pic_checkpoint)); + pic->cp = (pic_checkpoint *)pic_obj_alloc(pic, sizeof(pic_checkpoint), PIC_TT_CP); pic->cp->prev = here; pic->cp->depth = here->depth + 1; pic->cp->in = in; diff --git a/extlib/benz/gc.c b/extlib/benz/gc.c index 59ea6850..d5cf55f0 100644 --- a/extlib/benz/gc.c +++ b/extlib/benz/gc.c @@ -329,20 +329,6 @@ gc_unmark(union header *p) p->s.mark = PIC_GC_UNMARK; } -static void -gc_mark_checkpoint(pic_state *pic, pic_checkpoint *cp) -{ - if (cp->prev) { - gc_mark_object(pic, (struct pic_object *)cp->prev); - } - if (cp->in) { - gc_mark_object(pic, (struct pic_object *)cp->in); - } - if (cp->out) { - gc_mark_object(pic, (struct pic_object *)cp->out); - } -} - static void gc_mark_object(pic_state *pic, struct pic_object *obj) { @@ -495,6 +481,20 @@ gc_mark_object(pic_state *pic, struct pic_object *obj) pic->regs = reg; break; } + case PIC_TT_CP: { + struct pic_checkpoint *cp = (struct pic_checkpoint *)obj; + + if (cp->prev) { + gc_mark_object(pic, (struct pic_object *)cp->prev); + } + if (cp->in) { + gc_mark_object(pic, (struct pic_object *)cp->in); + } + if (cp->out) { + gc_mark_object(pic, (struct pic_object *)cp->out); + } + break; + } case PIC_TT_NIL: case PIC_TT_BOOL: #if PIC_ENABLE_FLOAT @@ -565,7 +565,7 @@ gc_mark_phase(pic_state *pic) /* checkpoint */ if (pic->cp) { - gc_mark_checkpoint(pic, pic->cp); + gc_mark_object(pic, (struct pic_object *)pic->cp); } /* stack */ @@ -722,6 +722,9 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj) xh_destroy(®->hash); break; } + case PIC_TT_CP: { + break; + } case PIC_TT_NIL: case PIC_TT_BOOL: #if PIC_ENABLE_FLOAT diff --git a/extlib/benz/include/picrin.h b/extlib/benz/include/picrin.h index 373a3fa6..01220cfd 100644 --- a/extlib/benz/include/picrin.h +++ b/extlib/benz/include/picrin.h @@ -53,6 +53,7 @@ typedef struct pic_jmpbuf { } pic_jmpbuf; typedef struct pic_checkpoint { + PIC_OBJECT_HEADER struct pic_proc *in; struct pic_proc *out; int depth; diff --git a/extlib/benz/include/picrin/value.h b/extlib/benz/include/picrin/value.h index 703bcb8e..507832bb 100644 --- a/extlib/benz/include/picrin/value.h +++ b/extlib/benz/include/picrin/value.h @@ -158,14 +158,15 @@ enum pic_tt { PIC_TT_PORT, PIC_TT_ERROR, PIC_TT_ID, - PIC_TT_CXT, PIC_TT_ENV, PIC_TT_LIB, - PIC_TT_IREP, PIC_TT_DATA, PIC_TT_DICT, PIC_TT_REG, - PIC_TT_RECORD + PIC_TT_RECORD, + PIC_TT_CXT, + PIC_TT_IREP, + PIC_TT_CP }; #define PIC_OBJECT_HEADER \ @@ -336,6 +337,8 @@ pic_type_repr(enum pic_tt tt) return "reg"; case PIC_TT_RECORD: return "record"; + case PIC_TT_CP: + return "checkpoint"; } PIC_UNREACHABLE(); } diff --git a/extlib/benz/state.c b/extlib/benz/state.c index fec9536f..46e88ab7 100644 --- a/extlib/benz/state.c +++ b/extlib/benz/state.c @@ -355,7 +355,7 @@ pic_open(int argc, char *argv[], char **envp, pic_allocf allocf) pic->attrs = pic_make_reg(pic); /* root block */ - pic->cp = pic_malloc(pic, sizeof(pic_checkpoint)); + pic->cp = (pic_checkpoint *)pic_obj_alloc(pic, sizeof(pic_checkpoint), PIC_TT_CP); pic->cp->prev = NULL; pic->cp->depth = 0; pic->cp->in = pic->cp->out = NULL; @@ -401,14 +401,6 @@ pic_close(pic_state *pic) xh_entry *it; pic_allocf allocf = pic->allocf; - /* invoke exit handlers */ - while (pic->cp) { - if (pic->cp->out) { - pic_apply0(pic, pic->cp->out); - } - pic->cp = pic->cp->prev; - } - /* free symbol names */ for (it = xh_begin(&pic->syms); it != NULL; it = xh_next(it)) { allocf(xh_key(it, char *), 0);