From f6ab796ba70d6efbf6f94fe4df0cce96ec887c20 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Tue, 10 Oct 2017 00:01:16 +0200 Subject: [PATCH] Add ldobj(ldloca) -> ldloc transform; and remove special case in ProxyCallReplacer. --- .../Transforms/EarlyExpressionTransforms.cs | 25 +++++++++++++++++-- .../IL/Transforms/ExpressionTransforms.cs | 8 +++++- .../IL/Transforms/ProxyCallReplacer.cs | 25 +------------------ 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/Transforms/EarlyExpressionTransforms.cs b/ICSharpCode.Decompiler/IL/Transforms/EarlyExpressionTransforms.cs index c48bc0655..e5b667734 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/EarlyExpressionTransforms.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/EarlyExpressionTransforms.cs @@ -54,9 +54,30 @@ namespace ICSharpCode.Decompiler.IL.Transforms if (inst.Target.MatchLdLoca(out ILVariable v) && TypeUtils.IsCompatibleTypeForMemoryAccess(new ByReferenceType(v.Type), inst.Type) && inst.UnalignedPrefix == 0 - && !inst.IsVolatile) { + && !inst.IsVolatile) + { context.Step($"stobj(ldloca {v.Name}, ...) => stloc {v.Name}(...)", inst); - inst.ReplaceWith(new StLoc(v, inst.Value)); + inst.ReplaceWith(new StLoc(v, inst.Value) { ILRange = inst.ILRange }); + return true; + } + return false; + } + + protected internal override void VisitLdObj(LdObj inst) + { + base.VisitLdObj(inst); + LdObjToLdLoc(inst, context); + } + + internal static bool LdObjToLdLoc(LdObj inst, ILTransformContext context) + { + if (inst.Target.MatchLdLoca(out ILVariable v) + && TypeUtils.IsCompatibleTypeForMemoryAccess(new ByReferenceType(v.Type), inst.Type) + && inst.UnalignedPrefix == 0 + && !inst.IsVolatile) + { + context.Step($"ldobj(ldloca {v.Name}, ...) => ldloc {v.Name}(...)", inst); + inst.ReplaceWith(new LdLoc(v) { ILRange = inst.ILRange }); return true; } return false; diff --git a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs index 4b97e7ac0..5256f7da7 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs @@ -275,7 +275,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms } return false; } - + + protected internal override void VisitLdObj(LdObj inst) + { + base.VisitLdObj(inst); + EarlyExpressionTransforms.LdObjToLdLoc(inst, context); + } + protected internal override void VisitStObj(StObj inst) { base.VisitStObj(inst); diff --git a/ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs b/ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs index 1ea28340d..717d880cc 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs @@ -69,30 +69,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms Call newInst = (Call)call.Clone(); - newInst.Arguments.Clear(); - - 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); - } - - newInst.Arguments.Add(thisArg); - - // add everything except first argument - for (int i = 1; i < inst.Arguments.Count; i++) { - newInst.Arguments.Add(inst.Arguments[i]); - } - } + newInst.Arguments.ReplaceList(inst.Arguments); inst.ReplaceWith(newInst); } }