support closure call
This commit is contained in:
parent
49e1f54195
commit
5c8d81e8b5
|
@ -7,9 +7,13 @@
|
||||||
#include "picconf.h"
|
#include "picconf.h"
|
||||||
#include "picrin/value.h"
|
#include "picrin/value.h"
|
||||||
|
|
||||||
|
struct pic_code;
|
||||||
|
|
||||||
typedef struct pic_callinfo {
|
typedef struct pic_callinfo {
|
||||||
struct pic_proc *proc;
|
struct pic_proc *proc;
|
||||||
int argc;
|
int argc;
|
||||||
|
struct pic_code *pc;
|
||||||
|
pic_value *sp;
|
||||||
} pic_callinfo;
|
} pic_callinfo;
|
||||||
|
|
||||||
typedef struct {
|
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_eval(pic_state *, pic_value, struct pic_env *);
|
||||||
pic_value pic_run(pic_state *, struct pic_proc *, pic_value);
|
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 *);
|
void pic_raise(pic_state *, const char *);
|
||||||
|
|
||||||
|
|
39
src/vm.c
39
src/vm.c
|
@ -375,6 +375,7 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args)
|
||||||
{
|
{
|
||||||
struct pic_code *pc;
|
struct pic_code *pc;
|
||||||
pic_callinfo *ci;
|
pic_callinfo *ci;
|
||||||
|
pic_value val;
|
||||||
int ai = pic_gc_arena_preserve(pic);
|
int ai = pic_gc_arena_preserve(pic);
|
||||||
|
|
||||||
pc = proc->u.irep->code;
|
pc = proc->u.irep->code;
|
||||||
|
@ -417,17 +418,31 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args)
|
||||||
ci = PUSHCI();
|
ci = PUSHCI();
|
||||||
ci->proc = proc;
|
ci->proc = proc;
|
||||||
ci->argc = pc->u.i;
|
ci->argc = pc->u.i;
|
||||||
|
ci->pc = pc;
|
||||||
|
ci->sp = pic->sp;
|
||||||
if (pic_proc_cfunc_p(c)) {
|
if (pic_proc_cfunc_p(c)) {
|
||||||
v = proc->u.cfunc(pic);
|
v = proc->u.cfunc(pic);
|
||||||
pic->sp -= ci->argc;
|
pic->sp -= ci->argc;
|
||||||
POPCI();
|
POPCI();
|
||||||
ci = pic->ci - 1;
|
|
||||||
PUSH(v);
|
PUSH(v);
|
||||||
|
pic_gc_arena_restore(pic, ai);
|
||||||
|
NEXT;
|
||||||
}
|
}
|
||||||
else {
|
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;
|
NEXT;
|
||||||
}
|
}
|
||||||
CASE(OP_LAMBDA) {
|
CASE(OP_LAMBDA) {
|
||||||
|
@ -483,7 +498,23 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args)
|
||||||
|
|
||||||
STOP:
|
STOP:
|
||||||
POPCI();
|
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
|
void
|
||||||
|
|
Loading…
Reference in New Issue