diff --git a/contrib/10.callcc/callcc.c b/contrib/10.callcc/callcc.c index 36ac9ed5..b3f7d6e4 100644 --- a/contrib/10.callcc/callcc.c +++ b/contrib/10.callcc/callcc.c @@ -258,10 +258,13 @@ pic_callcc_full(pic_state *pic, struct pic_proc *proc) } static pic_value -pic_callcc_full_trampoline(pic_state *pic, struct pic_proc *proc) +pic_callcc_callcc(pic_state *pic) { + struct pic_proc *proc; struct pic_fullcont *cont; + pic_get_args(pic, "l", &proc); + save_cont(pic, &cont); if (setjmp(cont->jmp)) { return pic_values_by_list(pic, cont->results); @@ -277,20 +280,10 @@ pic_callcc_full_trampoline(pic_state *pic, struct pic_proc *proc) /* save the continuation object in proc */ pic_proc_env_set(pic, c, "cont", pic_obj_value(dat)); - return pic_apply_trampoline(pic, proc, pic_list1(pic, pic_obj_value(c))); + return pic_apply_trampoline_list(pic, proc, pic_list1(pic, pic_obj_value(c))); } } -static pic_value -pic_callcc_callcc(pic_state *pic) -{ - struct pic_proc *cb; - - pic_get_args(pic, "l", &cb); - - return pic_callcc_full_trampoline(pic, cb); -} - #define pic_redefun(pic, lib, name, func) \ pic_set(pic, lib, name, pic_obj_value(pic_make_proc(pic, func))) diff --git a/extlib/benz/cont.c b/extlib/benz/cont.c index b5b25b4f..46b5908c 100644 --- a/extlib/benz/cont.c +++ b/extlib/benz/cont.c @@ -289,16 +289,19 @@ static pic_value pic_cont_call_with_values(pic_state *pic) { struct pic_proc *producer, *consumer; - size_t argc; - pic_value args[256]; pic_get_args(pic, "ll", &producer, &consumer); pic_apply(pic, producer, pic_nil_value()); - argc = pic_receive(pic, 256, args); + do { + size_t argc = pic_receive(pic, 0, NULL); + pic_value args[argc]; - return pic_apply_trampoline(pic, consumer, pic_list_by_array(pic, argc, args)); + pic_receive(pic, argc, args); + + return pic_apply_trampoline(pic, consumer, argc, args); + } while (0); } void diff --git a/extlib/benz/include/picrin.h b/extlib/benz/include/picrin.h index ab1a7f98..700d1a28 100644 --- a/extlib/benz/include/picrin.h +++ b/extlib/benz/include/picrin.h @@ -201,7 +201,8 @@ pic_value pic_apply2(pic_state *, struct pic_proc *, pic_value, pic_value); pic_value pic_apply3(pic_state *, struct pic_proc *, pic_value, pic_value, pic_value); pic_value pic_apply4(pic_state *, struct pic_proc *, pic_value, pic_value, pic_value, pic_value); pic_value pic_apply5(pic_state *, struct pic_proc *, pic_value, pic_value, pic_value, pic_value, pic_value); -pic_value pic_apply_trampoline(pic_state *, struct pic_proc *, pic_value); +pic_value pic_apply_trampoline(pic_state *, struct pic_proc *, size_t, pic_value *); +pic_value pic_apply_trampoline_list(pic_state *, struct pic_proc *, pic_value); pic_value pic_eval(pic_state *, pic_value, struct pic_env *); struct pic_proc *pic_compile(pic_state *, pic_value, struct pic_env *); diff --git a/extlib/benz/proc.c b/extlib/benz/proc.c index ea8d71d1..4c00885b 100644 --- a/extlib/benz/proc.c +++ b/extlib/benz/proc.c @@ -86,7 +86,7 @@ pic_proc_apply(pic_state *pic) arg_list = pic_cons(pic, args[argc], arg_list); } - return pic_apply_trampoline(pic, proc, arg_list); + return pic_apply_trampoline_list(pic, proc, arg_list); } void diff --git a/extlib/benz/vm.c b/extlib/benz/vm.c index 89dbe518..abf6f014 100644 --- a/extlib/benz/vm.c +++ b/extlib/benz/vm.c @@ -957,10 +957,11 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args) } pic_value -pic_apply_trampoline(pic_state *pic, struct pic_proc *proc, pic_value args) +pic_apply_trampoline(pic_state *pic, struct pic_proc *proc, size_t argc, pic_value *args) { - pic_value v, it, *sp; + pic_value *sp; pic_callinfo *ci; + size_t i; PIC_INIT_CODE_I(pic->iseq[0], OP_NOP, 0); PIC_INIT_CODE_I(pic->iseq[1], OP_TAILCALL, -1); @@ -968,22 +969,36 @@ pic_apply_trampoline(pic_state *pic, struct pic_proc *proc, pic_value args) *pic->sp++ = pic_obj_value(proc); sp = pic->sp; - pic_for_each (v, args, it) { - *sp++ = v; + for (i = 0; i < argc; ++i) { + *sp++ = args[i]; } ci = PUSHCI(); ci->ip = pic->iseq; ci->fp = pic->sp; - ci->retc = (int)pic_length(pic, args); + ci->retc = (int)argc; if (ci->retc == 0) { return pic_undef_value(); } else { - return pic_car(pic, args); + return args[0]; } } +pic_value +pic_apply_trampoline_list(pic_state *pic, struct pic_proc *proc, pic_value args) +{ + size_t i, argc = pic_length(pic, args); + pic_value val, it, argv[argc]; + + i = 0; + pic_for_each (val, args, it) { + argv[i++] = val; + } + + return pic_apply_trampoline(pic, proc, argc, argv); +} + pic_value pic_apply0(pic_state *pic, struct pic_proc *proc) {