Browse Source

Merge branch 'master' of git://github.com/icsharpcode/ILSpy into Debugger

pull/191/merge
Eusebiu Marcu 15 years ago
parent
commit
32c3941e27
  1. 35
      ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs
  2. 2
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  3. 105
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs
  4. 19
      ICSharpCode.Decompiler/ILAst/ILAstTypes.cs
  5. 111
      ICSharpCode.Decompiler/ILAst/InitializerPeepholeTransforms.cs
  6. 120
      ICSharpCode.Decompiler/ILAst/Pattern.cs
  7. 112
      ICSharpCode.Decompiler/ILAst/PatternMatching.cs
  8. 80
      ICSharpCode.Decompiler/ILAst/YieldReturnDecompiler.cs

35
ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs

@ -132,29 +132,28 @@ namespace ICSharpCode.Decompiler.Ast @@ -132,29 +132,28 @@ namespace ICSharpCode.Decompiler.Ast
var n = node.Ancestors.FirstOrDefault(a => a.Annotation<MemberMapping>() != null);
if (n != default(AstType)) {
MemberMapping mapping = n.Annotation<MemberMapping>();
// var map = mapping.MemberCodeMappings.Find(s => s.SourceCodeLine == output.CurrentLine);
foreach (var range in ranges) {
var map = mapping.MemberCodeMappings.Find(s => s.SourceCodeLine == output.CurrentLine);
if (map == null) {
// check if the range is in previous mapping
var prevmap = mapping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From <= range.From &&
m.ILInstructionOffset.To >= range.To);
if (prevmap != null)
continue;
mapping.MemberCodeMappings.Add(new SourceCodeMapping {
foreach (var range in ranges) {
// // check if the range is in previous mapping
// var prevmap = mapping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From <= range.From &&
// m.ILInstructionOffset.To >= range.To);
//
// if (prevmap != null)
// continue;
//
// if (map == null) {
mapping.MemberCodeMappings.Add(/*map = */new SourceCodeMapping {
ILInstructionOffset = range,
SourceCodeLine = output.CurrentLine,
MemberMapping = mapping
});
} else {
if (map.ILInstructionOffset.From > range.From)
map.ILInstructionOffset.From = range.From;
if (map.ILInstructionOffset.To < range.To)
map.ILInstructionOffset.To = range.To;
}
// } else {
// if (map.ILInstructionOffset.From > range.From)
// map.ILInstructionOffset.From = range.From;
// if (map.ILInstructionOffset.To < range.To)
// map.ILInstructionOffset.To = range.To;
// }
}
}
}

2
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -97,7 +97,7 @@ @@ -97,7 +97,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" />

105
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,98 +641,6 @@ namespace ICSharpCode.Decompiler.ILAst @@ -639,98 +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;
}
/// <summary>
/// Perform one pass of a given optimization on this block.
/// This block must consist of only basicblocks.
@ -807,15 +717,6 @@ namespace ICSharpCode.Decompiler.ILAst @@ -807,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) {

111
ICSharpCode.Decompiler/ILAst/InitializerPeepholeTransforms.cs

@ -17,57 +17,72 @@ namespace ICSharpCode.Decompiler.ILAst @@ -17,57 +17,72 @@ namespace ICSharpCode.Decompiler.ILAst
readonly ILBlock method;
#region Array Initializers
StoreToVariable newArrPattern;
ILCall initializeArrayPattern;
public InitializerPeepholeTransforms(ILBlock method)
{
this.method = method;
newArrPattern = new StoreToVariable(new ILExpression(
ILCode.Newarr, ILExpression.AnyOperand, new ILExpression(ILCode.Ldc_I4, ILExpression.AnyOperand)));
initializeArrayPattern = new ILCall(
"System.Runtime.CompilerServices.RuntimeHelpers", "InitializeArray",
new LoadFromVariable(newArrPattern), new ILExpression(ILCode.Ldtoken, ILExpression.AnyOperand));
}
public void TransformArrayInitializers(ILBlock block, ref int i)
{
if (!newArrPattern.Match(block.Body[i]))
return;
ILExpression newArrInst = ((ILExpression)block.Body[i]).Arguments[0];
int arrayLength = (int)newArrInst.Arguments[0].Operand;
if (arrayLength == 0)
return;
if (initializeArrayPattern.Match(block.Body.ElementAtOrDefault(i + 1))) {
if (HandleStaticallyInitializedArray(newArrPattern, block, i, newArrInst, arrayLength)) {
i -= new ILInlining(method).InlineInto(block, i + 1, aggressive: true) - 1;
ILVariable v, v2, v3;
ILExpression newarrExpr;
TypeReference arrayType;
ILExpression lengthExpr;
int arrayLength;
if (block.Body[i].Match(ILCode.Stloc, out v, out newarrExpr) &&
newarrExpr.Match(ILCode.Newarr, out arrayType, out lengthExpr) &&
lengthExpr.Match(ILCode.Ldc_I4, out arrayLength) &&
arrayLength > 0)
{
MethodReference methodRef;
ILExpression methodArg1;
ILExpression methodArg2;
FieldDefinition field;
if (block.Body.ElementAtOrDefault(i + 1).Match(ILCode.Call, out methodRef, out methodArg1, out methodArg2) &&
methodRef.DeclaringType.FullName == "System.Runtime.CompilerServices.RuntimeHelpers" &&
methodRef.Name == "InitializeArray" &&
methodArg1.Match(ILCode.Ldloc, out v2) &&
v == v2 &&
methodArg2.Match(ILCode.Ldtoken, out field) &&
field != null && field.InitialValue != null)
{
ILExpression[] newArr = new ILExpression[arrayLength];
if (DecodeArrayInitializer(TypeAnalysis.GetTypeCode(arrayType), field.InitialValue, newArr)) {
block.Body[i] = new ILExpression(ILCode.Stloc, v, new ILExpression(ILCode.InitArray, arrayType, newArr));
block.Body.RemoveAt(i + 1);
i -= new ILInlining(method).InlineInto(block, i + 1, aggressive: true) - 1;
return;
}
}
return;
}
List<ILExpression> operands = new List<ILExpression>();
int numberOfInstructionsToRemove = 0;
for (int j = i + 1; j < block.Body.Count; j++) {
ILExpression expr = block.Body[j] as ILExpression;
if (expr == null || !IsStoreToArray(expr.Code))
break;
if (!(expr.Arguments[0].Code == ILCode.Ldloc && expr.Arguments[0].Operand == newArrPattern.LastVariable))
break;
if (expr.Arguments[1].Code != ILCode.Ldc_I4)
break;
int pos = (int)expr.Arguments[1].Operand;
const int maxConsecutiveDefaultValueExpressions = 10;
if (pos < operands.Count || pos > operands.Count + maxConsecutiveDefaultValueExpressions)
break;
while (operands.Count < pos)
operands.Add(new ILExpression(ILCode.DefaultValue, newArrInst.Operand));
operands.Add(expr.Arguments[2]);
numberOfInstructionsToRemove++;
}
if (operands.Count == arrayLength) {
((ILExpression)block.Body[i]).Arguments[0] = new ILExpression(
ILCode.InitArray, newArrInst.Operand, operands.ToArray());
block.Body.RemoveRange(i + 1, numberOfInstructionsToRemove);
i -= new ILInlining(method).InlineInto(block, i + 1, aggressive: true) - 1;
List<ILExpression> operands = new List<ILExpression>();
int numberOfInstructionsToRemove = 0;
for (int j = i + 1; j < block.Body.Count; j++) {
ILExpression expr = block.Body[j] as ILExpression;
int pos;
if (expr != null &&
IsStoreToArray(expr.Code) &&
expr.Arguments[0].Match(ILCode.Ldloc, out v3) &&
v == v3 &&
expr.Arguments[1].Match(ILCode.Ldc_I4, out pos) &&
pos >= operands.Count &&
pos <= operands.Count + maxConsecutiveDefaultValueExpressions)
{
while (operands.Count < pos)
operands.Add(new ILExpression(ILCode.DefaultValue, arrayType));
operands.Add(expr.Arguments[2]);
numberOfInstructionsToRemove++;
} else {
break;
}
}
if (operands.Count == arrayLength) {
((ILExpression)block.Body[i]).Arguments[0] = new ILExpression(ILCode.InitArray, arrayType, operands);
block.Body.RemoveRange(i + 1, numberOfInstructionsToRemove);
i -= new ILInlining(method).InlineInto(block, i + 1, aggressive: true) - 1;
}
}
}
@ -89,20 +104,6 @@ namespace ICSharpCode.Decompiler.ILAst @@ -89,20 +104,6 @@ namespace ICSharpCode.Decompiler.ILAst
}
}
static bool HandleStaticallyInitializedArray(StoreToVariable newArrPattern, ILBlock block, int i, ILExpression newArrInst, int arrayLength)
{
FieldDefinition field = ((ILExpression)block.Body[i + 1]).Arguments[1].Operand as FieldDefinition;
if (field == null || field.InitialValue == null)
return false;
ILExpression[] newArr = new ILExpression[arrayLength];
if (DecodeArrayInitializer(TypeAnalysis.GetTypeCode(newArrInst.Operand as TypeReference), field.InitialValue, newArr)) {
block.Body[i] = new ILExpression(ILCode.Stloc, newArrPattern.LastVariable, new ILExpression(ILCode.InitArray, newArrInst.Operand, newArr));
block.Body.RemoveAt(i + 1);
return true;
}
return false;
}
static bool DecodeArrayInitializer(TypeCode elementType, byte[] initialValue, ILExpression[] output)
{
switch (elementType) {

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;
}
}
}

