|
|
|
@ -169,7 +169,10 @@ namespace ICSharpCode.Decompiler.ILAst
@@ -169,7 +169,10 @@ namespace ICSharpCode.Decompiler.ILAst
|
|
|
|
|
bool InlineIfPossible(ILVariable v, ILExpression inlinedExpression, ILNode next, bool aggressive) |
|
|
|
|
{ |
|
|
|
|
// ensure the variable is accessed only a single time
|
|
|
|
|
if (!(numStloc.GetOrDefault(v) == 1 && numLdloc.GetOrDefault(v) == 1 && numLdloca.GetOrDefault(v) == 0)) |
|
|
|
|
if (numStloc.GetOrDefault(v) != 1) |
|
|
|
|
return false; |
|
|
|
|
int ldloc = numLdloc.GetOrDefault(v); |
|
|
|
|
if (ldloc > 1 || ldloc + numLdloca.GetOrDefault(v) != 1) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
if (next is ILCondition) |
|
|
|
@ -180,7 +183,12 @@ namespace ICSharpCode.Decompiler.ILAst
@@ -180,7 +183,12 @@ namespace ICSharpCode.Decompiler.ILAst
|
|
|
|
|
ILExpression parent; |
|
|
|
|
int pos; |
|
|
|
|
if (FindLoadInNext(next as ILExpression, v, inlinedExpression, out parent, out pos) == true) { |
|
|
|
|
if (!aggressive && !v.IsGenerated && !NonAggressiveInlineInto((ILExpression)next, parent, inlinedExpression)) |
|
|
|
|
if (ldloc == 0) |
|
|
|
|
{ |
|
|
|
|
if (!IsGeneratedValueTypeTemporary((ILExpression)next, parent, pos, v)) |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
else if (!aggressive && !v.IsGenerated && !NonAggressiveInlineInto((ILExpression)next, parent, inlinedExpression)) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
// Assign the ranges of the ldloc instruction:
|
|
|
|
@ -192,6 +200,15 @@ namespace ICSharpCode.Decompiler.ILAst
@@ -192,6 +200,15 @@ namespace ICSharpCode.Decompiler.ILAst
|
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Is this a temporary variable generated by the C# compiler for instance method calls on immutable value type values
|
|
|
|
|
/// </summary>
|
|
|
|
|
bool IsGeneratedValueTypeTemporary(ILExpression next, ILExpression parent, int pos, ILVariable v) |
|
|
|
|
{ |
|
|
|
|
return pos == 0 && v.Type != null && v.Type.IsValueType && next.Code == ILCode.Stloc |
|
|
|
|
&& (parent.Code == ILCode.Call || parent.Code == ILCode.Callvirt) && ((MethodReference)parent.Operand).HasThis; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool NonAggressiveInlineInto(ILExpression next, ILExpression parent, ILExpression inlinedExpression) |
|
|
|
|
{ |
|
|
|
@ -214,7 +231,7 @@ namespace ICSharpCode.Decompiler.ILAst
@@ -214,7 +231,7 @@ namespace ICSharpCode.Decompiler.ILAst
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets whether 'expressionBeingMoved' can be inlined into 'expr'.
|
|
|
|
|
/// </summary>
|
|
|
|
@ -243,7 +260,7 @@ namespace ICSharpCode.Decompiler.ILAst
@@ -243,7 +260,7 @@ namespace ICSharpCode.Decompiler.ILAst
|
|
|
|
|
|
|
|
|
|
ILExpression arg = expr.Arguments[i]; |
|
|
|
|
|
|
|
|
|
if (arg.Code == ILCode.Ldloc && arg.Operand == v) { |
|
|
|
|
if ((arg.Code == ILCode.Ldloc || arg.Code == ILCode.Ldloca) && arg.Operand == v) { |
|
|
|
|
parent = expr; |
|
|
|
|
pos = i; |
|
|
|
|
return true; |
|
|
|
|