- fixed: Script defined pointers were not added to the FlatPointers array.

This commit is contained in:
Christoph Oelckers 2016-11-17 22:21:08 +01:00
parent e4dfb13d25
commit 6461f5995b
2 changed files with 98 additions and 14 deletions

View file

@ -419,6 +419,16 @@ void PType::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset>
{ {
} }
//==========================================================================
//
// PType :: SetDefaultValue
//
//==========================================================================
void PType::SetPointer(void *base, unsigned offset, TArray<size_t> *stroffs) const
{
}
//========================================================================== //==========================================================================
// //
// PType :: InitializeValue // PType :: InitializeValue
@ -1550,6 +1560,21 @@ void PPointer::GetTypeIDs(intptr_t &id1, intptr_t &id2) const
id2 = 0; id2 = 0;
} }
//==========================================================================
//
// PPointer :: SetDefaultValue
//
//==========================================================================
void PPointer::SetPointer(void *base, unsigned offset, TArray<size_t> *special) const
{
if (PointedType != nullptr && PointedType->IsKindOf(RUNTIME_CLASS(PClass)))
{
// Add to the list of pointers for this class.
special->Push(offset);
}
}
//========================================================================== //==========================================================================
// //
// PPointer :: WriteValue // PPointer :: WriteValue
@ -1869,6 +1894,20 @@ void PArray::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset>
} }
} }
//==========================================================================
//
// PArray :: SetDefaultValue
//
//==========================================================================
void PArray::SetPointer(void *base, unsigned offset, TArray<size_t> *special) const
{
for (unsigned i = 0; i < ElementCount; ++i)
{
ElementType->SetPointer(base, offset + i*ElementSize, special);
}
}
//========================================================================== //==========================================================================
// //
// NewArray // NewArray
@ -2104,6 +2143,23 @@ void PStruct::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset
} }
} }
//==========================================================================
//
// PStruct :: SetPointer
//
//==========================================================================
void PStruct::SetPointer(void *base, unsigned offset, TArray<size_t> *special) const
{
for (const PField *field : Fields)
{
if (!(field->Flags & VARF_Native))
{
field->Type->SetPointer(base, unsigned(offset + field->Offset), special);
}
}
}
//========================================================================== //==========================================================================
// //
// PStruct :: WriteValue // PStruct :: WriteValue
@ -3045,14 +3101,9 @@ void PClass::InitializeDefaults()
assert(ParentClass != NULL); assert(ParentClass != NULL);
ParentClass->InitializeSpecials(Defaults); ParentClass->InitializeSpecials(Defaults);
// and initialize our own special values. for (const PField *field : Fields)
auto it = Symbols.GetIterator();
PSymbolTable::MapType::Pair *pair;
while (it.NextPair(pair))
{ {
auto field = dyn_cast<PField>(pair->Value); if (!(field->Flags & VARF_Native))
if (field != nullptr && !(field->Flags & VARF_Native))
{ {
field->Type->SetDefaultValue(Defaults, unsigned(field->Offset), &SpecialInits); field->Type->SetDefaultValue(Defaults, unsigned(field->Offset), &SpecialInits);
} }
@ -3270,7 +3321,7 @@ void PClass::BuildFlatPointers ()
return; return;
} }
else if (ParentClass == NULL) else if (ParentClass == NULL)
{ // No parent: FlatPointers is the same as Pointers. { // No parent (i.e. DObject: FlatPointers is the same as Pointers.
if (Pointers == NULL) if (Pointers == NULL)
{ // No pointers: Make FlatPointers a harmless non-NULL. { // No pointers: Make FlatPointers a harmless non-NULL.
FlatPointers = &TheEnd; FlatPointers = &TheEnd;
@ -3283,7 +3334,19 @@ void PClass::BuildFlatPointers ()
else else
{ {
ParentClass->BuildFlatPointers (); ParentClass->BuildFlatPointers ();
if (Pointers == NULL)
TArray<size_t> ScriptPointers;
// Collect all pointers in scripted fields. These are not part of the Pointers list.
for (auto field : Fields)
{
if (!(field->Flags & VARF_Native))
{
field->Type->SetPointer(Defaults, unsigned(field->Offset), &ScriptPointers);
}
}
if (Pointers == nullptr && ScriptPointers.Size() == 0)
{ // No new pointers: Just use the same FlatPointers as the parent. { // No new pointers: Just use the same FlatPointers as the parent.
FlatPointers = ParentClass->FlatPointers; FlatPointers = ParentClass->FlatPointers;
} }
@ -3291,20 +3354,34 @@ void PClass::BuildFlatPointers ()
{ // New pointers: Create a new FlatPointers array and add them. { // New pointers: Create a new FlatPointers array and add them.
int numPointers, numSuperPointers; int numPointers, numSuperPointers;
// Count pointers defined by this class. if (Pointers != nullptr)
for (numPointers = 0; Pointers[numPointers] != ~(size_t)0; numPointers++) {
{ } // Count pointers defined by this class.
for (numPointers = 0; Pointers[numPointers] != ~(size_t)0; numPointers++)
{
}
}
else numPointers = 0;
// Count pointers defined by superclasses. // Count pointers defined by superclasses.
for (numSuperPointers = 0; ParentClass->FlatPointers[numSuperPointers] != ~(size_t)0; numSuperPointers++) for (numSuperPointers = 0; ParentClass->FlatPointers[numSuperPointers] != ~(size_t)0; numSuperPointers++)
{ } { }
// Concatenate them into a new array // Concatenate them into a new array
size_t *flat = new size_t[numPointers + numSuperPointers + 1]; size_t *flat = new size_t[numPointers + numSuperPointers + ScriptPointers.Size() + 1];
if (numSuperPointers > 0) if (numSuperPointers > 0)
{ {
memcpy (flat, ParentClass->FlatPointers, sizeof(size_t)*numSuperPointers); memcpy (flat, ParentClass->FlatPointers, sizeof(size_t)*numSuperPointers);
} }
memcpy (flat + numSuperPointers, Pointers, sizeof(size_t)*(numPointers+1)); if (numPointers > 0)
{
memcpy(flat + numSuperPointers, Pointers, sizeof(size_t)*numPointers);
}
if (ScriptPointers.Size() > 0)
{
memcpy(flat + numSuperPointers + numPointers, &ScriptPointers[0], sizeof(size_t) * ScriptPointers.Size());
}
flat[numSuperPointers + numPointers + ScriptPointers.Size()] = ~(size_t)0;
FlatPointers = flat; FlatPointers = flat;
} }
} }

