Browse Source

Add addressof(ldloc) => ldloca transform to EarlyExpressionTransforms

pull/1586/head
Siegfried Pammer 6 years ago
parent
commit
19a7898786
  1. 22
      ICSharpCode.Decompiler/IL/Transforms/EarlyExpressionTransforms.cs
  2. 17
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

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

@ -66,6 +66,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
protected internal override void VisitLdObj(LdObj inst)
{
base.VisitLdObj(inst);
AddressOfLdLocToLdLoca(inst, context);
LdObjToLdLoc(inst, context);
}
@ -83,6 +84,27 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false;
}
internal static void AddressOfLdLocToLdLoca(LdObj inst, ILTransformContext context)
{
// ldobj(...(addressof(ldloc V))) where ... can be zero or more ldflda instructions
// =>
// ldobj(...(ldloca V))
var temp = inst.Target;
var range = temp.ILRanges;
while (temp.MatchLdFlda(out var ldfldaTarget, out _)) {
temp = ldfldaTarget;
range = range.Concat(temp.ILRanges);
}
if (temp.MatchAddressOf(out var addressOfTarget) && addressOfTarget.MatchLdLoc(out var v)) {
context.Step($"ldobj(...(addressof(ldloca {v.Name}))) => ldobj(...(ldloca {v.Name}))", inst);
var replacement = new LdLoca(v).WithILRange(addressOfTarget);
foreach (var r in range) {
replacement = replacement.WithILRange(r);
}
temp.ReplaceWith(replacement);
}
}
protected internal override void VisitCall(Call inst)
{
var expr = HandleCall(inst, context);

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

@ -393,23 +393,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
protected internal override void VisitLdObj(LdObj inst)
{
base.VisitLdObj(inst);
EarlyExpressionTransforms.AddressOfLdLocToLdLoca(inst, context);
EarlyExpressionTransforms.LdObjToLdLoc(inst, context);
// ldobj(...(addressof(ldloc V)) where ... can be zero or more ldflda instructions
// =>
// ldobj(...(ldloca V))
var temp = inst.Target;
var range = temp.ILRanges;
while (temp.MatchLdFlda(out var ldfldaTarget, out _)) {
temp = ldfldaTarget;
range = range.Concat(temp.ILRanges);
}
if (temp.MatchAddressOf(out var addressOfTarget) && addressOfTarget.MatchLdLoc(out var v)) {
var replacement = new LdLoca(v).WithILRange(addressOfTarget);
foreach (var r in range) {
replacement = replacement.WithILRange(r);
}
temp.ReplaceWith(replacement);
}
}
protected internal override void VisitStObj(StObj inst)

Loading…
Cancel
Save