219 lines
5.1 KiB
C
219 lines
5.1 KiB
C
|
|
||
|
/*
|
||
|
* recurse.c
|
||
|
*
|
||
|
* contains routines which handle recursive structures
|
||
|
*/
|
||
|
|
||
|
#include "compact.h"
|
||
|
|
||
|
|
||
|
extern CV_typ_t usCurFirstNonPrim; // The current first non primitive type index
|
||
|
|
||
|
COUNTER (cnt_IdenticalTree1);
|
||
|
COUNTER (cnt_IdenticalTree2);
|
||
|
|
||
|
/** IdenticalTree_ (IdenticalTree inlined part)
|
||
|
*
|
||
|
* Given a recursive LocalIndex and a GlobalIndex, it checks the
|
||
|
* two type trees to be structurally equivalent by recursively
|
||
|
* checking subtypes which have recursive local indices
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#pragma optimize("a",on)
|
||
|
|
||
|
#ifdef _M_IX86
|
||
|
#pragma function(memcmp)
|
||
|
#endif
|
||
|
|
||
|
bool_t _fastcall IdenticalTree_(TENTRY * LocalEntry, CV_typ_t LocalIndex,
|
||
|
TYPPTR pGlobalType, CV_typ_t GlobalIndex)
|
||
|
{
|
||
|
ushort i;
|
||
|
ushort length;
|
||
|
ushort index;
|
||
|
TENTRY *TmpLocalEntry;
|
||
|
ushort j, k;
|
||
|
CV_typ_t forward;
|
||
|
TYPPTR pType1;
|
||
|
CV_typ_t NextIndex;
|
||
|
TYPPTR NextString;
|
||
|
uchar **pBuf;
|
||
|
|
||
|
int x;
|
||
|
|
||
|
LocalEntry->flags.IsBeingMatched = TRUE;
|
||
|
LocalEntry->CompactedIndex = GlobalIndex;
|
||
|
pType1 = (TYPPTR)LocalEntry->TypeString;
|
||
|
length = pType1->len + sizeof (pType1->len);
|
||
|
j = 0;
|
||
|
i = 0;
|
||
|
|
||
|
x = 0;
|
||
|
|
||
|
while (i < length) {
|
||
|
reiterate:
|
||
|
++x;
|
||
|
if (j == LocalEntry->Count) {
|
||
|
index = length; // no more recursive indices
|
||
|
}
|
||
|
else {
|
||
|
if (IndexIsGlobal(LocalEntry, j)) {
|
||
|
j++;
|
||
|
goto reiterate;
|
||
|
}
|
||
|
if (LocalEntry->flags.LargeList) {
|
||
|
index = LocalEntry->IndexUnion.IndexString[j];
|
||
|
}
|
||
|
else {
|
||
|
index = LocalEntry->IndexUnion.Index[j];
|
||
|
}
|
||
|
j ++;
|
||
|
}
|
||
|
|
||
|
k = index - i;
|
||
|
|
||
|
if (k)
|
||
|
{
|
||
|
if (memcmp(((uchar *)pType1) + i, ((uchar *)pGlobalType) + i, k))
|
||
|
{
|
||
|
//goto leave_false;
|
||
|
LocalEntry->flags.IsBeingMatched = FALSE;
|
||
|
return (FALSE);
|
||
|
}
|
||
|
i = index;
|
||
|
}
|
||
|
|
||
|
i += sizeof (CV_typ_t);
|
||
|
}
|
||
|
|
||
|
BreakOnIndex (LocalIndex);
|
||
|
for (i = 0; i < LocalEntry->Count; i++) {
|
||
|
if (IndexIsGlobal(LocalEntry, i)) continue;
|
||
|
if (LocalEntry->flags.LargeList) {
|
||
|
index = LocalEntry->IndexUnion.IndexString[i];
|
||
|
}
|
||
|
else {
|
||
|
index = LocalEntry->IndexUnion.Index[i];
|
||
|
}
|
||
|
TmpLocalEntry = GetTypeEntry (
|
||
|
(CV_typ_t)(*(CV_typ_t *)((uchar *)pType1 + index) - usCurFirstNonPrim), &forward);
|
||
|
NextIndex = *(CV_typ_t *)((uchar *)pGlobalType + index);
|
||
|
if (NextIndex < usCurFirstNonPrim) {
|
||
|
goto leave_false;
|
||
|
}
|
||
|
pBuf = pGType[(NextIndex - CV_FIRST_NONPRIM) / GTYPE_INC];
|
||
|
NextString = (TYPPTR)pBuf[(NextIndex - CV_FIRST_NONPRIM) % GTYPE_INC];
|
||
|
COUNT (cnt_IdenticalTree2);
|
||
|
#if DBG
|
||
|
if (DbArray[5]) {
|
||
|
printf("Local index: 0x%4.4x, Global Index: 0x%4.4x\n",
|
||
|
*(CV_typ_t *)((uchar *)pType1 + index), NextIndex);
|
||
|
}
|
||
|
#endif
|
||
|
if (!IdenticalTree (TmpLocalEntry, *(CV_typ_t *)((uchar *)pType1 + index),
|
||
|
NextString, NextIndex)) {
|
||
|
goto leave_false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// current nodes no longer being matched
|
||
|
LocalEntry->flags.IsBeingMatched = FALSE;
|
||
|
LocalEntry->flags.IsMatched = TRUE;
|
||
|
return (TRUE);
|
||
|
|
||
|
leave_false:
|
||
|
// current nodes no longer being matched
|
||
|
LocalEntry->flags.IsBeingMatched = FALSE;
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
#pragma intrinsic(memcmp)
|
||
|
#pragma optimize("a", off)
|
||
|
|
||
|
|
||
|
/** AddRecursiveType
|
||
|
*
|
||
|
* AddRecursiveType (OldIndex)
|
||
|
*
|
||
|
* Entry OldIndex = module level index to be added
|
||
|
*
|
||
|
* Exit all recursive types added to the global types table
|
||
|
*
|
||
|
* Returns global type index
|
||
|
*/
|
||
|
|
||
|
COUNTER (cnt_AddRecursiveType1);
|
||
|
COUNTER (cnt_AddRecursiveType2);
|
||
|
|
||
|
CV_typ_t _fastcall AddRecursiveType (CV_typ_t OldIndex)
|
||
|
{
|
||
|
TENTRY *OldEntry;
|
||
|
uchar *TypeString;
|
||
|
TYPPTR pType;
|
||
|
ushort i;
|
||
|
ushort offset;
|
||
|
CV_typ_t forward;
|
||
|
CV_typ_t type;
|
||
|
HSFWD *pHash;
|
||
|
FWD_t IsFwdRef;
|
||
|
|
||
|
BreakOnIndex(OldIndex);
|
||
|
|
||
|
COUNT (cnt_AddRecursiveType1);
|
||
|
DASSERT (OldIndex >= usCurFirstNonPrim);
|
||
|
OldEntry = GetTypeEntry ((CV_typ_t)(OldIndex - usCurFirstNonPrim), &forward);
|
||
|
if (OldEntry->flags.IsForward) {
|
||
|
OldIndex = OldEntry->ForwardIndex;
|
||
|
COUNT (cnt_AddRecursiveType1);
|
||
|
OldEntry = GetTypeEntry ((CV_typ_t)(OldIndex - usCurFirstNonPrim), &forward);
|
||
|
}
|
||
|
if ((OldEntry->flags.IsInserted) || (OldEntry->flags.IsPreComp) ||
|
||
|
(OldEntry->flags.IsMatched)) {
|
||
|
return (OldEntry->CompactedIndex);
|
||
|
}
|
||
|
if ((IsFwdRef = FindFwdRef (OldEntry, &pHash, FALSE)) == FWD_globalfwd) {
|
||
|
OldEntry->CompactedIndex = pHash->index;
|
||
|
pType = (TYPPTR)OldEntry->TypeString;
|
||
|
OldEntry->TypeString = (uchar *)pHash->pType;
|
||
|
}
|
||
|
else {
|
||
|
InsertIntoTypeSegment (OldEntry);
|
||
|
pType = (TYPPTR)OldEntry->TypeString;
|
||
|
}
|
||
|
|
||
|
OldEntry->flags.IsInserted = TRUE;
|
||
|
AddTypeToTypeTable (OldEntry);
|
||
|
TypeString = (uchar *)pType;
|
||
|
for (i = 0; i < OldEntry->Count; i++) {
|
||
|
if (IndexIsGlobal(OldEntry, i)) continue;
|
||
|
if (OldEntry->flags.LargeList) {
|
||
|
offset = OldEntry->IndexUnion.IndexString[i];
|
||
|
}
|
||
|
else {
|
||
|
offset = OldEntry->IndexUnion.Index[i];
|
||
|
}
|
||
|
type = AddRecursiveType(*(CV_typ_t *)(TypeString + offset));
|
||
|
DASSERT (TypeString == (uchar *)pType);
|
||
|
*(CV_typ_t *)(TypeString + offset) = type;
|
||
|
SetIndexGlobal(OldEntry, i);
|
||
|
}
|
||
|
if (IsFwdRef == FWD_globalfwd) {
|
||
|
memmove (pHash->pType, pType, pType->len + sizeof (pType->len));
|
||
|
}
|
||
|
AddTypeToStringTable (OldEntry->TypeString, OldEntry->CompactedIndex);
|
||
|
pType = (TYPPTR)(OldEntry->TypeString);
|
||
|
|
||
|
// If adding a class, setup the derivation information
|
||
|
|
||
|
switch (pType->leaf) {
|
||
|
case LF_CLASS:
|
||
|
case LF_STRUCTURE:
|
||
|
DoDerivationList (OldEntry->CompactedIndex,
|
||
|
(((plfClass)&(pType->leaf))->field));
|
||
|
break;
|
||
|
}
|
||
|
return (OldEntry->CompactedIndex);
|
||
|
}
|