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
This commit is contained in:
parent
dd36a52048
commit
e23d61d124
1 changed files with 19 additions and 2 deletions
|
@ -16,8 +16,16 @@ struct DevirtualizedCall {
|
||||||
u64 this_ptr;
|
u64 this_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// https://rants.vastheman.com/2021/09/21/msvc/
|
||||||
template<auto mfp>
|
template<auto mfp>
|
||||||
DevirtualizedCall Devirtualize(mcl::class_type<decltype(mfp)>* this_) {
|
DevirtualizedCall DevirtualizeWindows(mcl::class_type<decltype(mfp)>* this_) {
|
||||||
|
static_assert(sizeof(mfp) == 8);
|
||||||
|
return DevirtualizedCall{mcl::bit_cast<u64>(mfp), reinterpret_cast<u64>(this_)};
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/ARM-software/abi-aa/blob/main/cppabi64/cppabi64.rst#representation-of-pointer-to-member-function
|
||||||
|
template<auto mfp>
|
||||||
|
DevirtualizedCall DevirtualizeDefault(mcl::class_type<decltype(mfp)>* this_) {
|
||||||
struct MemberFunctionPointer {
|
struct MemberFunctionPointer {
|
||||||
// Address of non-virtual function or index into vtable.
|
// Address of non-virtual function or index into vtable.
|
||||||
u64 ptr;
|
u64 ptr;
|
||||||
|
@ -34,7 +42,16 @@ DevirtualizedCall Devirtualize(mcl::class_type<decltype(mfp)>* this_) {
|
||||||
u64 vtable = mcl::bit_cast_pointee<u64>(this_ptr);
|
u64 vtable = mcl::bit_cast_pointee<u64>(this_ptr);
|
||||||
fn_ptr = mcl::bit_cast_pointee<u64>(vtable + fn_ptr);
|
fn_ptr = mcl::bit_cast_pointee<u64>(vtable + fn_ptr);
|
||||||
}
|
}
|
||||||
return {fn_ptr, this_ptr};
|
return DevirtualizedCall{fn_ptr, this_ptr};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<auto mfp>
|
||||||
|
DevirtualizedCall Devirtualize(mcl::class_type<decltype(mfp)>* this_) {
|
||||||
|
#if defined(_WIN32)
|
||||||
|
return DevirtualizeWindows<mfp>(this_);
|
||||||
|
#else
|
||||||
|
return DevirtualizeDefault<mfp>(this_);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::Backend::Arm64
|
} // namespace Dynarmic::Backend::Arm64
|
||||||
|
|
Loading…
Reference in a new issue