- Make TypeTable a GC root.

- Instantiate some basic types.

SVN r2298 (scripting)
This commit is contained in:
Randy Heit 2010-04-22 04:12:42 +00:00
parent ee55e0319f
commit dde5e1928f
3 changed files with 345 additions and 16 deletions

View file

@ -356,11 +356,8 @@ static void MarkRoot()
Mark(*(afunc->VMPointer));
}
}
// Mark classes
for (unsigned j = 0; j < PClass::AllClasses.Size(); ++j)
{
Mark(PClass::AllClasses[j]);
}
// Mark types
TypeTable.Mark();
// Mark bot stuff.
Mark(bglobal.firstthing);
Mark(bglobal.body1);

View file

@ -61,6 +61,16 @@ FTypeTable TypeTable;
TArray<PClass *> PClass::AllClasses;
bool PClass::bShutdown;
PInt *TypeSInt8, *TypeUInt8;
PInt *TypeSInt16, *TypeUInt16;
PInt *TypeSInt32, *TypeUInt32;
PFloat *TypeFloat32, *TypeFloat64;
PString *TypeString;
PName *TypeName;
PSound *TypeSound;
PColor *TypeColor;
// PRIVATE DATA DEFINITIONS ------------------------------------------------
// A harmless non-NULL FlatPointer for classes without pointers.
@ -159,11 +169,13 @@ PClassClass::PClassClass()
/* PType ******************************************************************/
IMPLEMENT_ABSTRACT_CLASS(PType)
IMPLEMENT_ABSTRACT_POINTY_CLASS(PType)
DECLARE_POINTER(HashNext)
END_POINTERS
//==========================================================================
//
// PType Constructor
// PType Default Constructor
//
//==========================================================================
@ -172,6 +184,17 @@ PType::PType()
{
}
//==========================================================================
//
// PType Parameterized Constructor
//
//==========================================================================
PType::PType(unsigned int size, unsigned int align)
: Size(size), Align(align), HashNext(NULL)
{
}
//==========================================================================
//
// PType Destructor
@ -193,11 +216,23 @@ bool PType::IsMatch(const void *id1, const void *id2) const
return false;
}
//==========================================================================
//
// PType :: GetTypeIDs
//
//==========================================================================
void PType::GetTypeIDs(const void *&id1, const void *&id2) const
{
id1 = NULL;
id2 = NULL;
}
//==========================================================================
//
// PType :: StaticInit STATIC
//
// Set up TypeTableType values for every PType child.
// Set up TypeTableType values for every PType child and create basic types.
//
//==========================================================================
@ -220,6 +255,20 @@ void PType::StaticInit()
RUNTIME_CLASS(PPrototype)->TypeTableType = RUNTIME_CLASS(PPrototype);
RUNTIME_CLASS(PFunction)->TypeTableType = RUNTIME_CLASS(PFunction);
RUNTIME_CLASS(PClass)->TypeTableType = RUNTIME_CLASS(PClass);
TypeTable.AddType(TypeSInt8 = new PInt(1, false));
TypeTable.AddType(TypeUInt8 = new PInt(1, true));
TypeTable.AddType(TypeSInt16 = new PInt(2, false));
TypeTable.AddType(TypeUInt16 = new PInt(2, true));
TypeTable.AddType(TypeSInt32 = new PInt(4, false));
TypeTable.AddType(TypeUInt32 = new PInt(4, true));
TypeTable.AddType(TypeFloat32 = new PFloat(4));
TypeTable.AddType(TypeFloat64 = new PFloat(8));
TypeTable.AddType(TypeString = new PString);
TypeTable.AddType(TypeName = new PName);
TypeTable.AddType(TypeSound = new PSound);
TypeTable.AddType(TypeColor = new PColor);
}
@ -227,6 +276,27 @@ void PType::StaticInit()
IMPLEMENT_ABSTRACT_CLASS(PBasicType)
//==========================================================================
//
// PBasicType Default Constructor
//
//==========================================================================
PBasicType::PBasicType()
{
}
//==========================================================================
//
// PBasicType Parameterized Constructor
//
//==========================================================================
PBasicType::PBasicType(unsigned int size, unsigned int align)
: PType(size, align)
{
}
/* PCompoundType **********************************************************/
IMPLEMENT_ABSTRACT_CLASS(PCompoundType)
@ -251,30 +321,133 @@ bool PNamedType::IsMatch(const void *id1, const void *id2) const
return Outer == outer && TypeName == name;
}
//==========================================================================
//
// PNamedType :: GetTypeIDs
//
//==========================================================================
void PNamedType::GetTypeIDs(const void *&id1, const void *&id2) const
{
id1 = Outer;
id2 = (void *)(intptr_t)TypeName;
}
/* PInt *******************************************************************/
IMPLEMENT_CLASS(PInt)
//==========================================================================
//
// PInt Default Constructor
//
//==========================================================================
PInt::PInt()
: PBasicType(4, 4)
{
}
//==========================================================================
//
// PInt Parameterized Constructor
//
//==========================================================================
PInt::PInt(unsigned int size, bool unsign)
: PBasicType(size, size), Unsigned(unsign)
{
}
/* PFloat *****************************************************************/
IMPLEMENT_CLASS(PFloat)
//==========================================================================
//
// PFloat Default Constructor
//
//==========================================================================
PFloat::PFloat()
: PBasicType(4, 4)
{
}
//==========================================================================
//
// PFloat Parameterized Constructor
//
//==========================================================================
PFloat::PFloat(unsigned int size)
: PBasicType(size, size)
{
}
/* PString ****************************************************************/
IMPLEMENT_CLASS(PString)
//==========================================================================
//
// PString Default Constructor
//
//==========================================================================
PString::PString()
: PBasicType(sizeof(FString), __alignof(FString))
{
}
/* PName ******************************************************************/
IMPLEMENT_CLASS(PName)
//==========================================================================
//
// PName Default Constructor
//
//==========================================================================
PName::PName()
: PInt(sizeof(FName), true)
{
assert(sizeof(FName) == __alignof(FName));
}
/* PSound *****************************************************************/
IMPLEMENT_CLASS(PSound)
//==========================================================================
//
// PSound Default Constructor
//
//==========================================================================
PSound::PSound()
: PInt(sizeof(FSoundID), true)
{
assert(sizeof(FSoundID) == __alignof(FSoundID));
}
/* PColor *****************************************************************/
IMPLEMENT_CLASS(PColor)
//==========================================================================
//
// PColor Default Constructor
//
//==========================================================================
PColor::PColor()
: PInt(sizeof(PalEntry), true)
{
assert(sizeof(PalEntry) == __alignof(PalEntry));
}
/* PPointer ***************************************************************/
IMPLEMENT_POINTY_CLASS(PPointer)
@ -295,6 +468,19 @@ bool PPointer::IsMatch(const void *id1, const void *id2) const
return pointat == PointedType;
}
//==========================================================================
//
// PPointer :: GetTypeIDs
//
//==========================================================================
void PPointer::GetTypeIDs(const void *&id1, const void *&id2) const
{
id1 = PointedType;
id2 = NULL;
}
/* PClassPointer **********************************************************/
IMPLEMENT_POINTY_CLASS(PClassPointer)
@ -316,6 +502,20 @@ bool PClassPointer::IsMatch(const void *id1, const void *id2) const
return classat == ClassRestriction;
}
//==========================================================================
//
// PClassPointer :: GetTypeIDs
//
//==========================================================================
void PClassPointer::GetTypeIDs(const void *&id1, const void *&id2) const
{
assert(PointedType == RUNTIME_CLASS(PClass));
id1 = PointedType;
id2 = ClassRestriction;
}
/* PEnum ******************************************************************/
IMPLEMENT_POINTY_CLASS(PEnum)
@ -342,6 +542,18 @@ bool PArray::IsMatch(const void *id1, const void *id2) const
return elemtype == ElementType && count == ElementCount;
}
//==========================================================================
//
// PArray :: GetTypeIDs
//
//==========================================================================
void PArray::GetTypeIDs(const void *&id1, const void *&id2) const
{
id1 = ElementType;
id2 = (void *)(intptr_t)ElementCount;
}
/* PVector ****************************************************************/
IMPLEMENT_CLASS(PVector)
@ -352,6 +564,12 @@ IMPLEMENT_POINTY_CLASS(PDynArray)
DECLARE_POINTER(ElementType)
END_POINTERS
//==========================================================================
//
// PDynArray :: IsMatch
//
//==========================================================================
bool PDynArray::IsMatch(const void *id1, const void *id2) const
{
assert(id2 == NULL);
@ -360,6 +578,19 @@ bool PDynArray::IsMatch(const void *id1, const void *id2) const
return elemtype == ElementType;
}
//==========================================================================
//
// PDynArray :: GetTypeIDs
//
//==========================================================================
void PDynArray::GetTypeIDs(const void *&id1, const void *&id2) const
{
id1 = ElementType;
id2 = NULL;
}
/* PMap *******************************************************************/
IMPLEMENT_POINTY_CLASS(PMap)
@ -381,6 +612,18 @@ bool PMap::IsMatch(const void *id1, const void *id2) const
return keyty == KeyType && valty == ValueType;
}
//==========================================================================
//
// PMap :: GetTypeIDs
//
//==========================================================================
void PMap::GetTypeIDs(const void *&id1, const void *&id2) const
{
id1 = KeyType;
id2 = ValueType;
}
/* PStruct ****************************************************************/
IMPLEMENT_CLASS(PStruct)
@ -415,6 +658,18 @@ bool PPrototype::IsMatch(const void *id1, const void *id2) const
return *args == ArgumentTypes && *rets == ReturnTypes;
}
//==========================================================================
//
// PPrototype :: GetTypeIDs
//
//==========================================================================
void PPrototype::GetTypeIDs(const void *&id1, const void *&id2) const
{
id1 = &ArgumentTypes;
id2 = &ReturnTypes;
}
//==========================================================================
//
// PPrototype :: PropagateMark
@ -970,7 +1225,7 @@ size_t PClass::PropagateMark()
//
//==========================================================================
PType *FTypeTable::FindType(PClass *metatype, void *parm1, void *parm2, size_t *bucketnum)
PType *FTypeTable::FindType(PClass *metatype, const void *parm1, const void *parm2, size_t *bucketnum)
{
size_t bucket = Hash(metatype, parm1, parm2) % HASH_SIZE;
if (bucketnum != NULL)
@ -989,11 +1244,11 @@ PType *FTypeTable::FindType(PClass *metatype, void *parm1, void *parm2, size_t *
//==========================================================================
//
// FTypeTable :: AddType
// FTypeTable :: AddType - Fully Parameterized Version
//
//==========================================================================
void FTypeTable::AddType(PType *type, PClass *metatype, void *parm1, void *parm2, size_t bucket)
void FTypeTable::AddType(PType *type, PClass *metatype, const void *parm1, const void *parm2, size_t bucket)
{
#ifdef _DEBUG
size_t bucketcheck;
@ -1003,6 +1258,29 @@ void FTypeTable::AddType(PType *type, PClass *metatype, void *parm1, void *parm2
#endif
type->HashNext = TypeHash[bucket];
TypeHash[bucket] = type;
GC::WriteBarrier(type);
}
//==========================================================================
//
// FTypeTable :: AddType - Simple Version
//
//==========================================================================
void FTypeTable::AddType(PType *type)
{
PClass *metatype;
const void *parm1, *parm2;
size_t bucket;
metatype = type->GetClass()->TypeTableType;
type->GetTypeIDs(parm1, parm2);
bucket = Hash(metatype, parm1, parm2) % HASH_SIZE;
assert(FindType(metatype, parm1, parm2, NULL) == NULL && "Type must not be inserted more than once");
type->HashNext = TypeHash[bucket];
TypeHash[bucket] = type;
GC::WriteBarrier(type);
}
//==========================================================================
@ -1011,7 +1289,7 @@ void FTypeTable::AddType(PType *type, PClass *metatype, void *parm1, void *parm2
//
//==========================================================================
size_t FTypeTable::Hash(void *p1, void *p2, void *p3)
size_t FTypeTable::Hash(const void *p1, const void *p2, const void *p3)
{
size_t i1 = (size_t)p1;
size_t i2 = (size_t)p2;
@ -1024,6 +1302,25 @@ size_t FTypeTable::Hash(void *p1, void *p2, void *p3)
return (~i1 ^ i2) + i3 * 961748927; // i3 is multiplied by a prime
}
//==========================================================================
//
// FTypeTable :: Mark
//
// Mark all types in this table for the garbage collector.
//
//==========================================================================
void FTypeTable::Mark()
{
for (int i = HASH_SIZE - 1; i >= 0; --i)
{
if (TypeHash[i] != NULL)
{
GC::Mark(TypeHash[i]);
}
}
}
#include "c_dispatch.h"
CCMD(typetable)
{

View file

@ -172,6 +172,7 @@ class PType : public DObject
// and we can't define it until we've defined PClass. But we can't define that
// without defining PType.
DECLARE_ABSTRACT_CLASS(PType, DObject)
HAS_OBJECT_POINTERS;
protected:
enum { MetaClassNum = CLASSREG_PClassType };
public:
@ -183,6 +184,7 @@ public:
PType *HashNext; // next type in this type table
PType();
PType(unsigned int size, unsigned int align);
virtual ~PType();
// Returns true if this type matches the two identifiers. Referring to the
@ -193,6 +195,9 @@ public:
// management.
virtual bool IsMatch(const void *id1, const void *id2) const;
// Get the type IDs used by IsMatch
virtual void GetTypeIDs(const void *&id1, const void *&id2) const;
static void StaticInit();
};
@ -201,6 +206,9 @@ public:
class PBasicType : public PType
{
DECLARE_ABSTRACT_CLASS(PBasicType, PType);
public:
PBasicType();
PBasicType(unsigned int size, unsigned int align);
};
class PCompoundType : public PType
@ -219,6 +227,7 @@ public:
PNamedType() : Outer(NULL) {}
virtual bool IsMatch(const void *id1, const void *id2) const;
virtual void GetTypeIDs(const void *&id1, const void *&id2) const;
};
// Basic types --------------------------------------------------------------
@ -226,16 +235,28 @@ public:
class PInt : public PBasicType
{
DECLARE_CLASS(PInt, PBasicType);
public:
PInt(unsigned int size, bool unsign);
bool Unsigned;
protected:
PInt();
};
class PFloat : public PBasicType
{
DECLARE_CLASS(PFloat, PBasicType);
public:
PFloat(unsigned int size);
protected:
PFloat();
};
class PString : public PBasicType
{
DECLARE_CLASS(PString, PBasicType);
public:
PString();
};
// Variations of integer types ----------------------------------------------
@ -243,16 +264,22 @@ class PString : public PBasicType
class PName : public PInt
{
DECLARE_CLASS(PName, PInt);
public:
PName();
};
class PSound : public PInt
{
DECLARE_CLASS(PSound, PInt);
public:
PSound();
};
class PColor : public PInt
{
DECLARE_CLASS(PColor, PInt);
public:
PColor();
};
// Pointers -----------------------------------------------------------------
@ -265,6 +292,7 @@ public:
PType *PointedType;
virtual bool IsMatch(const void *id1, const void *id2) const;
virtual void GetTypeIDs(const void *&id1, const void *&id2) const;
};
class PClass;
@ -278,6 +306,7 @@ public:
typedef PClass *Type2;
virtual bool IsMatch(const void *id1, const void *id2) const;
virtual void GetTypeIDs(const void *&id1, const void *&id2) const;
};
// Struct/class fields ------------------------------------------------------
@ -318,6 +347,7 @@ public:
unsigned int ElementCount;
virtual bool IsMatch(const void *id1, const void *id2) const;
virtual void GetTypeIDs(const void *&id1, const void *&id2) const;
};
// A vector is an array with extra operations.
@ -335,6 +365,7 @@ public:
PType *ElementType;
virtual bool IsMatch(const void *id1, const void *id2) const;
virtual void GetTypeIDs(const void *&id1, const void *&id2) const;
};
class PMap : public PCompoundType
@ -346,6 +377,7 @@ public:
PType *ValueType;
virtual bool IsMatch(const void *id1, const void *id2) const;
virtual void GetTypeIDs(const void *&id1, const void *&id2) const;
};
class PStruct : public PNamedType
@ -366,9 +398,10 @@ public:
size_t PropagateMark();
virtual bool IsMatch(const void *id1, const void *id2) const;
virtual void GetTypeIDs(const void *&id1, const void *&id2) const;
};
// TBD: Should we support overloading?
// TBD: Should we really support overloading?
class PFunction : public PNamedType
{
DECLARE_CLASS(PFunction, PNamedType);
@ -492,10 +525,12 @@ struct FTypeTable
PType *TypeHash[HASH_SIZE];
PType *FindType(PClass *metatype, void *parm1, void *parm2, size_t *bucketnum);
void AddType(PType *type, PClass *metatype, void *parm1, void *parm2, size_t bucket);
PType *FindType(PClass *metatype, const void *parm1, const void *parm2, size_t *bucketnum);
void AddType(PType *type, PClass *metatype, const void *parm1, const void *parm2, size_t bucket);
void AddType(PType *type);
void Mark();
static size_t Hash(void *p1, void *p2, void *p3);
static size_t Hash(const void *p1, const void *p2, const void *p3);
};