[bugfix] fix crash on deeply nested lambdas
This commit is contained in:
parent
14ad038051
commit
5947240614
|
@ -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,11 +699,12 @@ 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:
|
||||||
irep->code[i].u.r.depth--;
|
if (irep->code[i].u.r.depth > d)
|
||||||
|
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) {
|
||||||
|
|
18
src/vm.c
18
src/vm.c
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue