From af3422848874d626652e7cf4f3b4431216bdaf17 Mon Sep 17 00:00:00 2001 From: ds5678 <49847914+ds5678@users.noreply.github.com> Date: Mon, 13 May 2024 15:33:16 -0700 Subject: [PATCH] Improve unstripping support for newarr: * Fail for struct target types * Use Il2CppStringArray for System.String --- .../Utils/UnstripTranslator.cs | 94 +++++++++++-------- 1 file changed, 53 insertions(+), 41 deletions(-) diff --git a/Il2CppInterop.Generator/Utils/UnstripTranslator.cs b/Il2CppInterop.Generator/Utils/UnstripTranslator.cs index d9a9e4b8..1d146dc0 100644 --- a/Il2CppInterop.Generator/Utils/UnstripTranslator.cs +++ b/Il2CppInterop.Generator/Utils/UnstripTranslator.cs @@ -41,47 +41,47 @@ public static bool TranslateMethod(MethodDefinition original, MethodDefinition t { if (bodyInstruction.Operand is null) { - switch (bodyInstruction.OpCode.Code) + switch (bodyInstruction.OpCode.Code) { - case CilCode.Ldlen: - //This is Il2CppArrayBase.Length - return false; - - 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; - - case CilCode.Stelem_Ref: - //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 - return false; - - case >= CilCode.Stelem_I and <= CilCode.Stelem_R8: - //This is Il2CppStructArray.set_Item - return false; - - case >= CilCode.Ldind_I1 and <= CilCode.Ldind_Ref: - //This is for by ref parameters - break; - - case >= CilCode.Stind_Ref and <= CilCode.Stind_R8: - //This is for by ref parameters - break; + case CilCode.Ldlen: + //This is Il2CppArrayBase.Length + return false; + + 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; + + case CilCode.Stelem_Ref: + //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 + return false; + + case >= CilCode.Stelem_I and <= CilCode.Stelem_R8: + //This is Il2CppStructArray.set_Item + return false; + + case >= CilCode.Ldind_I1 and <= CilCode.Ldind_Ref: + //This is for by ref parameters + break; + + case >= CilCode.Stind_Ref and <= CilCode.Stind_R8: + //This is for by ref parameters + break; } var newInstruction = targetBuilder.Add(bodyInstruction.OpCode); @@ -198,7 +198,19 @@ public static bool TranslateMethod(MethodDefinition original, MethodDefinition t { var newInstruction = targetBuilder.Add(OpCodes.Conv_I8); - var il2cppTypeArray = imports.Il2CppReferenceArray.MakeGenericInstanceType(targetType).ToTypeDefOrRef(); + ITypeDefOrRef il2cppTypeArray; + if (targetType.IsValueType) + { + return false; + } + else if (targetType.FullName == "System.String") + { + il2cppTypeArray = imports.Il2CppStringArray.ToTypeDefOrRef(); + } + else + { + il2cppTypeArray = imports.Il2CppReferenceArray.MakeGenericInstanceType(targetType).ToTypeDefOrRef(); + } targetBuilder.Add(OpCodes.Newobj, imports.Module.DefaultImporter.ImportMethod( CecilAdapter.CreateInstanceMethodReference(".ctor", imports.Module.Void(), il2cppTypeArray, imports.Module.Long()))); instructionMap.Add(bodyInstruction, newInstruction);