80
ICSharpCode.Decompiler/ILAst/YieldReturnDecompiler.cs

@ -181,11 +181,17 @@ namespace ICSharpCode.Decompiler.ILAst @@ -181,11 +181,17 @@ namespace ICSharpCode.Decompiler.ILAst
{
ILBlock method = CreateILAst(enumeratorCtor);
ILExpression stfldPattern = new ILExpression(ILCode.Stfld, ILExpression.AnyOperand, LoadFromArgument.This, new LoadFromArgument(0));
foreach (ILNode node in method.Body) {
if (stfldPattern.Match(node)) {
stateField = GetFieldDefinition(((ILExpression)node).Operand as FieldReference);
FieldReference field;
ILExpression instExpr;
ILExpression stExpr;
ParameterDefinition arg;
if (node.Match(ILCode.Stfld, out field, out instExpr, out stExpr) &&
instExpr.MatchThis() &&
stExpr.Match(ILCode.Ldarg, out arg) &&
arg.Index == 0)
{
stateField = GetFieldDefinition(field);
}
}
if (stateField == null)
@ -210,8 +216,6 @@ namespace ICSharpCode.Decompiler.ILAst @@ -210,8 +216,6 @@ namespace ICSharpCode.Decompiler.ILAst
#endregion
#region Figure out what the 'current' field is (analysis of get_Current())
static readonly ILExpression returnFieldFromThisPattern = new ILExpression(ILCode.Ret, null, new ILExpression(ILCode.Ldfld, ILExpression.AnyOperand, LoadFromArgument.This));
/// <summary>
/// Looks at the enumerator's get_Current method and figures out which of the fields holds the current value.
/// </summary>
@ -223,18 +227,29 @@ namespace ICSharpCode.Decompiler.ILAst @@ -223,18 +227,29 @@ namespace ICSharpCode.Decompiler.ILAst
ILBlock method = CreateILAst(getCurrentMethod);
if (method.Body.Count == 1) {
// release builds directly return the current field
if (returnFieldFromThisPattern.Match(method.Body[0])) {
currentField = GetFieldDefinition(((ILExpression)method.Body[0]).Arguments[0].Operand as FieldReference);
ILExpression retExpr;
FieldReference field;
ILExpression ldFromObj;
if (method.Body[0].Match(ILCode.Ret, out retExpr) &&
retExpr.Match(ILCode.Ldfld, out field, out ldFromObj) &&
ldFromObj.MatchThis())
{
currentField = GetFieldDefinition(field);
}
} else {
StoreToVariable v = new StoreToVariable(new ILExpression(ILCode.Ldfld, ILExpression.AnyOperand, LoadFromArgument.This));
if (v.Match(method.Body[0])) {
int i = 1;
if (i == method.Body.Count - 1) {
if (new ILExpression(ILCode.Ret, null, new LoadFromVariable(v)).Match(method.Body[i])) {
currentField = GetFieldDefinition(((ILExpression)method.Body[0]).Arguments[0].Operand as FieldReference);
}
}
} else if (method.Body.Count == 2) {
ILVariable v, v2;
ILExpression stExpr;
FieldReference field;
ILExpression ldFromObj;
ILExpression retExpr;
if (method.Body[0].Match(ILCode.Stloc, out v, out stExpr) &&
stExpr.Match(ILCode.Ldfld, out field, out ldFromObj) &&
ldFromObj.MatchThis() &&
method.Body[1].Match(ILCode.Ret, out retExpr) &&
retExpr.Match(ILCode.Ldloc, out v2) &&
v == v2)
{
currentField = GetFieldDefinition(field);
}
}
if (currentField == null)
@ -251,16 +266,19 @@ namespace ICSharpCode.Decompiler.ILAst @@ -251,16 +266,19 @@ namespace ICSharpCode.Decompiler.ILAst
if (getEnumeratorMethod == null)
return; // no mappings (maybe it's just an IEnumerator implementation?)
ILExpression mappingPattern = new ILExpression(
ILCode.Stfld, ILExpression.AnyOperand, new AnyILExpression(),
new ILExpression(ILCode.Ldfld, ILExpression.AnyOperand, LoadFromArgument.This));
ILBlock method = CreateILAst(getEnumeratorMethod);
foreach (ILNode node in method.Body) {
if (mappingPattern.Match(node)) {
ILExpression stfld = (ILExpression)node;
FieldDefinition storedField = GetFieldDefinition(stfld.Operand as FieldReference);
FieldDefinition loadedField = GetFieldDefinition(stfld.Arguments[1].Operand as FieldReference);
FieldReference stField;
ILExpression stToObj;
ILExpression stExpr;
FieldReference ldField;
ILExpression ldFromObj;
if (node.Match(ILCode.Stfld, out stField, out stToObj, out stExpr) &&
stExpr.Match(ILCode.Ldfld, out ldField, out ldFromObj) &&
ldFromObj.MatchThis())
{
FieldDefinition storedField = GetFieldDefinition(stField);
FieldDefinition loadedField = GetFieldDefinition(ldField);
if (storedField != null && loadedField != null) {
ParameterDefinition mappedParameter;
if (fieldToParameterMap.TryGetValue(loadedField, out mappedParameter))
@ -671,7 +689,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -671,7 +689,7 @@ namespace ICSharpCode.Decompiler.ILAst
ILExpression disposeArg;
if (!faultBlock.Body[0].Match(ILCode.Call, out disposeMethodRef, out disposeArg))
throw new YieldAnalysisFailedException();
if (GetMethodDefinition(disposeMethodRef) != disposeMethod || !LoadFromArgument.This.Match(disposeArg))
if (GetMethodDefinition(disposeMethodRef) != disposeMethod || !disposeArg.MatchThis())
throw new YieldAnalysisFailedException();
if (!faultBlock.Body[1].Match(ILCode.Endfinally))
throw new YieldAnalysisFailedException();
@ -757,7 +775,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -757,7 +775,7 @@ namespace ICSharpCode.Decompiler.ILAst
// Copy all instructions from the old body to newBody.
for (int pos = startPos; pos < bodyLength; pos++) {
ILExpression expr = body[pos] as ILExpression;
if (expr != null && expr.Code == ILCode.Stfld && LoadFromArgument.This.Match(expr.Arguments[0])) {
if (expr != null && expr.Code == ILCode.Stfld && expr.Arguments[0].MatchThis()) {
// Handle stores to 'state' or 'current'
if (GetFieldDefinition(expr.Operand as FieldReference) == stateField) {
if (expr.Arguments[1].Code != ILCode.Ldc_I4)
@ -794,7 +812,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -794,7 +812,7 @@ namespace ICSharpCode.Decompiler.ILAst
} else {
throw new YieldAnalysisFailedException();
}
} else if (expr != null && expr.Code == ILCode.Call && expr.Arguments.Count == 1 && LoadFromArgument.This.Match(expr.Arguments[0])) {
} else if (expr != null && expr.Code == ILCode.Call && expr.Arguments.Count == 1 && expr.Arguments[0].MatchThis()) {
MethodDefinition method = GetMethodDefinition(expr.Operand as MethodReference);
if (method == null)
throw new YieldAnalysisFailedException();
@ -857,7 +875,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -857,7 +875,7 @@ namespace ICSharpCode.Decompiler.ILAst
FieldReference stfld;
List<ILExpression> args;
if (block.Body.Count > 0 && block.Body[0].Match(ILCode.Stfld, out stfld, out args)) {
if (GetFieldDefinition(stfld) == stateField && LoadFromArgument.This.Match(args[0]))
if (GetFieldDefinition(stfld) == stateField && args[0].MatchThis())
block.Body.RemoveAt(0);
}
// Convert ret to endfinally
@ -879,7 +897,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -879,7 +897,7 @@ namespace ICSharpCode.Decompiler.ILAst
if (field != null) {
switch (expr.Code) {
case ILCode.Ldfld:
if (LoadFromArgument.This.Match(expr.Arguments[0])) {
if (expr.Arguments[0].MatchThis()) {
if (fieldToParameterMap.ContainsKey(field)) {
expr.Code = ILCode.Ldarg;
expr.Operand = fieldToParameterMap[field];
@ -891,7 +909,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -891,7 +909,7 @@ namespace ICSharpCode.Decompiler.ILAst
}
break;
case ILCode.Stfld:
if (LoadFromArgument.This.Match(expr.Arguments[0])) {
if (expr.Arguments[0].MatchThis()) {
if (fieldToParameterMap.ContainsKey(field)) {
expr.Code = ILCode.Starg;
expr.Operand = fieldToParameterMap[field];

Loading…
Cancel
Save