diff --git a/src/vm.c b/src/vm.c index c2d0b1e0..9e4509f4 100644 --- a/src/vm.c +++ b/src/vm.c @@ -747,7 +747,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value argv) /* invoke! */ pic->sp[0] = proc->u.func.f(pic); - pic->sp += ci->retc; + pic->sp += pic->ci->retc; pic_gc_arena_restore(pic, ai); goto L_RET; @@ -994,29 +994,26 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value argv) } VM_LOOP_END; } -static pic_code trampoline_iseq[] = { - { OP_NOP, {0} }, - { OP_TAILCALL, {0} }, -}; - pic_value pic_apply_trampoline(pic_state *pic, struct pic_proc *proc, pic_value args) { - pic_value v, call_list, *fp = pic->ci->fp; + static const pic_code iseq = { OP_TAILCALL, { .i = -1 } }; + + pic_value v, *sp; pic_callinfo *ci; - call_list = pic_cons(pic, pic_obj_value(proc), args); + *pic->sp++ = pic_obj_value(proc); - pic_for_each (v, call_list) { - *fp++ = v; + sp = pic->sp; + pic_for_each (v, args) { + *sp++ = v; } - trampoline_iseq[1].u.i = pic_length(pic, call_list); - ci = PUSHCI(); - ci->ip = trampoline_iseq; - ci->fp = fp - 1; /* the last argument is pushed by the VM */ - return v; + ci->ip = (pic_code *)&iseq - 1; + ci->fp = pic->sp; + ci->retc = pic_length(pic, args); + return pic_obj_value(proc); } pic_value