From 1c261c61709a26a6116d8f699c5893f7f63ccfbd Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Wed, 6 Mar 2019 22:02:48 +0100 Subject: [PATCH] Optimize ProxyCallReplacer: ignore calls to static methods as those can never be a call to a proxy. Enable FixProxyCalls test for rosyln+opt --- .../PrettyTestRunner.cs | 2 +- .../TestCases/Pretty/FixProxyCalls.cs | 4 +- .../IL/Transforms/ProxyCallReplacer.cs | 37 +++++++++++-------- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs index cc89c266d..1e15135f1 100644 --- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs +++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs @@ -252,7 +252,7 @@ namespace ICSharpCode.Decompiler.Tests } [Test] - public void FixProxyCalls([Values(CompilerOptions.None, CompilerOptions.Optimize, CompilerOptions.UseRoslyn)] CompilerOptions cscOptions) + public void FixProxyCalls([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions) { RunForLibrary(cscOptions: cscOptions); } diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/FixProxyCalls.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/FixProxyCalls.cs index b0a6363b7..338416d97 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/FixProxyCalls.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/FixProxyCalls.cs @@ -92,9 +92,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty internal class H : G { + private Action action; + protected internal override void Test(string test) { - Action action = delegate(string a) { + action = delegate(string a) { base.Test(a); }; if (test.Equals(1)) { diff --git a/ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs b/ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs index 5c3680109..6b5383150 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs @@ -17,6 +17,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms void Run(CallInstruction inst, ILTransformContext context) { + if (inst.Method.IsStatic) + return; if (inst.Method.MetadataToken.IsNil || inst.Method.MetadataToken.Kind != HandleKind.MethodDefinition) return; var handle = (MethodDefinitionHandle)inst.Method.MetadataToken; @@ -42,28 +44,33 @@ namespace ICSharpCode.Decompiler.IL.Transforms if (blockContainer.Blocks.Count != 1) return; var block = blockContainer.Blocks[0]; - Call call = null; - if (block.Instructions.Count == 1) { - // leave IL_0000 (call Test(ldloc this, ldloc A_1)) - if (!block.Instructions[0].MatchLeave(blockContainer, out ILInstruction returnValue)) - return; - call = returnValue as Call; - } else if (block.Instructions.Count == 2) { - // call Test(ldloc this, ldloc A_1) - // leave IL_0000(nop) - call = block.Instructions[0] as Call; - if (!block.Instructions[1].MatchLeave(blockContainer, out ILInstruction returnValue)) - return; - if (!returnValue.MatchNop()) + Call call; + ILInstruction returnValue; + switch (block.Instructions.Count) { + case 1: + // leave IL_0000 (call Test(ldloc this, ldloc A_1)) + if (!block.Instructions[0].MatchLeave(blockContainer, out returnValue)) + return; + call = returnValue as Call; + break; + case 2: + // call Test(ldloc this, ldloc A_1) + // leave IL_0000(nop) + call = block.Instructions[0] as Call; + if (!block.Instructions[1].MatchLeave(blockContainer, out returnValue)) + return; + if (!returnValue.MatchNop()) + return; + break; + default: return; } if (call == null || call.Method.IsConstructor) { return; } - if (call.Method.IsStatic != inst.Method.IsStatic || call.Method.Parameters.Count != inst.Method.Parameters.Count) { + if (call.Method.IsStatic || call.Method.Parameters.Count != inst.Method.Parameters.Count) { return; } - // check if original arguments are only correct ldloc calls for (int i = 0; i < call.Arguments.Count; i++) { var originalArg = call.Arguments[i];