From 86b42f176af69b58b493396dff0a5958e073b39b Mon Sep 17 00:00:00 2001 From: jduncanator <1518948+jduncanator@users.noreply.github.com> Date: Fri, 25 Oct 2019 10:34:35 +1100 Subject: [PATCH] svc: Implement `ref` parameters (#798) Allows passing data into and out of the same registers when calling via the Kernel ABI. This allows implementing specific supervisor calls like "CallSecureMonitor", that expect their args and results in the same registers. --- Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs index 70b6db0c4e..b740253fd5 100644 --- a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs +++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs @@ -231,7 +231,16 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall if (!methodArgs[index].IsOut) { - throw new InvalidOperationException($"Method \"{svcName}\" has a invalid ref type \"{argType.Name}\"."); + generator.Emit(OpCodes.Ldarg_1); + generator.Emit(OpCodes.Ldc_I4, index); + + MethodInfo info = typeof(IExecutionContext).GetMethod(nameof(IExecutionContext.GetX)); + + generator.Emit(OpCodes.Call, info); + + ConvertToArgType(argType); + + generator.Emit(OpCodes.Stloc, local); } generator.Emit(OpCodes.Ldloca, local);