diff --git a/include/picrin.h b/include/picrin.h index 792c8a04..8b11b64f 100644 --- a/include/picrin.h +++ b/include/picrin.h @@ -7,11 +7,19 @@ #include "picconf.h" #include "picrin/value.h" +typedef struct pic_callinfo { + struct pic_proc *proc; + int argc; +} pic_callinfo; + typedef struct { pic_value *sp; pic_value *stbase, *stend; pic_value sDEFINE, sCONS; + pic_callinfo *ci; + pic_callinfo *cibase, *ciend; + pic_value sADD, sSUB, sMUL, sDIV; struct pic_env *global_env; diff --git a/src/state.c b/src/state.c index 3e7b1565..a59ddac2 100644 --- a/src/state.c +++ b/src/state.c @@ -29,6 +29,10 @@ pic_open() pic->stbase = pic->sp = (pic_value *)malloc(sizeof(pic_value) * PIC_STACK_SIZE); pic->stend = pic->stbase + PIC_STACK_SIZE; + /* callinfo */ + pic->cibase = pic->ci = (pic_callinfo *)malloc(sizeof(pic_callinfo) * PIC_STACK_SIZE); + pic->ciend = pic->ciend + PIC_STACK_SIZE; + /* memory heap */ pic->heap = (struct heap_page *)malloc(sizeof(struct heap_page)); init_heap_page(pic->heap); diff --git a/src/vm.c b/src/vm.c index 75178ebf..664cfe1a 100644 --- a/src/vm.c +++ b/src/vm.c @@ -317,6 +317,9 @@ pic_codegen(pic_state *pic, pic_value obj, struct pic_env *env) #define PUSH(v) (*pic->sp++ = (v)) #define POP() (*--pic->sp) +#define PUSHCI() (++pic->ci) +#define POPCI() (pic->ci--) + pic_value pic_run(pic_state *pic, struct pic_proc *proc, pic_value args) { @@ -324,6 +327,8 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args) int ai = pic_gc_arena_preserve(pic); pc = proc->u.irep->code; + pic->ci->proc = proc; + pic->ci->argc = 0; VM_LOOP { CASE(OP_PUSHNIL) { @@ -349,12 +354,17 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args) CASE(OP_CALL) { pic_value c; struct pic_proc *proc; + pic_callinfo *ci; int ai = pic_gc_arena_preserve(pic); pic_gc_protect(pic, c = POP()); proc = pic_proc_ptr(c); + ci = PUSHCI(); + ci->proc = proc; + ci->argc = pc->u.i; PUSH(proc->u.cfunc(pic)); pic_gc_arena_restore(pic, ai); + POPCI(); NEXT; } CASE(OP_CONS) {