Browse Source

Added method to calculate unassigned ILRanges

pull/100/head
David Srbecký 15 years ago
parent
commit
616503f9a9
  1. 2
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  2. 17
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs
  3. 61
      ICSharpCode.Decompiler/ILAst/ILAstTypes.cs

2
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -93,7 +93,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -93,7 +93,7 @@ namespace ICSharpCode.Decompiler.Ast
if (node is ILLabel) {
yield return new Ast.LabelStatement { Label = ((ILLabel)node).Name };
} else if (node is ILExpression) {
List<ILRange> ilRanges = ((ILExpression)node).GetILRanges();
List<ILRange> ilRanges = ILRange.OrderAndJoint(node.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.ILRanges));
AstNode codeExpr = TransformExpression((ILExpression)node);
if (codeExpr != null) {
codeExpr = codeExpr.WithAnnotation(ilRanges);

17
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -137,6 +137,8 @@ namespace ICSharpCode.Decompiler.ILAst @@ -137,6 +137,8 @@ namespace ICSharpCode.Decompiler.ILAst
TypeAnalysis.Run(context, method);
GotoRemoval.RemoveRedundantCode(method);
// ReportUnassignedILRanges(method);
}
/// <summary>
@ -163,8 +165,14 @@ namespace ICSharpCode.Decompiler.ILAst @@ -163,8 +165,14 @@ namespace ICSharpCode.Decompiler.ILAst
} else if (body[i].Match(ILCode.Nop)){
// Ignore nop
} else if (body[i].Match(ILCode.Pop, out popExpr)) {
if (!popExpr.HasNoSideEffects())
ILVariable v;
if (!popExpr.Match(ILCode.Ldloc, out v))
throw new Exception("Pop should have just ldloc at this stage");
// Best effort to move the ILRange to previous statement
ILVariable prevVar;
ILExpression prevExpr;
if (i - 1 >= 0 && body[i - 1].Match(ILCode.Stloc, out prevVar, out prevExpr) && prevVar == v)
prevExpr.ILRanges.AddRange(((ILExpression)body[i]).ILRanges);
// Ignore pop
} else {
newBody.Add(body[i]);
@ -620,6 +628,13 @@ namespace ICSharpCode.Decompiler.ILAst @@ -620,6 +628,13 @@ namespace ICSharpCode.Decompiler.ILAst
FlattenIfStatements(child);
}
}
void ReportUnassignedILRanges(ILBlock method)
{
var unassigned = ILRange.Invert(method.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.ILRanges), context.CurrentMethod.Body.CodeSize).ToList();
if (unassigned.Count > 0)
Debug.WriteLine(string.Format("Unassigned ILRanges for {0}.{1}: {2}", this.context.CurrentMethod.DeclaringType.Name, this.context.CurrentMethod.Name, string.Join(", ", unassigned.Select(r => r.ToString()))));
}
}
public static class ILAstOptimizerExtensionMethods

61
ICSharpCode.Decompiler/ILAst/ILAstTypes.cs

@ -214,7 +214,45 @@ namespace ICSharpCode.Decompiler.ILAst @@ -214,7 +214,45 @@ namespace ICSharpCode.Decompiler.ILAst
public override string ToString()
{
return string.Format("{0}-{1}", From, To);
return string.Format("{0}-{1}", From.ToString("X"), To.ToString("X"));
}
public static List<ILRange> OrderAndJoint(IEnumerable<ILRange> input)
{
List<ILRange> ranges = input.OrderBy(r => r.From).ToList();
for (int i = 0; i < ranges.Count - 1;) {
ILRange curr = ranges[i];
ILRange next = ranges[i + 1];
// Merge consequtive ranges if they intersect
if (curr.From <= next.From && next.From <= curr.To) {
curr.To = Math.Max(curr.To, next.To);
ranges.RemoveAt(i + 1);
} else {
i++;
}
}
return ranges;
}
public static IEnumerable<ILRange> Invert(IEnumerable<ILRange> input, int codeSize)
{
var ordered = OrderAndJoint(input);
if (ordered.Count == 0) {
yield return new ILRange() { From = 0, To = codeSize };
} else {
// Gap before the first element
if (ordered.First().From != 0)
yield return new ILRange() { From = 0, To = ordered.First().From };
// Gaps between elements
for (int i = 0; i < ordered.Count - 1; i++)
yield return new ILRange() { From = ordered[i].To, To = ordered[i + 1].From };
// Gap after the last element
Debug.Assert(ordered.Last().To <= codeSize);
if (ordered.Last().To != codeSize)
yield return new ILRange() { From = ordered.Last().To, To = codeSize };
}
}
}
@ -281,27 +319,6 @@ namespace ICSharpCode.Decompiler.ILAst @@ -281,27 +319,6 @@ namespace ICSharpCode.Decompiler.ILAst
}
}
public List<ILRange> GetILRanges()
{
List<ILRange> ranges = new List<ILRange>();
foreach(ILExpression expr in this.GetSelfAndChildrenRecursive<ILExpression>()) {
ranges.AddRange(expr.ILRanges);
}
ranges = ranges.OrderBy(r => r.From).ToList();
for (int i = 0; i < ranges.Count - 1;) {
ILRange curr = ranges[i];
ILRange next = ranges[i + 1];
// Merge consequtive ranges if they intersect
if (curr.From <= next.From && next.From <= curr.To) {
curr.To = Math.Max(curr.To, next.To);
ranges.RemoveAt(i + 1);
} else {
i++;
}
}
return ranges;
}
public virtual bool Match(ILNode other)
{
ILExpression expr = other as ILExpression;

Loading…
Cancel
Save