Browse Source

Fix bugs in async/await decompiler.

pull/368/merge
Daniel Grunwald 12 years ago
parent
commit
6ba013d9dd
  1. 16
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  2. 3
      ICSharpCode.Decompiler/ILAst/AsyncDecompiler.cs
  3. 1
      ICSharpCode.Decompiler/ILAst/ILInlining.cs
  4. 11
      ICSharpCode.Decompiler/Tests/Async.cs

16
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -849,7 +849,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -849,7 +849,7 @@ namespace ICSharpCode.Decompiler.Ast
args[args.Count - 1].AddAnnotation(new ParameterDeclarationAnnotation(byteCode));
return args[args.Count - 1];
case ILCode.Await:
return new UnaryOperatorExpression(UnaryOperatorType.Await, arg1);
return new UnaryOperatorExpression(UnaryOperatorType.Await, UnpackDirectionExpression(arg1));
case ILCode.NullableOf:
case ILCode.ValueOf:
return arg1;
@ -975,10 +975,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -975,10 +975,7 @@ namespace ICSharpCode.Decompiler.Ast
// Unpack any DirectionExpression that is used as target for the call
// (calling methods on value types implicitly passes the first argument by reference)
if (target is DirectionExpression) {
target = ((DirectionExpression)target).Expression;
target.Remove(); // detach from DirectionExpression
}
target = UnpackDirectionExpression(target);
if (cecilMethodDef != null) {
// convert null.ToLower() to ((string)null).ToLower()
@ -1078,6 +1075,15 @@ namespace ICSharpCode.Decompiler.Ast @@ -1078,6 +1075,15 @@ namespace ICSharpCode.Decompiler.Ast
return target.Invoke(cecilMethod.Name, ConvertTypeArguments(cecilMethod), methodArgs).WithAnnotation(cecilMethod);
}
static Expression UnpackDirectionExpression(Expression target)
{
if (target is DirectionExpression) {
return ((DirectionExpression)target).Expression.Detach();
} else {
return target;
}
}
static void AdjustArgumentsForMethodCall(MethodReference cecilMethod, List<Expression> methodArgs)
{
// Convert 'ref' into 'out' where necessary

3
ICSharpCode.Decompiler/ILAst/AsyncDecompiler.cs

@ -475,7 +475,8 @@ namespace ICSharpCode.Decompiler.ILAst @@ -475,7 +475,8 @@ namespace ICSharpCode.Decompiler.ILAst
newBody.RemoveAt(newBody.Count - 1); // remove AwaitUnsafeOnCompleted call
if (callAwaitUnsafeOnCompleted == null || callAwaitUnsafeOnCompleted.Code != ILCode.Call)
throw new SymbolicAnalysisFailedException();
if (((MethodReference)callAwaitUnsafeOnCompleted.Operand).Name != "AwaitUnsafeOnCompleted")
string methodName = ((MethodReference)callAwaitUnsafeOnCompleted.Operand).Name;
if (methodName != "AwaitUnsafeOnCompleted" && methodName != "AwaitOnCompleted")
throw new SymbolicAnalysisFailedException();
if (callAwaitUnsafeOnCompleted.Arguments.Count != 3)
throw new SymbolicAnalysisFailedException();

1
ICSharpCode.Decompiler/ILAst/ILInlining.cs

@ -334,6 +334,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -334,6 +334,7 @@ namespace ICSharpCode.Decompiler.ILAst
case ILCode.Stfld:
case ILCode.Ldfld:
case ILCode.Ldflda:
case ILCode.Await:
return true;
}
}

11
ICSharpCode.Decompiler/Tests/Async.cs

@ -20,6 +20,7 @@ @@ -20,6 +20,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
public class Async
@ -36,6 +37,16 @@ public class Async @@ -36,6 +37,16 @@ public class Async
Console.WriteLine("No Await");
}
public async void AwaitYield()
{
await Task.Yield();
}
public async void AwaitDefaultYieldAwaitable()
{
await default(YieldAwaitable);
}
public async Task SimpleVoidTaskMethod()
{
Console.WriteLine("Before");

Loading…
Cancel
Save