Store type together with pointers to allow safe substitution

This commit is contained in:
Ricardo Luís Vaz Silva 2024-03-13 14:22:19 -03:00 committed by Rachael Alexanderson
parent 6b7065899d
commit e85ec240bf
5 changed files with 216 additions and 174 deletions

View file

@ -363,54 +363,49 @@ size_t DObject::PropagateMark()
const PClass *info = GetClass();
if (!PClass::bShutdown)
{
const size_t *offsets = info->FlatPointers;
if (offsets == NULL)
if (info->FlatPointers == nullptr)
{
const_cast<PClass *>(info)->BuildFlatPointers();
offsets = info->FlatPointers;
}
while (*offsets != ~(size_t)0)
{
GC::Mark((DObject **)((uint8_t *)this + *offsets));
offsets++;
info->BuildFlatPointers();
assert(info->FlatPointers);
}
offsets = info->ArrayPointers;
if (offsets == NULL)
for(size_t i = 0; i < info->FlatPointersSize; i++)
{
const_cast<PClass *>(info)->BuildArrayPointers();
offsets = info->ArrayPointers;
GC::Mark((DObject **)((uint8_t *)this + info->FlatPointers[i].first));
}
while (*offsets != ~(size_t)0)
if (info->ArrayPointers == nullptr)
{
auto aray = (TArray<DObject*>*)((uint8_t *)this + *offsets);
info->BuildArrayPointers();
assert(info->ArrayPointers);
}
for(size_t i = 0; i < info->ArrayPointersSize; i++)
{
auto aray = (TArray<DObject*>*)((uint8_t *)this + info->ArrayPointers[i].first);
for (auto &p : *aray)
{
GC::Mark(&p);
}
offsets++;
}
if (info->MapPointers == nullptr)
{
const std::pair<size_t,PType *> *maps = info->MapPointers;
if (maps == NULL)
{
const_cast<PClass *>(info)->BuildMapPointers();
maps = info->MapPointers;
}
while (maps->first != ~(size_t)0)
{
if(maps->second->RegType == REGT_STRING)
{ // FString,DObject*
PropagateMarkMap((ZSMap<FString,DObject*>*)((uint8_t *)this + maps->first));
}
else
{ // uint32_t,DObject*
PropagateMarkMap((ZSMap<uint32_t,DObject*>*)((uint8_t *)this + maps->first));
}
maps++;
}
info->BuildMapPointers();
assert(info->MapPointers);
}
for(size_t i = 0; i < info->MapPointersSize; i++)
{
PMap * type = static_cast<PMap*>(info->MapPointers[i].second);
if(type->KeyType->RegType == REGT_STRING)
{ // FString,DObject*
PropagateMarkMap((ZSMap<FString,DObject*>*)((uint8_t *)this + info->MapPointers[i].first));
}
else
{ // uint32_t,DObject*
PropagateMarkMap((ZSMap<uint32_t,DObject*>*)((uint8_t *)this + info->MapPointers[i].first));
}
}
return info->Size;
}
@ -423,35 +418,51 @@ size_t DObject::PropagateMark()
//
//==========================================================================
template<typename M>
static void MapPointerSubstitution(M *map, size_t &changed, DObject *old, DObject *notOld)
{
TMapIterator<typename M::KeyType, DObject*> it(*map);
typename M::Pair * p;
while(it.NextPair(p))
{
if (p->Value == old)
{
p->Value = notOld;
changed++;
}
}
}
size_t DObject::PointerSubstitution (DObject *old, DObject *notOld)
{
const PClass *info = GetClass();
const size_t *offsets = info->FlatPointers;
size_t changed = 0;
if (offsets == NULL)
if (info->FlatPointers == nullptr)
{
const_cast<PClass *>(info)->BuildFlatPointers();
offsets = info->FlatPointers;
}
while (*offsets != ~(size_t)0)
{
if (*(DObject **)((uint8_t *)this + *offsets) == old)
{
*(DObject **)((uint8_t *)this + *offsets) = notOld;
changed++;
}
offsets++;
info->BuildFlatPointers();
assert(info->FlatPointers);
}
offsets = info->ArrayPointers;
if (offsets == NULL)
for(size_t i = 0; i < info->FlatPointersSize; i++)
{
const_cast<PClass *>(info)->BuildArrayPointers();
offsets = info->ArrayPointers;
size_t offset = info->FlatPointers[i].first;
if (*(DObject **)((uint8_t *)this + offset) == old)
{
*(DObject **)((uint8_t *)this + offset) = notOld;
changed++;
}
}
while (*offsets != ~(size_t)0)
if (info->ArrayPointers == nullptr)
{
auto aray = (TArray<DObject*>*)((uint8_t *)this + *offsets);
info->BuildArrayPointers();
assert(info->ArrayPointers);
}
for(size_t i = 0; i < info->ArrayPointersSize; i++)
{
auto aray = (TArray<DObject*>*)((uint8_t *)this + info->ArrayPointers[i].first);
for (auto &p : *aray)
{
if (p == old)
@ -460,9 +471,26 @@ size_t DObject::PointerSubstitution (DObject *old, DObject *notOld)
changed++;
}
}
offsets++;
}
if (info->MapPointers == nullptr)
{
info->BuildMapPointers();
assert(info->MapPointers);
}
for(size_t i = 0; i < info->MapPointersSize; i++)
{
PMap * type = static_cast<PMap*>(info->MapPointers[i].second);
if(type->KeyType->RegType == REGT_STRING)
{ // FString,DObject*
MapPointerSubstitution((ZSMap<FString,DObject*>*)((uint8_t *)this + info->MapPointers[i].first), changed, old, notOld);
}
else
{ // uint32_t,DObject*
MapPointerSubstitution((ZSMap<uint32_t,DObject*>*)((uint8_t *)this + info->MapPointers[i].first), changed, old, notOld);
}
}
return changed;
}

