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;
}
LINE_STARTF("m_stream->ReusableAddOffset({0}", MakeMemberAccess(info, member, modifier))
if (writeType == MemberWriteType::ARRAY_POINTER)
{
LINEF("m_stream->ReusableAddOffset({0}, {1});",
MakeMemberAccess(info, member, modifier),
MakeEvaluation(modifier.GetArrayPointerCountEvaluation()))
if (member->m_type && !member->m_type->m_has_matching_cross_platform_structure)
{
LINE_MIDDLEF(", {0}", member->m_type->m_definition->GetSize())
}
LINE_MIDDLEF(", {0}", MakeEvaluation(modifier.GetArrayPointerCountEvaluation()))
}
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();
if (evaluation)
{
LINEF("m_stream->ReusableAddOffset({0}, {1});",
MakeMemberAccess(info, member, modifier),
MakeEvaluation(modifier.GetPointerArrayCountEvaluation()))
LINE_MIDDLEF(", {0}", MakeEvaluation(modifier.GetPointerArrayCountEvaluation()))
}
else
{
LINEF("m_stream->ReusableAddOffset({0}, {1});", MakeMemberAccess(info, member, modifier), modifier.GetArraySize())
LINE_MIDDLEF(", {0}", modifier.GetArraySize())
}
}
else
{
LINEF("m_stream->ReusableAddOffset({0});", MakeMemberAccess(info, member, modifier))
}
LINE_END(");")
WriteMember_TypeCheck(info, member, modifier, writeType);
}

View File

@@ -17,12 +17,13 @@ namespace
class ReusableEntry
{
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_end_ptr(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(startPtr) + entrySize * entryCount)),
m_start_zone_ptr(startZonePtr),
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;
size_t m_entry_size;
size_t m_entry_count;
size_t m_block_size;
};
class InMemoryZoneOutputStream final : public ZoneOutputStream
@@ -245,7 +247,9 @@ namespace
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);
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();
for (auto i = 0u; i < m_pointer_byte_count; i++)
@@ -258,7 +262,7 @@ namespace
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());
@@ -268,12 +272,12 @@ namespace
if (foundEntriesForType == m_reusable_entries.end())
{
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)));
}
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 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;
template<typename T> bool ReusableShouldWrite(T* pPtr, const ZoneOutputOffset outputOffset)
@@ -103,12 +103,17 @@ public:
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)
{
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)