aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjduncanator <1518948+jduncanator@users.noreply.github.com>2019-10-25 10:34:35 +1100
committerGitHub <noreply@github.com>2019-10-25 10:34:35 +1100
commit86b42f176af69b58b493396dff0a5958e073b39b (patch)
tree835b2afaf9611a4c6258c177e7462a84c66e6089
parent1772128ce0fc058e6280001aace3a77a7a96897b (diff)
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.
-rw-r--r--Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs11
1 files changed, 10 insertions, 1 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SvcTable.cs
index 70b6db0c..b740253f 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);