diff --git a/lib/error.c b/lib/error.c index 65eabc06..ee8e9e95 100644 --- a/lib/error.c +++ b/lib/error.c @@ -39,8 +39,6 @@ pic_prepare_try(pic_state *pic) { struct context *cxt = pic_alloca(pic, sizeof(struct context)); - cxt->ai = pic->cxt->ai; - pic->cxt->ai--; /* cxt should be freed after this try ends */ cxt->pc = NULL; cxt->fp = NULL; cxt->sp = NULL; diff --git a/lib/ext/file.c b/lib/ext/file.c index 689bd950..4efc9422 100644 --- a/lib/ext/file.c +++ b/lib/ext/file.c @@ -5,6 +5,7 @@ #include #include "picrin.h" +#include "../object.h" #if PIC_USE_FILE diff --git a/lib/gc.c b/lib/gc.c index 1b9ebf2b..2b4e1c70 100644 --- a/lib/gc.c +++ b/lib/gc.c @@ -144,11 +144,11 @@ pic_free(pic_state *pic, void *ptr) static void gc_protect(pic_state *pic, struct object *obj) { - if (pic->cxt->ai >= pic->arena_size) { + if (pic->ai >= pic->arena_size) { pic->arena_size = pic->arena_size * 2 + 1; pic->arena = pic_realloc(pic, pic->arena, sizeof(struct object *) * pic->arena_size); } - pic->arena[pic->cxt->ai++] = obj; + pic->arena[pic->ai++] = obj; } pic_value @@ -165,13 +165,13 @@ pic_protect(pic_state *pic, pic_value v) size_t pic_enter(pic_state *pic) { - return pic->cxt->ai; + return pic->ai; } void pic_leave(pic_state *pic, size_t state) { - pic->cxt->ai = state; + pic->ai = state; } void * @@ -332,7 +332,7 @@ gc_mark_phase(pic_state *pic) } /* arena */ - for (j = 0; j < pic->cxt->ai; ++j) { + for (j = 0; j < pic->ai; ++j) { gc_mark_object(pic, (struct object *)pic->arena[j]); } diff --git a/lib/include/picrin.h b/lib/include/picrin.h index 0426c186..664050af 100644 --- a/lib/include/picrin.h +++ b/lib/include/picrin.h @@ -297,13 +297,14 @@ pic_value pic_raise_continuable(pic_state *pic, pic_value err); PIC_NORETURN void pic_raise(pic_state *, pic_value v); PIC_NORETURN void pic_error(pic_state *, const char *msg, int n, ...); -#define pic_try pic_try_(PIC_GENSYM(cont), PIC_GENSYM(jmp)) -#define pic_try_(cont, jmp) \ +#define pic_try pic_try_(PIC_GENSYM(jmp)) +#define pic_try_(jmp) \ do { \ extern PIC_JMPBUF *pic_prepare_try(pic_state *); \ extern void pic_enter_try(pic_state *); \ extern void pic_exit_try(pic_state *); \ extern pic_value pic_abort_try(pic_state *); \ + size_t pic_try_ai_ = pic_enter(pic); \ PIC_JMPBUF *jmp = pic_prepare_try(pic); \ if (PIC_SETJMP(*jmp) == 0) { \ pic_enter_try(pic); @@ -312,6 +313,8 @@ PIC_NORETURN void pic_error(pic_state *, const char *msg, int n, ...); pic_exit_try(pic); \ } else { \ e = pic_abort_try(pic); \ + pic_leave(pic, pic_try_ai_); \ + pic_protect(pic, e); \ goto label; \ } \ } while (0); \ diff --git a/lib/proc.c b/lib/proc.c index 10771a05..019153fd 100644 --- a/lib/proc.c +++ b/lib/proc.c @@ -360,7 +360,7 @@ pic_value pic_apply(pic_state *pic, pic_value proc, int argc, pic_value *argv) { struct context cxt; - size_t arena_base = pic->cxt->ai; + size_t arena_base = pic->ai; #define MKCALL(argc) (cxt.tmpcode[0] = OP_CALL, cxt.tmpcode[1] = (argc), cxt.tmpcode) @@ -376,15 +376,14 @@ pic_apply(pic_state *pic, pic_value proc, int argc, pic_value *argv) } cxt.fp = NULL; cxt.irep = NULL; - cxt.ai = pic->cxt->ai; cxt.prev = pic->cxt; pic->cxt = &cxt; - if (PIC_SETJMP(cxt.jmp) != 0) { - /* pass */ - } +#define SAVE (pic->ai = arena_base) -#define SAVE (cxt.ai = arena_base) + if (PIC_SETJMP(cxt.jmp) != 0) { + SAVE; + } #define A (cxt.pc[1]) #define B (cxt.pc[2]) diff --git a/lib/state.c b/lib/state.c index 7534c54c..808ec504 100644 --- a/lib/state.c +++ b/lib/state.c @@ -171,7 +171,6 @@ pic_open(pic_allocf allocf, void *userdata) pic->userdata = userdata; /* context */ - pic->default_cxt.ai = 0; pic->default_cxt.pc = NULL; pic->default_cxt.fp = NULL; pic->default_cxt.sp = NULL; @@ -182,6 +181,7 @@ pic_open(pic_allocf allocf, void *userdata) /* arena */ pic->arena = allocf(userdata, NULL, PIC_ARENA_SIZE * sizeof(struct object *)); pic->arena_size = PIC_ARENA_SIZE; + pic->ai = 0; if (! pic->arena) { goto EXIT_ARENA; @@ -250,7 +250,7 @@ pic_close(pic_state *pic) /* clear out root objects */ pic->cxt = &pic->default_cxt; - pic->cxt->ai = 0; + pic->ai = 0; pic->halt = pic_invalid_value(pic); pic->globals = pic_invalid_value(pic); pic->features = pic_invalid_value(pic); diff --git a/lib/state.h b/lib/state.h index c96b3f39..60fd9907 100644 --- a/lib/state.h +++ b/lib/state.h @@ -16,7 +16,6 @@ KHASH_DECLARE(oblist, struct string *, struct symbol *) struct context { PIC_JMPBUF jmp; - size_t ai; /* vm */ const code_t *pc; @@ -35,6 +34,7 @@ struct pic_state { struct context *cxt, default_cxt; + size_t ai; pic_value dyn_env; pic_value features; /* list of symbols */