Browse Source

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

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

26
ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs

@ -641,6 +641,17 @@ namespace ICSharpCode.Decompiler.ILAst @@ -641,6 +641,17 @@ namespace ICSharpCode.Decompiler.ILAst
&& falseValue.Arguments[0].Match(ILCode.Ldloc, out loadedVariable) && loadedVariable == arrayVariable
&& 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);
nextPos = i + 1;
return true;
@ -657,16 +668,17 @@ namespace ICSharpCode.Decompiler.ILAst @@ -657,16 +668,17 @@ namespace ICSharpCode.Decompiler.ILAst
bool MatchFixedArrayInitializerCondition(ILExpression condition, out ILExpression initValue)
{
ILExpression logicAnd;
ILVariable arrayVar1, arrayVar2;
ILVariable arrayVar;
if (condition.Match(ILCode.LogicNot, out logicAnd) && logicAnd.Code == ILCode.LogicAnd) {
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];
if (arrayLength.Code == ILCode.Conv_I4)
arrayLength = arrayLength.Arguments[0];
if (arrayLength.Code == ILCode.Ldlen && arrayLength.Arguments[0].Match(ILCode.Ldloc, out arrayVar2)) {
return arrayVar1 == arrayVar2;
}
return arrayLength.Code == ILCode.Ldlen && arrayLength.Arguments[0].MatchLdloc(arrayVar);
}
}
initValue = null;
@ -716,7 +728,9 @@ namespace ICSharpCode.Decompiler.ILAst @@ -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))
return false;
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;
if (!(calledMethod.Name == "get_OffsetToStringData" && calledMethod.DeclaringType.FullName == "System.Runtime.CompilerServices.RuntimeHelpers"))
return false;

Loading…
Cancel
Save