View file

@ -252,6 +252,7 @@ public:
// initialization when the object is created and destruction when the // initialization when the object is created and destruction when the
// object is destroyed. // object is destroyed.
virtual void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special=NULL) const; virtual void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special=NULL) const;
virtual void SetPointer(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL) const;
// Initialize the value, if needed (e.g. strings) // Initialize the value, if needed (e.g. strings)
virtual void InitializeValue(void *addr, const void *def) const; virtual void InitializeValue(void *addr, const void *def) const;
@ -552,6 +553,7 @@ public:
virtual bool IsMatch(intptr_t id1, intptr_t id2) const; virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const; virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) const override;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override; void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override; bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
@ -569,6 +571,9 @@ public:
class PClass *ClassRestriction; class PClass *ClassRestriction;
// this is only here to block PPointer's implementation
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) const override {}
virtual bool IsMatch(intptr_t id1, intptr_t id2) const; virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const; virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
protected: protected:
@ -626,6 +631,7 @@ public:
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override; bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special) const override; void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special) const override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *special) const override;
protected: protected:
PArray(); PArray();
@ -679,6 +685,7 @@ public:
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override; void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override; bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *specials) const override; void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *specials) const override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *specials) const override;
static void WriteFields(FSerializer &ar, const void *addr, const TArray<PField *> &fields); static void WriteFields(FSerializer &ar, const void *addr, const TArray<PField *> &fields);
bool ReadFields(FSerializer &ar, void *addr) const; bool ReadFields(FSerializer &ar, void *addr) const;