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:
parent
b6b308649c
commit
ee03654060
@ -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
199
C/grow.c
@ -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
|
||||
|
@ -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) {
|
||||
|
34
C/parser.c
34
C/parser.c
@ -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";
|
||||
|
18
C/scanner.c
18
C/scanner.c
@ -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 == '(')
|
||||
|
@ -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 **));
|
||||
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user