Skip to content

Commit

Permalink
解决ios的async/await报错 fix Tencent#222 (Tencent#230)
Browse files Browse the repository at this point in the history
  • Loading branch information
annayxguo authored and EricZRY committed Dec 30, 2021
1 parent 33530df commit fe6ac1d
Showing 1 changed file with 38 additions and 1 deletion.
39 changes: 38 additions & 1 deletion Source/VSProj/Src/Tools/CodeTranslator.cs
Expand Up @@ -263,6 +263,15 @@ int addExternMethod(MethodReference callee, MethodDefinition caller)
return ushort.MaxValue;
}

if (callee.Name == "AwaitUnsafeOnCompleted")
{

if (!awaitUnsafeOnCompletedMethods.Any(m => ((GenericInstanceMethod)callee).GenericArguments[0] == ((GenericInstanceMethod)m).GenericArguments[0]))
{
awaitUnsafeOnCompletedMethods.Add(callee);
}
}

if (externMethodToId.ContainsKey(callee))
{
return externMethodToId[callee];
Expand Down Expand Up @@ -2162,6 +2171,29 @@ 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);
instructions.Add(Instruction.Create(OpCodes.Ldloca_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)));
}
instructions.Add(Instruction.Create(OpCodes.Ret));
itfBridgeType.Methods.Add(targetMethod);
}


/// <summary>
/// 获取一个方法的适配器
/// </summary>
Expand Down Expand Up @@ -3187,6 +3219,7 @@ void redirectFieldRename()
bool hasRedirect = false;
ProcessMode mode;
GenerateConfigure configure;
List<MethodReference> awaitUnsafeOnCompletedMethods = new List<MethodReference>();

public ProcessResult Process(AssemblyDefinition assembly, AssemblyDefinition ilfixAassembly,
GenerateConfigure configure, ProcessMode mode)
Expand Down Expand Up @@ -3242,7 +3275,11 @@ void redirectFieldRename()
if (mode == ProcessMode.Inject)
{
redirectFieldRename();
}
if (awaitUnsafeOnCompletedMethods.Count != 0)
{
EmitRefAwaitUnsafeOnCompletedMethod();
}
}

return ProcessResult.OK;
}
Expand Down

0 comments on commit fe6ac1d

Please sign in to comment.