mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-06-08 21:45:40 +00:00
fix: dynamic array reallocation for x64
This commit is contained in:
parent
d157ae6da6
commit
f1a95997fe
@ -189,13 +189,13 @@ bool MemberComputations::IsInRuntimeBlock() const
|
|||||||
return m_info->m_fast_file_block != nullptr && m_info->m_fast_file_block->m_type == FastFileBlockType::RUNTIME;
|
return m_info->m_fast_file_block != nullptr && m_info->m_fast_file_block->m_type == FastFileBlockType::RUNTIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemberComputations::IsFirstMember() const
|
bool MemberComputations::IsFirstUsedMember() const
|
||||||
{
|
{
|
||||||
const auto parentUsedMembers = StructureComputations(m_info->m_parent).GetUsedMembers();
|
const auto parentUsedMembers = StructureComputations(m_info->m_parent).GetUsedMembers();
|
||||||
return !parentUsedMembers.empty() && parentUsedMembers[0] == m_info;
|
return !parentUsedMembers.empty() && parentUsedMembers[0] == m_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemberComputations::IsLastMember() const
|
bool MemberComputations::IsLastUsedMember() const
|
||||||
{
|
{
|
||||||
const auto parentUsedMembers = StructureComputations(m_info->m_parent).GetUsedMembers();
|
const auto parentUsedMembers = StructureComputations(m_info->m_parent).GetUsedMembers();
|
||||||
return !parentUsedMembers.empty() && parentUsedMembers[parentUsedMembers.size() - 1] == m_info;
|
return !parentUsedMembers.empty() && parentUsedMembers[parentUsedMembers.size() - 1] == m_info;
|
||||||
|
@ -25,8 +25,8 @@ public:
|
|||||||
[[nodiscard]] bool IsNotInDefaultNormalBlock() const;
|
[[nodiscard]] bool IsNotInDefaultNormalBlock() const;
|
||||||
[[nodiscard]] bool IsInTempBlock() const;
|
[[nodiscard]] bool IsInTempBlock() const;
|
||||||
[[nodiscard]] bool IsInRuntimeBlock() const;
|
[[nodiscard]] bool IsInRuntimeBlock() const;
|
||||||
[[nodiscard]] bool IsFirstMember() const;
|
[[nodiscard]] bool IsFirstUsedMember() const;
|
||||||
[[nodiscard]] bool IsLastMember() const;
|
[[nodiscard]] bool IsLastUsedMember() const;
|
||||||
[[nodiscard]] bool HasDynamicArraySize() const;
|
[[nodiscard]] bool HasDynamicArraySize() const;
|
||||||
[[nodiscard]] bool IsDynamicMember() const;
|
[[nodiscard]] bool IsDynamicMember() const;
|
||||||
[[nodiscard]] bool IsAfterPartialLoad() const;
|
[[nodiscard]] bool IsAfterPartialLoad() const;
|
||||||
|
@ -56,6 +56,18 @@ DeclarationModifier* DeclarationModifierComputations::GetNextDeclarationModifier
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<DeclarationModifier*> DeclarationModifierComputations::GetAllDeclarationModifiers() const
|
||||||
|
{
|
||||||
|
const auto& declarationModifiers = m_information->m_member->m_type_declaration->m_declaration_modifiers;
|
||||||
|
std::vector<DeclarationModifier*> all;
|
||||||
|
all.reserve(declarationModifiers.size());
|
||||||
|
|
||||||
|
for (const auto& mod : declarationModifiers)
|
||||||
|
all.emplace_back(mod.get());
|
||||||
|
|
||||||
|
return all;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<DeclarationModifier*> DeclarationModifierComputations::GetFollowingDeclarationModifiers() const
|
std::vector<DeclarationModifier*> DeclarationModifierComputations::GetFollowingDeclarationModifiers() const
|
||||||
{
|
{
|
||||||
std::vector<DeclarationModifier*> following;
|
std::vector<DeclarationModifier*> following;
|
||||||
|
@ -12,6 +12,7 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] DeclarationModifier* GetDeclarationModifier() const;
|
[[nodiscard]] DeclarationModifier* GetDeclarationModifier() const;
|
||||||
[[nodiscard]] DeclarationModifier* GetNextDeclarationModifier() const;
|
[[nodiscard]] DeclarationModifier* GetNextDeclarationModifier() const;
|
||||||
|
[[nodiscard]] std::vector<DeclarationModifier*> GetAllDeclarationModifiers() const;
|
||||||
[[nodiscard]] std::vector<DeclarationModifier*> GetFollowingDeclarationModifiers() const;
|
[[nodiscard]] std::vector<DeclarationModifier*> GetFollowingDeclarationModifiers() const;
|
||||||
[[nodiscard]] const std::vector<int>& GetArrayIndices() const;
|
[[nodiscard]] const std::vector<int>& GetArrayIndices() const;
|
||||||
[[nodiscard]] bool IsArray() const;
|
[[nodiscard]] bool IsArray() const;
|
||||||
|
@ -26,6 +26,18 @@ MemberInformation* StructureComputations::GetDynamicMember() const
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool StructureComputations::HasNonDynamicMember() const
|
||||||
|
{
|
||||||
|
for (const auto& member : m_info->m_ordered_members)
|
||||||
|
{
|
||||||
|
const MemberComputations memberComputations(member.get());
|
||||||
|
if (!memberComputations.ShouldIgnore() && !memberComputations.IsAfterPartialLoad())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<MemberInformation*> StructureComputations::GetUsedMembers() const
|
std::vector<MemberInformation*> StructureComputations::GetUsedMembers() const
|
||||||
{
|
{
|
||||||
std::vector<MemberInformation*> members;
|
std::vector<MemberInformation*> members;
|
||||||
|
@ -9,6 +9,7 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] bool IsAsset() const;
|
[[nodiscard]] bool IsAsset() const;
|
||||||
[[nodiscard]] MemberInformation* GetDynamicMember() const;
|
[[nodiscard]] MemberInformation* GetDynamicMember() const;
|
||||||
|
[[nodiscard]] bool HasNonDynamicMember() const;
|
||||||
[[nodiscard]] std::vector<MemberInformation*> GetUsedMembers() const;
|
[[nodiscard]] std::vector<MemberInformation*> GetUsedMembers() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -70,6 +70,13 @@ namespace
|
|||||||
PrintFillStructMethodDeclaration(type->m_info);
|
PrintFillStructMethodDeclaration(type->m_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (const auto* type : m_env.m_used_types)
|
||||||
|
{
|
||||||
|
if (type->m_info && type->m_type == type->m_info->m_definition && StructureComputations(type->m_info).GetDynamicMember())
|
||||||
|
{
|
||||||
|
PrintDynamicFillMethodDeclaration(type->m_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (const auto* type : m_env.m_used_types)
|
for (const auto* type : m_env.m_used_types)
|
||||||
{
|
{
|
||||||
@ -174,6 +181,14 @@ namespace
|
|||||||
PrintFillStructMethod(type->m_info);
|
PrintFillStructMethod(type->m_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (const auto* type : m_env.m_used_types)
|
||||||
|
{
|
||||||
|
if (type->m_info && type->m_type == type->m_info->m_definition && StructureComputations(type->m_info).GetDynamicMember())
|
||||||
|
{
|
||||||
|
LINE("")
|
||||||
|
PrintDynamicFillMethod(*type->m_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (const auto* type : m_env.m_used_types)
|
for (const auto* type : m_env.m_used_types)
|
||||||
{
|
{
|
||||||
@ -240,7 +255,12 @@ namespace
|
|||||||
|
|
||||||
void PrintFillStructMethodDeclaration(const StructureInformation* info) const
|
void PrintFillStructMethodDeclaration(const StructureInformation* info) const
|
||||||
{
|
{
|
||||||
LINEF("void FillStruct_{1}(const ZoneStreamFillReadAccessor& fillAccessor);", LoaderClassName(m_env.m_asset), MakeSafeTypeName(info->m_definition))
|
LINEF("void FillStruct_{0}(const ZoneStreamFillReadAccessor& fillAccessor);", MakeSafeTypeName(info->m_definition))
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintDynamicFillMethodDeclaration(const StructureInformation* info) const
|
||||||
|
{
|
||||||
|
LINEF("size_t LoadDynamicFill_{0}(const ZoneStreamFillReadAccessor& parentFill);", MakeSafeTypeName(info->m_definition))
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintHeaderPtrArrayLoadMethodDeclaration(const DataDefinition* def) const
|
void PrintHeaderPtrArrayLoadMethodDeclaration(const DataDefinition* def) const
|
||||||
@ -255,6 +275,7 @@ namespace
|
|||||||
|
|
||||||
void PrintHeaderLoadMethodDeclaration(const StructureInformation* info) const
|
void PrintHeaderLoadMethodDeclaration(const StructureInformation* info) const
|
||||||
{
|
{
|
||||||
|
const StructureComputations computations(info);
|
||||||
LINEF("void Load_{0}(bool atStreamStart);", MakeSafeTypeName(info->m_definition))
|
LINEF("void Load_{0}(bool atStreamStart);", MakeSafeTypeName(info->m_definition))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,9 +584,99 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintFillStruct_Member_Condition_Struct(const StructureInformation& structInfo, const MemberInformation& member)
|
||||||
|
{
|
||||||
|
if (member.m_condition)
|
||||||
|
{
|
||||||
|
LINEF("if ({0})", MakeEvaluation(member.m_condition.get()))
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
PrintFillStruct_Member(structInfo, member, DeclarationModifierComputations(&member), 0u);
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
PrintFillStruct_Member(structInfo, member, DeclarationModifierComputations(&member), 0u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintFillStruct_Member_Condition_Union(const StructureInformation& structInfo, const MemberInformation& member)
|
||||||
|
{
|
||||||
|
const MemberComputations computations(&member);
|
||||||
|
|
||||||
|
if (computations.IsFirstUsedMember())
|
||||||
|
{
|
||||||
|
if (member.m_condition)
|
||||||
|
{
|
||||||
|
LINEF("if ({0})", MakeEvaluation(member.m_condition.get()))
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
PrintFillStruct_Member(structInfo, member, DeclarationModifierComputations(&member), 0u);
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrintFillStruct_Member(structInfo, member, DeclarationModifierComputations(&member), 0u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (computations.IsLastUsedMember())
|
||||||
|
{
|
||||||
|
if (member.m_condition)
|
||||||
|
{
|
||||||
|
LINEF("else if ({0})", MakeEvaluation(member.m_condition.get()))
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
PrintFillStruct_Member(structInfo, member, DeclarationModifierComputations(&member), 0u);
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LINE("else")
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
PrintFillStruct_Member(structInfo, member, DeclarationModifierComputations(&member), 0u);
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (member.m_condition)
|
||||||
|
{
|
||||||
|
LINEF("else if ({0})", MakeEvaluation(member.m_condition.get()))
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
PrintFillStruct_Member(structInfo, member, DeclarationModifierComputations(&member), 0u);
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LINEF("#error Middle member of union2 must have condition ({0})", member.m_member->m_name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PrintFillStruct_Struct(const StructureInformation& info)
|
void PrintFillStruct_Struct(const StructureInformation& info)
|
||||||
{
|
{
|
||||||
const auto* dynamicMember = StructureComputations(&info).GetDynamicMember();
|
const auto* dynamicMember = StructureComputations(&info).GetDynamicMember();
|
||||||
|
|
||||||
|
if (dynamicMember)
|
||||||
|
{
|
||||||
for (const auto& member : info.m_ordered_members)
|
for (const auto& member : info.m_ordered_members)
|
||||||
{
|
{
|
||||||
const MemberComputations computations(member.get());
|
const MemberComputations computations(member.get());
|
||||||
@ -575,9 +686,22 @@ namespace
|
|||||||
PrintFillStruct_Member(info, *member, DeclarationModifierComputations(member.get()), 0u);
|
PrintFillStruct_Member(info, *member, DeclarationModifierComputations(member.get()), 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always fill dynamic members last
|
if (info.m_definition->GetType() == DataDefinitionType::UNION)
|
||||||
if (dynamicMember)
|
PrintFillStruct_Member_Condition_Union(info, *dynamicMember);
|
||||||
PrintFillStruct_Member(info, *dynamicMember, DeclarationModifierComputations(dynamicMember), 0u);
|
else
|
||||||
|
PrintFillStruct_Member_Condition_Struct(info, *dynamicMember);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const auto& member : info.m_ordered_members)
|
||||||
|
{
|
||||||
|
const MemberComputations computations(member.get());
|
||||||
|
if (computations.ShouldIgnore())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
PrintFillStruct_Member(info, *member, DeclarationModifierComputations(member.get()), 0u);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintFillStructMethod(const StructureInformation* info)
|
void PrintFillStructMethod(const StructureInformation* info)
|
||||||
@ -595,13 +719,197 @@ namespace
|
|||||||
LINE("}")
|
LINE("}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintDynamicOversize_DynamicMember(const StructureInformation& info, const MemberInformation& member) const
|
||||||
|
{
|
||||||
|
const MemberComputations memberComputations(&member);
|
||||||
|
const DeclarationModifierComputations modifier(&member);
|
||||||
|
|
||||||
|
if (memberComputations.HasDynamicArraySize())
|
||||||
|
{
|
||||||
|
LINEF("const auto dynamicArrayEntries = static_cast<size_t>({0});", MakeEvaluation(modifier.GetDynamicArraySizeEvaluation()))
|
||||||
|
LINEF("m_stream.AppendToFill(dynamicArrayEntries * {0});", member.m_member->m_type_declaration->m_type->GetSize())
|
||||||
|
LINEF("return dynamicArrayEntries * sizeof({0}{1}) + offsetof({2}, {3});",
|
||||||
|
MakeTypeDecl(member.m_member->m_type_declaration.get()),
|
||||||
|
MakeFollowingReferences(modifier.GetAllDeclarationModifiers()),
|
||||||
|
info.m_definition->GetFullName(),
|
||||||
|
member.m_member->m_name)
|
||||||
|
}
|
||||||
|
else if (member.m_type && StructureComputations(member.m_type).GetDynamicMember())
|
||||||
|
{
|
||||||
|
LINEF("return LoadDynamicFill_{0}(fillAccessor.AtOffset({1})) + offsetof({2}, {3});",
|
||||||
|
MakeSafeTypeName(member.m_type->m_definition),
|
||||||
|
member.m_member->m_offset,
|
||||||
|
info.m_definition->GetFullName(),
|
||||||
|
member.m_member->m_name)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LINEF("m_stream.AppendToFill({0});", member.m_member->m_type_declaration->GetSize())
|
||||||
|
LINEF("return sizeof({0}{1}) + offsetof({2}, {3});",
|
||||||
|
MakeTypeDecl(member.m_member->m_type_declaration.get()),
|
||||||
|
MakeFollowingReferences(modifier.GetAllDeclarationModifiers()),
|
||||||
|
info.m_definition->GetFullName(),
|
||||||
|
member.m_member->m_name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynamicOverSize_Struct_Condition(const StructureInformation& info, const MemberInformation& member)
|
||||||
|
{
|
||||||
|
if (member.m_condition)
|
||||||
|
{
|
||||||
|
LINEF("if ({0})", MakeEvaluation(member.m_condition.get()))
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
PrintFillStruct_Member(info, member, DeclarationModifierComputations(&member), 0u);
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
PrintFillStruct_Member(info, member, DeclarationModifierComputations(&member), 0u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintDynamicOversize_Struct(const StructureInformation& info)
|
||||||
|
{
|
||||||
|
const StructureComputations structureComputations(&info);
|
||||||
|
const auto dynamicMember = structureComputations.GetDynamicMember();
|
||||||
|
|
||||||
|
LINEF("const auto fillAccessor = m_stream.AppendToFill({0}).AtOffset(parentFill.Offset());", dynamicMember->m_member->m_offset)
|
||||||
|
LINE("")
|
||||||
|
|
||||||
|
for (const auto& member : info.m_ordered_members)
|
||||||
|
{
|
||||||
|
const MemberComputations computations(member.get());
|
||||||
|
if (computations.ShouldIgnore() || computations.IsDynamicMember())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DynamicOverSize_Struct_Condition(info, *member);
|
||||||
|
}
|
||||||
|
|
||||||
|
LINE("")
|
||||||
|
|
||||||
|
PrintDynamicOversize_DynamicMember(info, *dynamicMember);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintDynamicOversize_Union(const StructureInformation& info)
|
||||||
|
{
|
||||||
|
LINE("const auto& fillAccessor = parentFill;")
|
||||||
|
|
||||||
|
for (const auto& member : info.m_ordered_members)
|
||||||
|
{
|
||||||
|
const MemberComputations computations(member.get());
|
||||||
|
if (computations.ShouldIgnore())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (computations.IsFirstUsedMember())
|
||||||
|
{
|
||||||
|
LINE("")
|
||||||
|
if (member->m_condition)
|
||||||
|
{
|
||||||
|
LINEF("if ({0})", MakeEvaluation(member->m_condition.get()))
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
PrintDynamicOversize_DynamicMember(info, *member);
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrintDynamicOversize_DynamicMember(info, *member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (computations.IsLastUsedMember())
|
||||||
|
{
|
||||||
|
if (member->m_condition)
|
||||||
|
{
|
||||||
|
LINEF("else if ({0})", MakeEvaluation(member->m_condition.get()))
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
PrintDynamicOversize_DynamicMember(info, *member);
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LINE("else")
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
PrintDynamicOversize_DynamicMember(info, *member);
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (member->m_condition)
|
||||||
|
{
|
||||||
|
LINEF("else if ({0})", MakeEvaluation(member->m_condition.get()))
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
PrintDynamicOversize_DynamicMember(info, *member);
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LINEF("#error Middle member of union must have condition ({0})", member->m_member->m_name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintDynamicFillMethod(const StructureInformation& info)
|
||||||
|
{
|
||||||
|
LINEF("size_t {0}::LoadDynamicFill_{1}(const ZoneStreamFillReadAccessor& parentFill)",
|
||||||
|
LoaderClassName(m_env.m_asset),
|
||||||
|
MakeSafeTypeName(info.m_definition))
|
||||||
|
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
LINEF("{0} temp{1};", info.m_definition->GetFullName(), MakeSafeTypeName(info.m_definition))
|
||||||
|
LINEF("{0} = &temp{1};", MakeTypeVarName(info.m_definition), MakeSafeTypeName(info.m_definition))
|
||||||
|
|
||||||
|
if (info.m_definition->GetType() == DataDefinitionType::UNION)
|
||||||
|
{
|
||||||
|
PrintDynamicOversize_Union(info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrintDynamicOversize_Struct(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
|
||||||
void PrintLoadPtrArrayMethod_Loading(const DataDefinition* def, const StructureInformation* info) const
|
void PrintLoadPtrArrayMethod_Loading(const DataDefinition* def, const StructureInformation* info) const
|
||||||
|
{
|
||||||
|
if (info && !info->m_has_matching_cross_platform_structure && StructureComputations(info).GetDynamicMember())
|
||||||
|
{
|
||||||
|
LINEF("const auto allocSize = LoadDynamicFill_{0}(m_stream.LoadWithFill(0));", MakeSafeTypeName(def))
|
||||||
|
LINEF("*{0} = static_cast<{1}*>(m_stream.AllocOutOfBlock({2}, allocSize));", MakeTypePtrVarName(def), def->GetFullName(), def->GetAlignment())
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
LINEF("*{0} = m_stream.{1}<{2}>({3});",
|
LINEF("*{0} = m_stream.{1}<{2}>({3});",
|
||||||
MakeTypePtrVarName(def),
|
MakeTypePtrVarName(def),
|
||||||
m_env.m_architecture_mismatch ? "AllocOutOfBlock" : "Alloc",
|
m_env.m_architecture_mismatch ? "AllocOutOfBlock" : "Alloc",
|
||||||
def->GetFullName(),
|
def->GetFullName(),
|
||||||
def->GetAlignment())
|
def->GetAlignment())
|
||||||
|
}
|
||||||
|
|
||||||
if (info && !info->m_is_leaf)
|
if (info && !info->m_is_leaf)
|
||||||
{
|
{
|
||||||
@ -911,7 +1219,7 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadMember_DynamicArray(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier) const
|
void LoadMember_DynamicArray(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier)
|
||||||
{
|
{
|
||||||
if (member->m_type && !member->m_type->m_is_leaf)
|
if (member->m_type && !member->m_type->m_is_leaf)
|
||||||
{
|
{
|
||||||
@ -923,11 +1231,22 @@ namespace
|
|||||||
}
|
}
|
||||||
else if (info->m_has_matching_cross_platform_structure)
|
else if (info->m_has_matching_cross_platform_structure)
|
||||||
{
|
{
|
||||||
|
if (m_env.m_architecture_mismatch)
|
||||||
|
{
|
||||||
|
LINE("if (atStreamStart)")
|
||||||
|
m_intendation++;
|
||||||
|
}
|
||||||
|
|
||||||
LINEF("m_stream.Load<{0}{1}>({2}, {3});",
|
LINEF("m_stream.Load<{0}{1}>({2}, {3});",
|
||||||
MakeTypeDecl(member->m_member->m_type_declaration.get()),
|
MakeTypeDecl(member->m_member->m_type_declaration.get()),
|
||||||
MakeFollowingReferences(modifier.GetFollowingDeclarationModifiers()),
|
MakeFollowingReferences(modifier.GetFollowingDeclarationModifiers()),
|
||||||
MakeMemberAccess(info, member, modifier),
|
MakeMemberAccess(info, member, modifier),
|
||||||
MakeEvaluation(modifier.GetDynamicArraySizeEvaluation()))
|
MakeEvaluation(modifier.GetDynamicArraySizeEvaluation()))
|
||||||
|
|
||||||
|
if (m_env.m_architecture_mismatch)
|
||||||
|
{
|
||||||
|
m_intendation--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -974,6 +1293,7 @@ namespace
|
|||||||
if (member->m_type && !member->m_type->m_is_leaf && !computations.IsInRuntimeBlock())
|
if (member->m_type && !member->m_type->m_is_leaf && !computations.IsInRuntimeBlock())
|
||||||
{
|
{
|
||||||
LINEF("{0} = {1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier))
|
LINEF("{0} = {1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier))
|
||||||
|
|
||||||
LINEF("Load_{0}(true);", MakeSafeTypeName(member->m_type->m_definition))
|
LINEF("Load_{0}(true);", MakeSafeTypeName(member->m_type->m_definition))
|
||||||
|
|
||||||
if (member->m_type->m_post_load_action)
|
if (member->m_type->m_post_load_action)
|
||||||
@ -1000,7 +1320,7 @@ namespace
|
|||||||
void LoadMember_TypeCheck(const StructureInformation* info,
|
void LoadMember_TypeCheck(const StructureInformation* info,
|
||||||
const MemberInformation* member,
|
const MemberInformation* member,
|
||||||
const DeclarationModifierComputations& modifier,
|
const DeclarationModifierComputations& modifier,
|
||||||
const MemberLoadType loadType) const
|
const MemberLoadType loadType)
|
||||||
{
|
{
|
||||||
if (member->m_is_string)
|
if (member->m_is_string)
|
||||||
{
|
{
|
||||||
@ -1076,6 +1396,13 @@ namespace
|
|||||||
&& ((member.m_type && !member.m_type->m_has_matching_cross_platform_structure) || loadType == MemberLoadType::POINTER_ARRAY);
|
&& ((member.m_type && !member.m_type->m_has_matching_cross_platform_structure) || loadType == MemberLoadType::POINTER_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool
|
||||||
|
ShouldPreAllocDynamic(const MemberInformation& member, const DeclarationModifierComputations& modifier, const MemberLoadType loadType) const
|
||||||
|
{
|
||||||
|
return ShouldAllocOutOfBlock(member, loadType) && (modifier.IsSinglePointer() || modifier.IsPointerArray()) && member.m_type
|
||||||
|
&& StructureComputations(member.m_type).GetDynamicMember();
|
||||||
|
}
|
||||||
|
|
||||||
void LoadMember_Alloc(const StructureInformation* info,
|
void LoadMember_Alloc(const StructureInformation* info,
|
||||||
const MemberInformation* member,
|
const MemberInformation* member,
|
||||||
const DeclarationModifierComputations& modifier,
|
const DeclarationModifierComputations& modifier,
|
||||||
@ -1091,7 +1418,26 @@ namespace
|
|||||||
const auto followingReferences = MakeFollowingReferences(modifier.GetFollowingDeclarationModifiers());
|
const auto followingReferences = MakeFollowingReferences(modifier.GetFollowingDeclarationModifiers());
|
||||||
|
|
||||||
const auto allocOutOfBlock = ShouldAllocOutOfBlock(*member, loadType);
|
const auto allocOutOfBlock = ShouldAllocOutOfBlock(*member, loadType);
|
||||||
|
const auto preAllocDynamic = ShouldPreAllocDynamic(*member, modifier, loadType);
|
||||||
|
|
||||||
|
if (preAllocDynamic)
|
||||||
|
{
|
||||||
|
LINEF("const auto allocSize = LoadDynamicFill_{0}(m_stream.LoadWithFill(0));", MakeSafeTypeName(member->m_type->m_definition))
|
||||||
|
LINE_STARTF("{0} = static_cast<{1}{2}*>(m_stream.AllocOutOfBlock(", MakeMemberAccess(info, member, modifier), typeDecl, followingReferences)
|
||||||
|
|
||||||
|
if (member->m_alloc_alignment)
|
||||||
|
{
|
||||||
|
LINE_MIDDLE(MakeEvaluation(member->m_alloc_alignment.get()))
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LINE_MIDDLEF("{0}", modifier.GetAlignment())
|
||||||
|
}
|
||||||
|
|
||||||
|
LINE_ENDF(", allocSize));", member->m_type->m_definition->GetFullName())
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
LINE_STARTF("{0} = m_stream.", MakeMemberAccess(info, member, modifier))
|
LINE_STARTF("{0} = m_stream.", MakeMemberAccess(info, member, modifier))
|
||||||
if (allocOutOfBlock)
|
if (allocOutOfBlock)
|
||||||
LINE_MIDDLE("AllocOutOfBlock")
|
LINE_MIDDLE("AllocOutOfBlock")
|
||||||
@ -1101,8 +1447,8 @@ namespace
|
|||||||
LINE_MIDDLEF("<{0}{1}>(", typeDecl, followingReferences)
|
LINE_MIDDLEF("<{0}{1}>(", typeDecl, followingReferences)
|
||||||
|
|
||||||
// This used to use `alignof()` to calculate alignment but due to inconsistencies between compilers and bugs discovered in MSVC
|
// This used to use `alignof()` to calculate alignment but due to inconsistencies between compilers and bugs discovered in MSVC
|
||||||
// (Alignment specified via `__declspec(align())` showing as correct via intellisense but is incorrect when compiled for types that have a larger
|
// (Alignment specified via `__declspec(align())` showing as correct via intellisense but is incorrect when compiled for types that have a
|
||||||
// alignment than the specified value) this was changed to make ZoneCodeGenerator calculate what is supposed to be used as alignment when
|
// larger alignment than the specified value) this was changed to make ZoneCodeGenerator calculate what is supposed to be used as alignment when
|
||||||
// allocating. This is more reliable when being used with different compilers and the value used can be seen in the source code directly
|
// allocating. This is more reliable when being used with different compilers and the value used can be seen in the source code directly
|
||||||
if (member->m_alloc_alignment)
|
if (member->m_alloc_alignment)
|
||||||
{
|
{
|
||||||
@ -1119,6 +1465,7 @@ namespace
|
|||||||
LINE_MIDDLEF(", {0}", MakeEvaluation(modifier.GetPointerArrayCountEvaluation()))
|
LINE_MIDDLEF(", {0}", MakeEvaluation(modifier.GetPointerArrayCountEvaluation()))
|
||||||
|
|
||||||
LINE_END(");")
|
LINE_END(");")
|
||||||
|
}
|
||||||
|
|
||||||
const MemberComputations computations(member);
|
const MemberComputations computations(member);
|
||||||
if (computations.IsInTempBlock())
|
if (computations.IsInTempBlock())
|
||||||
@ -1380,7 +1727,7 @@ namespace
|
|||||||
{
|
{
|
||||||
const MemberComputations computations(member);
|
const MemberComputations computations(member);
|
||||||
|
|
||||||
if (computations.IsFirstMember())
|
if (computations.IsFirstUsedMember())
|
||||||
{
|
{
|
||||||
LINE("")
|
LINE("")
|
||||||
if (member->m_condition)
|
if (member->m_condition)
|
||||||
@ -1399,7 +1746,7 @@ namespace
|
|||||||
LoadMember_Reference(info, member, DeclarationModifierComputations(member));
|
LoadMember_Reference(info, member, DeclarationModifierComputations(member));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (computations.IsLastMember())
|
else if (computations.IsLastUsedMember())
|
||||||
{
|
{
|
||||||
if (member->m_condition)
|
if (member->m_condition)
|
||||||
{
|
{
|
||||||
@ -1464,13 +1811,18 @@ namespace
|
|||||||
{
|
{
|
||||||
const StructureComputations computations(info);
|
const StructureComputations computations(info);
|
||||||
LINEF("void {0}::Load_{1}(const bool atStreamStart)", LoaderClassName(m_env.m_asset), info->m_definition->m_name)
|
LINEF("void {0}::Load_{1}(const bool atStreamStart)", LoaderClassName(m_env.m_asset), info->m_definition->m_name)
|
||||||
|
|
||||||
LINE("{")
|
LINE("{")
|
||||||
m_intendation++;
|
m_intendation++;
|
||||||
|
|
||||||
LINEF("assert({0} != nullptr);", MakeTypeVarName(info->m_definition))
|
LINEF("assert({0} != nullptr);", MakeTypeVarName(info->m_definition))
|
||||||
|
|
||||||
const auto* dynamicMember = computations.GetDynamicMember();
|
const auto* dynamicMember = computations.GetDynamicMember();
|
||||||
if (!(info->m_definition->GetType() == DataDefinitionType::UNION && dynamicMember))
|
if (!info->m_has_matching_cross_platform_structure && dynamicMember && !info->m_non_embedded_reference_exists)
|
||||||
|
{
|
||||||
|
LINE("assert(!atStreamStart);")
|
||||||
|
}
|
||||||
|
else if (!(info->m_definition->GetType() == DataDefinitionType::UNION && dynamicMember))
|
||||||
{
|
{
|
||||||
LINE("")
|
LINE("")
|
||||||
LINE("if (atStreamStart)")
|
LINE("if (atStreamStart)")
|
||||||
@ -1494,9 +1846,20 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (dynamicMember == nullptr)
|
||||||
{
|
{
|
||||||
LINEF("FillStruct_{0}(m_stream.LoadWithFill({1}));", MakeSafeTypeName(info->m_definition), info->m_definition->GetSize())
|
LINEF("FillStruct_{0}(m_stream.LoadWithFill({1}));", MakeSafeTypeName(info->m_definition), info->m_definition->GetSize())
|
||||||
}
|
}
|
||||||
|
else if (info->m_non_embedded_reference_exists)
|
||||||
|
{
|
||||||
|
LINEF("FillStruct_{0}(m_stream.GetLastFill());", MakeSafeTypeName(info->m_definition))
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LINE("assert(false);")
|
||||||
|
}
|
||||||
|
}
|
||||||
m_intendation--;
|
m_intendation--;
|
||||||
}
|
}
|
||||||
else if (!m_env.m_architecture_mismatch)
|
else if (!m_env.m_architecture_mismatch)
|
||||||
|
@ -655,7 +655,7 @@ namespace
|
|||||||
{
|
{
|
||||||
const MemberComputations computations(member);
|
const MemberComputations computations(member);
|
||||||
|
|
||||||
if (computations.IsFirstMember())
|
if (computations.IsFirstUsedMember())
|
||||||
{
|
{
|
||||||
LINE("")
|
LINE("")
|
||||||
if (member->m_condition)
|
if (member->m_condition)
|
||||||
@ -674,7 +674,7 @@ namespace
|
|||||||
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (computations.IsLastMember())
|
else if (computations.IsLastUsedMember())
|
||||||
{
|
{
|
||||||
if (member->m_condition)
|
if (member->m_condition)
|
||||||
{
|
{
|
||||||
|
@ -874,7 +874,7 @@ namespace
|
|||||||
{
|
{
|
||||||
const MemberComputations computations(member);
|
const MemberComputations computations(member);
|
||||||
|
|
||||||
if (computations.IsFirstMember())
|
if (computations.IsFirstUsedMember())
|
||||||
{
|
{
|
||||||
LINE("")
|
LINE("")
|
||||||
if (member->m_condition)
|
if (member->m_condition)
|
||||||
@ -893,7 +893,7 @@ namespace
|
|||||||
WriteMember_Reference(info, member, DeclarationModifierComputations(member));
|
WriteMember_Reference(info, member, DeclarationModifierComputations(member));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (computations.IsLastMember())
|
else if (computations.IsLastUsedMember())
|
||||||
{
|
{
|
||||||
if (member->m_condition)
|
if (member->m_condition)
|
||||||
{
|
{
|
||||||
|
@ -175,7 +175,7 @@ void ContentLoader::Load()
|
|||||||
#ifdef ARCH_x86
|
#ifdef ARCH_x86
|
||||||
m_stream.LoadDataRaw(&assetList, sizeof(assetList));
|
m_stream.LoadDataRaw(&assetList, sizeof(assetList));
|
||||||
#else
|
#else
|
||||||
auto fillAccessor = m_stream.LoadWithFill(16u);
|
const auto fillAccessor = m_stream.LoadWithFill(16u);
|
||||||
varScriptStringList = &varXAssetList->stringList;
|
varScriptStringList = &varXAssetList->stringList;
|
||||||
fillAccessor.Fill(varScriptStringList->count, 0u);
|
fillAccessor.Fill(varScriptStringList->count, 0u);
|
||||||
fillAccessor.FillPtr(varScriptStringList->strings, 4u);
|
fillAccessor.FillPtr(varScriptStringList->strings, 4u);
|
||||||
|
@ -11,11 +11,13 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
ZoneStreamFillReadAccessor::ZoneStreamFillReadAccessor(const void* dataBuffer, void* blockBuffer, const size_t bufferSize, const unsigned pointerByteCount)
|
ZoneStreamFillReadAccessor::ZoneStreamFillReadAccessor(
|
||||||
|
const void* dataBuffer, void* blockBuffer, const size_t bufferSize, const unsigned pointerByteCount, const size_t offset)
|
||||||
: m_data_buffer(dataBuffer),
|
: m_data_buffer(dataBuffer),
|
||||||
m_block_buffer(blockBuffer),
|
m_block_buffer(blockBuffer),
|
||||||
m_buffer_size(bufferSize),
|
m_buffer_size(bufferSize),
|
||||||
m_pointer_byte_count(pointerByteCount)
|
m_pointer_byte_count(pointerByteCount),
|
||||||
|
m_offset(offset)
|
||||||
{
|
{
|
||||||
// Otherwise we cannot insert alias
|
// Otherwise we cannot insert alias
|
||||||
assert(m_pointer_byte_count <= sizeof(uintptr_t));
|
assert(m_pointer_byte_count <= sizeof(uintptr_t));
|
||||||
@ -23,9 +25,17 @@ ZoneStreamFillReadAccessor::ZoneStreamFillReadAccessor(const void* dataBuffer, v
|
|||||||
|
|
||||||
ZoneStreamFillReadAccessor ZoneStreamFillReadAccessor::AtOffset(const size_t offset) const
|
ZoneStreamFillReadAccessor ZoneStreamFillReadAccessor::AtOffset(const size_t offset) const
|
||||||
{
|
{
|
||||||
assert(offset < m_buffer_size);
|
assert(offset <= m_buffer_size);
|
||||||
return ZoneStreamFillReadAccessor(
|
return ZoneStreamFillReadAccessor(static_cast<const char*>(m_data_buffer) + offset,
|
||||||
static_cast<const char*>(m_data_buffer) + offset, static_cast<char*>(m_block_buffer) + offset, m_buffer_size - offset, m_pointer_byte_count);
|
static_cast<char*>(m_block_buffer) + offset,
|
||||||
|
m_buffer_size - offset,
|
||||||
|
m_pointer_byte_count,
|
||||||
|
m_offset + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ZoneStreamFillReadAccessor::Offset() const
|
||||||
|
{
|
||||||
|
return m_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneStreamFillReadAccessor::InsertPointerRedirect(const uintptr_t aliasValue, const size_t offset) const
|
void ZoneStreamFillReadAccessor::InsertPointerRedirect(const uintptr_t aliasValue, const size_t offset) const
|
||||||
@ -117,7 +127,7 @@ namespace
|
|||||||
|
|
||||||
auto* block = m_block_stack.top();
|
auto* block = m_block_stack.top();
|
||||||
|
|
||||||
Align(align);
|
Align(*block, align);
|
||||||
|
|
||||||
if (m_block_offsets[block->m_index] > block->m_buffer_size)
|
if (m_block_offsets[block->m_index] > block->m_buffer_size)
|
||||||
throw BlockOverflowException(block);
|
throw BlockOverflowException(block);
|
||||||
@ -134,7 +144,7 @@ namespace
|
|||||||
|
|
||||||
auto* block = m_block_stack.top();
|
auto* block = m_block_stack.top();
|
||||||
|
|
||||||
Align(align);
|
Align(*block, align);
|
||||||
|
|
||||||
if (m_block_offsets[block->m_index] > block->m_buffer_size)
|
if (m_block_offsets[block->m_index] > block->m_buffer_size)
|
||||||
throw BlockOverflowException(block);
|
throw BlockOverflowException(block);
|
||||||
@ -163,23 +173,7 @@ namespace
|
|||||||
// Theoretically ptr should always be at the current block offset.
|
// Theoretically ptr should always be at the current block offset.
|
||||||
assert(dst == &block->m_buffer[m_block_offsets[block->m_index]]);
|
assert(dst == &block->m_buffer[m_block_offsets[block->m_index]]);
|
||||||
|
|
||||||
switch (block->m_type)
|
LoadDataFromBlock(*block, dst, size);
|
||||||
{
|
|
||||||
case XBlockType::BLOCK_TYPE_TEMP:
|
|
||||||
case XBlockType::BLOCK_TYPE_NORMAL:
|
|
||||||
m_stream.Load(dst, size);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case XBlockType::BLOCK_TYPE_RUNTIME:
|
|
||||||
std::memset(dst, 0, size);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case XBlockType::BLOCK_TYPE_DELAY:
|
|
||||||
assert(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
IncBlockPos(size);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -218,7 +212,7 @@ namespace
|
|||||||
|
|
||||||
ZoneStreamFillReadAccessor LoadWithFill(const size_t size) override
|
ZoneStreamFillReadAccessor LoadWithFill(const size_t size) override
|
||||||
{
|
{
|
||||||
m_fill_buffer.reserve(size);
|
m_fill_buffer.resize(size);
|
||||||
auto* dst = m_fill_buffer.data();
|
auto* dst = m_fill_buffer.data();
|
||||||
|
|
||||||
// If no block has been pushed, load raw
|
// If no block has been pushed, load raw
|
||||||
@ -227,65 +221,78 @@ namespace
|
|||||||
const auto* block = m_block_stack.top();
|
const auto* block = m_block_stack.top();
|
||||||
auto* blockBufferForFill = &block->m_buffer[m_block_offsets[block->m_index]];
|
auto* blockBufferForFill = &block->m_buffer[m_block_offsets[block->m_index]];
|
||||||
|
|
||||||
switch (block->m_type)
|
LoadDataFromBlock(*block, dst, size);
|
||||||
|
|
||||||
|
return ZoneStreamFillReadAccessor(dst, blockBufferForFill, size, m_pointer_byte_count, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_stream.Load(dst, size);
|
||||||
|
return ZoneStreamFillReadAccessor(dst, nullptr, size, m_pointer_byte_count, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneStreamFillReadAccessor AppendToFill(const size_t appendSize) override
|
||||||
{
|
{
|
||||||
case XBlockType::BLOCK_TYPE_TEMP:
|
const auto appendOffset = m_fill_buffer.size();
|
||||||
case XBlockType::BLOCK_TYPE_NORMAL:
|
m_fill_buffer.resize(appendOffset + appendSize);
|
||||||
m_stream.Load(dst, size);
|
auto* dst = m_fill_buffer.data() + appendOffset;
|
||||||
break;
|
|
||||||
|
|
||||||
case XBlockType::BLOCK_TYPE_RUNTIME:
|
const auto newTotalSize = appendOffset + appendSize;
|
||||||
std::memset(dst, 0, size);
|
// If no block has been pushed, load raw
|
||||||
break;
|
if (!m_block_stack.empty())
|
||||||
|
{
|
||||||
|
const auto* block = m_block_stack.top();
|
||||||
|
auto* blockBufferForFill = &block->m_buffer[m_block_offsets[block->m_index]] - appendOffset;
|
||||||
|
|
||||||
case XBlockType::BLOCK_TYPE_DELAY:
|
LoadDataFromBlock(*block, dst, appendSize);
|
||||||
assert(false);
|
|
||||||
break;
|
return ZoneStreamFillReadAccessor(m_fill_buffer.data(), blockBufferForFill, newTotalSize, m_pointer_byte_count, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
IncBlockPos(size);
|
m_stream.Load(dst, appendSize);
|
||||||
|
return ZoneStreamFillReadAccessor(m_fill_buffer.data(), nullptr, newTotalSize, m_pointer_byte_count, 0);
|
||||||
return ZoneStreamFillReadAccessor(dst, blockBufferForFill, size, m_pointer_byte_count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stream.Load(dst, size);
|
ZoneStreamFillReadAccessor GetLastFill() override
|
||||||
return ZoneStreamFillReadAccessor(dst, nullptr, size, m_pointer_byte_count);
|
{
|
||||||
|
assert(!m_fill_buffer.empty());
|
||||||
|
|
||||||
|
if (!m_block_stack.empty())
|
||||||
|
{
|
||||||
|
const auto* block = m_block_stack.top();
|
||||||
|
auto* blockBufferForFill = &block->m_buffer[m_block_offsets[block->m_index]] - m_fill_buffer.size();
|
||||||
|
|
||||||
|
return ZoneStreamFillReadAccessor(m_fill_buffer.data(), blockBufferForFill, m_fill_buffer.size(), m_pointer_byte_count, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ZoneStreamFillReadAccessor(m_fill_buffer.data(), nullptr, m_fill_buffer.size(), m_pointer_byte_count, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* InsertPointerNative() override
|
void* InsertPointerNative() override
|
||||||
{
|
{
|
||||||
m_block_stack.push(m_insert_block);
|
|
||||||
|
|
||||||
// Alignment of pointer should always be its size
|
// Alignment of pointer should always be its size
|
||||||
Align(m_pointer_byte_count);
|
Align(*m_insert_block, m_pointer_byte_count);
|
||||||
|
|
||||||
if (m_block_offsets[m_insert_block->m_index] + m_pointer_byte_count > m_insert_block->m_buffer_size)
|
if (m_block_offsets[m_insert_block->m_index] + m_pointer_byte_count > m_insert_block->m_buffer_size)
|
||||||
throw BlockOverflowException(m_insert_block);
|
throw BlockOverflowException(m_insert_block);
|
||||||
|
|
||||||
auto* ptr = static_cast<void*>(&m_insert_block->m_buffer[m_block_offsets[m_insert_block->m_index]]);
|
auto* ptr = static_cast<void*>(&m_insert_block->m_buffer[m_block_offsets[m_insert_block->m_index]]);
|
||||||
|
|
||||||
IncBlockPos(m_pointer_byte_count);
|
IncBlockPos(*m_insert_block, m_pointer_byte_count);
|
||||||
|
|
||||||
m_block_stack.pop();
|
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t InsertPointerAliasLookup() override
|
uintptr_t InsertPointerAliasLookup() override
|
||||||
{
|
{
|
||||||
m_block_stack.push(m_insert_block);
|
|
||||||
|
|
||||||
// Alignment of pointer should always be its size
|
// Alignment of pointer should always be its size
|
||||||
Align(m_pointer_byte_count);
|
Align(*m_insert_block, m_pointer_byte_count);
|
||||||
|
|
||||||
if (m_block_offsets[m_insert_block->m_index] + m_pointer_byte_count > m_insert_block->m_buffer_size)
|
if (m_block_offsets[m_insert_block->m_index] + m_pointer_byte_count > m_insert_block->m_buffer_size)
|
||||||
throw BlockOverflowException(m_insert_block);
|
throw BlockOverflowException(m_insert_block);
|
||||||
|
|
||||||
auto* ptr = static_cast<void*>(&m_insert_block->m_buffer[m_block_offsets[m_insert_block->m_index]]);
|
auto* ptr = static_cast<void*>(&m_insert_block->m_buffer[m_block_offsets[m_insert_block->m_index]]);
|
||||||
|
|
||||||
IncBlockPos(m_pointer_byte_count);
|
IncBlockPos(*m_insert_block, m_pointer_byte_count);
|
||||||
|
|
||||||
m_block_stack.pop();
|
|
||||||
|
|
||||||
const auto newLookupIndex = static_cast<uintptr_t>(m_alias_lookup.size()) + 1;
|
const auto newLookupIndex = static_cast<uintptr_t>(m_alias_lookup.size()) + 1;
|
||||||
m_alias_lookup.emplace_back(nullptr);
|
m_alias_lookup.emplace_back(nullptr);
|
||||||
@ -410,24 +417,37 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void IncBlockPos(const size_t size)
|
void LoadDataFromBlock(const XBlock& block, void* dst, const size_t size)
|
||||||
{
|
{
|
||||||
assert(!m_block_stack.empty());
|
switch (block.m_type)
|
||||||
|
{
|
||||||
|
case XBlockType::BLOCK_TYPE_TEMP:
|
||||||
|
case XBlockType::BLOCK_TYPE_NORMAL:
|
||||||
|
m_stream.Load(dst, size);
|
||||||
|
break;
|
||||||
|
|
||||||
if (m_block_stack.empty())
|
case XBlockType::BLOCK_TYPE_RUNTIME:
|
||||||
return;
|
std::memset(dst, 0, size);
|
||||||
|
break;
|
||||||
|
|
||||||
const auto* block = m_block_stack.top();
|
case XBlockType::BLOCK_TYPE_DELAY:
|
||||||
m_block_offsets[block->m_index] += size;
|
assert(false);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Align(const unsigned align)
|
IncBlockPos(block, size);
|
||||||
{
|
}
|
||||||
assert(!m_block_stack.empty());
|
|
||||||
|
|
||||||
|
void IncBlockPos(const XBlock& block, const size_t size)
|
||||||
|
{
|
||||||
|
m_block_offsets[block.m_index] += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Align(const XBlock& block, const unsigned align)
|
||||||
|
{
|
||||||
if (align > 0)
|
if (align > 0)
|
||||||
{
|
{
|
||||||
const auto blockIndex = m_block_stack.top()->m_index;
|
const auto blockIndex = block.m_index;
|
||||||
m_block_offsets[blockIndex] = utils::Align(m_block_offsets[blockIndex], static_cast<size_t>(align));
|
m_block_offsets[blockIndex] = utils::Align(m_block_offsets[blockIndex], static_cast<size_t>(align));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,10 @@
|
|||||||
class ZoneStreamFillReadAccessor
|
class ZoneStreamFillReadAccessor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ZoneStreamFillReadAccessor(const void* dataBuffer, void* blockBuffer, size_t bufferSize, unsigned pointerByteCount);
|
ZoneStreamFillReadAccessor(const void* dataBuffer, void* blockBuffer, size_t bufferSize, unsigned pointerByteCount, size_t offset);
|
||||||
|
|
||||||
[[nodiscard]] ZoneStreamFillReadAccessor AtOffset(size_t offset) const;
|
[[nodiscard]] ZoneStreamFillReadAccessor AtOffset(size_t offset) const;
|
||||||
|
[[nodiscard]] size_t Offset() const;
|
||||||
|
|
||||||
template<typename T> void Fill(T& value, const size_t offset) const
|
template<typename T> void Fill(T& value, const size_t offset) const
|
||||||
{
|
{
|
||||||
@ -48,6 +49,7 @@ private:
|
|||||||
void* m_block_buffer;
|
void* m_block_buffer;
|
||||||
size_t m_buffer_size;
|
size_t m_buffer_size;
|
||||||
unsigned m_pointer_byte_count;
|
unsigned m_pointer_byte_count;
|
||||||
|
size_t m_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ZoneInputStream : public IZoneStream
|
class ZoneInputStream : public IZoneStream
|
||||||
@ -104,6 +106,8 @@ public:
|
|||||||
virtual void LoadDataInBlock(void* dst, size_t size) = 0;
|
virtual void LoadDataInBlock(void* dst, size_t size) = 0;
|
||||||
virtual void LoadNullTerminated(void* dst) = 0;
|
virtual void LoadNullTerminated(void* dst) = 0;
|
||||||
virtual ZoneStreamFillReadAccessor LoadWithFill(size_t size) = 0;
|
virtual ZoneStreamFillReadAccessor LoadWithFill(size_t size) = 0;
|
||||||
|
virtual ZoneStreamFillReadAccessor AppendToFill(size_t appendSize) = 0;
|
||||||
|
virtual ZoneStreamFillReadAccessor GetLastFill() = 0;
|
||||||
|
|
||||||
template<typename T> void Load(T* dst)
|
template<typename T> void Load(T* dst)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user