diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 5e56bab56..b9d518abf 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -541,7 +541,6 @@ void PType::StaticInit() RUNTIME_CLASS(PEnum)->TypeTableType = RUNTIME_CLASS(PEnum); RUNTIME_CLASS(PArray)->TypeTableType = RUNTIME_CLASS(PArray); RUNTIME_CLASS(PDynArray)->TypeTableType = RUNTIME_CLASS(PDynArray); - RUNTIME_CLASS(PVector)->TypeTableType = RUNTIME_CLASS(PVector); RUNTIME_CLASS(PMap)->TypeTableType = RUNTIME_CLASS(PMap); RUNTIME_CLASS(PStruct)->TypeTableType = RUNTIME_CLASS(PStruct); RUNTIME_CLASS(PPrototype)->TypeTableType = RUNTIME_CLASS(PPrototype); @@ -1870,6 +1869,39 @@ void PArray::SetDefaultValue(void *base, unsigned offset, TArray } } +//========================================================================== +// +// PArray :: InitializeValue +// This is needed for local array variables +// +//========================================================================== + +void PArray::InitializeValue(void *addr, const void *def) const +{ + char *caddr = (char*)addr; + char *cdef = (char*)def; + for (unsigned i = 0; i < ElementCount; ++i) + { + ElementType->InitializeValue(caddr + i * ElementSize, cdef + i * ElementSize); + } +} + +//========================================================================== +// +// PArray :: DestroyValue +// This is needed for local array variables +// +//========================================================================== + +void PArray::DestroyValue(void *addr) const +{ + char *caddr = (char*)addr; + for (unsigned i = 0; i < ElementCount; ++i) + { + ElementType->DestroyValue(caddr + i * ElementSize); + } +} + //========================================================================== // // NewArray @@ -1891,56 +1923,6 @@ PArray *NewArray(PType *type, unsigned int count) return (PArray *)atype; } -/* PVector ****************************************************************/ - -IMPLEMENT_CLASS(PVector, false, false, false, false) - -//========================================================================== -// -// PVector - Default Constructor -// -//========================================================================== - -PVector::PVector() -: PArray(TypeFloat32, 3) -{ - mDescriptiveName = "Vector"; -} - -//========================================================================== -// -// PVector - Parameterized Constructor -// -//========================================================================== - -PVector::PVector(unsigned int size) -: PArray(TypeFloat32, size) -{ - mDescriptiveName.Format("Vector<%d>", size); - assert(size >= 2 && size <= 4); -} - -//========================================================================== -// -// NewVector -// -// Returns a PVector with the given dimension, making sure not to create -// duplicates. -// -//========================================================================== - -PVector *NewVector(unsigned int size) -{ - size_t bucket; - PType *type = TypeTable.FindType(RUNTIME_CLASS(PVector), (intptr_t)TypeFloat32, size, &bucket); - if (type == NULL) - { - type = new PVector(size); - TypeTable.AddType(type, RUNTIME_CLASS(PVector), (intptr_t)TypeFloat32, size, bucket); - } - return (PVector *)type; -} - /* PDynArray **************************************************************/ IMPLEMENT_CLASS(PDynArray, false, true, false, false) @@ -2003,6 +1985,28 @@ void PDynArray::GetTypeIDs(intptr_t &id1, intptr_t &id2) const id2 = 0; } +//========================================================================== +// +// PDynArray :: InitializeValue +// +//========================================================================== + +void PDynArray::InitializeValue(void *addr, const void *def) const +{ + // DynArrays are not implemented yet. +} + +//========================================================================== +// +// PDynArray :: DestroyValue +// +//========================================================================== + +void PDynArray::DestroyValue(void *addr) const +{ + // DynArrays are not implemented yet. +} + //========================================================================== // // NewDynArray @@ -2087,6 +2091,28 @@ void PMap::GetTypeIDs(intptr_t &id1, intptr_t &id2) const id2 = (intptr_t)ValueType; } +//========================================================================== +// +// PMap :: InitializeValue +// +//========================================================================== + +void PMap::InitializeValue(void *addr, const void *def) const +{ + // Maps are not implemented yet. +} + +//========================================================================== +// +// PMap :: DestroyValue +// +//========================================================================== + +void PMap::DestroyValue(void *addr) const +{ + // Maps are not implemented yet. +} + //========================================================================== // // NewMap @@ -2309,6 +2335,76 @@ size_t PStruct::PropagateMark() return Fields.Size() * sizeof(void*) + Super::PropagateMark(); } +//========================================================================== +// +// PStruct :: InitializeValue +// This is needed for local array variables +// +//========================================================================== + +void PStruct::InitializeValue(void *addr, const void *def) const +{ + char *caddr = (char*)addr; + char *cdef = (char*)def; + + for (auto tao : SpecialInits) + { + tao.first->InitializeValue(caddr + tao.second, cdef + tao.second); + } +} + +//========================================================================== +// +// PStruct :: DestroyValue +// This is needed for local array variables +// +//========================================================================== + +void PStruct::DestroyValue(void *addr) const +{ + char *caddr = (char*)addr; + for (auto tao : SpecialInits) + { + tao.first->DestroyValue(caddr + tao.second); + } +} + + +//========================================================================== +// +// PStruct :: InitializeSpecialInits +// +// Initialize special field list. +// +//========================================================================== + +void PStruct::InitializeSpecialInits() +{ + // and initialize our own special values. + auto it = Symbols.GetIterator(); + PSymbolTable::MapType::Pair *pair; + + while (it.NextPair(pair)) + { + auto field = dyn_cast(pair->Value); + if (field != nullptr && !(field->Flags & VARF_Native)) + { + field->Type->SetDefaultValue(nullptr, unsigned(field->Offset), &SpecialInits); + } + } +} + +//========================================================================== +// +// PStruct :: RequireConstruction +// +//========================================================================== + +bool PStruct::RequireConstruction() const +{ + return SpecialInits.Size() > 0; +} + //========================================================================== // // NewStruct diff --git a/src/dobjtype.h b/src/dobjtype.h index 186cb8117..dcf316fec 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -256,6 +256,9 @@ public: // Initialize the value, if needed (e.g. strings) virtual void InitializeValue(void *addr, const void *def) const; + // This is for stack variables that may need construction/destruction at runtime + virtual bool RequireConstruction() const { return false; } + // Destroy the value, if needed (e.g. strings) virtual void DestroyValue(void *addr) const; @@ -489,6 +492,7 @@ public: void SetDefaultValue(void *base, unsigned offset, TArray *special=NULL) const override; void InitializeValue(void *addr, const void *def) const override; void DestroyValue(void *addr) const override; + virtual bool RequireConstruction() const override { return true; } }; // Variations of integer types ---------------------------------------------- @@ -626,22 +630,14 @@ public: bool ReadValue(FSerializer &ar, const char *key,void *addr) const override; void SetDefaultValue(void *base, unsigned offset, TArray *special) const override; + void InitializeValue(void *addr, const void *def) const override; + void DestroyValue(void *addr) const override; + bool RequireConstruction() const override { return ElementType->RequireConstruction(); } protected: PArray(); }; -// A vector is an array with extra operations. -class PVector : public PArray -{ - DECLARE_CLASS(PVector, PArray); - HAS_OBJECT_POINTERS; -public: - PVector(unsigned int size); -protected: - PVector(); -}; - class PDynArray : public PCompoundType { DECLARE_CLASS(PDynArray, PCompoundType); @@ -653,6 +649,9 @@ public: virtual bool IsMatch(intptr_t id1, intptr_t id2) const; virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const; + void InitializeValue(void *addr, const void *def) const override; + void DestroyValue(void *addr) const override; + bool RequireConstruction() const override { return true; } protected: PDynArray(); }; @@ -669,6 +668,9 @@ public: virtual bool IsMatch(intptr_t id1, intptr_t id2) const; virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const; + void InitializeValue(void *addr, const void *def) const override; + void DestroyValue(void *addr) const override; + bool RequireConstruction() const override { return true; } protected: PMap(); }; @@ -676,6 +678,10 @@ protected: class PStruct : public PNamedType { DECLARE_CLASS(PStruct, PNamedType); + +protected: + TArray SpecialInits; + public: PStruct(FName name, PTypeBase *outer); @@ -693,6 +699,12 @@ public: static void WriteFields(FSerializer &ar, const void *addr, const TArray &fields); bool ReadFields(FSerializer &ar, void *addr) const; + + void InitializeValue(void *addr, const void *def) const override; + void DestroyValue(void *addr) const override; + bool RequireConstruction() const override; + void InitializeSpecialInits(); + protected: PStruct(); }; @@ -759,7 +771,6 @@ class PClass : public PStruct protected: // We unravel _WITH_META here just as we did for PType. enum { MetaClassNum = CLASSREG_PClassClass }; - TArray SpecialInits; void Derive(PClass *newclass, FName name); void InitializeSpecials(void *addr) const; void SetSuper(); @@ -889,7 +900,6 @@ struct FTypeTable extern FTypeTable TypeTable; // Returns a type from the TypeTable. Will create one if it isn't present. -PVector *NewVector(unsigned int size); PMap *NewMap(PType *keytype, PType *valuetype); PArray *NewArray(PType *type, unsigned int count); PDynArray *NewDynArray(PType *type);