View file

@ -80,9 +80,7 @@ DEFINE_GLOBAL(WP_NOCHANGE);
// PRIVATE DATA DEFINITIONS ------------------------------------------------
// A harmless non-nullptr FlatPointer for classes without pointers.
static const size_t TheEnd = ~(size_t)0;
static const std::pair<size_t,PType *> TheMapEnd = {~(size_t)0 , nullptr};
static const std::pair<size_t,PType *> TheEnd = {~(size_t)0 , nullptr};
//==========================================================================
//
@ -768,75 +766,81 @@ PSymbol *PClass::FindSymbol(FName symname, bool searchparents) const
//
//==========================================================================
void PClass::BuildFlatPointers ()
void PClass::BuildFlatPointers() const
{
using pairType = std::pair<size_t, PObjectPointer *>;
if (FlatPointers != nullptr)
{ // Already built: Do nothing.
return;
}
else if (ParentClass == nullptr)
{ // No parent (i.e. DObject: FlatPointers is the same as Pointers.
if (Pointers == nullptr)
{ // No pointers: Make FlatPointers a harmless non-nullptr.
FlatPointers = &TheEnd;
}
else
{
FlatPointers = Pointers;
}
}
else
{
ParentClass->BuildFlatPointers ();
TArray<size_t> ScriptPointers;
// Collect all pointers in scripted fields. These are not part of the Pointers list.
for (auto field : Fields)
TArray<pairType> NativePointers;
if (Pointers != nullptr)
{
if (!(field->Flags & VARF_Native))
for (size_t i = 0; Pointers[i] != ~(size_t)0; i++)
{
field->Type->SetPointer(Defaults, unsigned(field->Offset), &ScriptPointers);
NativePointers.Push({Pointers[i], nullptr}); // native pointers have a null type
}
}
if (Pointers == nullptr && ScriptPointers.Size() == 0)
{ // No new pointers: Just use the same FlatPointers as the parent.
FlatPointers = ParentClass->FlatPointers;
if (ParentClass == nullptr)
{ // No parent (i.e. DObject): FlatPointers is the same as Pointers.
if (NativePointers.Size() == 0)
{ // No pointers: Make FlatPointers a harmless non-nullptr.
FlatPointers = (pairType*)(&TheEnd);
FlatPointersSize = 0;
}
else
{
pairType *flat = (pairType*)ClassDataAllocator.Alloc(sizeof(pairType) * NativePointers.Size());
memcpy(flat, NativePointers.Data(), sizeof(pairType) * NativePointers.Size());
FlatPointers = flat;
FlatPointersSize = NativePointers.Size();
}
}
else
{ // New pointers: Create a new FlatPointers array and add them.
int numPointers, numSuperPointers;
{
ParentClass->BuildFlatPointers();
if (Pointers != nullptr)
TArray<pairType> ScriptPointers;
// Collect all pointers in scripted fields. These are not part of the Pointers list.
for (auto field : Fields)
{
// Count pointers defined by this class.
for (numPointers = 0; Pointers[numPointers] != ~(size_t)0; numPointers++)
if (!(field->Flags & VARF_Native))
{
field->Type->SetPointer(Defaults, unsigned(field->Offset), &ScriptPointers);
}
}
else numPointers = 0;
// Count pointers defined by superclasses.
for (numSuperPointers = 0; ParentClass->FlatPointers[numSuperPointers] != ~(size_t)0; numSuperPointers++)
{ }
if (NativePointers.Size() == 0 && ScriptPointers.Size() == 0)
{ // No new pointers: Just use the same FlatPointers as the parent.
FlatPointers = ParentClass->FlatPointers;
FlatPointersSize = ParentClass->FlatPointersSize;
}
else
{ // New pointers: Create a new FlatPointers array and add them.
// Concatenate them into a new array
pairType *flat = (pairType*)ClassDataAllocator.Alloc(sizeof(pairType) * (ParentClass->FlatPointersSize + NativePointers.Size() + ScriptPointers.Size()));
// Concatenate them into a new array
size_t *flat = (size_t*)ClassDataAllocator.Alloc(sizeof(size_t) * (numPointers + numSuperPointers + ScriptPointers.Size() + 1));
if (numSuperPointers > 0)
{
memcpy (flat, ParentClass->FlatPointers, sizeof(size_t)*numSuperPointers);
if (ParentClass->FlatPointersSize > 0)
{
memcpy (flat, ParentClass->FlatPointers, sizeof(pairType) * ParentClass->FlatPointersSize);
}
if (NativePointers.Size() > 0)
{
memcpy(flat + ParentClass->FlatPointersSize, NativePointers.Data(), sizeof(pairType) * NativePointers.Size());
}
if (ScriptPointers.Size() > 0)
{
memcpy(flat + ParentClass->FlatPointersSize + NativePointers.Size(), &ScriptPointers[0], sizeof(pairType) * ScriptPointers.Size());
}
FlatPointers = flat;
FlatPointersSize = ParentClass->FlatPointersSize + NativePointers.Size() + ScriptPointers.Size();
}
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;
}
}
}
@ -849,21 +853,24 @@ void PClass::BuildFlatPointers ()
//
//==========================================================================
void PClass::BuildArrayPointers()
void PClass::BuildArrayPointers() const
{
using pairType = std::pair<size_t, PDynArray *>;
if (ArrayPointers != nullptr)
{ // Already built: Do nothing.
return;
}
else if (ParentClass == nullptr)
{ // No parent (i.e. DObject: FlatPointers is the same as Pointers.
ArrayPointers = &TheEnd;
{ // No parent (i.e. DObject): Make ArrayPointers a harmless non-nullptr.
ArrayPointers = (pairType*)(&TheEnd);
ArrayPointersSize = 0;
}
else
{
ParentClass->BuildArrayPointers();
TArray<size_t> ScriptPointers;
TArray<pairType> ScriptPointers;
// Collect all arrays to pointers in scripted fields.
for (auto field : Fields)
@ -877,28 +884,24 @@ void PClass::BuildArrayPointers()
if (ScriptPointers.Size() == 0)
{ // No new pointers: Just use the same ArrayPointers as the parent.
ArrayPointers = ParentClass->ArrayPointers;
ArrayPointersSize = ParentClass->ArrayPointersSize;
}
else
{ // New pointers: Create a new FlatPointers array and add them.
int numSuperPointers;
// Count pointers defined by superclasses.
for (numSuperPointers = 0; ParentClass->ArrayPointers[numSuperPointers] != ~(size_t)0; numSuperPointers++)
{
}
{ // New pointers: Create a new ArrayPointers array and add them.
// Concatenate them into a new array
size_t *flat = (size_t*)ClassDataAllocator.Alloc(sizeof(size_t) * (numSuperPointers + ScriptPointers.Size() + 1));
if (numSuperPointers > 0)
pairType *flat = (pairType*)ClassDataAllocator.Alloc(sizeof(pairType) * (ParentClass->ArrayPointersSize + ScriptPointers.Size()));
if (ParentClass->ArrayPointersSize > 0)
{
memcpy(flat, ParentClass->ArrayPointers, sizeof(size_t)*numSuperPointers);
memcpy(flat, ParentClass->ArrayPointers, sizeof(pairType) * ParentClass->ArrayPointersSize);
}
if (ScriptPointers.Size() > 0)
{
memcpy(flat + numSuperPointers, &ScriptPointers[0], sizeof(size_t) * ScriptPointers.Size());
memcpy(flat + ParentClass->ArrayPointersSize, ScriptPointers.Data(), sizeof(pairType) * ScriptPointers.Size());
}
flat[numSuperPointers + ScriptPointers.Size()] = ~(size_t)0;
ArrayPointers = flat;
ArrayPointersSize = ParentClass->ArrayPointersSize + ScriptPointers.Size();
}
}
}
@ -911,21 +914,24 @@ void PClass::BuildArrayPointers()
//
//==========================================================================
void PClass::BuildMapPointers()
void PClass::BuildMapPointers() const
{
using pairType = std::pair<size_t, PMap *>;
if (MapPointers != nullptr)
{ // Already built: Do nothing.
return;
}
else if (ParentClass == nullptr)
{ // No parent (i.e. DObject: FlatPointers is the same as Pointers.
MapPointers = &TheMapEnd;
{ // No parent (i.e. DObject): Make MapPointers a harmless non-nullptr.
MapPointers = (pairType*)(&TheEnd);
MapPointersSize = 0;
}
else
{
ParentClass->BuildMapPointers();
TArray<std::pair<size_t,PType *>> ScriptPointers;
TArray<pairType> ScriptPointers;
// Collect all arrays to pointers in scripted fields.
for (auto field : Fields)
@ -939,28 +945,23 @@ void PClass::BuildMapPointers()
if (ScriptPointers.Size() == 0)
{ // No new pointers: Just use the same ArrayPointers as the parent.
MapPointers = ParentClass->MapPointers;
MapPointersSize = ParentClass->MapPointersSize;
}
else
{ // New pointers: Create a new FlatPointers array and add them.
int numSuperPointers;
// Count pointers defined by superclasses.
for (numSuperPointers = 0; ParentClass->MapPointers[numSuperPointers].first != ~(size_t)0; numSuperPointers++)
{
}
{ // New pointers: Create a new FlatPointers array and add them.
// Concatenate them into a new array
std::pair<size_t,PType *> *flat = (std::pair<size_t,PType *>*)ClassDataAllocator.Alloc(sizeof(std::pair<size_t,PType *>) * (numSuperPointers + ScriptPointers.Size() + 1));
if (numSuperPointers > 0)
pairType *flat = (pairType*)ClassDataAllocator.Alloc(sizeof(pairType) * (ParentClass->MapPointersSize + ScriptPointers.Size()));
if (ParentClass->MapPointersSize > 0)
{
memcpy(flat, ParentClass->MapPointers, sizeof(std::pair<size_t,PType *>)*numSuperPointers);
memcpy(flat, ParentClass->MapPointers, sizeof(pairType) * ParentClass->MapPointersSize);
}
if (ScriptPointers.Size() > 0)
{
memcpy(flat + numSuperPointers, &ScriptPointers[0], sizeof(std::pair<size_t,PType *>) * ScriptPointers.Size());
memcpy(flat + ParentClass->MapPointersSize, ScriptPointers.Data(), sizeof(pairType) * ScriptPointers.Size());
}
flat[numSuperPointers + ScriptPointers.Size()] = TheMapEnd;
MapPointers = flat;
MapPointersSize = ParentClass->MapPointersSize + ScriptPointers.Size();
}
}
}

View file

@ -27,6 +27,9 @@ class PClassType;
struct FNamespaceManager;
class PSymbol;
class PField;
class PObjectPointer;
class PDynArray;
class PMap;
enum
{
@ -53,10 +56,15 @@ public:
// Per-class information -------------------------------------
PClass *ParentClass = nullptr; // the class this class derives from
const size_t *Pointers = nullptr; // object pointers defined by this class *only*
const size_t *FlatPointers = nullptr; // object pointers defined by this class and all its superclasses; not initialized by default
const size_t *ArrayPointers = nullptr; // dynamic arrays containing object pointers.
const std::pair<size_t,PType *> *MapPointers = nullptr; // maps containing object pointers.
const size_t * Pointers = nullptr; // native object pointers defined by this class *only*
mutable size_t FlatPointersSize = 0;
mutable const std::pair<size_t, PObjectPointer*> * FlatPointers = nullptr; // object pointers defined by this class and all its superclasses; not initialized by default.
mutable size_t ArrayPointersSize = 0;
mutable const std::pair<size_t, PDynArray *> * ArrayPointers = nullptr; // dynamic arrays containing object pointers.
mutable size_t MapPointersSize = 0;
mutable const std::pair<size_t, PMap *> * MapPointers = nullptr; // maps containing object pointers.
uint8_t *Defaults = nullptr;
uint8_t *Meta = nullptr; // Per-class static script data
unsigned Size = sizeof(DObject);
@ -86,9 +94,11 @@ public:
PClass *CreateDerivedClass(FName name, unsigned int size, bool *newlycreated = nullptr, int fileno = 0);
void InitializeActorInfo();
void BuildFlatPointers();
void BuildArrayPointers();
void BuildMapPointers();
void BuildFlatPointers() const;
void BuildArrayPointers() const;
void BuildMapPointers() const;
void DestroySpecials(void *addr);
void DestroyMeta(void *addr);
const PClass *NativeClass() const;

View file

@ -196,15 +196,15 @@ void PType::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset>
//
//==========================================================================
void PType::SetPointer(void *base, unsigned offset, TArray<size_t> *stroffs)
void PType::SetPointer(void *base, unsigned offset, TArray<std::pair<size_t, PObjectPointer *>> *stroffs)
{
}
void PType::SetPointerArray(void *base, unsigned offset, TArray<size_t> *stroffs)
void PType::SetPointerArray(void *base, unsigned offset, TArray<std::pair<size_t, PDynArray *>> *stroffs)
{
}
void PType::SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t,PType *>> *ptrofs)
void PType::SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t, PMap *>> *ptrofs)
{
}
@ -1575,10 +1575,10 @@ PObjectPointer::PObjectPointer(PClass *cls, bool isconst)
//
//==========================================================================
void PObjectPointer::SetPointer(void *base, unsigned offset, TArray<size_t> *special)
void PObjectPointer::SetPointer(void *base, unsigned offset, TArray<std::pair<size_t, PObjectPointer *>> *special)
{
// Add to the list of pointers for this class.
special->Push(offset);
special->Push({offset, this});
}
//==========================================================================
@ -1706,7 +1706,7 @@ bool PClassPointer::isCompatible(PType *type)
//
//==========================================================================
void PClassPointer::SetPointer(void *base, unsigned offset, TArray<size_t> *special)
void PClassPointer::SetPointer(void *base, unsigned offset, TArray<std::pair<size_t, PObjectPointer *>> *special)
{
}
@ -1908,7 +1908,7 @@ void PArray::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset>
//
//==========================================================================
void PArray::SetPointer(void *base, unsigned offset, TArray<size_t> *special)
void PArray::SetPointer(void *base, unsigned offset, TArray<std::pair<size_t, PObjectPointer *>> *special)
{
for (unsigned i = 0; i < ElementCount; ++i)
{
@ -1922,7 +1922,7 @@ void PArray::SetPointer(void *base, unsigned offset, TArray<size_t> *special)
//
//==========================================================================
void PArray::SetPointerArray(void *base, unsigned offset, TArray<size_t> *special)
void PArray::SetPointerArray(void *base, unsigned offset, TArray<std::pair<size_t, PDynArray *>> *special)
{
if (ElementType->isStruct() || ElementType->isDynArray())
{
@ -1939,7 +1939,7 @@ void PArray::SetPointerArray(void *base, unsigned offset, TArray<size_t> *specia
//
//==========================================================================
void PArray::SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t,PType *>> *special)
void PArray::SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t, PMap *>> *special)
{
if(ElementType->isStruct() || ElementType->isMap())
{
@ -2254,12 +2254,12 @@ void PDynArray::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffs
//
//==========================================================================
void PDynArray::SetPointerArray(void *base, unsigned offset, TArray<size_t> *special)
void PDynArray::SetPointerArray(void *base, unsigned offset, TArray<std::pair<size_t, PDynArray *>> *special)
{
if (ElementType->isObjectPointer())
{
// Add to the list of pointer arrays for this class.
special->Push(offset);
special->Push({offset, this});
}
}
@ -2524,12 +2524,12 @@ void PMap::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *
//
//==========================================================================
void PMap::SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t,PType *>> *special)
void PMap::SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t, PMap *>> *special)
{
if (ValueType->isObjectPointer())
{
// Add to the list of pointer arrays for this class.
special->Push(std::make_pair(offset,KeyType));
special->Push(std::make_pair(offset, this));
}
}
@ -3264,7 +3264,7 @@ void PStruct::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset
//
//==========================================================================
void PStruct::SetPointer(void *base, unsigned offset, TArray<size_t> *special)
void PStruct::SetPointer(void *base, unsigned offset, TArray<std::pair<size_t, PObjectPointer *>> *special)
{
auto it = Symbols.GetIterator();
PSymbolTable::MapType::Pair *pair;
@ -3284,7 +3284,7 @@ void PStruct::SetPointer(void *base, unsigned offset, TArray<size_t> *special)
//
//==========================================================================
void PStruct::SetPointerArray(void *base, unsigned offset, TArray<size_t> *special)
void PStruct::SetPointerArray(void *base, unsigned offset, TArray<std::pair<size_t, PDynArray *>> *special)
{
auto it = Symbols.GetIterator();
PSymbolTable::MapType::Pair *pair;
@ -3304,7 +3304,7 @@ void PStruct::SetPointerArray(void *base, unsigned offset, TArray<size_t> *speci
//
//==========================================================================
void PStruct::SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t,PType *>> *special)
void PStruct::SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t, PMap *>> *special)
{
auto it = Symbols.GetIterator();
PSymbolTable::MapType::Pair *pair;

View file

@ -68,8 +68,11 @@ class PPointer;
class PClassPointer;
class PFunctionPointer;
class PArray;
class PDynArray;
class PMap;
class PStruct;
class PClassType;
class PObjectPointer;
struct ZCC_ExprConstant;
class PType : public PTypeBase
@ -129,9 +132,9 @@ public:
// initialization when the object is created and destruction when the
// object is destroyed.
virtual void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special=NULL);
virtual void SetPointer(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL);
virtual void SetPointerArray(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL);
virtual void SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t,PType *>> *ptrofs = NULL);
virtual void SetPointer(void *base, unsigned offset, TArray<std::pair<size_t, PObjectPointer *>> *ptrofs = NULL);
virtual void SetPointerArray(void *base, unsigned offset, TArray<std::pair<size_t, PDynArray *>> *ptrofs = NULL);
virtual void SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t, PMap *>> *ptrofs = NULL);
// Initialize the value, if needed (e.g. strings)
virtual void InitializeValue(void *addr, const void *def) const;
@ -455,7 +458,7 @@ public:
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) override;
void SetPointer(void *base, unsigned offset, TArray<std::pair<size_t, PObjectPointer *>> *special = NULL) override;
PClass *PointedClass() const;
};
@ -471,7 +474,7 @@ public:
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) override;
void SetPointer(void *base, unsigned offset, TArray<std::pair<size_t, PObjectPointer *>> *special = NULL) override;
bool IsMatch(intptr_t id1, intptr_t id2) const override;
void GetTypeIDs(intptr_t &id1, intptr_t &id2) const override;
};
@ -503,9 +506,9 @@ public:
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special) override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *special) override;
void SetPointerArray(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL) override;
void SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t,PType *>> *ptrofs = NULL) override;
void SetPointer(void *base, unsigned offset, TArray<std::pair<size_t, PObjectPointer *>> *special) override;
void SetPointerArray(void *base, unsigned offset, TArray<std::pair<size_t, PDynArray *>> *ptrofs = NULL) override;
void SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t, PMap *>> *ptrofs = NULL) override;
};
class PStaticArray : public PArray
@ -535,7 +538,7 @@ public:
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *specials) override;
void InitializeValue(void *addr, const void *def) const override;
void DestroyValue(void *addr) const override;
void SetPointerArray(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL) override;
void SetPointerArray(void *base, unsigned offset, TArray<std::pair<size_t, PDynArray *>> *ptrofs = NULL) override;
};
class PMap : public PCompoundType
@ -579,7 +582,7 @@ public:
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *specials) override;
void InitializeValue(void *addr, const void *def) const override;
void DestroyValue(void *addr) const override;
void SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t,PType *>> *ptrofs) override;
void SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t, PMap *>> *ptrofs) override;
};
@ -653,9 +656,9 @@ public:
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *specials) override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *specials) override;
void SetPointerArray(void *base, unsigned offset, TArray<size_t> *special) override;
void SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t,PType *>> *ptrofs) override;
void SetPointer(void *base, unsigned offset, TArray<std::pair<size_t, PObjectPointer *>> *specials) override;
void SetPointerArray(void *base, unsigned offset, TArray<std::pair<size_t, PDynArray *>> *special) override;
void SetPointerMap(void *base, unsigned offset, TArray<std::pair<size_t, PMap *>> *ptrofs) override;
};
class PPrototype : public PCompoundType