Browse Source

Fix regression in TransformPostIncDecOperatorOnAddress;

Add pattern for Roslyn inc/dec operator on addresses
pull/892/merge
Siegfried Pammer 8 years ago
parent
commit
cf8d4936e6
  1. 36
      ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs

36
ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs

@ -47,6 +47,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -47,6 +47,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
continue;
if (TransformRoslynCompoundAssignmentCall(block, i))
continue;
if (TransformRoslynPostIncDecOperatorOnAddress(block, i))
continue;
}
}
@ -299,12 +301,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -299,12 +301,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms
bool TransformPostIncDecOperatorOnAddress(Block block, int i)
{
var inst = block.Instructions[i] as StLoc;
if (!inst.Variable.IsSingleDefinition || inst.Variable.LoadCount != 2)
return false;
var nextInst = block.Instructions.ElementAtOrDefault(i + 1) as StLoc;
var stobj = block.Instructions.ElementAtOrDefault(i + 2) as StObj;
if (inst == null || nextInst == null || stobj == null)
return false;
if (!inst.Variable.IsSingleDefinition || inst.Variable.LoadCount != 2)
return false;
if (!(inst.Value is LdElema || inst.Value is LdFlda || inst.Value is LdsFlda))
return false;
ILInstruction target;
@ -323,7 +325,35 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -323,7 +325,35 @@ namespace ICSharpCode.Decompiler.IL.Transforms
block.Instructions.RemoveAt(i + 1);
return true;
}
/// <code>
/// stloc l(ldobj(ldflda(target)))
/// stobj(ldflda(target), binary.op(ldloc l, ldc.i4 1))
/// -->
/// compound.op.old(ldobj(ldflda(target)), ldc.i4 1)
/// </code>
bool TransformRoslynPostIncDecOperatorOnAddress(Block block, int i)
{
var inst = block.Instructions[i] as StLoc;
var stobj = block.Instructions.ElementAtOrDefault(i + 1) as StObj;
if (inst == null || stobj == null)
return false;
if (!inst.Value.MatchLdObj(out var loadTarget, out var loadType) || !loadTarget.MatchLdFlda(out var fieldTarget, out var field))
return false;
if (!stobj.Target.MatchLdFlda(out var fieldTarget2, out var field2))
return false;
if (!fieldTarget.Match(fieldTarget2).Success || !field.Equals(field2))
return false;
var binary = stobj.Value as BinaryNumericInstruction;
if (binary == null || !binary.Left.MatchLdLoc(inst.Variable) || !binary.Right.MatchLdcI4(1)
|| (binary.Operator != BinaryNumericOperator.Add && binary.Operator != BinaryNumericOperator.Sub))
return false;
context.Step($"TransformRoslynPostIncDecOperator", inst);
stobj.ReplaceWith(new CompoundAssignmentInstruction(binary, inst.Value, binary.Right, loadType, CompoundAssignmentType.EvaluatesToOldValue));
block.Instructions.RemoveAt(i);
return true;
}
/// <code>
/// stloc s(ldflda)
/// stloc s2(ldobj(ldflda(ldloc s)))

Loading…
Cancel
Save