From 38988b7770ad87854b710dc9a66e6f42ac1c90bd Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Sun, 17 Nov 2013 16:02:58 +0900 Subject: [PATCH] add global exception handler stack --- include/config.h | 1 + include/picrin.h | 3 +++ include/picrin/cont.h | 3 +++ src/cont.c | 10 ++++++++++ src/gc.c | 11 +++++++++++ src/state.c | 5 +++++ 6 files changed, 33 insertions(+) diff --git a/include/config.h b/include/config.h index 7ba98bf7..d951a29d 100644 --- a/include/config.h +++ b/include/config.h @@ -14,6 +14,7 @@ #define PIC_ARENA_SIZE 100 #define PIC_HEAP_SIZE (1<<19) #define PIC_STACK_SIZE 1024 +#define PIC_RESCUE_SIZE 30 #define PIC_IREP_SIZE 256 #define PIC_GLOBALS_SIZE 1024 #define PIC_MACROS_SIZE 1024 diff --git a/include/picrin.h b/include/picrin.h index ba528020..75754923 100644 --- a/include/picrin.h +++ b/include/picrin.h @@ -37,6 +37,9 @@ typedef struct { pic_callinfo *ci; pic_callinfo *cibase, *ciend; + struct pic_proc **rescue; + size_t ridx, rlen; + pic_sym sDEFINE, sLAMBDA, sIF, sBEGIN, sQUOTE, sSETBANG; pic_sym sQUASIQUOTE, sUNQUOTE, sUNQUOTE_SPLICING; pic_sym sDEFINE_SYNTAX, sDEFINE_MACRO; diff --git a/include/picrin/cont.h b/include/picrin/cont.h index d6b5b9dc..e08dba57 100644 --- a/include/picrin/cont.h +++ b/include/picrin/cont.h @@ -16,6 +16,9 @@ struct pic_cont { pic_callinfo *ci_ptr; size_t ci_offset, ci_len; + struct pic_proc **rescue; + size_t ridx, rlen; + struct pic_object *arena[PIC_ARENA_SIZE]; int arena_idx; diff --git a/src/cont.c b/src/cont.c index d1d48990..0afbc92a 100644 --- a/src/cont.c +++ b/src/cont.c @@ -48,6 +48,11 @@ save_cont(pic_state *pic) 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); + cont->ridx = pic->ridx; + cont->rlen = pic->rlen; + cont->rescue = (struct pic_proc **)pic_alloc(pic, sizeof(struct pic_proc *) * cont->rlen); + memcpy(cont->rescue, pic->rescue, sizeof(struct pic_proc *) * cont->rlen); + cont->arena_idx = pic->arena_idx; memcpy(cont->arena, pic->arena, sizeof(struct pic_object *) * PIC_ARENA_SIZE); @@ -92,6 +97,11 @@ restore_cont(pic_state *pic, struct pic_cont *cont) pic->ci = pic->cibase + cont->ci_offset; pic->ciend = pic->cibase + cont->ci_len; + pic->rescue = (struct pic_proc **)pic_realloc(pic, pic->rescue, sizeof(struct pic_proc *) * cont->rlen); + memcpy(pic->rescue, cont->rescue, sizeof(struct pic_object *) * cont->rlen); + pic->ridx = cont->ridx; + pic->rlen = cont->rlen; + 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 9616296c..9213ff7b 100644 --- a/src/gc.c +++ b/src/gc.c @@ -241,6 +241,11 @@ gc_mark_object(pic_state *pic, struct pic_object *obj) } } + /* exception handlers */ + for (i = 0; i < cont->ridx; ++i) { + gc_mark_object(pic, (struct pic_object *)cont->rescue[i]); + } + /* arena */ for (i = 0; i < cont->arena_idx; ++i) { gc_mark_object(pic, cont->arena[i]); @@ -295,6 +300,11 @@ gc_mark_phase(pic_state *pic) } } + /* exception handlers */ + for (i = 0; i < pic->ridx; ++i) { + gc_mark_object(pic, (struct pic_object *)pic->rescue[i]); + } + /* arena */ for (i = 0; i < pic->arena_idx; ++i) { gc_mark_object(pic, pic->arena[i]); @@ -358,6 +368,7 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj) pic_free(pic, cont->stk_ptr); pic_free(pic, cont->st_ptr); pic_free(pic, cont->ci_ptr); + pic_free(pic, cont->rescue); PIC_BLK_DECREF(pic, cont->blk); break; } diff --git a/src/state.c b/src/state.c index 9e7d1d36..b85ca9c1 100644 --- a/src/state.c +++ b/src/state.c @@ -37,6 +37,11 @@ pic_open(int argc, char *argv[], char **envp) pic->cibase = pic->ci = (pic_callinfo *)malloc(sizeof(pic_callinfo) * PIC_STACK_SIZE); pic->ciend = pic->cibase + PIC_STACK_SIZE; + /* exception handlers */ + pic->rescue = (struct pic_proc **)malloc(sizeof(struct pic_proc *) * PIC_RESCUE_SIZE); + pic->ridx = 0; + pic->rlen = PIC_RESCUE_SIZE; + /* memory heap */ pic->heap = (struct heap_page *)malloc(sizeof(struct heap_page)); init_heap_page(pic->heap);