From 3c48c17debe9655f6b46476f409ee03562c320be Mon Sep 17 00:00:00 2001 From: Skyth <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Mon, 25 Nov 2024 00:58:11 +0300 Subject: [PATCH] Handle float/double arguments properly in GuestToHostFunction. --- UnleashedRecomp/kernel/function.h | 32 ++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/UnleashedRecomp/kernel/function.h b/UnleashedRecomp/kernel/function.h index e52e4ba9..14e88ea7 100644 --- a/UnleashedRecomp/kernel/function.h +++ b/UnleashedRecomp/kernel/function.h @@ -193,10 +193,10 @@ struct Argument int ordinal{}; }; -template -constexpr std::array::value> GatherFunctionArguments() +template +constexpr std::array> GatherFunctionArguments(const T1& tpl) { - std::array::value> args{}; + std::array> args{}; int floatOrdinal{}; size_t i{}; @@ -205,9 +205,9 @@ constexpr std::array::value> GatherFunctionArguments { std::apply([&](const auto& first, const auto&... rest) { - auto append = [&](const T & v) + auto append = [&](const T2& v) { - if constexpr (is_precise_v) + if constexpr (is_precise_v) { args[i] = { 1, floatOrdinal++ }; } @@ -221,12 +221,18 @@ constexpr std::array::value> GatherFunctionArguments append(first); (append(rest), ...); - }, function_args(Func)); + }, tpl); } return args; } +template +constexpr std::array::value> GatherFunctionArguments() +{ + return GatherFunctionArguments(function_args(Func)); +} + template struct arg_ordinal_t { @@ -248,19 +254,19 @@ FORCEINLINE std::enable_if_t<(I < sizeof...(TArgs)), void> _translate_args_to_ho _translate_args_to_host(ctx, base, tpl); } -template +template FORCEINLINE void _translate_args_to_guest(PPCContext& ctx, uint8_t* base, std::tuple&) noexcept requires (I >= sizeof...(TArgs)) { } -template +template FORCEINLINE std::enable_if_t<(I < sizeof...(TArgs)), void> _translate_args_to_guest(PPCContext& ctx, uint8_t* base, std::tuple& tpl) noexcept { using T = std::tuple_element_t>; - ArgTranslator::SetValue(ctx, base, I, std::get(tpl)); + ArgTranslator::SetValue(ctx, base, GatherFunctionArguments(std::tuple{})[I].ordinal, std::get(tpl)); - _translate_args_to_guest(ctx, base, tpl); + _translate_args_to_guest(ctx, base, tpl); } template @@ -302,9 +308,9 @@ FORCEINLINE PPC_FUNC(HostToGuestFunction) } template -FORCEINLINE T GuestToHostFunction(const TFunction& func, TArgs... argv) +FORCEINLINE T GuestToHostFunction(const TFunction& func, TArgs&&... argv) { - auto args = std::make_tuple(argv...); + auto args = std::make_tuple(std::forward(argv)...); auto& currentCtx = *GetPPCContext(); PPCContext newCtx; // NOTE: No need for zero initialization, has lots of unnecessary code generation. @@ -313,7 +319,7 @@ FORCEINLINE T GuestToHostFunction(const TFunction& func, TArgs... argv) newCtx.r13 = currentCtx.r13; newCtx.fpscr = currentCtx.fpscr; - _translate_args_to_guest>(newCtx, (uint8_t*)g_memory.base, args); + _translate_args_to_guest(newCtx, (uint8_t*)g_memory.base, args); SetPPCContext(newCtx);