fix bad overflow handling in ==
This commit is contained in:
parent
d59fa6c28b
commit
30caf35bff
233
H/absmi.h
233
H/absmi.h
|
@ -1302,173 +1302,190 @@ iequ_complex(register CELL *pt0, register CELL *pt0_end,
|
||||||
register CELL *pt1
|
register CELL *pt1
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
register CELL **to_visit = (CELL **) H;
|
#ifdef THREADS
|
||||||
|
#undef Yap_REGS
|
||||||
|
register REGSTORE *regp = Yap_regp;
|
||||||
|
#define Yap_REGS (*regp)
|
||||||
|
#elif defined(SHADOW_REGS)
|
||||||
|
#if defined(B) || defined(TR)
|
||||||
|
register REGSTORE *regp = &Yap_REGS;
|
||||||
|
|
||||||
#ifdef RATIONAL_TREES
|
#define Yap_REGS (*regp)
|
||||||
register CELL *visited = AuxSp;
|
#endif /* defined(B) || defined(TR) || defined(HB) */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SHADOW_HB
|
||||||
|
register CELL *HBREG = HB;
|
||||||
|
#endif /* SHADOW_HB */
|
||||||
|
|
||||||
|
struct unif_record *unif = (struct unif_record *)AuxBase;
|
||||||
|
struct v_record *to_visit = (struct v_record *)AuxSp;
|
||||||
|
#define unif_base ((struct unif_record *)AuxBase)
|
||||||
|
#define to_visit_base ((struct v_record *)AuxSp)
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
while (pt0 < pt0_end) {
|
while (pt0 < pt0_end) {
|
||||||
register CELL *ptd0 = ++pt0;
|
register CELL *ptd0 = pt0+1;
|
||||||
register CELL d0 = *ptd0;
|
register CELL d0;
|
||||||
|
|
||||||
++pt1;
|
++pt1;
|
||||||
deref_head(d0, eq_comp_unk);
|
pt0 = ptd0;
|
||||||
eq_comp_nvar:
|
d0 = *ptd0;
|
||||||
|
deref_head(d0, iequ_comp_unk);
|
||||||
|
iequ_comp_nvar:
|
||||||
{
|
{
|
||||||
register CELL *ptd1 = pt1;
|
register CELL *ptd1 = pt1;
|
||||||
register CELL d1 = *ptd1;
|
register CELL d1 = *ptd1;
|
||||||
|
|
||||||
deref_head(d1, eq_comp_nvar_unk);
|
deref_head(d1, iequ_comp_nvar_unk);
|
||||||
eq_comp_nvar_nvar:
|
iequ_comp_nvar_nvar:
|
||||||
if (d0 == d1)
|
if (d0 == d1)
|
||||||
continue;
|
continue;
|
||||||
else if (IsPairTerm(d0)) {
|
if (IsPairTerm(d0)) {
|
||||||
if (!IsPairTerm(d1)) {
|
if (!IsPairTerm(d1)) {
|
||||||
UNWIND_CUNIF();
|
goto cufail;
|
||||||
return (FALSE);
|
|
||||||
}
|
}
|
||||||
#ifdef RATIONAL_TREES
|
|
||||||
/* now link the two structures so that no one else will */
|
/* now link the two structures so that no one else will */
|
||||||
/* come here */
|
/* come here */
|
||||||
if (d0 > d1) {
|
|
||||||
visited -= 2;
|
|
||||||
visited[0] = (CELL) pt0;
|
|
||||||
visited[1] = *pt0;
|
|
||||||
*pt0 = d1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
visited -= 2;
|
|
||||||
visited[0] = (CELL) pt1;
|
|
||||||
visited[1] = *pt1;
|
|
||||||
*pt1 = d0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* store the terms to visit */
|
/* store the terms to visit */
|
||||||
if (pt0 < pt0_end) {
|
if (RATIONAL_TREES || pt0 < pt0_end) {
|
||||||
to_visit[0] = pt0;
|
to_visit --;
|
||||||
to_visit[1] = pt0_end;
|
#ifdef RATIONAL_TREES
|
||||||
to_visit[2] = pt1;
|
unif++;
|
||||||
to_visit += 3;
|
#endif
|
||||||
|
if ((void *)to_visit < (void *)unif) {
|
||||||
|
CELL **urec = (CELL **)unif;
|
||||||
|
to_visit = (struct v_record *)Yap_shift_visit((CELL **)to_visit, &urec);
|
||||||
|
unif = (struct unif_record *)urec;
|
||||||
|
}
|
||||||
|
to_visit->start0 = pt0;
|
||||||
|
to_visit->end0 = pt0_end;
|
||||||
|
to_visit->start1 = pt1;
|
||||||
|
#ifdef RATIONAL_TREES
|
||||||
|
unif[-1].old = *pt0;
|
||||||
|
unif[-1].ptr = pt0;
|
||||||
|
*pt0 = d1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
pt0_end = (pt0 = RepPair(d0) - 1) + 2;
|
pt0_end = (pt0 = RepPair(d0) - 1) + 2;
|
||||||
pt0_end = RepPair(d0) + 1;
|
|
||||||
pt1 = RepPair(d1) - 1;
|
pt1 = RepPair(d1) - 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (IsApplTerm(d0)) {
|
if (IsApplTerm(d0)) {
|
||||||
register Functor f;
|
register Functor f;
|
||||||
register CELL *ap2, *ap3;
|
register CELL *ap2, *ap3;
|
||||||
|
|
||||||
|
if (!IsApplTerm(d1)) {
|
||||||
|
goto cufail;
|
||||||
|
}
|
||||||
/* store the terms to visit */
|
/* store the terms to visit */
|
||||||
ap2 = RepAppl(d0);
|
ap2 = RepAppl(d0);
|
||||||
f = (Functor) (*ap2);
|
|
||||||
if (IsExtensionFunctor(f)) {
|
|
||||||
switch ((CELL)f) {
|
|
||||||
case (CELL)FunctorDBRef:
|
|
||||||
if (d0 == d1) continue;
|
|
||||||
UNWIND_CUNIF();
|
|
||||||
return (FALSE);
|
|
||||||
case (CELL)FunctorLongInt:
|
|
||||||
if (IsLongIntTerm(d1) && (Int)(ap2[1]) == LongIntOfTerm(d1)) continue;
|
|
||||||
UNWIND_CUNIF();
|
|
||||||
return (FALSE);
|
|
||||||
case (CELL)FunctorDouble:
|
|
||||||
if (IsFloatTerm(d1) && FloatOfTerm(d0) == FloatOfTerm(d1)) continue;
|
|
||||||
UNWIND_CUNIF();
|
|
||||||
return (FALSE);
|
|
||||||
#ifdef USE_GMP
|
|
||||||
case (CELL)FunctorBigInt:
|
|
||||||
if (IsBigIntTerm(d1) && Yap_gmp_tcmp_big_big(d0,d1) == 0) continue;
|
|
||||||
UNWIND_CUNIF();
|
|
||||||
return (FALSE);
|
|
||||||
#endif /* USE_GMP */
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!IsApplTerm(d1)) {
|
|
||||||
UNWIND_CUNIF();
|
|
||||||
return (FALSE);
|
|
||||||
}
|
|
||||||
ap3 = RepAppl(d1);
|
ap3 = RepAppl(d1);
|
||||||
|
f = (Functor) (*ap2);
|
||||||
/* compare functors */
|
/* compare functors */
|
||||||
if (f != (Functor) *ap3) {
|
if (f != (Functor) *ap3)
|
||||||
UNWIND_CUNIF();
|
goto cufail;
|
||||||
return (FALSE);
|
if (IsExtensionFunctor(f)) {
|
||||||
|
if (unify_extension(f, d0, ap2, d1))
|
||||||
|
continue;
|
||||||
|
goto cufail;
|
||||||
}
|
}
|
||||||
#ifdef RATIONAL_TREES
|
|
||||||
/* now link the two structures so that no one else will */
|
/* now link the two structures so that no one else will */
|
||||||
/* come here */
|
/* come here */
|
||||||
if (d0 > d1) {
|
|
||||||
visited -= 2;
|
|
||||||
visited[0] = (CELL) pt0;
|
|
||||||
visited[1] = *pt0;
|
|
||||||
*pt0 = d1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
visited -= 2;
|
|
||||||
visited[0] = (CELL) pt1;
|
|
||||||
visited[1] = *pt1;
|
|
||||||
*pt1 = d0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* store the terms to visit */
|
/* store the terms to visit */
|
||||||
if (pt0 < pt0_end) {
|
if (RATIONAL_TREES || pt0 < pt0_end) {
|
||||||
to_visit[0] = pt0;
|
to_visit --;
|
||||||
to_visit[1] = pt0_end;
|
#ifdef RATIONAL_TREES
|
||||||
to_visit[2] = pt1;
|
unif++;
|
||||||
to_visit += 3;
|
#endif
|
||||||
|
if ((void *)to_visit < (void *)unif) {
|
||||||
|
CELL **urec = (CELL **)unif;
|
||||||
|
to_visit = (struct v_record *)Yap_shift_visit((CELL **)to_visit, &urec);
|
||||||
|
unif = (struct unif_record *)urec;
|
||||||
|
}
|
||||||
|
to_visit->start0 = pt0;
|
||||||
|
to_visit->end0 = pt0_end;
|
||||||
|
to_visit->start1 = pt1;
|
||||||
|
#ifdef RATIONAL_TREES
|
||||||
|
unif[-1].old = *pt0;
|
||||||
|
unif[-1].ptr = pt0;
|
||||||
|
*pt0 = d1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
d0 = ArityOfFunctor(f);
|
d0 = ArityOfFunctor(f);
|
||||||
pt0 = ap2;
|
pt0 = ap2;
|
||||||
pt0_end = ap2 + d0;
|
pt0_end = ap2 + d0;
|
||||||
pt1 = ap3;
|
pt1 = ap3;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
|
||||||
UNWIND_CUNIF();
|
|
||||||
return (FALSE);
|
|
||||||
}
|
}
|
||||||
|
goto cufail;
|
||||||
|
|
||||||
|
derefa_body(d1, ptd1, iequ_comp_nvar_unk, iequ_comp_nvar_nvar);
|
||||||
|
/* d1 and pt2 have the unbound value, whereas d0 is bound */
|
||||||
|
goto cufail;
|
||||||
|
|
||||||
derefa_body(d1, ptd1, eq_comp_nvar_unk, eq_comp_nvar_nvar);
|
|
||||||
/* d1 and pt2 have the unbound value, whereas d0 is bound */
|
|
||||||
UNWIND_CUNIF();
|
|
||||||
return (FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
derefa_body(d0, ptd0, eq_comp_unk, eq_comp_nvar);
|
derefa_body(d0, ptd0, iequ_comp_unk, iequ_comp_nvar);
|
||||||
|
/* first arg var */
|
||||||
{
|
{
|
||||||
register CELL d1;
|
register CELL d1;
|
||||||
register CELL *ptd1;
|
register CELL *ptd1;
|
||||||
|
|
||||||
d1 = *( ptd1 = pt1);
|
ptd1 = pt1;
|
||||||
|
d1 = ptd1[0];
|
||||||
/* pt2 is unbound */
|
/* pt2 is unbound */
|
||||||
deref_head(d1, eq_comp_var_unk);
|
deref_head(d1, iequ_comp_var_unk);
|
||||||
eq_comp_var_nvar:
|
iequ_comp_var_nvar:
|
||||||
/* pt2 is unbound and d1 is bound */
|
/* pt2 is unbound and d1 is bound */
|
||||||
UNWIND_CUNIF();
|
goto cufail;
|
||||||
return (FALSE);
|
|
||||||
|
|
||||||
derefa_body(d1, ptd1, eq_comp_var_unk, eq_comp_var_nvar);
|
derefa_body(d1, ptd1, iequ_comp_var_unk, iequ_comp_var_nvar);
|
||||||
/* pt2 and pt3 are unbound */
|
/* pt2 and pt3 are unbound */
|
||||||
if (ptd0 == ptd1)
|
if (ptd0 == ptd1)
|
||||||
continue;
|
continue;
|
||||||
UNWIND_CUNIF();
|
goto cufail;
|
||||||
return (FALSE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Do we still have compound terms to visit */
|
/* Do we still have compound terms to visit */
|
||||||
if (to_visit > (CELL **) H) {
|
if (to_visit < to_visit_base) {
|
||||||
to_visit -= 3;
|
pt0 = to_visit->start0;
|
||||||
pt0 = to_visit[0];
|
pt0_end = to_visit->end0;
|
||||||
pt0_end = to_visit[1];
|
pt1 = to_visit->start1;
|
||||||
pt1 = to_visit[2];
|
to_visit++;
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
/* successful exit */
|
#ifdef RATIONAL_TREES
|
||||||
UNWIND_CUNIF();
|
/* restore bindigs */
|
||||||
return (TRUE);
|
while (unif-- != unif_base) {
|
||||||
|
CELL *pt0;
|
||||||
|
|
||||||
|
pt0 = unif->ptr;
|
||||||
|
*pt0 = unif->old;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
cufail:
|
||||||
|
#ifdef RATIONAL_TREES
|
||||||
|
/* restore bindigs */
|
||||||
|
while (unif-- != unif_base) {
|
||||||
|
CELL *pt0;
|
||||||
|
|
||||||
|
pt0 = unif->ptr;
|
||||||
|
*pt0 = unif->old;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return FALSE;
|
||||||
|
#ifdef THREADS
|
||||||
|
#undef Yap_REGS
|
||||||
|
#define Yap_REGS (*Yap_regp)
|
||||||
|
#elif defined(SHADOW_REGS)
|
||||||
|
#if defined(B) || defined(TR)
|
||||||
|
#undef Yap_REGS
|
||||||
|
#endif /* defined(B) || defined(TR) */
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Reference in New Issue