Browse Source

Add support for decompiling "this.field1 = this.field2 = val;"

pull/100/head
Daniel Grunwald 15 years ago
parent
commit
60f4525b04
  1. 22
      ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs
  2. 4
      ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs

22
ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs

@ -252,19 +252,19 @@ namespace ICSharpCode.Decompiler.ILAst @@ -252,19 +252,19 @@ namespace ICSharpCode.Decompiler.ILAst
return;
ILInlining inlining;
ILExpression stloc2 = block.Body.ElementAtOrDefault(i + 2) as ILExpression;
if (stloc2 != null && stloc2.Code == ILCode.Stloc && stloc2.Arguments[0].Code == ILCode.Ldloc && stloc2.Arguments[0].Operand == exprVar) {
ILExpression store2 = block.Body.ElementAtOrDefault(i + 2) as ILExpression;
if (StoreCanBeConvertedToAssignment(store2, exprVar)) {
// expr_44 = ...
// stloc(v1, expr_44)
// stloc(v2, expr_44)
// anystore(v2, expr_44)
// ->
// stloc(v1, stloc(v2, ...))
// stloc(v1, anystore(v2, ...))
inlining = new ILInlining(method);
if (inlining.numLdloc.GetOrDefault(exprVar) == 2 && inlining.numStloc.GetOrDefault(exprVar) == 1) {
block.Body.RemoveAt(i + 2); // remove stloc2
block.Body.RemoveAt(i + 2); // remove store2
block.Body.RemoveAt(i); // remove expr = ...
stloc1.Arguments[0] = stloc2;
stloc2.Arguments[0] = initializer;
stloc1.Arguments[0] = store2;
store2.Arguments[store2.Arguments.Count - 1] = initializer;
if (inlining.InlineIfPossible(block, ref i)) {
i++; // retry transformations on the new combined instruction
@ -283,6 +283,14 @@ namespace ICSharpCode.Decompiler.ILAst @@ -283,6 +283,14 @@ namespace ICSharpCode.Decompiler.ILAst
i++; // retry transformations on the new combined instruction
}
}
bool StoreCanBeConvertedToAssignment(ILExpression store, ILVariable exprVar)
{
if (store != null && (store.Code == ILCode.Stloc || store.Code == ILCode.Stfld || store.Code == ILCode.Stsfld)) {
return store.Arguments.Last().Code == ILCode.Ldloc && store.Arguments.Last().Operand == exprVar;
}
return false;
}
#endregion
}
}

4
ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs

@ -219,11 +219,11 @@ namespace ICSharpCode.Decompiler.ILAst @@ -219,11 +219,11 @@ namespace ICSharpCode.Decompiler.ILAst
InferTypeForExpression(expr.Arguments[0], ((FieldReference)expr.Operand).DeclaringType);
InferTypeForExpression(expr.Arguments[1], GetFieldType((FieldReference)expr.Operand));
}
return null;
return GetFieldType((FieldReference)expr.Operand);
case ILCode.Stsfld:
if (forceInferChildren)
InferTypeForExpression(expr.Arguments[0], GetFieldType((FieldReference)expr.Operand));
return null;
return GetFieldType((FieldReference)expr.Operand);
#endregion
#region Reference/Pointer instructions
case ILCode.Ldind_I:

Loading…
Cancel
Save