handle code space overflows while parsing.

git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1868 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
vsc 2007-04-18 06:30:41 +00:00
parent b6b308649c
commit ee03654060
7 changed files with 167 additions and 95 deletions

View File

@ -64,6 +64,8 @@ InlinedUnlockedMkFunctor(AtomEntry *ae, unsigned int arity)
return ((Functor) RepProp(p0));
}
p = (FunctorEntry *) Yap_AllocAtomSpace(sizeof(*p));
if (!p)
return NULL;
p->KindOfPE = FunctorProperty;
p->NameOfFE = AbsAtom(ae);
p->ArityOfFE = arity;

199
C/grow.c
View File

@ -70,7 +70,7 @@ STATIC_PROTO(void AdjustTrail, (int));
STATIC_PROTO(void AdjustLocal, (void));
STATIC_PROTO(void AdjustGlobal, (void));
STATIC_PROTO(void AdjustGrowStack, (void));
STATIC_PROTO(int static_growheap, (long,int,struct intermediates *));
STATIC_PROTO(int static_growheap, (long,int,struct intermediates *,tr_fr_ptr *, TokEntry **, VarEntry **));
STATIC_PROTO(void cpcellsd, (CELL *, CELL *, CELL));
STATIC_PROTO(CELL AdjustAppl, (CELL));
STATIC_PROTO(CELL AdjustPair, (CELL));
@ -508,6 +508,86 @@ AdjustRegs(int n)
}
}
static void
AdjustVarTable(VarEntry *ves)
{
ves->VarAdr = TermNil;
if (ves->VarRight != NULL) {
if (IsOldVarTableTrailPtr(ves->VarRight)) {
ves->VarRight = (VarEntry *)TrailAddrAdjust((ADDR)(ves->VarRight));
}
AdjustVarTable(ves->VarRight);
}
if (ves->VarLeft != NULL) {
if (IsOldVarTableTrailPtr(ves->VarLeft)) {
ves->VarLeft = (VarEntry *)TrailAddrAdjust((ADDR)(ves->VarLeft));
}
AdjustVarTable(ves->VarLeft);
}
}
/*
If we have to shift while we are scanning we need to adjust all
pointers created by the scanner (Tokens and Variables)
*/
static void
AdjustScannerStacks(TokEntry **tksp, VarEntry **vep)
{
TokEntry *tks = *tksp;
VarEntry *ves = *vep;
if (tks != NULL) {
if (IsOldTokenTrailPtr(tks)) {
tks = *tksp = TokEntryAdjust(tks);
}
}
while (tks != NULL) {
TokEntry *tktmp;
switch (tks->Tok) {
case Var_tok:
case String_tok:
if (IsOldTrail(tks->TokInfo))
tks->TokInfo = TrailAdjust(tks->TokInfo);
break;
case Name_tok:
tks->TokInfo = (Term)AtomAdjust((Atom)(tks->TokInfo));
break;
default:
break;
}
tktmp = tks->TokNext;
if (tktmp != NULL) {
if (IsOldTokenTrailPtr(tktmp)) {
tktmp = TokEntryAdjust(tktmp);
tks->TokNext = tktmp;
}
}
tks = tktmp;
}
if (ves != NULL) {
if (IsOldVarTableTrailPtr(ves))
ves = *vep = (VarEntry *)TrailAddrAdjust((ADDR)ves);
AdjustVarTable(ves);
}
ves = Yap_AnonVarTable;
if (ves != NULL) {
if (IsOldVarTableTrailPtr(ves))
ves = Yap_AnonVarTable = VarEntryAdjust(ves);
}
while (ves != NULL) {
VarEntry *vetmp = ves->VarLeft;
if (vetmp != NULL) {
if (IsOldVarTableTrailPtr(vetmp)) {
vetmp = VarEntryAdjust(vetmp);
}
ves->VarLeft = vetmp;
}
ves->VarAdr = TermNil;
ves = vetmp;
}
}
void
Yap_AdjustRegs(int n)
{
@ -516,7 +596,7 @@ Yap_AdjustRegs(int n)
/* Used by do_goal() when we're short of heap space */
static int
static_growheap(long size, int fix_code, struct intermediates *cip)
static_growheap(long size, int fix_code, struct intermediates *cip, tr_fr_ptr *old_trp, TokEntry **tksp, VarEntry **vep)
{
UInt start_growth_time, growth_time;
int gc_verbose;
@ -565,7 +645,18 @@ static_growheap(long size, int fix_code, struct intermediates *cip)
} else {
MoveGlobal();
}
AdjustStacksAndTrail();
if (old_trp) {
tr_fr_ptr nTR;
AdjustScannerStacks(tksp, vep);
nTR = TR;
*old_trp = PtoTRAdjust(*old_trp);
TR = *old_trp;
AdjustStacksAndTrail();
TR = nTR;
} else {
AdjustStacksAndTrail();
}
AdjustRegs(MaxTemps);
YAPLeaveCriticalSection();
ASP += 256;
@ -925,7 +1016,7 @@ fix_tabling_info(void)
#endif /* TABLING */
static int
do_growheap(int fix_code, UInt in_size, struct intermediates *cip)
do_growheap(int fix_code, UInt in_size, struct intermediates *cip, tr_fr_ptr *old_trp, TokEntry **tksp, VarEntry **vep)
{
unsigned long size = sizeof(CELL) * 16 * 1024L;
int shift_factor = (heap_overflows > 8 ? 8 : heap_overflows);
@ -940,7 +1031,7 @@ do_growheap(int fix_code, UInt in_size, struct intermediates *cip)
#endif
if (SizeOfOverflow > sz)
sz = AdjustPageSize(SizeOfOverflow);
while(sz >= sizeof(CELL) * 16 * 1024L && !static_growheap(sz, fix_code, cip)) {
while(sz >= sizeof(CELL) * 16 * 1024L && !static_growheap(sz, fix_code, cip, old_trp, tksp, vep)) {
size = size/2;
sz = size << shift_factor;
if (sz < in_size) {
@ -1030,7 +1121,7 @@ growatomtable(void)
while ((ntb = (AtomHashEntry *)Yap_AllocCodeSpace(nsize*sizeof(AtomHashEntry))) == NULL) {
/* leave for next time */
#if !USE_SYSTEM_MALLOC
if (!do_growheap(FALSE, nsize*sizeof(AtomHashEntry), NULL))
if (!do_growheap(FALSE, nsize*sizeof(AtomHashEntry), NULL, NULL, NULL, NULL))
#endif
return FALSE;
}
@ -1059,7 +1150,7 @@ growatomtable(void)
/* make sure there is no heap overflow */
int res;
YAPEnterCriticalSection();
res = do_growheap(FALSE, 0, NULL);
res = do_growheap(FALSE, 0, NULL, NULL, NULL, NULL);
YAPLeaveCriticalSection();
return res;
} else {
@ -1094,7 +1185,17 @@ Yap_growheap(int fix_code, UInt in_size, void *cip)
Yap_PrologMode &= ~GrowHeapMode;
return res;
}
res=do_growheap(fix_code, in_size, (struct intermediates *)cip);
res=do_growheap(fix_code, in_size, (struct intermediates *)cip, NULL, NULL, NULL);
Yap_PrologMode &= ~GrowHeapMode;
return res;
}
int
Yap_growheap_in_parser(tr_fr_ptr *old_trp, TokEntry **tksp, VarEntry **vep)
{
int res;
res=do_growheap(FALSE, 0L, NULL, old_trp, tksp, vep);
Yap_PrologMode &= ~GrowHeapMode;
return res;
}
@ -1142,86 +1243,6 @@ Yap_growstack(long size)
return res;
}
static void
AdjustVarTable(VarEntry *ves)
{
ves->VarAdr = TermNil;
if (ves->VarRight != NULL) {
if (IsOldVarTableTrailPtr(ves->VarRight)) {
ves->VarRight = (VarEntry *)TrailAddrAdjust((ADDR)(ves->VarRight));
}
AdjustVarTable(ves->VarRight);
}
if (ves->VarLeft != NULL) {
if (IsOldVarTableTrailPtr(ves->VarLeft)) {
ves->VarLeft = (VarEntry *)TrailAddrAdjust((ADDR)(ves->VarLeft));
}
AdjustVarTable(ves->VarLeft);
}
}
/*
If we have to shift while we are scanning we need to adjust all
pointers created by the scanner (Tokens and Variables)
*/
static void
AdjustScannerStacks(TokEntry **tksp, VarEntry **vep)
{
TokEntry *tks = *tksp;
VarEntry *ves = *vep;
if (tks != NULL) {
if (IsOldTokenTrailPtr(tks)) {
tks = *tksp = TokEntryAdjust(tks);
}
}
while (tks != NULL) {
TokEntry *tktmp;
switch (tks->Tok) {
case Var_tok:
case String_tok:
if (IsOldTrail(tks->TokInfo))
tks->TokInfo = TrailAdjust(tks->TokInfo);
break;
case Name_tok:
tks->TokInfo = (Term)AtomAdjust((Atom)(tks->TokInfo));
break;
default:
break;
}
tktmp = tks->TokNext;
if (tktmp != NULL) {
if (IsOldTokenTrailPtr(tktmp)) {
tktmp = TokEntryAdjust(tktmp);
tks->TokNext = tktmp;
}
}
tks = tktmp;
}
if (ves != NULL) {
if (IsOldVarTableTrailPtr(ves))
ves = *vep = (VarEntry *)TrailAddrAdjust((ADDR)ves);
AdjustVarTable(ves);
}
ves = Yap_AnonVarTable;
if (ves != NULL) {
if (IsOldVarTableTrailPtr(ves))
ves = Yap_AnonVarTable = VarEntryAdjust(ves);
}
while (ves != NULL) {
VarEntry *vetmp = ves->VarLeft;
if (vetmp != NULL) {
if (IsOldVarTableTrailPtr(vetmp)) {
vetmp = VarEntryAdjust(vetmp);
}
ves->VarLeft = vetmp;
}
ves->VarAdr = TermNil;
ves = vetmp;
}
}
static int
execute_growstack(long size0, int from_trail, int in_parser, tr_fr_ptr *old_trp, TokEntry **tksp, VarEntry **vep)
{
@ -1529,7 +1550,7 @@ p_growheap(void)
if (diff < 0) {
Yap_Error(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t1, "grow_heap/1");
}
return(static_growheap(diff, FALSE, NULL));
return(static_growheap(diff, FALSE, NULL, NULL, NULL, NULL));
}
static Int

View File

@ -3804,15 +3804,19 @@ static Int
int res;
if (!strcmp(Yap_ErrorMessage,"Stack Overflow") ||
!strcmp(Yap_ErrorMessage,"Trail Overflow")) {
!strcmp(Yap_ErrorMessage,"Trail Overflow") ||
!strcmp(Yap_ErrorMessage,"Heap Overflow")) {
/* ignore term we just built */
tr_fr_ptr old_TR = TR;
H = old_H;
TR = (tr_fr_ptr)ScannerStack;
if (!strcmp(Yap_ErrorMessage,"Stack Overflow"))
res = Yap_growstack_in_parser(&old_TR, &tokstart, &Yap_VarTable);
else if (!strcmp(Yap_ErrorMessage,"Heap Overflow"))
res = Yap_growheap_in_parser(&old_TR, &tokstart, &Yap_VarTable);
else
res = Yap_growtrail_in_parser(&old_TR, &tokstart, &Yap_VarTable);
if (res) {

View File

@ -310,6 +310,7 @@ ParseArgs(Atom a, JMPBUFF *FailBuff)
{
int nargs = 0;
Term *p, t;
Functor func;
#ifdef SFUNC
SFEntry *pe = (SFEntry *) Yap_GetAProp(a, SFProperty);
#endif
@ -340,6 +341,11 @@ ParseArgs(Atom a, JMPBUFF *FailBuff)
Yap_ErrorMessage = "Stack Overflow";
FAIL;
}
func = Yap_MkFunctor(a, nargs);
if (func == NULL) {
Yap_ErrorMessage = "Heap Overflow";
FAIL;
}
#ifdef SFUNC
if (pe)
t = MkSFTerm(Yap_MkFunctor(a, SFArity), nargs, p, pe->NilValue);
@ -349,7 +355,7 @@ ParseArgs(Atom a, JMPBUFF *FailBuff)
if (a == AtomDBRef && nargs == 2)
t = MkDBRefTerm((DBRef)IntegerOfTerm(p[0]));
else
t = Yap_MkApplTerm(Yap_MkFunctor(a, nargs), nargs, p);
t = Yap_MkApplTerm(func, nargs, p);
#endif
if (H > ASP-4096) {
Yap_ErrorMessage = "Stack Overflow";
@ -485,6 +491,10 @@ ParseTerm(int prio, JMPBUFF *FailBuff)
TRY(
/* build appl on the heap */
func = Yap_MkFunctor((Atom) t, 1);
if (func == NULL) {
Yap_ErrorMessage = "Heap Overflow";
FAIL;
}
t = ParseTerm(oprprio, FailBuff);
t = Yap_MkApplTerm(func, 1, &t);
/* check for possible overflow against local stack */
@ -517,9 +527,14 @@ ParseTerm(int prio, JMPBUFF *FailBuff)
t = MkAtomTerm(AtomNil);
else if (yap_flags[YAP_DOUBLE_QUOTES_FLAG] == STRING_AS_CHARS)
t = Yap_StringToListOfAtoms(p);
else if (yap_flags[YAP_DOUBLE_QUOTES_FLAG] == STRING_AS_ATOM)
t = MkAtomTerm(Yap_LookupAtom(p));
else
else if (yap_flags[YAP_DOUBLE_QUOTES_FLAG] == STRING_AS_ATOM) {
Atom at = Yap_LookupAtom(p);
if (at == NIL) {
Yap_ErrorMessage = "Heap Overflow";
FAIL;
}
t = MkAtomTerm(at);
} else
t = Yap_StringToList(p);
NextToken;
}
@ -602,6 +617,10 @@ ParseTerm(int prio, JMPBUFF *FailBuff)
Volatile int oldprio = curprio;
TRY3(
func = Yap_MkFunctor((Atom) Yap_tokptr->TokInfo, 2);
if (func == NULL) {
Yap_ErrorMessage = "Heap Overflow";
FAIL;
}
NextToken;
{
Term args[2];
@ -625,7 +644,12 @@ ParseTerm(int prio, JMPBUFF *FailBuff)
if (IsPosfixOp(opinfo, &opprio, &oplprio)
&& opprio <= prio && oplprio >= curprio) {
/* parse as posfix operator */
t = Yap_MkApplTerm(Yap_MkFunctor((Atom) Yap_tokptr->TokInfo, 1), 1, &t);
Functor fun = Yap_MkFunctor((Atom) Yap_tokptr->TokInfo, 1);
if (func == NULL) {
Yap_ErrorMessage = "Heap Overflow";
FAIL;
}
t = Yap_MkApplTerm(func, 1, &t);
/* check for possible overflow against local stack */
if (H > ASP-4096) {
Yap_ErrorMessage = "Stack Overflow";

View File

@ -1075,6 +1075,15 @@ Yap_tokenizer(int inp_stream)
t->TokInfo = Unsigned(Yap_LookupWideAtom((wchar_t *)TokImage));
} else {
t->TokInfo = Unsigned(Yap_LookupAtom(TokImage));
if (t->TokInfo == (CELL)NIL) {
Yap_Error_TYPE = OUT_OF_HEAP_ERROR;
Yap_ErrorMessage = "Code Space Overflow";
if (p)
t->Tok = Ord(kind = eot_tok);
/* serious error now */
UNLOCK(Stream[inp_stream].streamlock);
return l;
}
}
Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage);
t->Tok = Ord(kind = Name_tok);
@ -1113,6 +1122,15 @@ Yap_tokenizer(int inp_stream)
*charp++ = ch;
*charp = '\0';
t->TokInfo = Unsigned(Yap_LookupAtom(TokImage));
if (t->TokInfo == (CELL)NIL) {
Yap_Error_TYPE = OUT_OF_HEAP_ERROR;
Yap_ErrorMessage = "Code Space Overflow";
if (p)
t->Tok = Ord(kind = eot_tok);
/* serious error now */
UNLOCK(Stream[inp_stream].streamlock);
return l;
}
Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage);
t->Tok = Ord(kind = Name_tok);
if (ch == '(')

View File

@ -322,6 +322,7 @@ extern int
void STD_PROTO(Yap_plwrite,(Term,int (*)(int, wchar_t),int));
/* grow.c */
int STD_PROTO(Yap_growheap_in_parser, (tr_fr_ptr *, TokEntry **, VarEntry **));
int STD_PROTO(Yap_growstack_in_parser, (tr_fr_ptr *, TokEntry **, VarEntry **));
int STD_PROTO(Yap_growtrail_in_parser, (tr_fr_ptr *, TokEntry **, VarEntry **));

View File

@ -16,6 +16,8 @@
<h2>Yap-5.1.2:</h2>
<ul>
<li> FIXED: handle atom lookup and functor overflows while parsing
(obs from Bernd Gutmann).</li>
<li> FIXED: get rid of static structures for modules (obs from Bernd
Gutmann).</li>
<li> FIXED: SREG might be lost on trail/heap overflow, and that would