meta floating point vectorcall patch

This commit is contained in:
altalk23 2022-12-17 19:56:26 +03:00
parent 56cfbde73d
commit 608e18ee10
2 changed files with 75 additions and 11 deletions
loader/include/Geode/meta

View file

@ -21,7 +21,7 @@ namespace geode::core::meta::x86 {
public:
class Sequences {
private:
public:
// These are required for proper reordering.
static constexpr size_t length = sizeof...(Args);
@ -138,6 +138,27 @@ namespace geode::core::meta::x86 {
using from = typename MyConv::template arr_to_seq<from_arr>;
};
template <class Type>
struct TinyWrapper {
Type m_value;
TinyWrapper(Type value) : m_value(value) {}
// to make sure this class doesn't get registered as a hva
TinyWrapper(TinyWrapper const& other) : m_value(other.m_value) {}
};
template <class Type, size_t idx>
struct TypeReplace {
using type = Type;
};
template <class Type, size_t idx>
requires (std::is_floating_point_v<Type> && idx > Sequences::SSES && idx < Sequences::length)
struct TypeReplace<Type, idx> {
using type = TinyWrapper<Type>;
};
protected:
// Where all the logic is actually implemented.
template <class Class, class>
@ -154,7 +175,7 @@ namespace geode::core::meta::x86 {
public:
static Ret invoke(void* address, Tuple<Args..., float, int> const& all) {
return reinterpret_cast<Ret(__vectorcall*)(
typename Tuple<Args..., float, int>::template type_at<to>...
typename TypeReplace<typename Tuple<Args..., float, int>::template type_at<to>, to>::type...
)>(address)(all.template at<to>()...);
}
@ -163,7 +184,7 @@ namespace geode::core::meta::x86 {
/* It's wrapped to stop MSVC from giving me error messages with internal compiler
* info. WTF.
*/
typename Tuple<Args..., float, int>::template type_at_wrap<to>... raw
typename TypeReplace<typename Tuple<Args..., float, int>::template type_at_wrap<to>, to>::type... raw
) {
auto all = Tuple<>::make(raw...);
return detour(all.template at<from>()...);
@ -197,6 +218,27 @@ namespace geode::core::meta::x86 {
protected:
using Sequences = typename Membercall<Ret*, Class, Ret*, Args...>::Sequences;
template <class Type>
struct TinyWrapper {
Type m_value;
TinyWrapper(Type value) : m_value(value) {}
// to make sure this class doesn't get registered as a hva
TinyWrapper(TinyWrapper const& other) : m_value(other.m_value) {}
};
template <class Type, size_t idx>
struct TypeReplace {
using type = Type;
};
template <class Type, size_t idx>
requires (std::is_floating_point_v<Type> && idx > Sequences::SSES && idx < Sequences::length)
struct TypeReplace<Type, idx> {
using type = TinyWrapper<Type>;
};
// Where all the logic is actually implemented.
template <class Class, class>
@ -213,7 +255,7 @@ namespace geode::core::meta::x86 {
public:
static Ret* invoke(void* address, Tuple<Class, Ret*, Args..., float, int> const& all) {
return reinterpret_cast<Ret*(__vectorcall*)(
typename Tuple<Class, Ret*, Args..., float, int>::template type_at<to>...
typename TypeReplace<typename Tuple<Class, Ret*, Args..., float, int>::template type_at<to>, to>::type...
)>(address)(all.template at<to>()...);
}
@ -222,7 +264,7 @@ namespace geode::core::meta::x86 {
/* It's wrapped to stop MSVC from giving me error messages with internal compiler
* info. WTF.
*/
typename Tuple<Class, Ret*, Args..., float, int>::template type_at_wrap<to>... raw
typename TypeReplace<typename Tuple<Class, Ret*, Args..., float, int>::template type_at_wrap<to>, to>::type... raw
) {
auto all = Tuple<>::make(raw...);
return reinterpret_cast<Ret*(*)(Class, Ret*, Args...)>(detour)(all.template at<from>()...);

View file

@ -15,7 +15,7 @@ namespace geode::core::meta::x86 {
private:
// These go in a class to not pollute the namespace.
class Sequences {
private:
public:
// These are required for proper reordering.
static constexpr size_t length = sizeof...(Args);
@ -152,6 +152,27 @@ namespace geode::core::meta::x86 {
using stack = typename MyConv::template arr_to_seq<stack_arr>;
};
template <class Type>
struct TinyWrapper {
Type m_value;
TinyWrapper(Type value) : m_value(value) {}
// to make sure this class doesn't get registered as a hva
TinyWrapper(TinyWrapper const& other) : m_value(other.m_value) {}
};
template <class Type, size_t idx>
struct TypeReplace {
using type = Type;
};
template <class Type, size_t idx>
requires (std::is_floating_point_v<Type> && idx > Sequences::SSES && idx < Sequences::length)
struct TypeReplace<Type, idx> {
using type = TinyWrapper<Type>;
};
private:
// Where all the logic is actually implemented.
template <class Class, class, class>
@ -175,9 +196,9 @@ namespace geode::core::meta::x86 {
static Ret invoke(void* address, Tuple<Args..., float> const& all) {
if constexpr (!std::is_same_v<Ret, void>) {
Ret ret =
reinterpret_cast<Ret(__vectorcall*)(decltype(all.template at<to>())...)>(
address
)(all.template at<to>()...);
reinterpret_cast<Ret(__vectorcall*)(
typename TypeReplace<typename Tuple<Args..., float>::template type_at<to>, to>::type...
)>(address)(all.template at<to>()...);
if constexpr (fix != 0) {
__asm add esp, [fix]
@ -186,8 +207,9 @@ namespace geode::core::meta::x86 {
return ret;
}
else {
reinterpret_cast<Ret(__vectorcall*)(decltype(all.template at<to>())...)>(address
)(all.template at<to>()...);
reinterpret_cast<Ret(__vectorcall*)(
typename TypeReplace<typename Tuple<Args..., float>::template type_at<to>, to>::type...
)>(address)(all.template at<to>()...);
if constexpr (fix != 0) {
__asm add esp, [fix]