don't cons in call-with-values

This commit is contained in:
Yuichi Nishiwaki 2015-07-04 18:01:30 +09:00
parent 9eee644ad8
commit 25f80dc87d
5 changed files with 36 additions and 24 deletions

View File

@ -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)))

View File

@ -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

View File

@ -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 *);

View File

@ -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

View File

@ -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)
{