From 115fbc33c064ef7d04e248adc644c214d539e1bf Mon Sep 17 00:00:00 2001 From: zombieyang Date: Fri, 14 Jun 2024 10:12:50 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20=E7=94=A8class=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E7=9A=84AsyncMethodBuilder,=E4=BC=9A=E5=AF=BC=E8=87=B4IL2cpp?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Source/VSProj/Src/Tools/CodeTranslator.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/VSProj/Src/Tools/CodeTranslator.cs b/Source/VSProj/Src/Tools/CodeTranslator.cs index 104bc51..1c2c00e 100644 --- a/Source/VSProj/Src/Tools/CodeTranslator.cs +++ b/Source/VSProj/Src/Tools/CodeTranslator.cs @@ -2226,7 +2226,10 @@ void EmitRefAwaitUnsafeOnCompletedMethod() targetMethod.Body.Variables.Add(localTaskAwaiter); var localAsync = new VariableDefinition(awaitUnsafeOnCompletedMethods[j].DeclaringType); targetMethod.Body.Variables.Add(localAsync); - instructions.Add(Instruction.Create(OpCodes.Ldloca_S, localAsync)); + if (awaitUnsafeOnCompletedMethods[j].DeclaringType.IsValueType) + instructions.Add(Instruction.Create(OpCodes.Ldloca_S, localAsync)); + else + instructions.Add(Instruction.Create(OpCodes.Ldloc_S, localAsync)); instructions.Add(Instruction.Create(OpCodes.Ldloca_S, localTaskAwaiter)); instructions.Add(Instruction.Create(OpCodes.Ldloca_S, localBridge)); instructions.Add(Instruction.Create(OpCodes.Call, makeGenericMethod(awaitUnsafeOnCompletedMethods[j].GetElementMethod(), ((GenericInstanceMethod)awaitUnsafeOnCompletedMethods[j]).GenericArguments[0], itfBridgeType))); From 5f5493074c4d8d014e33d0c17ca7e6c235258ac8 Mon Sep 17 00:00:00 2001 From: zombieyang Date: Wed, 3 Jul 2024 12:09:08 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20AwaitUnsafeOnCompleted=E8=B6=85?= =?UTF-8?q?=E8=BF=87128=E4=B8=AA=E7=9A=84=E8=AF=9D=EF=BC=8C=E7=94=9F?= =?UTF-8?q?=E6=88=90=E7=9A=84Call=E4=B8=8D=E6=AD=A3=E7=A1=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Source/VSProj/Src/Tools/CodeTranslator.cs | 53 ++++++++++++++--------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/Source/VSProj/Src/Tools/CodeTranslator.cs b/Source/VSProj/Src/Tools/CodeTranslator.cs index 1c2c00e..3821406 100644 --- a/Source/VSProj/Src/Tools/CodeTranslator.cs +++ b/Source/VSProj/Src/Tools/CodeTranslator.cs @@ -276,7 +276,6 @@ int addExternMethod(MethodReference callee, MethodDefinition caller) if (callee.Name == "AwaitUnsafeOnCompleted") { - if (!awaitUnsafeOnCompletedMethods.Any(m => ((GenericInstanceMethod)callee).GenericArguments[0] == ((GenericInstanceMethod)m).GenericArguments[0])) { awaitUnsafeOnCompletedMethods.Add(callee); @@ -2215,27 +2214,39 @@ void addInterfaceToBridge(TypeReference itf) void EmitRefAwaitUnsafeOnCompletedMethod() { - MethodDefinition targetMethod = new MethodDefinition("RefAwaitUnsafeOnCompleteMethod", - Mono.Cecil.MethodAttributes.Public, assembly.MainModule.TypeSystem.Void); - var instructions = targetMethod.Body.Instructions; - var localBridge = new VariableDefinition(itfBridgeType); - targetMethod.Body.Variables.Add(localBridge); - for (int j = 0;j < awaitUnsafeOnCompletedMethods.Count;j++) - { - var localTaskAwaiter = new VariableDefinition(((GenericInstanceMethod)awaitUnsafeOnCompletedMethods[j]).GenericArguments[0]); - targetMethod.Body.Variables.Add(localTaskAwaiter); - var localAsync = new VariableDefinition(awaitUnsafeOnCompletedMethods[j].DeclaringType); - targetMethod.Body.Variables.Add(localAsync); - if (awaitUnsafeOnCompletedMethods[j].DeclaringType.IsValueType) - instructions.Add(Instruction.Create(OpCodes.Ldloca_S, localAsync)); - else - instructions.Add(Instruction.Create(OpCodes.Ldloc_S, localAsync)); - instructions.Add(Instruction.Create(OpCodes.Ldloca_S, localTaskAwaiter)); - instructions.Add(Instruction.Create(OpCodes.Ldloca_S, localBridge)); - instructions.Add(Instruction.Create(OpCodes.Call, makeGenericMethod(awaitUnsafeOnCompletedMethods[j].GetElementMethod(), ((GenericInstanceMethod)awaitUnsafeOnCompletedMethods[j]).GenericArguments[0], itfBridgeType))); + int m = 0; + int rm = 0; + while (m < awaitUnsafeOnCompletedMethods.Count) + { + MethodDefinition targetMethod = new MethodDefinition("RefAwaitUnsafeOnCompleteMethod" + (rm++), + Mono.Cecil.MethodAttributes.Public, assembly.MainModule.TypeSystem.Void); + var instructions = targetMethod.Body.Instructions; + + var localBridge = new VariableDefinition(itfBridgeType); + targetMethod.Body.Variables.Add(localBridge); + + int j = m; + for (; j < awaitUnsafeOnCompletedMethods.Count && j - m < 128; j++) + { + var localTaskAwaiter = new VariableDefinition(((GenericInstanceMethod)awaitUnsafeOnCompletedMethods[j]).GenericArguments[0]); + targetMethod.Body.Variables.Add(localTaskAwaiter); + var localAsync = new VariableDefinition(awaitUnsafeOnCompletedMethods[j].DeclaringType); + targetMethod.Body.Variables.Add(localAsync); + + if (awaitUnsafeOnCompletedMethods[j].DeclaringType.IsValueType) + instructions.Add(Instruction.Create(OpCodes.Ldloca_S, localAsync)); + else + instructions.Add(Instruction.Create(OpCodes.Ldloc_S, localAsync)); + instructions.Add(Instruction.Create(OpCodes.Ldloca_S, localTaskAwaiter)); + instructions.Add(Instruction.Create(OpCodes.Ldloca_S, localBridge)); + + instructions.Add(Instruction.Create(OpCodes.Call, makeGenericMethod(awaitUnsafeOnCompletedMethods[j].GetElementMethod(), ((GenericInstanceMethod)awaitUnsafeOnCompletedMethods[j]).GenericArguments[0], itfBridgeType))); + } + + m = j; + instructions.Add(Instruction.Create(OpCodes.Ret)); + itfBridgeType.Methods.Add(targetMethod); } - instructions.Add(Instruction.Create(OpCodes.Ret)); - itfBridgeType.Methods.Add(targetMethod); } private void EmitAsyncBuilderStartMethod(IEnumerable allTypes)