Browse Source

Removed the declarative pattern matching algorithm from ILAst

pull/100/head
David Srbecký 14 years ago
parent
commit
cce7300d66
  1. 2
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  2. 111
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs
  3. 19
      ICSharpCode.Decompiler/ILAst/ILAstTypes.cs
  4. 120
      ICSharpCode.Decompiler/ILAst/Pattern.cs
  5. 112
      ICSharpCode.Decompiler/ILAst/PatternMatching.cs

2
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -94,7 +94,7 @@ @@ -94,7 +94,7 @@
<Compile Include="ILAst\ILCodes.cs" />
<Compile Include="ILAst\ILInlining.cs" />
<Compile Include="ILAst\LoopsAndConditions.cs" />
<Compile Include="ILAst\Pattern.cs" />
<Compile Include="ILAst\PatternMatching.cs" />
<Compile Include="ILAst\PeepholeTransform.cs" />
<Compile Include="ILAst\TypeAnalysis.cs" />
<Compile Include="ILAst\YieldReturnDecompiler.cs" />

111
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -445,7 +445,9 @@ namespace ICSharpCode.Decompiler.ILAst @@ -445,7 +445,9 @@ namespace ICSharpCode.Decompiler.ILAst
labelGlobalRefCount.GetOrDefault(condBBLabel) == 1 &&
labelGlobalRefCount.GetOrDefault(rightBBLabel) == 1 &&
labelGlobalRefCount.GetOrDefault(endBBLabel) == 2 &&
scope.ContainsAll(condBB, rightBB, endBB)
scope.Contains(condBB) &&
scope.Contains(rightBB) &&
scope.Contains(endBB)
)
{
head.Body[head.Body.Count - 1] = new ILExpression(ILCode.Stloc, v, new ILExpression(ILCode.NullCoalescing, null, leftExpr, rightExpr));
@ -639,104 +641,6 @@ namespace ICSharpCode.Decompiler.ILAst @@ -639,104 +641,6 @@ namespace ICSharpCode.Decompiler.ILAst
public static class ILAstOptimizerExtensionMethods
{
public static bool Match(this ILNode node, ILCode code)
{
ILExpression expr = node as ILExpression;
return expr != null && expr.Prefixes == null && expr.Code == code;
}
public static bool Match<T>(this ILNode node, ILCode code, out T operand)
{
ILExpression expr = node as ILExpression;
if (expr != null && expr.Prefixes == null && expr.Code == code) {
operand = (T)expr.Operand;
Debug.Assert(expr.Arguments.Count == 0);
return true;
}
operand = default(T);
return false;
}
public static bool Match(this ILNode node, ILCode code, out List<ILExpression> args)
{
ILExpression expr = node as ILExpression;
if (expr != null && expr.Prefixes == null && expr.Code == code) {
Debug.Assert(expr.Operand == null);
args = expr.Arguments;
return true;
}
args = null;
return false;
}
public static bool Match(this ILNode node, ILCode code, out ILExpression arg)
{
List<ILExpression> args;
if (node.Match(code, out args) && args.Count == 1) {
arg = args[0];
return true;
}
arg = null;
return false;
}
public static bool Match<T>(this ILNode node, ILCode code, out T operand, out List<ILExpression> args)
{
ILExpression expr = node as ILExpression;
if (expr != null && expr.Prefixes == null && expr.Code == code) {
operand = (T)expr.Operand;
args = expr.Arguments;
return true;
}
operand = default(T);
args = null;
return false;
}
public static bool Match<T>(this ILNode node, ILCode code, out T operand, out ILExpression arg)
{
List<ILExpression> args;
if (node.Match(code, out operand, out args) && args.Count == 1) {
arg = args[0];
return true;
}
arg = null;
return false;
}
public static bool Match<T>(this ILNode node, ILCode code, out T operand, out ILExpression arg1, out ILExpression arg2)
{
List<ILExpression> args;
if (node.Match(code, out operand, out args) && args.Count == 2) {
arg1 = args[0];
arg2 = args[1];
return true;
}
arg1 = null;
arg2 = null;
return false;
}
public static bool Match<T>(this ILBasicBlock bb, ILCode code, out T operand, out ILExpression arg, out ILLabel fallLabel)
{
if (bb.Body.Count == 1) {
if (bb.Body[0].Match(code, out operand, out arg)) {
fallLabel = bb.FallthoughGoto != null ? (ILLabel)bb.FallthoughGoto.Operand : null;
return true;
}
}
operand = default(T);
arg = null;
fallLabel = null;
return false;
}
public static bool MatchThis(this ILNode node)
{
ParameterDefinition parDef;
return node.Match(ILCode.Ldarg, out parDef) && parDef.Index == -1;
}
/// <summary>
/// Perform one pass of a given optimization on this block.
/// This block must consist of only basicblocks.
@ -813,15 +717,6 @@ namespace ICSharpCode.Decompiler.ILAst @@ -813,15 +717,6 @@ namespace ICSharpCode.Decompiler.ILAst
return ret;
}
public static bool ContainsAll<T>(this List<T> list, params T[] items)
{
foreach (T item in items) {
if (!list.Contains(item))
return false;
}
return true;
}
public static void RemoveOrThrow<T>(this ICollection<T> collection, T item)
{
if (!collection.Remove(item))

19
ICSharpCode.Decompiler/ILAst/ILAstTypes.cs

@ -319,25 +319,6 @@ namespace ICSharpCode.Decompiler.ILAst @@ -319,25 +319,6 @@ namespace ICSharpCode.Decompiler.ILAst
}
}
public virtual bool Match(ILNode other)
{
ILExpression expr = other as ILExpression;
return expr != null && this.Code == expr.Code
&& (this.Operand == AnyOperand || object.Equals(this.Operand, expr.Operand))
&& Match(this.Arguments, expr.Arguments);
}
protected static bool Match(IList<ILExpression> a, IList<ILExpression> b)
{
if (a.Count != b.Count)
return false;
for (int i = 0; i < a.Count; i++) {
if (!a[i].Match(b[i]))
return false;
}
return true;
}
public override void WriteTo(ITextOutput output)
{
if (Operand is ILVariable && ((ILVariable)Operand).IsGenerated) {

120
ICSharpCode.Decompiler/ILAst/Pattern.cs

@ -1,120 +0,0 @@ @@ -1,120 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using Mono.Cecil;
namespace ICSharpCode.Decompiler.ILAst
{
public interface IVariablePattern
{
bool MatchVariable(ILVariable v);
}
public class StoreToVariable : ILExpression, IVariablePattern
{
public bool MustBeGenerated;
public ILExpression LastMatch;
public ILVariable LastVariable {
get {
return LastMatch != null ? LastMatch.Operand as ILVariable : null;
}
}
public StoreToVariable(ILExpression arg) : base(ILCode.Pattern, null, arg)
{
}
public override bool Match(ILNode other)
{
ILExpression expr = other as ILExpression;
if (expr != null && expr.Code == ILCode.Stloc && (!MustBeGenerated || ((ILVariable)expr.Operand).IsGenerated) && Match(this.Arguments, expr.Arguments)) {
this.LastMatch = expr;
return true;
} else {
return false;
}
}
bool IVariablePattern.MatchVariable(ILVariable v)
{
return v == LastMatch.Operand;
}
}
public class LoadFromVariable : ILExpression
{
readonly IVariablePattern v;
public LoadFromVariable(IVariablePattern v) : base(ILCode.Pattern, null)
{
this.v = v;
}
public override bool Match(ILNode other)
{
ILExpression expr = other as ILExpression;
return expr != null && expr.Code == ILCode.Ldloc && v.MatchVariable(expr.Operand as ILVariable);
}
}
public class LoadFromArgument : ILExpression
{
int index;
public static readonly LoadFromArgument This = new LoadFromArgument(-1);
public LoadFromArgument(int index) : base(ILCode.Pattern, null)
{
this.index = index;
}
public override bool Match(ILNode other)
{
ILExpression expr = other as ILExpression;
return expr != null && expr.Code == ILCode.Ldarg && ((ParameterDefinition)expr.Operand).Index == index;
}
}
public class AnyILExpression : ILExpression
{
public ILExpression LastMatch;
public AnyILExpression() : base(ILCode.Pattern, null)
{
}
public override bool Match(ILNode other)
{
if (other is ILExpression) {
LastMatch = (ILExpression)other;
return true;
} else {
return false;
}
}
}
public class ILCall : ILExpression
{
string fullClassName;
string methodName;
public ILCall(string fullClassName, string methodName, params ILExpression[] args) : base(ILCode.Pattern, null, args)
{
this.fullClassName = fullClassName;
this.methodName = methodName;
}
public override bool Match(ILNode other)
{
ILExpression expr = other as ILExpression;
if (expr != null && expr.Code == ILCode.Call) {
MethodReference r = (MethodReference)expr.Operand;
if (r.Name == methodName && r.DeclaringType.FullName == fullClassName)
return Match(this.Arguments, expr.Arguments);
}
return false;
}
}
}

112
ICSharpCode.Decompiler/ILAst/PatternMatching.cs

@ -0,0 +1,112 @@ @@ -0,0 +1,112 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Mono.Cecil;
namespace ICSharpCode.Decompiler.ILAst
{
public static class PatternMatching
{
public static bool Match(this ILNode node, ILCode code)
{
ILExpression expr = node as ILExpression;
return expr != null && expr.Prefixes == null && expr.Code == code;
}
public static bool Match<T>(this ILNode node, ILCode code, out T operand)
{
ILExpression expr = node as ILExpression;
if (expr != null && expr.Prefixes == null && expr.Code == code) {
operand = (T)expr.Operand;
Debug.Assert(expr.Arguments.Count == 0);
return true;
}
operand = default(T);
return false;
}
public static bool Match(this ILNode node, ILCode code, out List<ILExpression> args)
{
ILExpression expr = node as ILExpression;
if (expr != null && expr.Prefixes == null && expr.Code == code) {
Debug.Assert(expr.Operand == null);
args = expr.Arguments;
return true;
}
args = null;
return false;
}
public static bool Match(this ILNode node, ILCode code, out ILExpression arg)
{
List<ILExpression> args;
if (node.Match(code, out args) && args.Count == 1) {
arg = args[0];
return true;
}
arg = null;
return false;
}
public static bool Match<T>(this ILNode node, ILCode code, out T operand, out List<ILExpression> args)
{
ILExpression expr = node as ILExpression;
if (expr != null && expr.Prefixes == null && expr.Code == code) {
operand = (T)expr.Operand;
args = expr.Arguments;
return true;
}
operand = default(T);
args = null;
return false;
}
public static bool Match<T>(this ILNode node, ILCode code, out T operand, out ILExpression arg)
{
List<ILExpression> args;
if (node.Match(code, out operand, out args) && args.Count == 1) {
arg = args[0];
return true;
}
arg = null;
return false;
}
public static bool Match<T>(this ILNode node, ILCode code, out T operand, out ILExpression arg1, out ILExpression arg2)
{
List<ILExpression> args;
if (node.Match(code, out operand, out args) && args.Count == 2) {
arg1 = args[0];
arg2 = args[1];
return true;
}
arg1 = null;
arg2 = null;
return false;
}
public static bool Match<T>(this ILBasicBlock bb, ILCode code, out T operand, out ILExpression arg, out ILLabel fallLabel)
{
if (bb.Body.Count == 1) {
if (bb.Body[0].Match(code, out operand, out arg)) {
fallLabel = bb.FallthoughGoto != null ? (ILLabel)bb.FallthoughGoto.Operand : null;
return true;
}
}
operand = default(T);
arg = null;
fallLabel = null;
return false;
}
public static bool MatchThis(this ILNode node)
{
ParameterDefinition parDef;
return node.Match(ILCode.Ldarg, out parDef) && parDef.Index == -1;
}
}
}
Loading…
Cancel
Save