Browse Source

Fixed issues with "fixed" statement that were introduced by recent changes.

pull/105/head
Daniel Grunwald 16 years ago
parent
commit
6376110913
  1. 11
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs
  2. 26
      ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs

11
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using ICSharpCode.Decompiler.FlowAnalysis; using ICSharpCode.Decompiler.FlowAnalysis;
using ICSharpCode.NRefactory.Utils;
using Mono.Cecil; using Mono.Cecil;
using Mono.Cecil.Cil; using Mono.Cecil.Cil;
using Mono.CSharp; using Mono.CSharp;
@ -176,14 +177,8 @@ namespace ICSharpCode.Decompiler.ILAst
} }
if (abortBeforeStep == ILAstOptimizationStep.IntroduceFixedStatements) return; if (abortBeforeStep == ILAstOptimizationStep.IntroduceFixedStatements) return;
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>()) { // we need post-order traversal, not pre-order, for "fixed" to work correctly
for (int i = block.Body.Count - 1; i >= 0; i--) { foreach (ILBlock block in TreeTraversal.PostOrder<ILNode>(method, n => n.GetChildren()).OfType<ILBlock>()) {
// TODO: Move before loops
if (i < block.Body.Count)
IntroduceFixedStatements(block.Body, i);
}
}
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>()) {
for (int i = block.Body.Count - 1; i >= 0; i--) { for (int i = block.Body.Count - 1; i >= 0; i--) {
// TODO: Move before loops // TODO: Move before loops
if (i < block.Body.Count) if (i < block.Body.Count)

26
ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs

@ -641,6 +641,17 @@ namespace ICSharpCode.Decompiler.ILAst
&& falseValue.Arguments[0].Match(ILCode.Ldloc, out loadedVariable) && loadedVariable == arrayVariable && falseValue.Arguments[0].Match(ILCode.Ldloc, out loadedVariable) && loadedVariable == arrayVariable
&& IsNullOrZero(falseValue.Arguments[1])) && IsNullOrZero(falseValue.Arguments[1]))
{ {
// OK, we detected the pattern for fixing an array.
// Now check whether the loading expression was a store ot a temp. var
// that can be eliminated.
if (arrayLoadingExpr.Code == ILCode.Stloc) {
ILInlining inlining = new ILInlining(method);
if (inlining.numLdloc.GetOrDefault(arrayVariable) == 2 &&
inlining.numStloc.GetOrDefault(arrayVariable) == 1 && inlining.numLdloca.GetOrDefault(arrayVariable) == 0)
{
arrayLoadingExpr = arrayLoadingExpr.Arguments[0];
}
}
initValue = new ILExpression(ILCode.Stloc, pinnedVar, arrayLoadingExpr); initValue = new ILExpression(ILCode.Stloc, pinnedVar, arrayLoadingExpr);
nextPos = i + 1; nextPos = i + 1;
return true; return true;
@ -657,16 +668,17 @@ namespace ICSharpCode.Decompiler.ILAst
bool MatchFixedArrayInitializerCondition(ILExpression condition, out ILExpression initValue) bool MatchFixedArrayInitializerCondition(ILExpression condition, out ILExpression initValue)
{ {
ILExpression logicAnd; ILExpression logicAnd;
ILVariable arrayVar1, arrayVar2; ILVariable arrayVar;
if (condition.Match(ILCode.LogicNot, out logicAnd) && logicAnd.Code == ILCode.LogicAnd) { if (condition.Match(ILCode.LogicNot, out logicAnd) && logicAnd.Code == ILCode.LogicAnd) {
initValue = UnpackDoubleNegation(logicAnd.Arguments[0]); initValue = UnpackDoubleNegation(logicAnd.Arguments[0]);
if (initValue.Match(ILCode.Ldloc, out arrayVar1)) { ILExpression arrayVarInitializer;
if (initValue.Match(ILCode.Ldloc, out arrayVar)
|| initValue.Match(ILCode.Stloc, out arrayVar, out arrayVarInitializer))
{
ILExpression arrayLength = logicAnd.Arguments[1]; ILExpression arrayLength = logicAnd.Arguments[1];
if (arrayLength.Code == ILCode.Conv_I4) if (arrayLength.Code == ILCode.Conv_I4)
arrayLength = arrayLength.Arguments[0]; arrayLength = arrayLength.Arguments[0];
if (arrayLength.Code == ILCode.Ldlen && arrayLength.Arguments[0].Match(ILCode.Ldloc, out arrayVar2)) { return arrayLength.Code == ILCode.Ldlen && arrayLength.Arguments[0].MatchLdloc(arrayVar);
return arrayVar1 == arrayVar2;
}
} }
} }
initValue = null; initValue = null;
@ -716,7 +728,9 @@ namespace ICSharpCode.Decompiler.ILAst
if (!(ifStmt.TrueBlock.Body[0].Match(ILCode.Stloc, out assignedVar, out assignedExpr) && assignedVar == var2 && assignedExpr.Code == ILCode.Add)) if (!(ifStmt.TrueBlock.Body[0].Match(ILCode.Stloc, out assignedVar, out assignedExpr) && assignedVar == var2 && assignedExpr.Code == ILCode.Add))
return false; return false;
MethodReference calledMethod; MethodReference calledMethod;
if (!(assignedExpr.Arguments[0].MatchLdloc(var1) && assignedExpr.Arguments[1].Match(ILCode.Call, out calledMethod))) if (!(assignedExpr.Arguments[0].MatchLdloc(var1)))
return false;
if (!(assignedExpr.Arguments[1].Match(ILCode.Call, out calledMethod) || assignedExpr.Arguments[1].Match(ILCode.CallGetter, out calledMethod)))
return false; return false;
if (!(calledMethod.Name == "get_OffsetToStringData" && calledMethod.DeclaringType.FullName == "System.Runtime.CompilerServices.RuntimeHelpers")) if (!(calledMethod.Name == "get_OffsetToStringData" && calledMethod.DeclaringType.FullName == "System.Runtime.CompilerServices.RuntimeHelpers"))
return false; return false;

Loading…
Cancel
Save