support closure call

This commit is contained in:
Yuichi Nishiwaki 2013-10-16 15:30:52 +09:00
parent 49e1f54195
commit 5c8d81e8b5
2 changed files with 40 additions and 5 deletions

View File

@ -7,9 +7,13 @@
#include "picconf.h"
#include "picrin/value.h"
struct pic_code;
typedef struct pic_callinfo {
struct pic_proc *proc;
int argc;
struct pic_code *pc;
pic_value *sp;
} pic_callinfo;
typedef struct {
@ -60,7 +64,7 @@ pic_value pic_parse(pic_state *, const char *);
pic_value pic_eval(pic_state *, pic_value, struct pic_env *);
pic_value pic_run(pic_state *, struct pic_proc *, pic_value);
struct pic_proc *pic_codegen(pic_state *, pic_value, struct pic_env*);
struct pic_proc *pic_codegen(pic_state *, pic_value, struct pic_env *);
void pic_raise(pic_state *, const char *);

View File

@ -375,6 +375,7 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args)
{
struct pic_code *pc;
pic_callinfo *ci;
pic_value val;
int ai = pic_gc_arena_preserve(pic);
pc = proc->u.irep->code;
@ -417,17 +418,31 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args)
ci = PUSHCI();
ci->proc = proc;
ci->argc = pc->u.i;
ci->pc = pc;
ci->sp = pic->sp;
if (pic_proc_cfunc_p(c)) {
v = proc->u.cfunc(pic);
pic->sp -= ci->argc;
POPCI();
ci = pic->ci - 1;
PUSH(v);
pic_gc_arena_restore(pic, ai);
NEXT;
}
else {
pic_raise(pic, "closure call not suppoted");
pc = proc->u.irep->code;
pic_gc_arena_restore(pic, ai);
JUMP;
}
pic_gc_arena_restore(pic, ai);
}
CASE(OP_RET) {
pic_value v;
v = POP();
pic->sp -= ci->argc;
ci = POPCI();
pc = ci->pc;
pic->sp = ci->sp;
PUSH(v);
NEXT;
}
CASE(OP_LAMBDA) {
@ -483,7 +498,23 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args)
STOP:
POPCI();
return POP();
val = POP();
#if GC_DEBUG
puts("**VM END STATE**");
printf("stbase = %p\nsp = %p\n", pic->stbase, pic->sp);
printf("cibase = %p\nci = %p\n", pic->cibase, pic->ci);
if (pic->stbase != pic->sp) {
pic_value *sp;
printf("* stack trace:");
for (sp = pic->stbase; pic->sp != sp; ++sp) {
pic_debug(pic, *sp);
puts("");
}
}
#endif
return val;
}
void