This commit is contained in:
Yuichi Nishiwaki 2016-03-14 10:54:25 +09:00
parent 5af735d796
commit 574c8ce884
1 changed files with 22 additions and 19 deletions

View File

@ -82,10 +82,16 @@ cont_mark(pic_state *pic, void *data, void (*mark)(pic_state *, pic_value))
static const pic_data_type cont_type = { "continuation", cont_dtor, cont_mark }; static const pic_data_type cont_type = { "continuation", cont_dtor, cont_mark };
static void save_cont(pic_state *, struct fullcont **); static void save_cont(pic_state *, struct fullcont *);
static void restore_cont(pic_state *, struct fullcont *); static void restore_cont(pic_state *, struct fullcont *);
static ptrdiff_t #if __GNUC__
# define NOINLINE __attribute__ ((noinline))
#else
# define NOINLINE
#endif
static ptrdiff_t NOINLINE
native_stack_length(char **pos) native_stack_length(char **pos)
{ {
char t; char t;
@ -99,17 +105,14 @@ native_stack_length(char **pos)
: &t - picrin_native_stack_start; : &t - picrin_native_stack_start;
} }
static void static void NOINLINE
save_cont(pic_state *pic, struct fullcont **c) save_cont(pic_state *pic, struct fullcont *cont)
{ {
void pic_vm_tear_off(pic_state *); void pic_vm_tear_off(pic_state *);
struct fullcont *cont;
char *pos; char *pos;
pic_vm_tear_off(pic); /* tear off */ pic_vm_tear_off(pic); /* tear off */
cont = *c = pic_malloc(pic, sizeof(struct fullcont));
cont->prev_jmp = pic->cc; cont->prev_jmp = pic->cc;
cont->cp = pic->cp; cont->cp = pic->cp;
@ -141,12 +144,13 @@ save_cont(pic_state *pic, struct fullcont **c)
cont->retv = NULL; cont->retv = NULL;
} }
static void static void NOINLINE
native_stack_extend(pic_state *pic, struct fullcont *cont) native_stack_extend(pic_state *pic, struct fullcont *cont)
{ {
volatile pic_value v[1024]; pic_value v[1024];
memset(v, 0, sizeof v);
((void)v);
restore_cont(pic, cont); restore_cont(pic, cont);
} }
@ -215,20 +219,19 @@ cont_call(pic_state *pic)
static pic_value static pic_value
pic_callcc(pic_state *pic, pic_value proc) pic_callcc(pic_state *pic, pic_value proc)
{ {
struct fullcont *cont; struct fullcont *cont = pic_malloc(pic, sizeof(struct fullcont));
save_cont(pic, &cont); if (setjmp(cont->jmp) != 0) {
if (setjmp(cont->jmp)) {
return pic_valuesk(pic, cont->retc, cont->retv); return pic_valuesk(pic, cont->retc, cont->retv);
} } else {
else { pic_value c[1];
pic_value c, args[1];
save_cont(pic, cont);
/* save the continuation object in proc */ /* save the continuation object in proc */
c = pic_lambda(pic, cont_call, 1, pic_data_value(pic, cont, &cont_type)); c[0] = pic_lambda(pic, cont_call, 1, pic_data_value(pic, cont, &cont_type));
args[0] = c; return pic_applyk(pic, proc, 1, c);
return pic_applyk(pic, proc, 1, args);
} }
} }