From af35f78c35fd18f97a4c76461df82176c00844a8 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);