diff --git a/src/codegen.c b/src/codegen.c index 808b66e7..c0142599 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -441,10 +441,11 @@ pic_codegen(pic_state *pic, pic_value obj, struct pic_env *env) if (! pic->jmp) { jmp_buf jmp; - pic->jmp = &jmp; - if (setjmp(*pic->jmp) != 0) { + if (setjmp(jmp) == 0) { + pic->jmp = &jmp; + } + else { /* error occured */ - pic->jmp = NULL; return NULL; } diff --git a/src/pair.c b/src/pair.c index 1a60e184..bbd17e5f 100644 --- a/src/pair.c +++ b/src/pair.c @@ -18,6 +18,9 @@ pic_car(pic_state *pic, pic_value obj) { struct pic_pair *pair; + if (! pic_pair_p(obj)) { + pic_error(pic, "pair required"); + } pair = (struct pic_pair *)obj.u.data; return pair->car; @@ -28,6 +31,9 @@ pic_cdr(pic_state *pic, pic_value obj) { struct pic_pair *pair; + if (! pic_pair_p(obj)) { + pic_error(pic, "pair required"); + } pair = (struct pic_pair *)obj.u.data; return pair->cdr; diff --git a/src/vm.c b/src/vm.c index bbe0c4ea..8b2c68e9 100644 --- a/src/vm.c +++ b/src/vm.c @@ -64,6 +64,7 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args) { struct pic_code *pc; int ai = pic_gc_arena_preserve(pic); + jmp_buf jmp; #if PIC_DIRECT_THREADED_VM static void *oplabels[] = { @@ -76,6 +77,13 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args) pc = proc->u.irep->code; + if (setjmp(jmp) == 0) { + pic->jmp = &jmp; + } + else { + goto L_RAISE; + } + /* adjust call frame */ pic->sp[0] = pic_obj_value(proc); pic->ci->argc = 1; @@ -158,11 +166,17 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args) pic_value v; pic_callinfo *ci; - v = POP(); - ci = POPCI(); - pc = ci->pc; - pic->sp -= ci->argc; - PUSH(v); + L_RAISE: + if (pic->errmsg) { + goto L_STOP; + } + else { + v = POP(); + ci = POPCI(); + pc = ci->pc; + pic->sp -= ci->argc; + PUSH(v); + } NEXT; } CASE(OP_LAMBDA) { @@ -232,8 +246,14 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args) CASE(OP_STOP) { pic_value val; + L_STOP: val = POP(); + pic->jmp = NULL; + if (pic->errmsg) { + return pic_undef_value(); + } + #if VM_DEBUG puts("**VM END STATE**"); printf("stbase = %p\nsp = %p\n", pic->stbase, pic->sp); diff --git a/tools/main.c b/tools/main.c index d6011621..a8f752cc 100644 --- a/tools/main.c +++ b/tools/main.c @@ -87,6 +87,11 @@ main() goto next; } v = pic_run(pic, proc, pic_nil_value()); + if (pic_undef_p(v)) { + printf("runtime error: %s\n", pic->errmsg); + pic->errmsg = NULL; + goto next; + } /* print */ printf("=> ");