2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2026-01-19 15:01:49 +00:00

fix: ReusableAddOffset not respecting differing block and memory sizes

This commit is contained in:
Jan Laupetin
2026-01-14 18:36:25 +00:00
parent 51300bb47c
commit 9f559fdcd0
3 changed files with 35 additions and 20 deletions

View File

@@ -731,31 +731,37 @@ namespace
return; return;
} }
LINE_STARTF("m_stream->ReusableAddOffset({0}", MakeMemberAccess(info, member, modifier))
if (writeType == MemberWriteType::ARRAY_POINTER) if (writeType == MemberWriteType::ARRAY_POINTER)
{ {
LINEF("m_stream->ReusableAddOffset({0}, {1});", if (member->m_type && !member->m_type->m_has_matching_cross_platform_structure)
MakeMemberAccess(info, member, modifier), {
MakeEvaluation(modifier.GetArrayPointerCountEvaluation())) LINE_MIDDLEF(", {0}", member->m_type->m_definition->GetSize())
}
LINE_MIDDLEF(", {0}", MakeEvaluation(modifier.GetArrayPointerCountEvaluation()))
} }
else if (writeType == MemberWriteType::POINTER_ARRAY) else if (writeType == MemberWriteType::POINTER_ARRAY)
{ {
if (member->m_type && !member->m_type->m_has_matching_cross_platform_structure)
{
LINE_MIDDLEF(", {0}", m_env.m_pointer_size)
}
const auto* evaluation = modifier.GetPointerArrayCountEvaluation(); const auto* evaluation = modifier.GetPointerArrayCountEvaluation();
if (evaluation) if (evaluation)
{ {
LINEF("m_stream->ReusableAddOffset({0}, {1});", LINE_MIDDLEF(", {0}", MakeEvaluation(modifier.GetPointerArrayCountEvaluation()))
MakeMemberAccess(info, member, modifier),
MakeEvaluation(modifier.GetPointerArrayCountEvaluation()))
} }
else else
{ {
LINEF("m_stream->ReusableAddOffset({0}, {1});", MakeMemberAccess(info, member, modifier), modifier.GetArraySize()) LINE_MIDDLEF(", {0}", modifier.GetArraySize())
} }
} }
else
{ LINE_END(");")
LINEF("m_stream->ReusableAddOffset({0});", MakeMemberAccess(info, member, modifier))
}
WriteMember_TypeCheck(info, member, modifier, writeType); WriteMember_TypeCheck(info, member, modifier, writeType);
} }

View File

@@ -17,12 +17,13 @@ namespace
class ReusableEntry class ReusableEntry
{ {
public: public:
ReusableEntry(void* startPtr, const size_t entrySize, const size_t entryCount, const uintptr_t startZonePtr) ReusableEntry(void* startPtr, const size_t entrySize, const size_t entryCount, const size_t blockSize, const uintptr_t startZonePtr)
: m_start_ptr(startPtr), : m_start_ptr(startPtr),
m_end_ptr(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(startPtr) + entrySize * entryCount)), m_end_ptr(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(startPtr) + entrySize * entryCount)),
m_start_zone_ptr(startZonePtr), m_start_zone_ptr(startZonePtr),
m_entry_size(entrySize), m_entry_size(entrySize),
m_entry_count(entryCount) m_entry_count(entryCount),
m_block_size(blockSize)
{ {
} }
@@ -31,6 +32,7 @@ namespace
uintptr_t m_start_zone_ptr; uintptr_t m_start_zone_ptr;
size_t m_entry_size; size_t m_entry_size;
size_t m_entry_count; size_t m_entry_count;
size_t m_block_size;
}; };
class InMemoryZoneOutputStream final : public ZoneOutputStream class InMemoryZoneOutputStream final : public ZoneOutputStream
@@ -245,7 +247,9 @@ namespace
if (ptr >= entry.m_start_ptr && ptr < entry.m_end_ptr) if (ptr >= entry.m_start_ptr && ptr < entry.m_end_ptr)
{ {
assert((reinterpret_cast<uintptr_t>(ptr) - reinterpret_cast<uintptr_t>(entry.m_start_ptr)) % entrySize == 0); assert((reinterpret_cast<uintptr_t>(ptr) - reinterpret_cast<uintptr_t>(entry.m_start_ptr)) % entrySize == 0);
const auto finalZonePointer = entry.m_start_zone_ptr + (reinterpret_cast<uintptr_t>(ptr) - reinterpret_cast<uintptr_t>(entry.m_start_ptr));
const auto entryIndex = (reinterpret_cast<uintptr_t>(ptr) - reinterpret_cast<uintptr_t>(entry.m_start_ptr)) / entry.m_entry_size;
const auto finalZonePointer = entry.m_start_zone_ptr + entryIndex * entry.m_block_size;
auto* writtenPtrOffset = outputOffset.Offset(); auto* writtenPtrOffset = outputOffset.Offset();
for (auto i = 0u; i < m_pointer_byte_count; i++) for (auto i = 0u; i < m_pointer_byte_count; i++)
@@ -258,7 +262,7 @@ namespace
return true; return true;
} }
void ReusableAddOffset(void* ptr, size_t size, size_t count, std::type_index type) override void ReusableAddOffset(void* ptr, const size_t size, const size_t count, const size_t blockSize, std::type_index type) override
{ {
assert(!m_block_stack.empty()); assert(!m_block_stack.empty());
@@ -268,12 +272,12 @@ namespace
if (foundEntriesForType == m_reusable_entries.end()) if (foundEntriesForType == m_reusable_entries.end())
{ {
std::vector<ReusableEntry> entries; std::vector<ReusableEntry> entries;
entries.emplace_back(ptr, size, count, zoneOffset); entries.emplace_back(ptr, size, count, blockSize, zoneOffset);
m_reusable_entries.emplace(std::make_pair(type, std::move(entries))); m_reusable_entries.emplace(std::make_pair(type, std::move(entries)));
} }
else else
{ {
foundEntriesForType->second.emplace_back(ptr, size, count, zoneOffset); foundEntriesForType->second.emplace_back(ptr, size, count, blockSize, zoneOffset);
} }
} }

