'apply' calls given procedure by trampoline

This commit is contained in:
Yuichi Nishiwaki 2014-02-04 15:46:52 +09:00
parent d3a3c78829
commit c3b45c6d16
1 changed files with 20 additions and 2 deletions

View File

@ -85,20 +85,38 @@ pic_proc_proc_p(pic_state *pic)
static pic_value static pic_value
pic_proc_apply(pic_state *pic) pic_proc_apply(pic_state *pic)
{ {
static struct pic_code iseq[3];
struct pic_proc *proc; struct pic_proc *proc;
pic_value *args, arg_list; pic_value *args;
size_t argc; size_t argc;
pic_value v, arg_list;
pic_get_args(pic, "l*", &proc, &argc, &args); pic_get_args(pic, "l*", &proc, &argc, &args);
if (argc == 0) { if (argc == 0) {
pic_error(pic, "apply: wrong number of arguments"); pic_error(pic, "apply: wrong number of arguments");
} }
arg_list = args[--argc]; arg_list = args[--argc];
while (argc--) { while (argc--) {
arg_list = pic_cons(pic, args[argc], arg_list); arg_list = pic_cons(pic, args[argc], arg_list);
} }
return pic_apply(pic, proc, arg_list);
*pic->ci->fp++ = pic_obj_value(proc);
pic_for_each (v, arg_list) {
*pic->ci->fp++ = v;
}
iseq[0].insn = OP_JMP; /* OP_NOP */
iseq[0].u.i = 1;
iseq[1].insn = OP_CALL;
iseq[1].u.i = pic_length(pic, arg_list) + 1;
iseq[2].insn = OP_RET;
pic->ci->ip = iseq;
/* the last argument is pushed by the VM */
pic->ci->fp--;
return v;
} }
static pic_value static pic_value