Browse Source

Yet another special case of compound assignment.

pull/728/merge
Siegfried Pammer 9 years ago
parent
commit
43a2c9d0be
  1. 38
      ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs

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

@ -36,7 +36,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -36,7 +36,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
this.context = context;
foreach (var block in function.Descendants.OfType<Block>()) {
for (int i = block.Instructions.Count - 1; i >= 0; i--) {
if (TransformPostIncDecOperatorOnAddress(block, i) || TransformCSharp4PostIncDecOperatorOnAddress(block, i)) {
if (TransformPostIncDecOperatorOnAddress(block, i) || TransformPostIncDecOnStaticField(block, i) || TransformCSharp4PostIncDecOperatorOnAddress(block, i)) {
block.Instructions.RemoveAt(i);
continue;
}
@ -241,7 +241,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -241,7 +241,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
ILInstruction baseFieldAddressLoad3;
if (!targetFieldLoad.MatchLdFlda(out baseFieldAddressLoad2, out targetField) || !baseFieldAddressLoad2.MatchLdLoc(baseFieldAddress.Variable))
return false;
if (!stobj.Target.MatchLdFlda(out baseFieldAddressLoad3, out targetField2) || !baseFieldAddressLoad3.MatchLdLoc(baseFieldAddress.Variable) || !targetField.Equals(targetField2))
if (!stobj.Target.MatchLdFlda(out baseFieldAddressLoad3, out targetField2) || !baseFieldAddressLoad3.MatchLdLoc(baseFieldAddress.Variable) || !SameField(targetField, targetField2))
return false;
baseAddress = new LdFlda(baseFieldAddress.Value, targetField);
} else if (baseFieldAddress.Value is LdElema) {
@ -261,5 +261,39 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -261,5 +261,39 @@ namespace ICSharpCode.Decompiler.IL.Transforms
block.Instructions.RemoveAt(i + 1);
return true;
}
/// <code>
/// stloc s(ldobj(ldsflda))
/// stobj (ldsflda, binary.op(ldloc s, ldc.i4 1))
/// -->
/// stloc s(compound.op.old(ldobj(ldsflda), ldc.i4 1))
/// </code>
static bool TransformPostIncDecOnStaticField(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;
ILInstruction target;
IType type;
IField field, field2;
if (inst.Variable.Kind != VariableKind.StackSlot || !inst.Value.MatchLdObj(out target, out type) || !target.MatchLdsFlda(out field))
return false;
if (!stobj.Target.MatchLdsFlda(out field2) || !SameField(field, field2))
return false;
var binary = stobj.Value as BinaryNumericInstruction;
if (binary == null || !binary.Left.MatchLdLoc(inst.Variable) || !binary.Right.MatchLdcI4(1))
return false;
var assignment = new CompoundAssignmentInstruction(binary.Operator, inst.Value, binary.Right, type, binary.CheckForOverflow, binary.Sign, CompoundAssignmentType.EvaluatesToOldValue);
stobj.ReplaceWith(new StLoc(inst.Variable, assignment));
return true;
}
static bool SameField(IField a, IField b)
{
a = (IField)a.MemberDefinition;
b = (IField)b.MemberDefinition;
return a.Equals(b);
}
}
}

Loading…
Cancel
Save