[bugfix] fix crash on deeply nested lambdas

This commit is contained in:
Yuichi Nishiwaki 2013-11-17 13:12:59 +09:00
parent 14ad038051
commit 5947240614
2 changed files with 27 additions and 4 deletions

View File

@ -687,7 +687,7 @@ valid_formal(pic_state *pic, pic_value formal)
} }
static void static void
lift_cv(pic_state *pic, struct pic_irep *irep) lift_cv(pic_state *pic, struct pic_irep *irep, int d)
{ {
int i; int i;
struct pic_code c; struct pic_code c;
@ -699,10 +699,11 @@ lift_cv(pic_state *pic, struct pic_irep *irep)
/* pass */ /* pass */
break; break;
case OP_LAMBDA: case OP_LAMBDA:
lift_cv(pic, pic->irep[c.u.i]); lift_cv(pic, pic->irep[c.u.i], d + 1);
break; break;
case OP_CREF: case OP_CREF:
case OP_CSET: case OP_CSET:
if (irep->code[i].u.r.depth > d)
irep->code[i].u.r.depth--; irep->code[i].u.r.depth--;
break; break;
} }
@ -817,7 +818,7 @@ codegen_lambda(codegen_state *state, pic_value obj)
++c; ++c;
} }
if (c == 0) { if (c == 0) {
lift_cv(pic, irep); lift_cv(pic, irep, 0);
irep->cv_tbl = NULL; irep->cv_tbl = NULL;
irep->cv_num = 0; irep->cv_num = 0;
} }
@ -911,6 +912,10 @@ print_irep(pic_state *pic, struct pic_irep *irep)
printf("## irep %p\n", irep); printf("## irep %p\n", irep);
printf("[clen = %zd, ccapa = %zd, argc = %d, localc = %d]\n", irep->clen, irep->ccapa, irep->argc, irep->localc); printf("[clen = %zd, ccapa = %zd, argc = %d, localc = %d]\n", irep->clen, irep->ccapa, irep->argc, irep->localc);
printf(":: cv_num = %d\n", irep->cv_num);
for (i = 0; i < irep->cv_num; ++i) {
printf(": %d -> %d\n", irep->cv_tbl[i], i);
}
for (i = 0; i < irep->clen; ++i) { for (i = 0; i < irep->clen; ++i) {
printf("[%2d] ", irep->code[i].insn); printf("[%2d] ", irep->code[i].insn);
switch (irep->code[i].insn) { switch (irep->code[i].insn) {

View File

@ -475,6 +475,24 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value argv)
} }
proc = pic_proc_ptr(x); proc = pic_proc_ptr(x);
#if VM_DEBUG
puts("== calling proc...");
printf(" proc = ");
pic_debug(pic, pic_obj_value(proc));
puts("");
printf(" argv = ");
pic_debug(pic, argv);
puts("");
if (! proc->cfunc_p) {
printf(" irep = ");
print_irep(pic, proc->u.irep);
}
else {
printf(" cfunc = %p\n", proc->u.cfunc);
}
puts("");
#endif
ci = PUSHCI(); ci = PUSHCI();
ci->argc = c.u.i; ci->argc = c.u.i;
ci->pc = pc; ci->pc = pc;