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;
|
||||
};
|
||||
|
||||
// https://rants.vastheman.com/2021/09/21/msvc/
|
||||
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 {
|
||||
// Address of non-virtual function or index into vtable.
|
||||
u64 ptr;
|
||||
|
@ -34,7 +42,16 @@ DevirtualizedCall Devirtualize(mcl::class_type<decltype(mfp)>* this_) {
|
|||
u64 vtable = mcl::bit_cast_pointee<u64>(this_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
|
||||
|
|
Loading…
Reference in a new issue