From 7b6c503d8a7618021704f9f6c6551b54cf440f62 Mon Sep 17 00:00:00 2001 From: ds5678 <49847914+ds5678@users.noreply.github.com> Date: Sat, 5 Oct 2024 06:17:23 -0700 Subject: [PATCH 1/4] Unstrip floating point array op codes * Ldelem_R4 * Ldelem_R8 * Stelem_R4 * Stelem_R8 --- .../Utils/RuntimeAssemblyReferences.cs | 23 ++++++++ .../Utils/UnstripTranslator.cs | 53 +++++++++++++++++-- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/Il2CppInterop.Generator/Utils/RuntimeAssemblyReferences.cs b/Il2CppInterop.Generator/Utils/RuntimeAssemblyReferences.cs index 112c4602..fbdfc204 100644 --- a/Il2CppInterop.Generator/Utils/RuntimeAssemblyReferences.cs +++ b/Il2CppInterop.Generator/Utils/RuntimeAssemblyReferences.cs @@ -30,6 +30,8 @@ public RuntimeAssemblyReferences(ModuleDefinition module, RewriteGlobalContext g public Lazy Il2CppStringArrayctor_size { get; private set; } public Memoize Il2CppStructArrayctor_size { get; private set; } public Lazy Il2CppArrayBase_get_Length { get; private set; } + public Memoize Il2CppArrayBase_get_Item { get; private set; } + public Memoize Il2CppArrayBase_set_Item { get; private set; } public Lazy IL2CPP_Il2CppObjectBaseToPtr { get; private set; } public Lazy IL2CPP_Il2CppObjectBaseToPtrNotNull { get; private set; } public Lazy IL2CPP_Il2CppStringToManaged { get; private set; } @@ -122,6 +124,8 @@ private void InitTypeRefs() var nonGenericIl2CppArrayBase = new TypeReference(Module, assemblyRef, "Il2CppInterop.Runtime.InteropTypes.Arrays", "Il2CppArrayBase").ToTypeSignature(); + var genericIl2CppArrayBase = new TypeReference(Module, assemblyRef, "Il2CppInterop.Runtime.InteropTypes.Arrays", "Il2CppArrayBase`1").ToTypeSignature(); + Il2CppStructArray = new TypeReference(Module, assemblyRef, "Il2CppInterop.Runtime.InteropTypes.Arrays", "Il2CppStructArray`1").ToTypeSignature(); Il2CppReferenceArray = new TypeReference(Module, assemblyRef, "Il2CppInterop.Runtime.InteropTypes.Arrays", "Il2CppReferenceArray`1").ToTypeSignature(); @@ -140,6 +144,7 @@ private void InitTypeRefs() allTypes["Il2CppInterop.Runtime.InteropTypes.Il2CppObjectBase"] = Il2CppObjectBase; allTypes["Il2CppInterop.Runtime.Runtime.Il2CppObjectPool"] = Il2CppObjectPool; allTypes["Il2CppInterop.Runtime.InteropTypes.Arrays.Il2CppArrayBase"] = nonGenericIl2CppArrayBase; + allTypes["Il2CppInterop.Runtime.InteropTypes.Arrays.Il2CppArrayBase"] = genericIl2CppArrayBase; allTypes["Il2CppInterop.Runtime.InteropTypes.Arrays.Il2CppStringArray"] = Il2CppStringArray; allTypes["Il2CppInterop.Runtime.InteropTypes.Arrays.Il2CppReferenceArray"] = Il2CppReferenceArray; allTypes["Il2CppInterop.Runtime.InteropTypes.Arrays.Il2CppStructArray"] = Il2CppStructArray; @@ -211,6 +216,24 @@ private void InitMethodRefs() return mr; }); + Il2CppArrayBase_get_Item = new((param) => + { + var owner = ResolveType("Il2CppInterop.Runtime.InteropTypes.Arrays.Il2CppArrayBase"); + var giOwner = owner.MakeGenericInstanceType(param).ToTypeDefOrRef(); + var mr = ReferenceCreator.CreateInstanceMethodReference("get_Item", new GenericParameterSignature(Module, GenericParameterType.Type, 0), + giOwner, ResolveType("System.Int32")); + return mr; + }); + + Il2CppArrayBase_set_Item = new((param) => + { + var owner = ResolveType("Il2CppInterop.Runtime.InteropTypes.Arrays.Il2CppArrayBase"); + var giOwner = owner.MakeGenericInstanceType(param).ToTypeDefOrRef(); + var mr = ReferenceCreator.CreateInstanceMethodReference("set_Item", Module.Void(), + giOwner, ResolveType("System.Int32"), new GenericParameterSignature(Module, GenericParameterType.Type, 0)); + return mr; + }); + IL2CPP_Il2CppObjectBaseToPtr = new Lazy(() => { var mr = ReferenceCreator.CreateStaticMethodReference("Il2CppObjectBaseToPtr", ResolveType("System.IntPtr"), diff --git a/Il2CppInterop.Generator/Utils/UnstripTranslator.cs b/Il2CppInterop.Generator/Utils/UnstripTranslator.cs index 4688f5df..f21cab57 100644 --- a/Il2CppInterop.Generator/Utils/UnstripTranslator.cs +++ b/Il2CppInterop.Generator/Utils/UnstripTranslator.cs @@ -77,14 +77,61 @@ public static bool TranslateMethod(MethodDefinition original, MethodDefinition t //This is Il2CppReferenceArray.set_Item but the T is not known because the operand is null. return false; - case >= CilCode.Ldelem_I1 and <= CilCode.Ldelem_R8: - //This is Il2CppStructArray.get_Item + case CilCode.Ldelem_I1: + case CilCode.Ldelem_I2: + case CilCode.Ldelem_I4: + case CilCode.Ldelem_U4: + //This is Il2CppArrayBase.get_Item but the T could be either the cooresponding primitive or an enum. return false; - case >= CilCode.Stelem_I and <= CilCode.Stelem_R8: + case CilCode.Ldelem_U1: + //This is Il2CppArrayBase.get_Item but the T could be either byte, bool, or an enum. + return false; + + case CilCode.Ldelem_U2: + //This is Il2CppArrayBase.get_Item but the T could be either ushort, char, or an enum. + return false; + + case CilCode.Ldelem_I8: + //This is Il2CppArrayBase.get_Item but the T could be either signed, unsigned, or an enum. + return false; + + case CilCode.Ldelem_I: + //This is Il2CppArrayBase.get_Item but the T could be either signed, unsigned, or a pointer. + return false; + + case CilCode.Ldelem_R4: + { + var getMethod = imports.Il2CppArrayBase_get_Item.Get(imports.Module.CorLibTypeFactory.Single); + newInstruction = targetBuilder.Add(OpCodes.Callvirt, imports.Module.DefaultImporter.ImportMethod(getMethod)); + } + break; + + case CilCode.Ldelem_R8: + { + var getMethod = imports.Il2CppArrayBase_get_Item.Get(imports.Module.CorLibTypeFactory.Double); + newInstruction = targetBuilder.Add(OpCodes.Callvirt, imports.Module.DefaultImporter.ImportMethod(getMethod)); + } + break; + + case >= CilCode.Stelem_I and <= CilCode.Stelem_I8: //This is Il2CppStructArray.set_Item return false; + case CilCode.Stelem_R4: + { + var setMethod = imports.Il2CppArrayBase_set_Item.Get(imports.Module.CorLibTypeFactory.Single); + newInstruction = targetBuilder.Add(OpCodes.Callvirt, imports.Module.DefaultImporter.ImportMethod(setMethod)); + } + break; + + case CilCode.Stelem_R8: + { + var setMethod = imports.Il2CppArrayBase_set_Item.Get(imports.Module.CorLibTypeFactory.Double); + newInstruction = targetBuilder.Add(OpCodes.Callvirt, imports.Module.DefaultImporter.ImportMethod(setMethod)); + } + break; + case >= CilCode.Ldind_I1 and <= CilCode.Ldind_Ref: //This is for by ref parameters goto default; From 3cfe08b003f9dea9dba6dc75749cbf3335101949 Mon Sep 17 00:00:00 2001 From: ds5678 <49847914+ds5678@users.noreply.github.com> Date: Sat, 5 Oct 2024 17:01:17 -0700 Subject: [PATCH 2/4] Some small fixes * Ldelema, Ldelem, and Stelem have type operands * Fail for value-type newarr --- .../Utils/UnstripTranslator.cs | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/Il2CppInterop.Generator/Utils/UnstripTranslator.cs b/Il2CppInterop.Generator/Utils/UnstripTranslator.cs index f21cab57..6187552c 100644 --- a/Il2CppInterop.Generator/Utils/UnstripTranslator.cs +++ b/Il2CppInterop.Generator/Utils/UnstripTranslator.cs @@ -57,18 +57,6 @@ public static bool TranslateMethod(MethodDefinition original, MethodDefinition t imports.Module.DefaultImporter.ImportMethod(imports.Il2CppArrayBase_get_Length.Value)); break; - case CilCode.Ldelema: - //This is Il2CppArrayBase.Pointer + index * sizeof(T) but the T is not known because the operand is null. - return false; - - case CilCode.Ldelem: - //This is Il2CppArrayBase.set_Item but the T is not known because the operand is null. - return false; - - case CilCode.Stelem: - //This is Il2CppArrayBase.set_Item but the T is not known because the operand is null. - return false; - case CilCode.Ldelem_Ref: //This is Il2CppReferenceArray.get_Item but the T is not known because the operand is null. return false; @@ -286,7 +274,7 @@ public static bool TranslateMethod(MethodDefinition original, MethodDefinition t imports.Module.DefaultImporter.ImportMethod(imports.Il2CppObjectBase_TryCast.Value.MakeGenericInstanceMethod(targetType))); instructionMap.Add(bodyInstruction, newInstruction); } - else if (bodyInstruction.OpCode == OpCodes.Newarr && !targetType.IsValueType) + else if (bodyInstruction.OpCode == OpCodes.Newarr) { var newInstruction = targetBuilder.Add(OpCodes.Conv_I8); @@ -307,6 +295,21 @@ public static bool TranslateMethod(MethodDefinition original, MethodDefinition t ReferenceCreator.CreateInstanceMethodReference(".ctor", imports.Module.Void(), il2cppTypeArray, imports.Module.Long()))); instructionMap.Add(bodyInstruction, newInstruction); } + else if (bodyInstruction.OpCode == OpCodes.Ldelema) + { + // Not implemented + return false; + } + else if (bodyInstruction.OpCode == OpCodes.Ldelem) + { + // Not implemented + return false; + } + else if (bodyInstruction.OpCode == OpCodes.Stelem) + { + // Not implemented + return false; + } else { var newInstruction = targetBuilder.Add(bodyInstruction.OpCode, targetType.ToTypeDefOrRef()); From ae838547d7177d3ee080a7fb64185723704382c4 Mon Sep 17 00:00:00 2001 From: ds5678 <49847914+ds5678@users.noreply.github.com> Date: Sat, 5 Oct 2024 17:21:41 -0700 Subject: [PATCH 3/4] ldelem and stelem --- Il2CppInterop.Generator/Utils/UnstripTranslator.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Il2CppInterop.Generator/Utils/UnstripTranslator.cs b/Il2CppInterop.Generator/Utils/UnstripTranslator.cs index 6187552c..325c162c 100644 --- a/Il2CppInterop.Generator/Utils/UnstripTranslator.cs +++ b/Il2CppInterop.Generator/Utils/UnstripTranslator.cs @@ -302,13 +302,15 @@ public static bool TranslateMethod(MethodDefinition original, MethodDefinition t } else if (bodyInstruction.OpCode == OpCodes.Ldelem) { - // Not implemented - return false; + var getMethod = imports.Il2CppArrayBase_get_Item.Get(targetType); + var newInstruction = targetBuilder.Add(OpCodes.Callvirt, imports.Module.DefaultImporter.ImportMethod(getMethod)); + instructionMap.Add(bodyInstruction, newInstruction); } else if (bodyInstruction.OpCode == OpCodes.Stelem) { - // Not implemented - return false; + var setMethod = imports.Il2CppArrayBase_set_Item.Get(targetType); + var newInstruction = targetBuilder.Add(OpCodes.Callvirt, imports.Module.DefaultImporter.ImportMethod(setMethod)); + instructionMap.Add(bodyInstruction, newInstruction); } else { From 9a1203c7d6c68738362b97acc6b1fa22ff805166 Mon Sep 17 00:00:00 2001 From: ds5678 <49847914+ds5678@users.noreply.github.com> Date: Sat, 5 Oct 2024 17:21:57 -0700 Subject: [PATCH 4/4] formatting --- Il2CppInterop.Generator/Utils/UnstripTranslator.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Il2CppInterop.Generator/Utils/UnstripTranslator.cs b/Il2CppInterop.Generator/Utils/UnstripTranslator.cs index 325c162c..217e03b7 100644 --- a/Il2CppInterop.Generator/Utils/UnstripTranslator.cs +++ b/Il2CppInterop.Generator/Utils/UnstripTranslator.cs @@ -302,14 +302,14 @@ public static bool TranslateMethod(MethodDefinition original, MethodDefinition t } else if (bodyInstruction.OpCode == OpCodes.Ldelem) { - var getMethod = imports.Il2CppArrayBase_get_Item.Get(targetType); - var newInstruction = targetBuilder.Add(OpCodes.Callvirt, imports.Module.DefaultImporter.ImportMethod(getMethod)); - instructionMap.Add(bodyInstruction, newInstruction); + var getMethod = imports.Il2CppArrayBase_get_Item.Get(targetType); + var newInstruction = targetBuilder.Add(OpCodes.Callvirt, imports.Module.DefaultImporter.ImportMethod(getMethod)); + instructionMap.Add(bodyInstruction, newInstruction); } else if (bodyInstruction.OpCode == OpCodes.Stelem) { - var setMethod = imports.Il2CppArrayBase_set_Item.Get(targetType); - var newInstruction = targetBuilder.Add(OpCodes.Callvirt, imports.Module.DefaultImporter.ImportMethod(setMethod)); + var setMethod = imports.Il2CppArrayBase_set_Item.Get(targetType); + var newInstruction = targetBuilder.Add(OpCodes.Callvirt, imports.Module.DefaultImporter.ImportMethod(setMethod)); instructionMap.Add(bodyInstruction, newInstruction); } else