View File

@@ -93,7 +93,7 @@ public:
virtual ZoneStreamFillWriteAccessor WriteWithFill(size_t size) = 0; virtual ZoneStreamFillWriteAccessor WriteWithFill(size_t size) = 0;
virtual bool ReusableShouldWrite(void* pPtr, ZoneOutputOffset outputOffset, size_t size, std::type_index type) = 0; virtual bool ReusableShouldWrite(void* pPtr, ZoneOutputOffset outputOffset, size_t size, std::type_index type) = 0;
virtual void ReusableAddOffset(void* ptr, size_t size, size_t count, std::type_index type) = 0; virtual void ReusableAddOffset(void* ptr, size_t size, size_t count, size_t blockSize, std::type_index type) = 0;
virtual void MarkFollowing(ZoneOutputOffset offset) = 0; virtual void MarkFollowing(ZoneOutputOffset offset) = 0;
template<typename T> bool ReusableShouldWrite(T* pPtr, const ZoneOutputOffset outputOffset) template<typename T> bool ReusableShouldWrite(T* pPtr, const ZoneOutputOffset outputOffset)
@@ -103,12 +103,17 @@ public:
template<typename T> void ReusableAddOffset(T* ptr) template<typename T> void ReusableAddOffset(T* ptr)
{ {
ReusableAddOffset(const_cast<void*>(reinterpret_cast<const void*>(ptr)), sizeof(T), 1, std::type_index(typeid(T))); ReusableAddOffset(const_cast<void*>(reinterpret_cast<const void*>(ptr)), sizeof(T), 1, sizeof(T), std::type_index(typeid(T)));
} }
template<typename T> void ReusableAddOffset(T* ptr, const size_t count) template<typename T> void ReusableAddOffset(T* ptr, const size_t count)
{ {
ReusableAddOffset(const_cast<void*>(reinterpret_cast<const void*>(ptr)), sizeof(T), count, std::type_index(typeid(T))); ReusableAddOffset(const_cast<void*>(reinterpret_cast<const void*>(ptr)), sizeof(T), count, sizeof(T), std::type_index(typeid(T)));
}
template<typename T> void ReusableAddOffset(T* ptr, const size_t blockSize, const size_t count)
{
ReusableAddOffset(const_cast<void*>(reinterpret_cast<const void*>(ptr)), sizeof(T), count, blockSize, std::type_index(typeid(T)));
} }
template<typename T> ZoneOutputOffset Write(T* dst) template<typename T> ZoneOutputOffset Write(T* dst)