diff --git a/src/dynarmic/backend/arm64/devirtualize.h b/src/dynarmic/backend/arm64/devirtualize.h index edddc954..14057db5 100644 --- a/src/dynarmic/backend/arm64/devirtualize.h +++ b/src/dynarmic/backend/arm64/devirtualize.h @@ -16,8 +16,16 @@ struct DevirtualizedCall { u64 this_ptr; }; +// https://rants.vastheman.com/2021/09/21/msvc/ template -DevirtualizedCall Devirtualize(mcl::class_type* this_) { +DevirtualizedCall DevirtualizeWindows(mcl::class_type* this_) { + static_assert(sizeof(mfp) == 8); + return DevirtualizedCall{mcl::bit_cast(mfp), reinterpret_cast(this_)}; +} + +// https://github.com/ARM-software/abi-aa/blob/main/cppabi64/cppabi64.rst#representation-of-pointer-to-member-function +template +DevirtualizedCall DevirtualizeDefault(mcl::class_type* this_) { struct MemberFunctionPointer { // Address of non-virtual function or index into vtable. u64 ptr; @@ -34,7 +42,16 @@ DevirtualizedCall Devirtualize(mcl::class_type* this_) { u64 vtable = mcl::bit_cast_pointee(this_ptr); fn_ptr = mcl::bit_cast_pointee(vtable + fn_ptr); } - return {fn_ptr, this_ptr}; + return DevirtualizedCall{fn_ptr, this_ptr}; +} + +template +DevirtualizedCall Devirtualize(mcl::class_type* this_) { +#if defined(_WIN32) + return DevirtualizeWindows(this_); +#else + return DevirtualizeDefault(this_); +#endif } } // namespace Dynarmic::Backend::Arm64