compact struct pic_jmpbuf
This commit is contained in:
parent
b0b1b77c65
commit
978c51bb26
28
cont.c
28
cont.c
|
@ -131,14 +131,19 @@ save_cont(pic_state *pic, struct pic_cont **c)
|
||||||
|
|
||||||
cont->sp_offset = pic->sp - pic->stbase;
|
cont->sp_offset = pic->sp - pic->stbase;
|
||||||
cont->st_len = pic->stend - pic->stbase;
|
cont->st_len = pic->stend - pic->stbase;
|
||||||
cont->st_ptr = (pic_value *)pic_alloc(pic, sizeof(pic_value) * cont->st_len);
|
cont->st_ptr = pic_alloc(pic, sizeof(pic_value) * cont->st_len);
|
||||||
memcpy(cont->st_ptr, pic->stbase, sizeof(pic_value) * cont->st_len);
|
memcpy(cont->st_ptr, pic->stbase, sizeof(pic_value) * cont->st_len);
|
||||||
|
|
||||||
cont->ci_offset = pic->ci - pic->cibase;
|
cont->ci_offset = pic->ci - pic->cibase;
|
||||||
cont->ci_len = pic->ciend - pic->cibase;
|
cont->ci_len = pic->ciend - pic->cibase;
|
||||||
cont->ci_ptr = (pic_callinfo *)pic_alloc(pic, sizeof(pic_callinfo) * cont->ci_len);
|
cont->ci_ptr = pic_alloc(pic, sizeof(pic_callinfo) * cont->ci_len);
|
||||||
memcpy(cont->ci_ptr, pic->cibase, sizeof(pic_callinfo) * cont->ci_len);
|
memcpy(cont->ci_ptr, pic->cibase, sizeof(pic_callinfo) * cont->ci_len);
|
||||||
|
|
||||||
|
cont->xp_offset = pic->xp - pic->xpbase;
|
||||||
|
cont->xp_len = pic->xpend - pic->xpbase;
|
||||||
|
cont->xp_ptr = pic_alloc(pic, sizeof(struct pic_proc *) * cont->xp_len);
|
||||||
|
memcpy(cont->xp_ptr, pic->xpbase, sizeof(struct pic_proc *) * cont->xp_len);
|
||||||
|
|
||||||
cont->ip = pic->ip;
|
cont->ip = pic->ip;
|
||||||
|
|
||||||
cont->arena_idx = pic->arena_idx;
|
cont->arena_idx = pic->arena_idx;
|
||||||
|
@ -146,11 +151,6 @@ save_cont(pic_state *pic, struct pic_cont **c)
|
||||||
cont->arena = (struct pic_object **)pic_alloc(pic, sizeof(struct pic_object *) * pic->arena_size);
|
cont->arena = (struct pic_object **)pic_alloc(pic, sizeof(struct pic_object *) * pic->arena_size);
|
||||||
memcpy(cont->arena, pic->arena, sizeof(struct pic_object *) * pic->arena_size);
|
memcpy(cont->arena, pic->arena, sizeof(struct pic_object *) * pic->arena_size);
|
||||||
|
|
||||||
cont->try_jmp_idx = pic->try_jmp_idx;
|
|
||||||
cont->try_jmp_size = pic->try_jmp_size;
|
|
||||||
cont->try_jmps = pic_alloc(pic, sizeof(struct pic_jmpbuf) * pic->try_jmp_size);
|
|
||||||
memcpy(cont->try_jmps, pic->try_jmps, sizeof(struct pic_jmpbuf) * pic->try_jmp_size);
|
|
||||||
|
|
||||||
cont->results = pic_undef_value();
|
cont->results = pic_undef_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,16 +178,21 @@ restore_cont(pic_state *pic, struct pic_cont *cont)
|
||||||
|
|
||||||
pic->wind = cont->wind;
|
pic->wind = cont->wind;
|
||||||
|
|
||||||
pic->stbase = (pic_value *)pic_realloc(pic, pic->stbase, sizeof(pic_value) * cont->st_len);
|
pic->stbase = pic_realloc(pic, pic->stbase, sizeof(pic_value) * cont->st_len);
|
||||||
memcpy(pic->stbase, cont->st_ptr, 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->sp = pic->stbase + cont->sp_offset;
|
||||||
pic->stend = pic->stbase + cont->st_len;
|
pic->stend = pic->stbase + cont->st_len;
|
||||||
|
|
||||||
pic->cibase = (pic_callinfo *)pic_realloc(pic, pic->cibase, sizeof(pic_callinfo) * cont->ci_len);
|
pic->cibase = pic_realloc(pic, pic->cibase, sizeof(pic_callinfo) * cont->ci_len);
|
||||||
memcpy(pic->cibase, cont->ci_ptr, 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->ci = pic->cibase + cont->ci_offset;
|
||||||
pic->ciend = pic->cibase + cont->ci_len;
|
pic->ciend = pic->cibase + cont->ci_len;
|
||||||
|
|
||||||
|
pic->xpbase = pic_realloc(pic, pic->xpbase, sizeof(struct pic_proc *) * cont->xp_len);
|
||||||
|
memcpy(pic->xpbase, cont->xp_ptr, sizeof(struct pic_proc *) * cont->xp_len);
|
||||||
|
pic->xp = pic->xpbase + cont->xp_offset;
|
||||||
|
pic->xpend = pic->xpbase + cont->xp_len;
|
||||||
|
|
||||||
pic->ip = cont->ip;
|
pic->ip = cont->ip;
|
||||||
|
|
||||||
pic->arena = (struct pic_object **)pic_realloc(pic, pic->arena, sizeof(struct pic_object *) * cont->arena_size);
|
pic->arena = (struct pic_object **)pic_realloc(pic, pic->arena, sizeof(struct pic_object *) * cont->arena_size);
|
||||||
|
@ -195,11 +200,6 @@ restore_cont(pic_state *pic, struct pic_cont *cont)
|
||||||
pic->arena_size = cont->arena_size;
|
pic->arena_size = cont->arena_size;
|
||||||
pic->arena_idx = cont->arena_idx;
|
pic->arena_idx = cont->arena_idx;
|
||||||
|
|
||||||
pic->try_jmps = pic_realloc(pic, pic->try_jmps, sizeof(struct pic_jmpbuf) * cont->try_jmp_size);
|
|
||||||
memcpy(pic->try_jmps, cont->try_jmps, sizeof(struct pic_jmpbuf) * cont->try_jmp_size);
|
|
||||||
pic->try_jmp_size = cont->try_jmp_size;
|
|
||||||
pic->try_jmp_idx = cont->try_jmp_idx;
|
|
||||||
|
|
||||||
memcpy(cont->stk_pos, cont->stk_ptr, cont->stk_len);
|
memcpy(cont->stk_pos, cont->stk_ptr, cont->stk_len);
|
||||||
|
|
||||||
longjmp(tmp->jmp, 1);
|
longjmp(tmp->jmp, 1);
|
||||||
|
|
40
error.c
40
error.c
|
@ -89,7 +89,7 @@ static pic_value
|
||||||
native_push_try(pic_state *pic)
|
native_push_try(pic_state *pic)
|
||||||
{
|
{
|
||||||
struct pic_proc *cont, *handler;
|
struct pic_proc *cont, *handler;
|
||||||
struct pic_jmpbuf *try_jmp;
|
size_t xp_len, xp_offset;
|
||||||
|
|
||||||
pic_get_args(pic, "l", &cont);
|
pic_get_args(pic, "l", &cont);
|
||||||
|
|
||||||
|
@ -97,13 +97,15 @@ native_push_try(pic_state *pic)
|
||||||
|
|
||||||
pic_attr_set(pic, handler, "@@escape", pic_obj_value(cont));
|
pic_attr_set(pic, handler, "@@escape", pic_obj_value(cont));
|
||||||
|
|
||||||
if (pic->try_jmp_idx >= pic->try_jmp_size) {
|
if (pic->xp >= pic->xpend) {
|
||||||
pic->try_jmp_size *= 2;
|
xp_len = (pic->xpend - pic->xpbase) * 2;
|
||||||
pic->try_jmps = pic_realloc(pic, pic->try_jmps, sizeof(struct pic_jmpbuf) * pic->try_jmp_size);
|
xp_offset = pic->xp - pic->xpbase;
|
||||||
|
pic->xpbase = pic_realloc(pic, pic->xpbase, sizeof(struct pic_proc *) * xp_len);
|
||||||
|
pic->xp = pic->xpbase + xp_offset;
|
||||||
|
pic->xpend = pic->xpbase + xp_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
try_jmp = pic->try_jmps + pic->try_jmp_idx++;
|
*pic->xp++ = handler;
|
||||||
try_jmp->handler = handler;
|
|
||||||
|
|
||||||
return pic_true_value();
|
return pic_true_value();
|
||||||
}
|
}
|
||||||
|
@ -121,7 +123,7 @@ pic_push_try(pic_state *pic)
|
||||||
void
|
void
|
||||||
pic_pop_try(pic_state *pic)
|
pic_pop_try(pic_state *pic)
|
||||||
{
|
{
|
||||||
--pic->try_jmp_idx;
|
--pic->xp;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pic_error *
|
struct pic_error *
|
||||||
|
@ -147,19 +149,17 @@ pic_raise_continuable(pic_state *pic, pic_value err)
|
||||||
struct pic_proc *handler;
|
struct pic_proc *handler;
|
||||||
pic_value v;
|
pic_value v;
|
||||||
|
|
||||||
if (pic->try_jmp_idx == 0) {
|
if (pic->xp == pic->xpbase) {
|
||||||
pic_panic(pic, "no exception handler registered");
|
pic_panic(pic, "no exception handler registered");
|
||||||
}
|
}
|
||||||
|
|
||||||
handler = pic->try_jmps[pic->try_jmp_idx - 1].handler;
|
handler = *--pic->xp;
|
||||||
|
|
||||||
pic_gc_protect(pic, pic_obj_value(handler));
|
pic_gc_protect(pic, pic_obj_value(handler));
|
||||||
|
|
||||||
pic->try_jmp_idx--;
|
v = pic_apply1(pic, handler, err);
|
||||||
|
|
||||||
v = pic_apply1(pic, pic->try_jmps[pic->try_jmp_idx].handler, err);
|
*pic->xp++ = handler;
|
||||||
|
|
||||||
pic->try_jmps[pic->try_jmp_idx++].handler = handler;
|
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
@ -197,19 +197,23 @@ pic_error_with_exception_handler(pic_state *pic)
|
||||||
{
|
{
|
||||||
struct pic_proc *handler, *thunk;
|
struct pic_proc *handler, *thunk;
|
||||||
pic_value val;
|
pic_value val;
|
||||||
|
size_t xp_len, xp_offset;
|
||||||
|
|
||||||
pic_get_args(pic, "ll", &handler, &thunk);
|
pic_get_args(pic, "ll", &handler, &thunk);
|
||||||
|
|
||||||
if (pic->try_jmp_idx >= pic->try_jmp_size) {
|
if (pic->xp >= pic->xpend) {
|
||||||
pic->try_jmp_size *= 2;
|
xp_len = (pic->xpend - pic->xpbase) * 2;
|
||||||
pic->try_jmps = pic_realloc(pic, pic->try_jmps, sizeof(struct pic_jmpbuf) * pic->try_jmp_size);
|
xp_offset = pic->xp - pic->xpbase;
|
||||||
|
pic->xpbase = pic_realloc(pic, pic->xpbase, sizeof(struct pic_proc *) * xp_len);
|
||||||
|
pic->xp = pic->xpbase + xp_offset;
|
||||||
|
pic->xpend = pic->xpbase + xp_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
pic->try_jmps[pic->try_jmp_idx++].handler = handler;
|
*pic->xp++ = handler;
|
||||||
|
|
||||||
val = pic_apply0(pic, thunk);
|
val = pic_apply0(pic, thunk);
|
||||||
|
|
||||||
pic->try_jmp_idx--;
|
--pic->xp;
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
33
gc.c
33
gc.c
|
@ -416,6 +416,7 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
|
||||||
struct pic_cont *cont = (struct pic_cont *)obj;
|
struct pic_cont *cont = (struct pic_cont *)obj;
|
||||||
pic_value *stack;
|
pic_value *stack;
|
||||||
pic_callinfo *ci;
|
pic_callinfo *ci;
|
||||||
|
struct pic_proc **xhandler;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
/* winder */
|
/* winder */
|
||||||
|
@ -433,18 +434,16 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* exception handlers */
|
||||||
|
for (xhandler = cont->xp_ptr; xhandler != cont->xp_ptr + cont->xp_offset; ++xhandler) {
|
||||||
|
gc_mark_object(pic, (struct pic_object *)*xhandler);
|
||||||
|
}
|
||||||
|
|
||||||
/* arena */
|
/* arena */
|
||||||
for (i = 0; i < (size_t)cont->arena_idx; ++i) {
|
for (i = 0; i < (size_t)cont->arena_idx; ++i) {
|
||||||
gc_mark_object(pic, cont->arena[i]);
|
gc_mark_object(pic, cont->arena[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* error handlers */
|
|
||||||
for (i = 0; i < cont->try_jmp_idx; ++i) {
|
|
||||||
if (cont->try_jmps[i].handler) {
|
|
||||||
gc_mark_object(pic, (struct pic_object *)cont->try_jmps[i].handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* result values */
|
/* result values */
|
||||||
gc_mark(pic, cont->results);
|
gc_mark(pic, cont->results);
|
||||||
break;
|
break;
|
||||||
|
@ -562,7 +561,8 @@ gc_mark_phase(pic_state *pic)
|
||||||
{
|
{
|
||||||
pic_value *stack;
|
pic_value *stack;
|
||||||
pic_callinfo *ci;
|
pic_callinfo *ci;
|
||||||
size_t i, j;
|
struct pic_proc **xhandler;
|
||||||
|
size_t j;
|
||||||
xh_entry *it;
|
xh_entry *it;
|
||||||
|
|
||||||
/* winder */
|
/* winder */
|
||||||
|
@ -582,8 +582,10 @@ gc_mark_phase(pic_state *pic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* error object */
|
/* exception handlers */
|
||||||
gc_mark(pic, pic->err);
|
for (xhandler = pic->xpbase; xhandler != pic->xp; ++xhandler) {
|
||||||
|
gc_mark_object(pic, (struct pic_object *)*xhandler);
|
||||||
|
}
|
||||||
|
|
||||||
/* arena */
|
/* arena */
|
||||||
for (j = 0; j < pic->arena_idx; ++j) {
|
for (j = 0; j < pic->arena_idx; ++j) {
|
||||||
|
@ -600,13 +602,10 @@ gc_mark_phase(pic_state *pic)
|
||||||
gc_mark_object(pic, xh_val(it, struct pic_object *));
|
gc_mark_object(pic, xh_val(it, struct pic_object *));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* error handlers */
|
/* error object */
|
||||||
for (i = 0; i < pic->try_jmp_idx; ++i) {
|
gc_mark(pic, pic->err);
|
||||||
if (pic->try_jmps[i].handler) {
|
|
||||||
gc_mark_object(pic, (struct pic_object *)pic->try_jmps[i].handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* features */
|
||||||
gc_mark(pic, pic->features);
|
gc_mark(pic, pic->features);
|
||||||
|
|
||||||
/* readers */
|
/* readers */
|
||||||
|
@ -669,8 +668,8 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
|
||||||
pic_free(pic, cont->stk_ptr);
|
pic_free(pic, cont->stk_ptr);
|
||||||
pic_free(pic, cont->st_ptr);
|
pic_free(pic, cont->st_ptr);
|
||||||
pic_free(pic, cont->ci_ptr);
|
pic_free(pic, cont->ci_ptr);
|
||||||
|
pic_free(pic, cont->xp_ptr);
|
||||||
pic_free(pic, cont->arena);
|
pic_free(pic, cont->arena);
|
||||||
pic_free(pic, cont->try_jmps);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PIC_TT_SENV: {
|
case PIC_TT_SENV: {
|
||||||
|
|
|
@ -75,6 +75,9 @@ typedef struct {
|
||||||
pic_callinfo *ci;
|
pic_callinfo *ci;
|
||||||
pic_callinfo *cibase, *ciend;
|
pic_callinfo *cibase, *ciend;
|
||||||
|
|
||||||
|
struct pic_proc **xp;
|
||||||
|
struct pic_proc **xpbase, **xpend;
|
||||||
|
|
||||||
pic_code *ip;
|
pic_code *ip;
|
||||||
|
|
||||||
struct pic_lib *lib;
|
struct pic_lib *lib;
|
||||||
|
@ -111,16 +114,14 @@ typedef struct {
|
||||||
|
|
||||||
struct pic_reader *reader;
|
struct pic_reader *reader;
|
||||||
|
|
||||||
pic_value err;
|
|
||||||
struct pic_jmpbuf *try_jmps;
|
|
||||||
size_t try_jmp_size, try_jmp_idx;
|
|
||||||
|
|
||||||
struct pic_heap *heap;
|
struct pic_heap *heap;
|
||||||
struct pic_object **arena;
|
struct pic_object **arena;
|
||||||
size_t arena_size, arena_idx;
|
size_t arena_size, arena_idx;
|
||||||
|
|
||||||
struct pic_port *xSTDIN, *xSTDOUT, *xSTDERR;
|
struct pic_port *xSTDIN, *xSTDOUT, *xSTDERR;
|
||||||
|
|
||||||
|
pic_value err;
|
||||||
|
|
||||||
char *native_stack_start;
|
char *native_stack_start;
|
||||||
} pic_state;
|
} pic_state;
|
||||||
|
|
||||||
|
|
|
@ -24,15 +24,15 @@ struct pic_cont {
|
||||||
pic_callinfo *ci_ptr;
|
pic_callinfo *ci_ptr;
|
||||||
size_t ci_offset, ci_len;
|
size_t ci_offset, ci_len;
|
||||||
|
|
||||||
|
struct pic_proc **xp_ptr;
|
||||||
|
size_t xp_offset, xp_len;
|
||||||
|
|
||||||
pic_code *ip;
|
pic_code *ip;
|
||||||
|
|
||||||
struct pic_object **arena;
|
struct pic_object **arena;
|
||||||
size_t arena_size;
|
size_t arena_size;
|
||||||
int arena_idx;
|
int arena_idx;
|
||||||
|
|
||||||
struct pic_jmpbuf *try_jmps;
|
|
||||||
size_t try_jmp_idx, try_jmp_size;
|
|
||||||
|
|
||||||
pic_value results;
|
pic_value results;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,15 +9,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct pic_jmpbuf {
|
|
||||||
jmp_buf here;
|
|
||||||
struct pic_proc *handler;
|
|
||||||
ptrdiff_t ci_offset;
|
|
||||||
ptrdiff_t sp_offset;
|
|
||||||
pic_code *ip;
|
|
||||||
jmp_buf *prev_jmp;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* do not return from try block! */
|
/* do not return from try block! */
|
||||||
|
|
||||||
#define pic_try \
|
#define pic_try \
|
||||||
|
|
12
state.c
12
state.c
|
@ -42,6 +42,10 @@ pic_open(int argc, char *argv[], char **envp)
|
||||||
pic->cibase = pic->ci = calloc(PIC_STACK_SIZE, sizeof(pic_callinfo));
|
pic->cibase = pic->ci = calloc(PIC_STACK_SIZE, sizeof(pic_callinfo));
|
||||||
pic->ciend = pic->cibase + PIC_STACK_SIZE;
|
pic->ciend = pic->cibase + PIC_STACK_SIZE;
|
||||||
|
|
||||||
|
/* exception handler */
|
||||||
|
pic->xpbase = pic->xp = calloc(PIC_RESCUE_SIZE, sizeof(struct pic_proc *));
|
||||||
|
pic->xpend = pic->xpbase + PIC_RESCUE_SIZE;
|
||||||
|
|
||||||
/* memory heap */
|
/* memory heap */
|
||||||
pic->heap = pic_heap_open();
|
pic->heap = pic_heap_open();
|
||||||
|
|
||||||
|
@ -70,11 +74,8 @@ pic_open(int argc, char *argv[], char **envp)
|
||||||
pic->reader->trie = pic_make_trie(pic);
|
pic->reader->trie = pic_make_trie(pic);
|
||||||
xh_init_int(&pic->reader->labels, sizeof(pic_value));
|
xh_init_int(&pic->reader->labels, sizeof(pic_value));
|
||||||
|
|
||||||
/* error handling */
|
/* raised error object */
|
||||||
pic->err = pic_undef_value();
|
pic->err = pic_undef_value();
|
||||||
pic->try_jmps = calloc(PIC_RESCUE_SIZE, sizeof(struct pic_jmpbuf));
|
|
||||||
pic->try_jmp_idx = 0;
|
|
||||||
pic->try_jmp_size = PIC_RESCUE_SIZE;
|
|
||||||
|
|
||||||
/* standard ports */
|
/* standard ports */
|
||||||
pic->xSTDIN = NULL;
|
pic->xSTDIN = NULL;
|
||||||
|
@ -191,6 +192,7 @@ pic_close(pic_state *pic)
|
||||||
/* clear out root objects */
|
/* clear out root objects */
|
||||||
pic->sp = pic->stbase;
|
pic->sp = pic->stbase;
|
||||||
pic->ci = pic->cibase;
|
pic->ci = pic->cibase;
|
||||||
|
pic->xp = pic->xpbase;
|
||||||
pic->arena_idx = 0;
|
pic->arena_idx = 0;
|
||||||
pic->err = pic_undef_value();
|
pic->err = pic_undef_value();
|
||||||
xh_clear(&pic->macros);
|
xh_clear(&pic->macros);
|
||||||
|
@ -206,6 +208,7 @@ pic_close(pic_state *pic)
|
||||||
/* free runtime context */
|
/* free runtime context */
|
||||||
free(pic->stbase);
|
free(pic->stbase);
|
||||||
free(pic->cibase);
|
free(pic->cibase);
|
||||||
|
free(pic->xpbase);
|
||||||
|
|
||||||
/* free reader struct */
|
/* free reader struct */
|
||||||
xh_destroy(&pic->reader->labels);
|
xh_destroy(&pic->reader->labels);
|
||||||
|
@ -213,7 +216,6 @@ pic_close(pic_state *pic)
|
||||||
free(pic->reader);
|
free(pic->reader);
|
||||||
|
|
||||||
/* free global stacks */
|
/* free global stacks */
|
||||||
free(pic->try_jmps);
|
|
||||||
xh_destroy(&pic->syms);
|
xh_destroy(&pic->syms);
|
||||||
xh_destroy(&pic->globals);
|
xh_destroy(&pic->globals);
|
||||||
xh_destroy(&pic->macros);
|
xh_destroy(&pic->macros);
|
||||||
|
|
Loading…
Reference in New Issue