fix overflow in copy_term's internal stack

git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@434 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
vsc 2002-04-08 22:10:14 +00:00
parent 0e6dd4734e
commit 83a9b6530e

View File

@ -30,7 +30,7 @@ typedef struct {
} *vcell; } *vcell;
STATIC_PROTO(void copy_complex_term, (CELL *, CELL *, CELL *, CELL *)); STATIC_PROTO(int copy_complex_term, (CELL *, CELL *, CELL *, CELL *));
STATIC_PROTO(CELL vars_in_complex_term, (CELL *, CELL *)); STATIC_PROTO(CELL vars_in_complex_term, (CELL *, CELL *));
STATIC_PROTO(Int p_non_singletons_in_term, (void)); STATIC_PROTO(Int p_non_singletons_in_term, (void));
STATIC_PROTO(CELL non_singletons_in_complex_term, (CELL *, CELL *)); STATIC_PROTO(CELL non_singletons_in_complex_term, (CELL *, CELL *));
@ -54,7 +54,8 @@ clean_tr(tr_fr_ptr TR0) {
} }
} }
static void copy_complex_term(register CELL *pt0, register CELL *pt0_end, CELL *ptf, CELL *HLow) static int
copy_complex_term(register CELL *pt0, register CELL *pt0_end, CELL *ptf, CELL *HLow)
{ {
CELL **to_visit = (CELL **)(HeapTop + sizeof(CELL)); CELL **to_visit = (CELL **)(HeapTop + sizeof(CELL));
@ -82,6 +83,9 @@ static void copy_complex_term(register CELL *pt0, register CELL *pt0_end, CELL *
*ptf = AbsPair(H); *ptf = AbsPair(H);
ptf++; ptf++;
#ifdef RATIONAL_TREES #ifdef RATIONAL_TREES
if (to_visit + 4 >= (CELL **)H0) {
goto heap_overflow;
}
to_visit[0] = pt0; to_visit[0] = pt0;
to_visit[1] = pt0_end; to_visit[1] = pt0_end;
to_visit[2] = ptf; to_visit[2] = ptf;
@ -91,6 +95,9 @@ static void copy_complex_term(register CELL *pt0, register CELL *pt0_end, CELL *
to_visit += 4; to_visit += 4;
#else #else
if (pt0 < pt0_end) { if (pt0 < pt0_end) {
if (to_visit + 3 >= (CELL **)H0) {
goto heap_overflow;
}
to_visit[0] = pt0; to_visit[0] = pt0;
to_visit[1] = pt0_end; to_visit[1] = pt0_end;
to_visit[2] = ptf; to_visit[2] = ptf;
@ -126,6 +133,9 @@ static void copy_complex_term(register CELL *pt0, register CELL *pt0_end, CELL *
ptf++; ptf++;
/* store the terms to visit */ /* store the terms to visit */
#ifdef RATIONAL_TREES #ifdef RATIONAL_TREES
if (to_visit + 4 >= (CELL **)H0) {
goto heap_overflow;
}
to_visit[0] = pt0; to_visit[0] = pt0;
to_visit[1] = pt0_end; to_visit[1] = pt0_end;
to_visit[2] = ptf; to_visit[2] = ptf;
@ -135,6 +145,9 @@ static void copy_complex_term(register CELL *pt0, register CELL *pt0_end, CELL *
to_visit += 4; to_visit += 4;
#else #else
if (pt0 < pt0_end) { if (pt0 < pt0_end) {
if (to_visit + 3 >= (CELL **)H0) {
goto heap_overflow;
}
to_visit[0] = pt0; to_visit[0] = pt0;
to_visit[1] = pt0_end; to_visit[1] = pt0_end;
to_visit[2] = ptf; to_visit[2] = ptf;
@ -231,7 +244,7 @@ static void copy_complex_term(register CELL *pt0, register CELL *pt0_end, CELL *
/* restore our nice, friendly, term to its original state */ /* restore our nice, friendly, term to its original state */
HB = HB0; HB = HB0;
clean_tr(TR0); clean_tr(TR0);
return; return(0);
overflow: overflow:
/* oops, we're in trouble */ /* oops, we're in trouble */
@ -249,6 +262,25 @@ static void copy_complex_term(register CELL *pt0, register CELL *pt0_end, CELL *
} }
#endif #endif
clean_tr(TR0); clean_tr(TR0);
return(-1);
heap_overflow:
/* oops, we're in trouble */
H = HLow;
/* we've done it */
/* restore our nice, friendly, term to its original state */
HB = HB0;
#ifdef RATIONAL_TREES
while (to_visit > (CELL **)(HeapTop + sizeof(CELL))) {
to_visit -= 4;
pt0 = to_visit[0];
pt0_end = to_visit[1];
ptf = to_visit[2];
*pt0 = (CELL)to_visit[3];
}
#endif
clean_tr(TR0);
return(-2);
} }
Term Term
@ -259,16 +291,25 @@ CopyTerm(Term inp) {
#if COROUTINING #if COROUTINING
if (IsAttachedTerm(t)) { if (IsAttachedTerm(t)) {
CELL *Hi; CELL *Hi;
int res;
restart_attached: restart_attached:
*H = t; *H = t;
Hi = H+1; Hi = H+1;
H += 2; H += 2;
copy_complex_term(Hi-2, Hi-1, Hi, Hi); if ((res = copy_complex_term(Hi-2, Hi-1, Hi, Hi)) < 0) {
if (H == Hi) { /* handle overflow */ if (res == -1) { /* handle overflow */
gc(2, ENV, P); gc(2, ENV, P);
t = Deref(ARG1); t = Deref(ARG1);
goto restart_attached; goto restart_attached;
} else { /* handle overflow */
if (!growheap(FALSE)) {
Error(SYSTEM_ERROR, TermNil, "YAP failed to reserve space in growheap");
return(FALSE);
}
t = Deref(ARG1);
goto restart_attached;
}
} }
return(Hi[0]); return(Hi[0]);
} }
@ -286,11 +327,22 @@ CopyTerm(Term inp) {
Hi = H; Hi = H;
tf = AbsPair(H); tf = AbsPair(H);
H += 2; H += 2;
copy_complex_term(ap-1, ap+1, Hi, Hi); {
if (H == Hi) { /* handle overflow */ int res;
gc(2, ENV, P); if ((res = copy_complex_term(ap-1, ap+1, Hi, Hi)) < 0) {
t = Deref(ARG1); if (res == -1) { /* handle overflow */
goto restart_list; gc(2, ENV, P);
t = Deref(ARG1);
goto restart_list;
} else { /* handle overflow */
if (!growheap(FALSE)) {
Error(SYSTEM_ERROR, TermNil, "YAP failed to reserve space in growheap");
return(FALSE);
}
t = Deref(ARG1);
goto restart_list;
}
}
} }
return(tf); return(tf);
} else { } else {
@ -306,11 +358,22 @@ CopyTerm(Term inp) {
tf = AbsAppl(H); tf = AbsAppl(H);
H[0] = (CELL)f; H[0] = (CELL)f;
H += 1+ArityOfFunctor(f); H += 1+ArityOfFunctor(f);
copy_complex_term(ap, ap+ArityOfFunctor(f), HB0+1, HB0); {
if (H == HB0) { int res;
gc(2, ENV, P); if ((res = copy_complex_term(ap, ap+ArityOfFunctor(f), HB0+1, HB0)) < 0) {
t = Deref(ARG1); if (res == -1) {
goto restart_appl; gc(2, ENV, P);
t = Deref(ARG1);
goto restart_appl;
} else { /* handle overflow */
if (!growheap(FALSE)) {
Error(SYSTEM_ERROR, TermNil, "YAP failed to reserve space in growheap");
return(FALSE);
}
t = Deref(ARG1);
goto restart_appl;
}
}
} }
return(tf); return(tf);
} }