302 lines
7.5 KiB
C
302 lines
7.5 KiB
C
/** compact6.c - basic compaction routine and initialization routines
|
|
* for C6 style Codeview information.
|
|
*/
|
|
|
|
|
|
#include "compact.h"
|
|
|
|
|
|
|
|
|
|
#define INDEXLIST 10
|
|
#define FIELDLIST 11
|
|
#define METHODLIST 12
|
|
|
|
extern ushort MaxIndex;
|
|
|
|
|
|
ushort recursive;
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* C6GetCompactedIndex
|
|
*
|
|
* Basic routine to do type compaction. Given an index to the
|
|
* local module index table, it matches the string and returns
|
|
* its index in the global compacted type segment. It takes
|
|
* care of insertion if the string is not already present
|
|
*
|
|
************************************************************************/
|
|
|
|
CV_typ_t _fastcall C6GetCompactedIndex (CV_typ_t OldIndex)
|
|
{
|
|
CV_typ_t retval;
|
|
|
|
retval = C6GetCompactedIndexRecur(OldIndex);
|
|
PickUpFwdRefs();
|
|
|
|
return(retval);
|
|
}
|
|
|
|
|
|
CV_typ_t _fastcall C6GetCompactedIndexRecur (CV_typ_t OldIndex)
|
|
{
|
|
TENTRY *OldEntry;
|
|
uchar *TypeString;
|
|
CV_typ_t OldRecursiveRoot;
|
|
uchar i = 0;
|
|
CV_typ_t dummy;
|
|
HSFWD *pHash;
|
|
|
|
|
|
if (OldIndex < 512) {
|
|
// if primitive index
|
|
recursive = FALSE;
|
|
return (C6MapPrimitive (OldIndex));
|
|
}
|
|
if (OldIndex >= MaxIndex + 512) {
|
|
// within limits
|
|
recursive = FALSE;
|
|
return (0);
|
|
}
|
|
DASSERT (MaxIndex > OldIndex - 512);
|
|
OldEntry = GetTypeEntry ((CV_typ_t)(OldIndex - 512), &dummy);
|
|
|
|
DASSERT (OldEntry != NULL);
|
|
// get table entry
|
|
|
|
if ((OldEntry->flags.IsInserted) || (OldEntry->flags.IsMatched) ||
|
|
(OldEntry->flags.IsParameter)) {
|
|
recursive = FALSE;
|
|
return (OldEntry->CompactedIndex);
|
|
}
|
|
else if (OldEntry->flags.IsDone) {
|
|
TENTRY *TmpEntry;
|
|
|
|
for (TmpEntry = OldEntry;
|
|
GetTypeEntry ((CV_typ_t)(TmpEntry->CompactedIndex - 512), &dummy)->flags.IsDone;
|
|
TmpEntry = GetTypeEntry ((CV_typ_t)(TmpEntry->CompactedIndex - 512), &dummy)) {
|
|
DASSERT (TmpEntry != NULL);
|
|
|
|
;
|
|
}
|
|
|
|
recursive = TRUE;
|
|
SetRecursiveRoot (TmpEntry->CompactedIndex);//set tree top
|
|
return (OldIndex);
|
|
}
|
|
else if (NoMoTypes) {
|
|
recursive = FALSE;
|
|
OldEntry->flags.IsMatched = TRUE;
|
|
OldEntry->CompactedIndex = T_NOTYPE;
|
|
return (T_NOTYPE);
|
|
}
|
|
else if (OldEntry->flags.IsBeingDone) {
|
|
// Since this type is currently in the process of being compacted
|
|
// this type must eventually reference its own index. I.e. This
|
|
// is a recursive type.
|
|
recursive = TRUE; // Currently working on a recursive type.
|
|
|
|
// Set RecursiveRoot (the recursive index number were currently looking
|
|
// for) to the deepest recursion level we have seen so far.
|
|
SetRecursiveRoot (OldIndex); // put it on stack
|
|
return (OldIndex); // return
|
|
}
|
|
else {
|
|
OldEntry->flags.IsBeingDone = TRUE; // being done
|
|
}
|
|
|
|
DASSERT (!OldEntry->flags.IsNewFormat);
|
|
|
|
Push (OldIndex);
|
|
|
|
OldRecursiveRoot = RecursiveRoot;
|
|
RecursiveRoot = 0;
|
|
|
|
TypeString = OldEntry->TypeString; // get the string
|
|
switch (TypeString[3]) {
|
|
case OLF_COBOLTYPEREF:
|
|
{
|
|
plfCobol0 plf;
|
|
|
|
ConvertObsolete ((CV_typ_t)(OldIndex - 512)); // obsolete records
|
|
plf = (plfCobol0) (OldEntry->TypeString + LNGTHSZ);
|
|
|
|
plf->type = C6GetCompactedIndexRecur( plf->type );
|
|
if (recursive) {
|
|
OldEntry->IndexUnion.Index[i++] =
|
|
(uchar)(offsetof (lfCobol0, type) + LNGTHSZ);
|
|
}
|
|
break;
|
|
}
|
|
|
|
|
|
case OLF_MODIFIER:
|
|
// Note: used to share processing with BARRAY
|
|
assert( OLF_MODIFIER && FALSE );
|
|
break;
|
|
|
|
case OLF_NEWTYPE:
|
|
// Note: used to share processing with BARRAY
|
|
assert( OLF_NEWTYPE && FALSE );
|
|
break;
|
|
|
|
case OLF_BARRAY:
|
|
{
|
|
plfBArray plf;
|
|
|
|
ConvertObsolete ((CV_typ_t)(OldIndex - 512)); // obsolete records
|
|
plf = (plfBArray) (OldEntry->TypeString + LNGTHSZ);
|
|
|
|
plf->utype = C6GetCompactedIndexRecur( plf->utype );
|
|
if (recursive) {
|
|
OldEntry->IndexUnion.Index[i ++] =
|
|
(uchar)(offsetof (lfBArray, utype) + LNGTHSZ);
|
|
}
|
|
break;
|
|
}
|
|
|
|
|
|
case OLF_POINTER:
|
|
case OLF_BASEPTR:
|
|
{
|
|
DASSERT (i == 0);
|
|
ConvertObsolete ((CV_typ_t)(OldIndex - 512)); // obsolete records
|
|
i = CompactPtr (OldEntry);
|
|
break;
|
|
}
|
|
|
|
case OLF_STRUCTURE:
|
|
{
|
|
plfStructure plf;
|
|
|
|
ConvertObsolete ((CV_typ_t)(OldIndex - 512)); // obsolete records
|
|
|
|
// see if the def'd structure had already packed global
|
|
// forward ref
|
|
|
|
if (FindFwdRef (OldEntry, &pHash, FALSE) == FWD_globalfwd){
|
|
Pop();
|
|
AddFwdRef(OldIndex, pHash);
|
|
recursive = FALSE;
|
|
RecursiveRoot = OldRecursiveRoot;
|
|
OldEntry->flags.IsMatched = TRUE;
|
|
return(OldEntry->CompactedIndex = pHash->index);
|
|
}
|
|
|
|
plf = (plfStructure) (OldEntry->TypeString + LNGTHSZ);
|
|
|
|
plf->field = CompactList( plf->field, plf->count);
|
|
if (recursive) {
|
|
OldEntry->IndexUnion.Index[i ++] =
|
|
(uchar)(offsetof (lfStructure, field) + LNGTHSZ);
|
|
}
|
|
// Note: a class will have to compact a couple more indicys
|
|
break;
|
|
}
|
|
|
|
case OLF_UNION:
|
|
assert( OLF_UNION && FALSE );
|
|
break;
|
|
|
|
case OLF_ENUM:
|
|
assert( OLF_ENUM && FALSE );
|
|
break;
|
|
|
|
case OLF_ARRAY:
|
|
{
|
|
plfArray plf;
|
|
|
|
ConvertObsolete ((CV_typ_t)(OldIndex - 512)); // obsolete records
|
|
plf = (plfArray) (OldEntry->TypeString + LNGTHSZ);
|
|
|
|
plf->elemtype = C6GetCompactedIndexRecur( plf->elemtype );
|
|
if (recursive) {
|
|
OldEntry->IndexUnion.Index[i ++] =
|
|
(uchar)(offsetof (lfArray, elemtype) + LNGTHSZ);
|
|
}
|
|
|
|
plf->idxtype = C6GetCompactedIndexRecur( plf->idxtype );
|
|
if (recursive) {
|
|
OldEntry->IndexUnion.Index[i ++] =
|
|
(uchar)(offsetof (lfArray, idxtype) + LNGTHSZ);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case OLF_PROCEDURE:
|
|
{
|
|
plfProc plf;
|
|
ConvertObsolete ((CV_typ_t)(OldIndex - 512)); // obsolete records
|
|
|
|
plf = (plfProc) (OldEntry->TypeString + LNGTHSZ);
|
|
|
|
plf->rvtype = C6GetCompactedIndexRecur( plf->rvtype );
|
|
if (recursive) {
|
|
OldEntry->IndexUnion.Index[i ++] =
|
|
(uchar)(offsetof (lfProc, rvtype) + LNGTHSZ);
|
|
}
|
|
|
|
plf->arglist = CompactList( plf->arglist, plf->parmcount);
|
|
if (recursive) {
|
|
OldEntry->IndexUnion.Index[i ++] =
|
|
(uchar)(offsetof (lfProc, arglist) + LNGTHSZ);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case OLF_PARAMETER:
|
|
{
|
|
OldEntry->CompactedIndex = C6GetCompactedIndexRecur (*(CV_typ_t UNALIGNED *)(OldEntry->TypeString + 5));
|
|
OldEntry->flags.IsParameter = TRUE;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
ConvertObsolete ((CV_typ_t)(OldIndex - 512));
|
|
break; // no lower type indices
|
|
}
|
|
}
|
|
Pop ();
|
|
|
|
OldEntry->Count = i;
|
|
|
|
if (RecursiveRoot == OldIndex) {
|
|
// This type eventually references it's own type index
|
|
// We have compacted every type this type references except this one
|
|
// and possibly some recursive types that reference this type.
|
|
// Now check the special global table used for recursive indexes and
|
|
// see if this type matches it. If a match is not found put the
|
|
// new recursive type in the global table.
|
|
|
|
recursive = FALSE;
|
|
|
|
// Restore the recursive root we were using before we had to call
|
|
// ourselves. The call may have modified it by compacting a
|
|
// recursive type.
|
|
RecursiveRoot = OldRecursiveRoot;
|
|
OldEntry->CompactedIndex = GetRecursiveIndex (OldEntry, OldIndex);
|
|
return (OldEntry->CompactedIndex);
|
|
}
|
|
else if (RecursiveRoot != 0) {
|
|
recursive = TRUE;
|
|
OldEntry->CompactedIndex = RecursiveRoot;
|
|
SetRecursiveRoot (OldRecursiveRoot);
|
|
OldEntry->flags.IsDone = TRUE;
|
|
return (OldIndex);
|
|
}
|
|
else {
|
|
// We are not compacting a type that references itself.
|
|
// So just try to find a matching string in the global table.
|
|
recursive = FALSE;
|
|
RecursiveRoot = OldRecursiveRoot;
|
|
if (OldEntry->flags.IsParameter == FALSE) {
|
|
OldEntry->flags.IsInserted = TRUE;
|
|
MatchIndex (OldEntry);
|
|
}
|
|
return (OldEntry->CompactedIndex);
|
|
}
|
|
}
|