mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
626 lines
18 KiB
626 lines
18 KiB
/*
|
|
* recurse.c
|
|
*
|
|
* contains routines which handle recursive structures
|
|
*/
|
|
|
|
#include "compact.h"
|
|
|
|
#ifdef WIN32
|
|
#define _fmemmove memmove
|
|
#endif
|
|
bool_t IdenticalTypes (TYPPTR, TYPPTR);
|
|
bool_t RetractTree(TENTRY *, CV_typ_t);
|
|
|
|
extern CV_typ_t usCurFirstNonPrim; // The current first non primitive type index
|
|
|
|
COUNTER (cnt_IdenticalTree1)
|
|
COUNTER (cnt_IdenticalTree2)
|
|
|
|
extern CV_typ_t NewIndex;
|
|
|
|
|
|
/** IdenticalTree
|
|
*
|
|
* 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
|
|
*
|
|
*/
|
|
|
|
|
|
bool_t DoIdenticalTree (TENTRY * LocalEntry, CV_typ_t LocalIndex,
|
|
TYPPTR pGlobalType, CV_typ_t GlobalIndex)
|
|
{
|
|
ushort i;
|
|
ushort length;
|
|
ushort index;
|
|
TENTRY *TmpLocalEntry;
|
|
TENTRY * pGlobalEntry = NULL;
|
|
ushort j;
|
|
CV_typ_t forward;
|
|
TYPPTR pType1;
|
|
uchar *pName1;
|
|
uchar *pName2;
|
|
CV_typ_t NextIndex;
|
|
TYPPTR NextString;
|
|
|
|
/*
|
|
* Profile tracing
|
|
*/
|
|
|
|
COUNT (cnt_IdenticalTree1);
|
|
|
|
/*
|
|
* If the global index is a primative then it cannot possible
|
|
* match --- we know the local is not a primative
|
|
*/
|
|
|
|
if (GlobalIndex < usCurFirstNonPrim) {
|
|
return (FALSE);
|
|
}
|
|
|
|
if (!LocalEntry->flags.IsDone) {
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
* If we have tentively matched the local entry, return TRUE if the
|
|
* tentitive is the same as the global index, or is identical to the
|
|
* global index.
|
|
*
|
|
* NOTENOTE(JLS): I don't think the else can possibly ever be true
|
|
*/
|
|
|
|
if (LocalEntry->flags.IsBeingMatched) {
|
|
if (LocalEntry->TreeIndex == GlobalIndex) {
|
|
return TRUE;
|
|
} else if (IdenticalTypes((TYPPTR) LocalEntry->TypeString,
|
|
(TYPPTR) pGlobalType)) {
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
else if (LocalEntry->flags.IsMatched) {
|
|
// DASSERT( GlobalIndex == LocalEntry->TreeIndex );
|
|
return( GlobalIndex == LocalEntry->TreeIndex);
|
|
}
|
|
else if (LocalEntry->flags.IsFwdPatch) {
|
|
return (LocalEntry->CompactedIndex == GlobalIndex);
|
|
}
|
|
/*
|
|
* If the real index has been assigned to the local entry then
|
|
* return TRUE iff the assigned index matches
|
|
*/
|
|
|
|
else if (LocalEntry->flags.IsInserted) {
|
|
return (LocalEntry->CompactedIndex == GlobalIndex);
|
|
}
|
|
|
|
/*
|
|
* If we are recursive and the indexes are the same then
|
|
* return TRUE
|
|
*/
|
|
|
|
else if (pGlobalType->leaf == 0xffff) {
|
|
if (*((CV_typ_t *) pGlobalType->data) == LocalIndex) {
|
|
return TRUE;
|
|
}
|
|
pGlobalEntry = GetTypeEntry((CV_typ_t) (*((CV_typ_t *) pGlobalType->data) - usCurFirstNonPrim), &forward);
|
|
pGlobalType = (TYPPTR) pGlobalEntry->TypeString;
|
|
}
|
|
|
|
/*
|
|
* If match is impossible then return immeadiately
|
|
*/
|
|
|
|
DASSERT( (LNGTHSZ + RECTYPSZ) == 4);
|
|
if ((*((long *) LocalEntry->TypeString)) != (*((long *) pGlobalType))) {
|
|
return FALSE;
|
|
}
|
|
|
|
LocalEntry->flags.IsBeingMatched = TRUE;
|
|
LocalEntry->TreeIndex = GlobalIndex;
|
|
pType1 = (TYPPTR)LocalEntry->TypeString;
|
|
length = pType1->len + sizeof (pType1->len);
|
|
j = 0;
|
|
i = 0;
|
|
|
|
// check for attempting to match a forward reference
|
|
|
|
if ((pType1->leaf == pGlobalType->leaf) && IsFwdRef (pGlobalType)) {
|
|
switch ((pType1)->leaf) {
|
|
case LF_CLASS:
|
|
case LF_STRUCTURE:
|
|
pName1 = (uchar *)&((plfClass)&(pType1->leaf))->data[0];
|
|
pName1 += C7SizeOfNumeric (pName1);
|
|
pName2 = (uchar *)&((plfClass)&(pGlobalType->leaf))->data[0];
|
|
pName2 += C7SizeOfNumeric (pName2);
|
|
break;
|
|
|
|
case LF_UNION:
|
|
pName1 = (uchar *)&((plfUnion)&(pType1->leaf))->data[0];
|
|
pName1 += C7SizeOfNumeric (pName1);
|
|
pName2 = (uchar *)&((plfUnion)&(pGlobalType->leaf))->data[0];
|
|
pName2 += C7SizeOfNumeric (pName2);
|
|
break;
|
|
|
|
case LF_ENUM:
|
|
pName1 = (uchar *)&((plfEnum)&(pType1->leaf))->Name[0];
|
|
pName2 = (uchar *)&((plfEnum)&(pGlobalType->leaf))->Name[0];
|
|
break;
|
|
}
|
|
if (strncmp (pName1, pName2, *pName1 + 1) == 0) {
|
|
// we are attempting to match a forward reference
|
|
|
|
AddPatchEntry (LocalIndex, LocalEntry, pGlobalType);
|
|
LocalEntry->flags.IsMatchFwdRef = TRUE;
|
|
return (TRUE);
|
|
}
|
|
goto leave_false;
|
|
}
|
|
|
|
while (i < length) {
|
|
if (j == LocalEntry->Count) {
|
|
index = length; // no more recursive indices
|
|
}
|
|
else {
|
|
if (LocalEntry->flags.LargeList) {
|
|
index = LocalEntry->IndexUnion.IndexString[j];
|
|
}
|
|
else {
|
|
index = LocalEntry->IndexUnion.Index[j];
|
|
}
|
|
j ++;
|
|
}
|
|
while (i < index) {
|
|
if (((uchar *)pType1)[i] != ((uchar *)pGlobalType)[i]) {
|
|
goto leave_false;
|
|
}
|
|
i++;
|
|
}
|
|
i += sizeof (CV_typ_t);
|
|
}
|
|
BreakOnIndex (LocalIndex);
|
|
for (i = 0; i < LocalEntry->Count; i++) {
|
|
if (LocalEntry->flags.LargeList) {
|
|
index = LocalEntry->IndexUnion.IndexString[i];
|
|
}
|
|
else {
|
|
index = LocalEntry->IndexUnion.Index[i];
|
|
}
|
|
NextIndex = *(CV_typ_t *)((uchar *)pGlobalType + index);
|
|
if (NextIndex < usCurFirstNonPrim) {
|
|
goto leave_false;
|
|
}
|
|
|
|
if (index <= LocalEntry->iDone) {
|
|
if (*(CV_typ_t *) ((uchar *) pType1 + index) != NextIndex) {
|
|
goto leave_false;
|
|
}
|
|
}else if (pGlobalEntry && (index > pGlobalEntry->iDone)) {
|
|
if (*(CV_typ_t *) ((uchar *) pType1 + index) != NextIndex) {
|
|
goto leave_false;
|
|
}
|
|
} else {
|
|
TmpLocalEntry = GetTypeEntry ((CV_typ_t)(*(CV_typ_t *)((uchar *)pType1 + index) - usCurFirstNonPrim), &forward);
|
|
DASSERT( NextIndex < NewIndex );
|
|
if (NextIndex >= NewIndex) {
|
|
goto leave_false;
|
|
}
|
|
|
|
NextString = (TYPPTR) RgGType[NextIndex - CV_FIRST_NONPRIM].pbType;
|
|
|
|
COUNT (cnt_IdenticalTree2);
|
|
|
|
if (!DoIdenticalTree (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);
|
|
}
|
|
|
|
bool_t IdenticalTree(TENTRY * pEntry, CV_typ_t idxLocal,
|
|
TYPPTR pTypeGlobal, CV_typ_t idxGlobal)
|
|
{
|
|
bool_t bRet;
|
|
struct BlockListEntry * pCur;
|
|
TENTRY * pEntryTmp;
|
|
int n;
|
|
int i;
|
|
|
|
bRet = DoIdenticalTree(pEntry, idxLocal, pTypeGlobal, idxGlobal);
|
|
|
|
for (pCur = BlockList, n = IndexBlocks;
|
|
pCur != NULL && n > 0;
|
|
pCur = pCur->Next, n--) {
|
|
|
|
for (i=pCur->Low, pEntryTmp = &pCur->ModuleIndexTable[pCur->Low];
|
|
i <= pCur->High;
|
|
i++, pEntryTmp++) {
|
|
|
|
if (pEntryTmp->flags.IsMatched) {
|
|
if (bRet &&
|
|
!pEntryTmp->flags.IsInserted &&
|
|
!pEntryTmp->flags.IsMatchFwdRef) {
|
|
pEntryTmp->flags.IsInserted = bRet;
|
|
pEntryTmp->CompactedIndex = pEntryTmp->TreeIndex;
|
|
}
|
|
pEntryTmp->flags.IsMatchFwdRef = FALSE;
|
|
pEntryTmp->flags.IsMatched = FALSE;
|
|
}
|
|
pEntryTmp->TreeIndex = 0;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
} /* IdenticalTree() */
|
|
|
|
/** 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 AddRecursiveType (CV_typ_t OldIndex)
|
|
{
|
|
TENTRY *OldEntry;
|
|
uchar *TypeString;
|
|
TYPPTR pType;
|
|
ushort i;
|
|
ushort offset;
|
|
CV_typ_t forward;
|
|
CV_typ_t type;
|
|
|
|
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);
|
|
}
|
|
pType = (TYPPTR)OldEntry->TypeString;
|
|
InsertIntoTypeSegment (OldEntry);
|
|
OldEntry->flags.IsInserted = TRUE;
|
|
OldEntry->flags.IsMatched = FALSE;
|
|
AddTypeToTypeTable (OldEntry);
|
|
TypeString = OldEntry->TypeString;
|
|
for (i = 0; i < OldEntry->Count; i++) {
|
|
if (OldEntry->flags.LargeList) {
|
|
offset = OldEntry->IndexUnion.IndexString[i];
|
|
}
|
|
else {
|
|
offset = OldEntry->IndexUnion.Index[i];
|
|
}
|
|
type = AddRecursiveType(*(CV_typ_t *)(TypeString + offset));
|
|
TypeString = OldEntry->TypeString;
|
|
*(CV_typ_t *)(TypeString + offset) = type;
|
|
OldEntry->iDone = offset;
|
|
}
|
|
OldEntry->iDone = (ushort) -1;
|
|
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);
|
|
}
|
|
|
|
|
|
AAA(TENTRY *OldEntry, CV_typ_t OldIndex)
|
|
{
|
|
uchar * pbTypeString;
|
|
CV_typ_t type;
|
|
TENTRY * TmpEntry;
|
|
int i;
|
|
int offset;
|
|
ushort forward;
|
|
|
|
DASSERT(OldEntry->flags.fBeingAdded);
|
|
|
|
pbTypeString = OldEntry->TypeString;
|
|
|
|
for (i=0; i<OldEntry->Count; i++) {
|
|
if (OldEntry->flags.LargeList) {
|
|
offset = OldEntry->IndexUnion.IndexString[i];
|
|
} else {
|
|
offset = OldEntry->IndexUnion.Index[i];
|
|
}
|
|
|
|
if (offset > OldEntry->iDone) {
|
|
type = *(CV_typ_t *)(pbTypeString + offset);
|
|
|
|
TmpEntry = GetTypeEntry((CV_typ_t) (type - usCurFirstNonPrim), &forward);
|
|
if ((TmpEntry->flags.IsFwdPatch == TRUE) ||
|
|
(TmpEntry->flags.IsInserted == TRUE) ||
|
|
(TmpEntry->flags.IsMatched == TRUE)) {
|
|
type = TmpEntry->CompactedIndex;
|
|
} else {
|
|
PsuedoInsertIntoTypeSegment(OldEntry, OldIndex);
|
|
AddTypeToTypeTable(OldEntry);
|
|
OldEntry->flags.IsInserted = TRUE;
|
|
OldEntry->flags.IsMatched = FALSE;
|
|
return OldEntry->CompactedIndex;
|
|
}
|
|
|
|
pbTypeString = OldEntry->TypeString;
|
|
*(CV_typ_t *)(pbTypeString + offset) = type;
|
|
OldEntry->iDone = offset;
|
|
}
|
|
}
|
|
|
|
MatchIndex(OldEntry);
|
|
OldEntry->flags.IsInserted = TRUE;
|
|
OldEntry->flags.IsMatched = FALSE;
|
|
|
|
OldEntry->iDone = (ushort) -1;
|
|
|
|
// If adding a class, setup the derivation information
|
|
|
|
switch (((TYPPTR) OldEntry->TypeString)->leaf) {
|
|
case LF_CLASS:
|
|
case LF_STRUCTURE:
|
|
DoDerivationList (OldEntry->CompactedIndex,
|
|
(((plfClass)&(((TYPPTR) (OldEntry->TypeString)))->leaf)->field));
|
|
break;
|
|
}
|
|
|
|
return (OldEntry->CompactedIndex);
|
|
} /* AAA() */
|
|
|
|
|
|
/** AddPatchType
|
|
*
|
|
* AddPatchType (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_AddPatchType1)
|
|
COUNTER (cnt_AddPatchType2)
|
|
COUNTER (cnt_AddPatchType3)
|
|
|
|
CV_typ_t AddPatchType (CV_typ_t OldIndex)
|
|
{
|
|
TENTRY *OldEntry;
|
|
TENTRY *TmpEntry;
|
|
uchar *TypeString;
|
|
TYPPTR pType;
|
|
ushort i;
|
|
ushort offset;
|
|
CV_typ_t forward;
|
|
CV_typ_t type;
|
|
|
|
COUNT (cnt_AddPatchType1);
|
|
DASSERT (OldIndex >= usCurFirstNonPrim);
|
|
OldEntry = GetTypeEntry ((CV_typ_t) (OldIndex - usCurFirstNonPrim), &forward);
|
|
if (OldEntry->flags.IsForward) {
|
|
COUNT (cnt_AddPatchType1);
|
|
OldIndex = OldEntry->ForwardIndex;
|
|
OldEntry = GetTypeEntry ((CV_typ_t) (OldIndex - usCurFirstNonPrim), &forward);
|
|
}
|
|
if ((OldEntry->flags.IsInserted) || (OldEntry->flags.IsPreComp) ||
|
|
(OldEntry->flags.IsMatched)) {
|
|
return (OldEntry->CompactedIndex);
|
|
}
|
|
pType = (TYPPTR)OldEntry->TypeString;
|
|
|
|
/*
|
|
* Mark as being processed
|
|
*/
|
|
|
|
OldEntry->flags.fBeingAdded = TRUE;
|
|
|
|
/*
|
|
* Attempt to add each of the sub-types refered to
|
|
*/
|
|
|
|
TypeString = OldEntry->TypeString;
|
|
for (i = 0; i < OldEntry->Count; i++) {
|
|
if (OldEntry->flags.LargeList) {
|
|
offset = OldEntry->IndexUnion.IndexString[i];
|
|
}
|
|
else {
|
|
offset = OldEntry->IndexUnion.Index[i];
|
|
}
|
|
|
|
if (offset > OldEntry->iDone) {
|
|
COUNT (cnt_AddPatchType3);
|
|
type = *(CV_typ_t *)(TypeString + offset);
|
|
TmpEntry = GetTypeEntry ((CV_typ_t) (type - usCurFirstNonPrim),
|
|
&forward);
|
|
if ((TmpEntry->flags.IsFwdPatch == TRUE) ||
|
|
(TmpEntry->flags.IsInserted == TRUE) ||
|
|
(TmpEntry->flags.IsMatched == TRUE)) {
|
|
type = TmpEntry->CompactedIndex;
|
|
}
|
|
else if (TmpEntry->flags.fBeingAdded == TRUE) {
|
|
type = AAA(TmpEntry, type);
|
|
}
|
|
else {
|
|
type = GetPatchIndex (TmpEntry, type);
|
|
}
|
|
TypeString = OldEntry->TypeString;
|
|
*(CV_typ_t *)(TypeString + offset) = type;
|
|
|
|
/*
|
|
* Keep track of how far we have progressed
|
|
*/
|
|
|
|
if (offset > OldEntry->iDone) {
|
|
OldEntry->iDone = offset;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* If it did not get patched in, then add the type to the global table
|
|
* at this point in time.
|
|
*/
|
|
|
|
if (OldEntry->flags.IsInserted == FALSE) {
|
|
MatchIndex(OldEntry);
|
|
OldEntry->flags.IsInserted = TRUE;
|
|
OldEntry->flags.IsMatched = FALSE;
|
|
} else {
|
|
|
|
/*
|
|
* If we faked a record then get the real record in place.
|
|
*/
|
|
|
|
if (OldEntry->flags.fPsuedoPatch) {
|
|
PsuedoBackPatch(OldEntry);
|
|
}
|
|
|
|
AddTypeToStringTable (OldEntry->TypeString, OldEntry->CompactedIndex);
|
|
}
|
|
|
|
DASSERT(!OldEntry->flags.fPsuedoPatch);
|
|
|
|
OldEntry->iDone = (ushort) -1;
|
|
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);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AddPatchEntry (CV_typ_t index, TENTRY *OldEntry, TYPPTR pType)
|
|
{
|
|
HSFWD *pHash;
|
|
int i;
|
|
|
|
if (pFwdPatch->cPatch == pFwdPatch->Max) {
|
|
pFwdPatch = (PFWDPATCH)NoErrorRealloc (pFwdPatch, sizeof (FWDPATCH) +
|
|
(pFwdPatch->Max + 10) * sizeof (PATCH));
|
|
pFwdPatch->Max += 10;
|
|
}
|
|
switch (FindFwdRef (OldEntry, &pHash, FALSE)) {
|
|
case FWD_none:
|
|
case FWD_local:
|
|
case FWD_global:
|
|
DASSERT (FALSE);
|
|
break;
|
|
|
|
case FWD_globalfwd:
|
|
i = pFwdPatch->cPatch;
|
|
pFwdPatch->Patch[i].index = index;
|
|
pFwdPatch->Patch[i].pHash = pHash;
|
|
pFwdPatch->cPatch++;
|
|
OldEntry->flags.IsBeingMatched = FALSE;
|
|
OldEntry->flags.IsMatched = TRUE;
|
|
OldEntry->CompactedIndex = pHash->index;
|
|
break;
|
|
}
|
|
}
|
|
|
|
COUNTER (cnt_PatchFwdRef)
|
|
|
|
|
|
|
|
void PatchFwdRef (void)
|
|
{
|
|
uint i;
|
|
CV_typ_t index;
|
|
HSFWD *pHash;
|
|
CV_typ_t forward;
|
|
TENTRY *OldEntry;
|
|
TENTRY *TmpEntry;
|
|
TYPPTR pType;
|
|
int offset;
|
|
CV_typ_t type;
|
|
|
|
|
|
COUNT (cnt_PatchFwdRef);
|
|
i = pFwdPatch->iPatch++;
|
|
index = pFwdPatch->Patch[i].index;
|
|
pHash = pFwdPatch->Patch[i].pHash;
|
|
OldEntry = GetTypeEntry ((CV_typ_t) (index - usCurFirstNonPrim), &forward);
|
|
if ((OldEntry->flags.IsInserted) || (OldEntry->flags.IsPreComp)) {
|
|
return;
|
|
}
|
|
if (IsFwdRef (pHash->pType) == FALSE) {
|
|
// somebody already patched this
|
|
return;
|
|
}
|
|
pType = (TYPPTR)OldEntry->TypeString;
|
|
#if defined (DUMP)
|
|
DumpPartialType (pHash->index, pType, TRUE);
|
|
#endif
|
|
_fmemmove (pHash->pType, pType, pType->len + sizeof (pType->len));
|
|
pType = pHash->pType;
|
|
OldEntry->CompactedIndex = pHash->index;
|
|
OldEntry->TypeString = (uchar *)pType;
|
|
OldEntry->flags.IsFwdPatch = TRUE;
|
|
OldEntry->flags.IsMatched = FALSE;
|
|
OldEntry->flags.IsBeingMatched = FALSE;
|
|
AddTypeToTypeTable (OldEntry);
|
|
for (i = 0; i < (uint)OldEntry->Count; i++) {
|
|
if (OldEntry->flags.LargeList) {
|
|
offset = OldEntry->IndexUnion.IndexString[i];
|
|
}
|
|
else {
|
|
offset = OldEntry->IndexUnion.Index[i];
|
|
}
|
|
type = *(CV_typ_t *)((uchar *)pType + offset);
|
|
TmpEntry = GetTypeEntry ((CV_typ_t) (type - usCurFirstNonPrim), &forward);
|
|
type = GetPatchIndex (TmpEntry, type);
|
|
pType = (TYPPTR)OldEntry->TypeString;
|
|
*(CV_typ_t *)((uchar *)pType + offset) = type;
|
|
OldEntry->iDone = offset;
|
|
}
|
|
OldEntry->iDone = (ushort) -1;
|
|
OldEntry->flags.IsInserted = TRUE;
|
|
OldEntry->flags.IsMatched = FALSE;
|
|
OldEntry->flags.IsFwdPatch = FALSE;
|
|
AddTypeToStringTable (OldEntry->TypeString, OldEntry->CompactedIndex);
|
|
}
|