From e23d61d12488dbf36c493c96c7607aaef176fab9 Mon Sep 17 00:00:00 2001 From: Wunk Date: Tue, 15 Nov 2022 12:22:47 -0800 Subject: [PATCH] backend/arm64: Add MSVC C++ ABI devirtualization (#718) MSVC C++ uses a non-standard ABI definition that must be specially handled: https://rants.vastheman.com/2021/09/21/msvc --- src/dynarmic/backend/arm64/devirtualize.h | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) 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