Browse Source

Add ldobj(ldloca) -> ldloc transform; and remove special case in ProxyCallReplacer.

pull/892/merge
Daniel Grunwald 8 years ago
parent
commit
f6ab796ba7
  1. 25
      ICSharpCode.Decompiler/IL/Transforms/EarlyExpressionTransforms.cs
  2. 6
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs
  3. 25
      ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs

25
ICSharpCode.Decompiler/IL/Transforms/EarlyExpressionTransforms.cs

@ -54,9 +54,30 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (inst.Target.MatchLdLoca(out ILVariable v) if (inst.Target.MatchLdLoca(out ILVariable v)
&& TypeUtils.IsCompatibleTypeForMemoryAccess(new ByReferenceType(v.Type), inst.Type) && TypeUtils.IsCompatibleTypeForMemoryAccess(new ByReferenceType(v.Type), inst.Type)
&& inst.UnalignedPrefix == 0 && inst.UnalignedPrefix == 0
&& !inst.IsVolatile) { && !inst.IsVolatile)
{
context.Step($"stobj(ldloca {v.Name}, ...) => stloc {v.Name}(...)", inst); 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 true;
} }
return false; return false;

6
ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

@ -276,6 +276,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false; return false;
} }
protected internal override void VisitLdObj(LdObj inst)
{
base.VisitLdObj(inst);
EarlyExpressionTransforms.LdObjToLdLoc(inst, context);
}
protected internal override void VisitStObj(StObj inst) protected internal override void VisitStObj(StObj inst)
{ {
base.VisitStObj(inst); base.VisitStObj(inst);

25
ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs

@ -69,30 +69,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
Call newInst = (Call)call.Clone(); Call newInst = (Call)call.Clone();
newInst.Arguments.Clear(); newInst.Arguments.ReplaceList(inst.Arguments);
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]);
}
}
inst.ReplaceWith(newInst); inst.ReplaceWith(newInst);
} }
} }

Loading…
Cancel
Save