Browse Source

Make the pre-increment operators work on static fields.

pull/100/head
Daniel Grunwald 15 years ago
parent
commit
52b178df90
  1. 4
      ICSharpCode.Decompiler/Ast/Transforms/ReplaceMethodCallsWithOperators.cs
  2. 10
      ICSharpCode.Decompiler/ILAst/PatternMatching.cs
  3. 22
      ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs
  4. 2
      ICSharpCode.Decompiler/ILAst/SimpleControlFlow.cs
  5. 12
      ICSharpCode.Decompiler/Tests/IncrementDecrement.cs

4
ICSharpCode.Decompiler/Ast/Transforms/ReplaceMethodCallsWithOperators.cs

@ -235,9 +235,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
static bool IsWithoutSideEffects(Expression left) static bool IsWithoutSideEffects(Expression left)
{ {
if (left is ThisReferenceExpression) if (left is ThisReferenceExpression || left is IdentifierExpression || left is TypeReferenceExpression)
return true;
if (left is IdentifierExpression)
return true; return true;
MemberReferenceExpression mre = left as MemberReferenceExpression; MemberReferenceExpression mre = left as MemberReferenceExpression;
if (mre != null) if (mre != null)

10
ICSharpCode.Decompiler/ILAst/PatternMatching.cs

@ -28,16 +28,6 @@ namespace ICSharpCode.Decompiler.ILAst
return false; return false;
} }
public static bool Match<T>(this ILNode node, ILCode code, T operand)
{
ILExpression expr = node as ILExpression;
if (expr != null && expr.Prefixes == null && expr.Code == code) {
Debug.Assert(expr.Arguments.Count == 0);
return operand.Equals(expr.Operand);
}
return false;
}
public static bool Match(this ILNode node, ILCode code, out List<ILExpression> args) public static bool Match(this ILNode node, ILCode code, out List<ILExpression> args)
{ {
ILExpression expr = node as ILExpression; ILExpression expr = node as ILExpression;

22
ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs

@ -190,16 +190,14 @@ namespace ICSharpCode.Decompiler.ILAst
// stloc(v, exprVar) // stloc(v, exprVar)
// -> // ->
// exprVar = stloc(v, ...)) // exprVar = stloc(v, ...))
ILExpression nextExpr = body.ElementAtOrDefault(pos + 1) as ILExpression;
ILVariable exprVar; ILVariable exprVar;
ILExpression initializer; ILExpression initializer;
if (!(expr.Match(ILCode.Stloc, out exprVar, out initializer) && exprVar.IsGenerated))
return false;
ILExpression nextExpr = body.ElementAtOrDefault(pos + 1) as ILExpression;
ILVariable v; ILVariable v;
ILExpression stLocArg; ILExpression stLocArg;
if (expr.Match(ILCode.Stloc, out exprVar, out initializer) && if (nextExpr.Match(ILCode.Stloc, out v, out stLocArg) && stLocArg.MatchLdloc(exprVar)) {
exprVar.IsGenerated &&
nextExpr.Match(ILCode.Stloc, out v, out stLocArg) &&
stLocArg.Match(ILCode.Ldloc, exprVar))
{
ILExpression store2 = body.ElementAtOrDefault(pos + 2) as ILExpression; ILExpression store2 = body.ElementAtOrDefault(pos + 2) as ILExpression;
if (StoreCanBeConvertedToAssignment(store2, exprVar)) { if (StoreCanBeConvertedToAssignment(store2, exprVar)) {
// expr_44 = ... // expr_44 = ...
@ -224,6 +222,18 @@ namespace ICSharpCode.Decompiler.ILAst
nextExpr.Arguments[0] = initializer; nextExpr.Arguments[0] = initializer;
((ILExpression)body[pos]).Arguments[0] = nextExpr; ((ILExpression)body[pos]).Arguments[0] = nextExpr;
return true; return true;
} else {
// exprVar = ...
// stsfld(fld, exprVar)
// ->
// exprVar = stsfld(fld, ...))
FieldReference field;
if (nextExpr.Match(ILCode.Stsfld, out field, out stLocArg) && stLocArg.MatchLdloc(exprVar)) {
body.RemoveAt(pos + 1); // remove stfld
nextExpr.Arguments[0] = initializer;
((ILExpression)body[pos]).Arguments[0] = nextExpr;
return true;
}
} }
return false; return false;
} }

2
ICSharpCode.Decompiler/ILAst/SimpleControlFlow.cs

@ -152,7 +152,7 @@ namespace ICSharpCode.Decompiler.ILAst
head.Body[head.Body.Count - 3].Match(ILCode.Stloc, out v, out leftExpr) && head.Body[head.Body.Count - 3].Match(ILCode.Stloc, out v, out leftExpr) &&
leftExpr.Match(ILCode.Ldloc, out leftVar) && leftExpr.Match(ILCode.Ldloc, out leftVar) &&
head.MatchLastAndBr(ILCode.Brtrue, out endBBLabel, out leftExpr2, out rightBBLabel) && head.MatchLastAndBr(ILCode.Brtrue, out endBBLabel, out leftExpr2, out rightBBLabel) &&
leftExpr2.Match(ILCode.Ldloc, leftVar) && leftExpr2.MatchLdloc(leftVar) &&
labelToBasicBlock.TryGetValue(rightBBLabel, out rightBB) && labelToBasicBlock.TryGetValue(rightBBLabel, out rightBB) &&
rightBB.MatchSingleAndBr(ILCode.Stloc, out v2, out rightExpr, out endBBLabel2) && rightBB.MatchSingleAndBr(ILCode.Stloc, out v2, out rightExpr, out endBBLabel2) &&
v == v2 && v == v2 &&

12
ICSharpCode.Decompiler/Tests/IncrementDecrement.cs

@ -10,6 +10,8 @@ public class IncrementDecrement
public int Field; public int Field;
} }
public static int StaticField;
private IncrementDecrement.MutableClass M() private IncrementDecrement.MutableClass M()
{ {
return new IncrementDecrement.MutableClass(); return new IncrementDecrement.MutableClass();
@ -35,11 +37,21 @@ public class IncrementDecrement
return ++m.Field; return ++m.Field;
} }
public int PreIncrementStaticField()
{
return ++IncrementDecrement.StaticField;
}
public int CompoundMultiplyInstanceField() public int CompoundMultiplyInstanceField()
{ {
return this.M().Field *= 10; return this.M().Field *= 10;
} }
public int CompoundXorStaticField()
{
return IncrementDecrement.StaticField ^= 100;
}
public int CompoundMultiplyArrayElement1(int[] array, int pos) public int CompoundMultiplyArrayElement1(int[] array, int pos)
{ {
return array[pos] *= 10; return array[pos] *= 10;

Loading…
Cancel
Save