|
|
@ -14,6 +14,14 @@ |
|
|
|
|
|
|
|
|
namespace Dynarmic::Backend::Arm64 { |
|
|
namespace Dynarmic::Backend::Arm64 { |
|
|
|
|
|
|
|
|
|
|
|
namespace impl { |
|
|
|
|
|
template<typename T, typename P> inline T bit_cast_pointee(const P source_ptr) noexcept { |
|
|
|
|
|
std::aligned_storage_t<sizeof(T), alignof(T)> dest; |
|
|
|
|
|
std::memcpy(&dest, bit_cast<void*>(source_ptr), sizeof(T)); |
|
|
|
|
|
return reinterpret_cast<T&>(dest); |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
struct DevirtualizedCall { |
|
|
struct DevirtualizedCall { |
|
|
u64 fn_ptr; |
|
|
u64 fn_ptr; |
|
|
u64 this_ptr; |
|
|
u64 this_ptr; |
|
|
@ -42,8 +50,8 @@ DevirtualizedCall DevirtualizeDefault(mcl::class_type<decltype(mfp)>* this_) { |
|
|
u64 fn_ptr = mfp_struct.ptr; |
|
|
u64 fn_ptr = mfp_struct.ptr; |
|
|
u64 this_ptr = std::bit_cast<u64>(this_) + (mfp_struct.adj >> 1); |
|
|
u64 this_ptr = std::bit_cast<u64>(this_) + (mfp_struct.adj >> 1); |
|
|
if (mfp_struct.adj & 1) { |
|
|
if (mfp_struct.adj & 1) { |
|
|
u64 vtable = *reinterpret_cast<u64 const*>(this_ptr); |
|
|
|
|
|
fn_ptr = *reinterpret_cast<u64 const*>(vtable + fn_ptr); |
|
|
|
|
|
|
|
|
u64 vtable = impl::bit_cast_pointee<u64>(this_ptr); |
|
|
|
|
|
fn_ptr = impl::bit_cast_pointee<u64>(vtable + fn_ptr); |
|
|
} |
|
|
} |
|
|
return DevirtualizedCall{fn_ptr, this_ptr}; |
|
|
return DevirtualizedCall{fn_ptr, this_ptr}; |
|
|
} |
|
|
} |
|
|
|