diff --git a/ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs b/ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs index f3f7c552f..b021fb840 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs @@ -36,12 +36,25 @@ namespace ICSharpCode.Decompiler.IL.Transforms if (blockContainer.Blocks.Count != 1) return; var block = blockContainer.Blocks[0]; - if (block.Instructions.Count != 1) - return; - if (!block.Instructions[0].MatchLeave(blockContainer, out ILInstruction returnValue)) - return; - if (!(returnValue is Call call)) + 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()) + return; + } + if (call == null) { return; + } + // check if original arguments are only correct ldloc calls for (int i = 0; i < call.Arguments.Count; i++) { var originalArg = call.Arguments[i]; @@ -56,25 +69,27 @@ namespace ICSharpCode.Decompiler.IL.Transforms newInst.Arguments.Clear(); - ILInstruction thisArg = inst.Arguments[0]; + if (inst.Arguments.Count > 0) { + ILInstruction thisArg = inst.Arguments[0]; - // special handling for first argument (this) - the underlying issue may be somewhere else - // normally - // leave IL_0000(await(callvirt<> n__0(ldobj xxHandler(ldloca this), ldobj System.Net.Http.HttpRequestMessage(ldloca request), ldobj System.Threading.CancellationToken(ldloca cancellationToken)))) - // would be decompiled to - // return await((DelegatingHandler)this).SendAsync(request, cancellationToken); - // this changes it to - // return await base.SendAsync(request, cancellationToken); - if (thisArg.MatchLdObj(out ILInstruction loadedObject, out IType objectType) && - loadedObject.MatchLdLoca(out ILVariable loadedVar)) { - thisArg = new LdLoc(loadedVar); - } + // special handling for first argument (this) - the underlying issue may be somewhere else + // normally + // leave IL_0000(await(callvirt<> n__0(ldobj xxHandler(ldloca this), ldobj System.Net.Http.HttpRequestMessage(ldloca request), ldobj System.Threading.CancellationToken(ldloca cancellationToken)))) + // would be decompiled to + // return await((DelegatingHandler)this).SendAsync(request, cancellationToken); + // this changes it to + // return await base.SendAsync(request, cancellationToken); + if (thisArg.MatchLdObj(out ILInstruction loadedObject, out IType objectType) && + loadedObject.MatchLdLoca(out ILVariable loadedVar)) { + thisArg = new LdLoc(loadedVar); + } - newInst.Arguments.Add(thisArg); + newInst.Arguments.Add(thisArg); - // add everything except first argument - for (int i = 1; i < inst.Arguments.Count; i++) { - newInst.Arguments.Add(inst.Arguments[i]); + // add everything except first argument + for (int i = 1; i < inst.Arguments.Count; i++) { + newInst.Arguments.Add(inst.Arguments[i]); + } } inst.ReplaceWith(newInst); }