diff --git a/src/dynarmic/src/dynarmic/backend/arm64/devirtualize.h b/src/dynarmic/src/dynarmic/backend/arm64/devirtualize.h index faa349a750..6c54d0ca9b 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/devirtualize.h +++ b/src/dynarmic/src/dynarmic/backend/arm64/devirtualize.h @@ -14,6 +14,14 @@ namespace Dynarmic::Backend::Arm64 { +namespace impl { +template inline T bit_cast_pointee(const P source_ptr) noexcept { + std::aligned_storage_t dest; + std::memcpy(&dest, bit_cast(source_ptr), sizeof(T)); + return reinterpret_cast(dest); +} +}; + struct DevirtualizedCall { u64 fn_ptr; u64 this_ptr; @@ -42,8 +50,8 @@ DevirtualizedCall DevirtualizeDefault(mcl::class_type* this_) { u64 fn_ptr = mfp_struct.ptr; u64 this_ptr = std::bit_cast(this_) + (mfp_struct.adj >> 1); if (mfp_struct.adj & 1) { - u64 vtable = *reinterpret_cast(this_ptr); - fn_ptr = *reinterpret_cast(vtable + fn_ptr); + u64 vtable = impl::bit_cast_pointee(this_ptr); + fn_ptr = impl::bit_cast_pointee(vtable + fn_ptr); } return DevirtualizedCall{fn_ptr, this_ptr}; } diff --git a/src/dynarmic/src/dynarmic/backend/x64/devirtualize.h b/src/dynarmic/src/dynarmic/backend/x64/devirtualize.h index 9a0736ff87..b63b4e7b36 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/devirtualize.h +++ b/src/dynarmic/src/dynarmic/backend/x64/devirtualize.h @@ -32,6 +32,12 @@ struct ThunkBuilder { } }; +template inline T bit_cast_pointee(const P source_ptr) noexcept { + std::aligned_storage_t dest; + std::memcpy(&dest, bit_cast(source_ptr), sizeof(T)); + return reinterpret_cast(dest); +} + } // namespace impl template @@ -61,8 +67,8 @@ ArgCallback DevirtualizeItanium(mcl::class_type* this_) { u64 fn_ptr = mfp_struct.ptr; u64 this_ptr = reinterpret_cast(this_) + mfp_struct.adj; if (mfp_struct.ptr & 1) { - u64 vtable = *reinterpret_cast(this_ptr); - fn_ptr = *reinterpret_cast(vtable + fn_ptr - 1); + u64 vtable = impl::bit_cast_pointee(this_ptr); + fn_ptr = impl::bit_cast_pointee(vtable + fn_ptr - 1); } return ArgCallback{fn_ptr, this_ptr}; }