From 66d806b2d9a0a21407074d3867a81c846c900217 Mon Sep 17 00:00:00 2001 From: MikeFH Date: Mon, 15 Jan 2018 17:34:04 +0100 Subject: [PATCH 1/3] Add support for async main method --- .../ICSharpCode.Decompiler.Tests.csproj | 1 + .../PrettyTestRunner.cs | 69 ++--- .../TestCases/Pretty/AsyncMain.cs | 14 ++ .../TestCases/Pretty/AsyncMain.opt.roslyn.il | 209 +++++++++++++++ .../TestCases/Pretty/AsyncMain.roslyn.il | 237 ++++++++++++++++++ .../CSharp/CSharpDecompiler.cs | 2 + .../IL/ControlFlow/AsyncAwaitDecompiler.cs | 6 + 7 files changed, 509 insertions(+), 29 deletions(-) create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.cs create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.opt.roslyn.il create mode 100644 ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.roslyn.il diff --git a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj index 4653b56adc..f92b8c6125 100644 --- a/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj @@ -63,6 +63,7 @@ + diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs index d246eed85b..6e5e021a0d 100644 --- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs @@ -69,167 +69,178 @@ public void AllFilesHaveTests() [Test] public void HelloWorld() { - Run(); - Run(asmOptions: AssemblerOptions.UseDebug); + RunForLibrary(); + RunForLibrary(asmOptions: AssemblerOptions.UseDebug); } [Test] public void InlineAssignmentTest([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void CompoundAssignmentTest([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void ShortCircuit([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void ExceptionHandling([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void Switch([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void DelegateConstruction([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void AnonymousTypes([Values(CompilerOptions.None, CompilerOptions.Optimize)] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void Async([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void Lock([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void Using([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void LiftedOperators([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void Generics([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void Loops([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void PropertiesAndEvents([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void AutoProperties([ValueSource("roslynOnlyOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void QueryExpressions([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void TypeAnalysisTests([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void CheckedUnchecked([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void UnsafeCode([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void PInvoke([ValueSource("defaultOptions")] CompilerOptions cscOptions) { // This tests needs our own disassembler; ildasm has a bug with marshalinfo. - Run(cscOptions: cscOptions, asmOptions: AssemblerOptions.UseOwnDisassembler); + RunForLibrary(cscOptions: cscOptions, asmOptions: AssemblerOptions.UseOwnDisassembler); } [Test] public void InitializerTests([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void ExpressionTrees([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void FixProxyCalls([Values(CompilerOptions.None, CompilerOptions.Optimize, CompilerOptions.UseRoslyn)] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void VariableNaming([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions); + RunForLibrary(cscOptions: cscOptions); } [Test] public void VariableNamingWithoutSymbols([ValueSource("defaultOptions")] CompilerOptions cscOptions) { - Run(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings { UseDebugSymbols = false }); + RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings { UseDebugSymbols = false }); } [Test] public void CS72_PrivateProtected([ValueSource("roslynOnlyOptions")] CompilerOptions cscOptions) + { + RunForLibrary(cscOptions: cscOptions); + } + + [Test] + public void AsyncMain([ValueSource("roslynOnlyOptions")] CompilerOptions cscOptions) { Run(cscOptions: cscOptions); } + void RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null) + { + Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CompilerOptions.Library, decompilerSettings); + } + void Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null) { var ilFile = Path.Combine(TestCasePath, testName) + Tester.GetSuffix(cscOptions) + ".il"; @@ -239,7 +250,7 @@ void Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions // re-create .il file if necessary CompilerResults output = null; try { - output = Tester.CompileCSharp(csFile, cscOptions | CompilerOptions.Library); + output = Tester.CompileCSharp(csFile, cscOptions); Tester.Disassemble(output.PathToAssembly, ilFile, asmOptions); } finally { if (output != null) @@ -247,7 +258,7 @@ void Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions } } - var executable = Tester.AssembleIL(ilFile, asmOptions | AssemblerOptions.Library); + var executable = Tester.AssembleIL(ilFile, asmOptions); var decompiled = Tester.DecompileCSharp(executable, decompilerSettings); CodeAssert.FilesAreEqual(csFile, decompiled, Tester.GetPreprocessorSymbols(cscOptions).ToArray()); diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.cs new file mode 100644 index 0000000000..0722cbaf6b --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.cs @@ -0,0 +1,14 @@ +using System; +using System.Threading.Tasks; + +namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty +{ + public class AsyncMain + { + public static async Task Main(string[] args) + { + await Task.Delay(1000); + Console.WriteLine("Hello Wolrd!"); + } + } +} diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.opt.roslyn.il new file mode 100644 index 0000000000..868dddd8f4 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.opt.roslyn.il @@ -0,0 +1,209 @@ + +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Copyright (c) Microsoft Corporation. Tous droits r?serv?s. + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly AsyncMain +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 ) + + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module AsyncMain.exe +// MVID: {B9141C5A-989C-49C7-986D-91A53478FC26} +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x050A0000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain + extends [mscorlib]System.Object +{ + .class auto ansi sealed nested private beforefieldinit '
d__0' + extends [mscorlib]System.ValueType + implements [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public int32 '<>1__state' + .field public valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder '<>t__builder' + .field private valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter '<>u__1' + .method private hidebysig newslot virtual final + instance void MoveNext() cil managed + { + .override [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine::MoveNext + // Code size 157 (0x9d) + .maxstack 3 + .locals init (int32 V_0, + valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter V_1, + class [mscorlib]System.Exception V_2) + IL_0000: ldarg.0 + IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>1__state' + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0043 + + IL_000a: ldc.i4 0x3e8 + IL_000f: call class [mscorlib]System.Threading.Tasks.Task [mscorlib]System.Threading.Tasks.Task::Delay(int32) + IL_0014: callvirt instance valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter [mscorlib]System.Threading.Tasks.Task::GetAwaiter() + IL_0019: stloc.1 + IL_001a: ldloca.s V_1 + IL_001c: call instance bool [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::get_IsCompleted() + IL_0021: brtrue.s IL_005f + + IL_0023: ldarg.0 + IL_0024: ldc.i4.0 + IL_0025: dup + IL_0026: stloc.0 + IL_0027: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>1__state' + IL_002c: ldarg.0 + IL_002d: ldloc.1 + IL_002e: stfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>u__1' + IL_0033: ldarg.0 + IL_0034: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>t__builder' + IL_0039: ldloca.s V_1 + IL_003b: ldarg.0 + IL_003c: call instance void [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::AwaitUnsafeOnCompletedd__0'>(!!0&, + !!1&) + IL_0041: leave.s IL_009c + + IL_0043: ldarg.0 + IL_0044: ldfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>u__1' + IL_0049: stloc.1 + IL_004a: ldarg.0 + IL_004b: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>u__1' + IL_0050: initobj [mscorlib]System.Runtime.CompilerServices.TaskAwaiter + IL_0056: ldarg.0 + IL_0057: ldc.i4.m1 + IL_0058: dup + IL_0059: stloc.0 + IL_005a: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>1__state' + IL_005f: ldloca.s V_1 + IL_0061: call instance void [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::GetResult() + IL_0066: ldstr "Hello Wolrd!" + IL_006b: call void [mscorlib]System.Console::WriteLine(string) + IL_0070: leave.s IL_0089 + + } // end .try + catch [mscorlib]System.Exception + { + IL_0072: stloc.2 + IL_0073: ldarg.0 + IL_0074: ldc.i4.s -2 + IL_0076: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>1__state' + IL_007b: ldarg.0 + IL_007c: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>t__builder' + IL_0081: ldloc.2 + IL_0082: call instance void [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::SetException(class [mscorlib]System.Exception) + IL_0087: leave.s IL_009c + + } // end handler + IL_0089: ldarg.0 + IL_008a: ldc.i4.s -2 + IL_008c: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>1__state' + IL_0091: ldarg.0 + IL_0092: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>t__builder' + IL_0097: call instance void [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::SetResult() + IL_009c: ret + } // end of method '
d__0'::MoveNext + + .method private hidebysig newslot virtual final + instance void SetStateMachine(class [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine stateMachine) cil managed + { + .custom instance void [mscorlib]System.Diagnostics.DebuggerHiddenAttribute::.ctor() = ( 01 00 00 00 ) + .override [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine::SetStateMachine + // Code size 13 (0xd) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>t__builder' + IL_0006: ldarg.1 + IL_0007: call instance void [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::SetStateMachine(class [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine) + IL_000c: ret + } // end of method '
d__0'::SetStateMachine + + } // end of class '
d__0' + + .method public hidebysig static class [mscorlib]System.Threading.Tasks.Task + Main(string[] args) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.AsyncStateMachineAttribute::.ctor(class [mscorlib]System.Type) = ( 01 00 42 49 43 53 68 61 72 70 43 6F 64 65 2E 44 // ..BICSharpCode.D + 65 63 6F 6D 70 69 6C 65 72 2E 54 65 73 74 73 2E // ecompiler.Tests. + 54 65 73 74 43 61 73 65 73 2E 50 72 65 74 74 79 // TestCases.Pretty + 2E 41 73 79 6E 63 4D 61 69 6E 2B 3C 4D 61 69 6E // .AsyncMain+
d__0.. + // Code size 49 (0x31) + .maxstack 2 + .locals init (valuetype ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0' V_0, + valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder V_1) + IL_0000: ldloca.s V_0 + IL_0002: call valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::Create() + IL_0007: stfld valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>t__builder' + IL_000c: ldloca.s V_0 + IL_000e: ldc.i4.m1 + IL_000f: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>1__state' + IL_0014: ldloc.0 + IL_0015: ldfld valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>t__builder' + IL_001a: stloc.1 + IL_001b: ldloca.s V_1 + IL_001d: ldloca.s V_0 + IL_001f: call instance void [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::Startd__0'>(!!0&) + IL_0024: ldloca.s V_0 + IL_0026: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>t__builder' + IL_002b: call instance class [mscorlib]System.Threading.Tasks.Task [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::get_Task() + IL_0030: ret + } // end of method AsyncMain::Main + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: ret + } // end of method AsyncMain::.ctor + + .method private hidebysig specialname static + void '
'(string[] args) cil managed + { + .entrypoint + // Code size 20 (0x14) + .maxstack 1 + .locals init (valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter V_0) + IL_0000: ldarg.0 + IL_0001: call class [mscorlib]System.Threading.Tasks.Task ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain::Main(string[]) + IL_0006: callvirt instance valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter [mscorlib]System.Threading.Tasks.Task::GetAwaiter() + IL_000b: stloc.0 + IL_000c: ldloca.s V_0 + IL_000e: call instance void [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::GetResult() + IL_0013: ret + } // end of method AsyncMain::'
' + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.roslyn.il new file mode 100644 index 0000000000..fab746d383 --- /dev/null +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.roslyn.il @@ -0,0 +1,237 @@ + +// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 +// Copyright (c) Microsoft Corporation. Tous droits r?serv?s. + + + +// Metadata version: v4.0.30319 +.assembly extern mscorlib +{ + .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. + .ver 4:0:0:0 +} +.assembly AsyncMain +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx + 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. + + // --- The following custom attribute is added automatically, do not uncomment ------- + // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) + + .permissionset reqmin + = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}} + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module AsyncMain.exe +// MVID: {9AD23895-984A-4198-A22B-F506741986BA} +.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) +.imagebase 0x00400000 +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 // WINDOWS_CUI +.corflags 0x00000001 // ILONLY +// Image base: 0x04F10000 + + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain + extends [mscorlib]System.Object +{ + .class auto ansi sealed nested private beforefieldinit '
d__0' + extends [mscorlib]System.Object + implements [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .field public int32 '<>1__state' + .field public valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder '<>t__builder' + .field public string[] args + .field private valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter '<>u__1' + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method '
d__0'::.ctor + + .method private hidebysig newslot virtual final + instance void MoveNext() cil managed + { + .override [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine::MoveNext + // Code size 170 (0xaa) + .maxstack 3 + .locals init (int32 V_0, + valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter V_1, + class ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0' V_2, + class [mscorlib]System.Exception V_3) + IL_0000: ldarg.0 + IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>1__state' + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_000c + + IL_000a: br.s IL_000e + + IL_000c: br.s IL_004c + + IL_000e: nop + IL_000f: ldc.i4 0x3e8 + IL_0014: call class [mscorlib]System.Threading.Tasks.Task [mscorlib]System.Threading.Tasks.Task::Delay(int32) + IL_0019: callvirt instance valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter [mscorlib]System.Threading.Tasks.Task::GetAwaiter() + IL_001e: stloc.1 + IL_001f: ldloca.s V_1 + IL_0021: call instance bool [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::get_IsCompleted() + IL_0026: brtrue.s IL_0068 + + IL_0028: ldarg.0 + IL_0029: ldc.i4.0 + IL_002a: dup + IL_002b: stloc.0 + IL_002c: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>1__state' + IL_0031: ldarg.0 + IL_0032: ldloc.1 + IL_0033: stfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>u__1' + IL_0038: ldarg.0 + IL_0039: stloc.2 + IL_003a: ldarg.0 + IL_003b: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>t__builder' + IL_0040: ldloca.s V_1 + IL_0042: ldloca.s V_2 + IL_0044: call instance void [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::AwaitUnsafeOnCompletedd__0'>(!!0&, + !!1&) + IL_0049: nop + IL_004a: leave.s IL_00a9 + + IL_004c: ldarg.0 + IL_004d: ldfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>u__1' + IL_0052: stloc.1 + IL_0053: ldarg.0 + IL_0054: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>u__1' + IL_0059: initobj [mscorlib]System.Runtime.CompilerServices.TaskAwaiter + IL_005f: ldarg.0 + IL_0060: ldc.i4.m1 + IL_0061: dup + IL_0062: stloc.0 + IL_0063: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>1__state' + IL_0068: ldloca.s V_1 + IL_006a: call instance void [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::GetResult() + IL_006f: nop + IL_0070: ldstr "Hello Wolrd!" + IL_0075: call void [mscorlib]System.Console::WriteLine(string) + IL_007a: nop + IL_007b: leave.s IL_0095 + + } // end .try + catch [mscorlib]System.Exception + { + IL_007d: stloc.3 + IL_007e: ldarg.0 + IL_007f: ldc.i4.s -2 + IL_0081: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>1__state' + IL_0086: ldarg.0 + IL_0087: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>t__builder' + IL_008c: ldloc.3 + IL_008d: call instance void [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::SetException(class [mscorlib]System.Exception) + IL_0092: nop + IL_0093: leave.s IL_00a9 + + } // end handler + IL_0095: ldarg.0 + IL_0096: ldc.i4.s -2 + IL_0098: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>1__state' + IL_009d: ldarg.0 + IL_009e: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>t__builder' + IL_00a3: call instance void [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::SetResult() + IL_00a8: nop + IL_00a9: ret + } // end of method '
d__0'::MoveNext + + .method private hidebysig newslot virtual final + instance void SetStateMachine(class [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine stateMachine) cil managed + { + .custom instance void [mscorlib]System.Diagnostics.DebuggerHiddenAttribute::.ctor() = ( 01 00 00 00 ) + .override [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine::SetStateMachine + // Code size 1 (0x1) + .maxstack 8 + IL_0000: ret + } // end of method '
d__0'::SetStateMachine + + } // end of class '
d__0' + + .method public hidebysig static class [mscorlib]System.Threading.Tasks.Task + Main(string[] args) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.AsyncStateMachineAttribute::.ctor(class [mscorlib]System.Type) = ( 01 00 42 49 43 53 68 61 72 70 43 6F 64 65 2E 44 // ..BICSharpCode.D + 65 63 6F 6D 70 69 6C 65 72 2E 54 65 73 74 73 2E // ecompiler.Tests. + 54 65 73 74 43 61 73 65 73 2E 50 72 65 74 74 79 // TestCases.Pretty + 2E 41 73 79 6E 63 4D 61 69 6E 2B 3C 4D 61 69 6E // .AsyncMain+
d__0.. + .custom instance void [mscorlib]System.Diagnostics.DebuggerStepThroughAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 59 (0x3b) + .maxstack 2 + .locals init (class ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0' V_0, + valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder V_1) + IL_0000: newobj instance void ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::.ctor() + IL_0005: stloc.0 + IL_0006: ldloc.0 + IL_0007: ldarg.0 + IL_0008: stfld string[] ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::args + IL_000d: ldloc.0 + IL_000e: call valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::Create() + IL_0013: stfld valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>t__builder' + IL_0018: ldloc.0 + IL_0019: ldc.i4.m1 + IL_001a: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>1__state' + IL_001f: ldloc.0 + IL_0020: ldfld valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>t__builder' + IL_0025: stloc.1 + IL_0026: ldloca.s V_1 + IL_0028: ldloca.s V_0 + IL_002a: call instance void [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::Startd__0'>(!!0&) + IL_002f: ldloc.0 + IL_0030: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain/'
d__0'::'<>t__builder' + IL_0035: call instance class [mscorlib]System.Threading.Tasks.Task [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder::get_Task() + IL_003a: ret + } // end of method AsyncMain::Main + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [mscorlib]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method AsyncMain::.ctor + + .method private hidebysig specialname static + void '
'(string[] args) cil managed + { + .entrypoint + // Code size 20 (0x14) + .maxstack 1 + .locals init (valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter V_0) + IL_0000: ldarg.0 + IL_0001: call class [mscorlib]System.Threading.Tasks.Task ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain::Main(string[]) + IL_0006: callvirt instance valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter [mscorlib]System.Threading.Tasks.Task::GetAwaiter() + IL_000b: stloc.0 + IL_000c: ldloca.s V_0 + IL_000e: call instance void [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::GetResult() + IL_0013: ret + } // end of method AsyncMain::'
' + +} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.AsyncMain + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs index 731c7c9646..dc5901dbcc 100644 --- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs @@ -204,6 +204,8 @@ public static bool MemberIsHidden(MemberReference member, DecompilerSettings set return true; if (settings.AnonymousMethods && method.HasGeneratedName() && method.IsCompilerGenerated()) return true; + if (settings.AsyncAwait && AsyncAwaitDecompiler.IsCompilerGeneratedMainMethod(method)) + return true; } TypeDefinition type = member as TypeDefinition; diff --git a/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs b/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs index 3746df2ada..31f87c729f 100644 --- a/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs +++ b/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs @@ -20,6 +20,7 @@ using ICSharpCode.Decompiler.IL.Transforms; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.Util; +using Mono.Cecil; using System; using System.Collections.Generic; using System.Diagnostics; @@ -44,6 +45,11 @@ public static bool IsCompilerGeneratedStateMachine(Mono.Cecil.TypeDefinition typ return false; } + public static bool IsCompilerGeneratedMainMethod(MethodDefinition method) + { + return method.Name.Equals("
", StringComparison.Ordinal); + } + enum AsyncMethodType { Void, From 14f9577a815bab03170df05fad97280eb5c0442d Mon Sep 17 00:00:00 2001 From: MikeFH Date: Mon, 15 Jan 2018 22:17:41 +0100 Subject: [PATCH 2/3] Fix lines starting with spaces --- ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.cs index 0722cbaf6b..6d7f03bf69 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/AsyncMain.cs @@ -4,11 +4,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { public class AsyncMain - { + { public static async Task Main(string[] args) { await Task.Delay(1000); Console.WriteLine("Hello Wolrd!"); } - } + } } From c299304034cf36388fc3a063b56510433f435dd2 Mon Sep 17 00:00:00 2001 From: MikeFH Date: Thu, 18 Jan 2018 13:59:26 +0100 Subject: [PATCH 3/3] Check that method is actually the entry point --- ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs b/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs index 31f87c729f..adc55b6858 100644 --- a/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs +++ b/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs @@ -47,7 +47,7 @@ public static bool IsCompilerGeneratedStateMachine(Mono.Cecil.TypeDefinition typ public static bool IsCompilerGeneratedMainMethod(MethodDefinition method) { - return method.Name.Equals("
", StringComparison.Ordinal); + return method == method.Module.Assembly?.EntryPoint && method.Name.Equals("
", StringComparison.Ordinal); } enum AsyncMethodType