diff --git a/src/reverse/ClassReference.cpp b/src/reverse/ClassReference.cpp index ba80815f..3de7a402 100644 --- a/src/reverse/ClassReference.cpp +++ b/src/reverse/ClassReference.cpp @@ -1,20 +1,36 @@ #include #include "ClassReference.h" +#include "CET.h" ClassReference::ClassReference(const TiltedPhoques::Locked& aView, RED4ext::CBaseRTTIType* apClass, RED4ext::ScriptInstance apInstance) : ClassType(aView, apClass) { - // Hack for now until we use their allocators, classes can actually be pointers to structs - // GI just happens to be a 8-byte struct with only a pointer in it - m_pInstance = std::make_unique(apClass->GetSize()); - memcpy(m_pInstance.get(), apInstance, apClass->GetSize()); + m_pInstance = apClass->GetAllocator()->AllocAligned(apClass->GetSize(), apClass->GetAlignment()).memory; + apClass->Construct(m_pInstance); + apClass->Assign(m_pInstance, apInstance); +} + +ClassReference::ClassReference(ClassReference&& aOther) noexcept + : ClassType(std::move(aOther)) + , m_pInstance(aOther.m_pInstance) +{ + aOther.m_pInstance = nullptr; +} + +ClassReference::~ClassReference() +{ + if (m_pInstance && CET::IsRunning()) + { + m_pType->Destruct(m_pInstance); + m_pType->GetAllocator()->Free(m_pInstance); + } } RED4ext::ScriptInstance ClassReference::GetHandle() const { - return m_pInstance.get(); + return m_pInstance; } RED4ext::ScriptInstance ClassReference::GetValuePtr() const diff --git a/src/reverse/ClassReference.h b/src/reverse/ClassReference.h index bb8e7598..edd36236 100644 --- a/src/reverse/ClassReference.h +++ b/src/reverse/ClassReference.h @@ -7,10 +7,12 @@ struct ClassReference : ClassType ClassReference(const TiltedPhoques::Locked& aView, RED4ext::CBaseRTTIType* apClass, RED4ext::ScriptInstance apInstance); + ClassReference(ClassReference&& aOther) noexcept; + virtual ~ClassReference(); virtual RED4ext::ScriptInstance GetHandle() const override; virtual RED4ext::ScriptInstance GetValuePtr() const override; private: - std::unique_ptr m_pInstance; + RED4ext::ScriptInstance m_pInstance; }; diff --git a/src/scripting/FunctionOverride.cpp b/src/scripting/FunctionOverride.cpp index e0c30b07..18ca1faf 100644 --- a/src/scripting/FunctionOverride.cpp +++ b/src/scripting/FunctionOverride.cpp @@ -219,7 +219,7 @@ void FunctionOverride::HandleOverridenFunction(RED4ext::IScriptable* apContext, auto* pType = pArg->type; auto* pAllocator = pType->GetAllocator(); - auto* pInstance = pAllocator->Alloc(pType->GetSize()).memory; + auto* pInstance = pAllocator->AllocAligned(pType->GetSize(), pType->GetAlignment()).memory; pType->Init(pInstance); bool isScriptRef = pArg->type->GetType() == RED4ext::ERTTIType::ScriptReference; @@ -227,13 +227,12 @@ void FunctionOverride::HandleOverridenFunction(RED4ext::IScriptable* apContext, // Exception here we need to allocate the inner object as well if (isScriptRef) { - RED4ext::ScriptRef* pScriptRef = (RED4ext::ScriptRef*)pInstance; - auto pInnerType = pScriptRef->innerType; - - auto pInnerInstance = pInnerType->GetAllocator()->Alloc(pInnerType->GetSize()).memory; - pInnerType->Init(pInnerInstance); - - pScriptRef->ref = pInnerInstance; + auto* pInnerType = ((RED4ext::CRTTIScriptReferenceType*)pType)->innerType; + auto* pScriptRef = (RED4ext::ScriptRef*)pInstance; + pScriptRef->innerType = pInnerType; + pScriptRef->hash = pInnerType->GetName(); + pScriptRef->ref = pInnerType->GetAllocator()->AllocAligned(pInnerType->GetSize(), pInnerType->GetAlignment()).memory; + pInnerType->Init(pScriptRef->ref); } RED4ext::CStackType arg; @@ -260,9 +259,10 @@ void FunctionOverride::HandleOverridenFunction(RED4ext::IScriptable* apContext, // Release inner values if (isScriptRef) { - RED4ext::ScriptRef* pScriptRef = (RED4ext::ScriptRef*)pInstance; + auto* pScriptRef = (RED4ext::ScriptRef*)pInstance; pScriptRef->innerType->Destroy(pScriptRef->ref); pScriptRef->innerType->GetAllocator()->Free(pScriptRef->ref); + pScriptRef->ref = nullptr; } if (!pArg->flags.isOut || apFrame->unk30)