Browse Source

Don't use named arguments when IL stack is empty after the stloc.

An empty stack indicates the statement is complete, so the code
is usually more readable if we keep the local variable.
pull/1167/head
Daniel Grunwald 8 years ago
parent
commit
ca09f09222
  1. 4
      ICSharpCode.Decompiler/IL/ILReader.cs
  2. 7
      ICSharpCode.Decompiler/IL/Instructions/StLoc.cs
  3. 5
      ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs

4
ICSharpCode.Decompiler/IL/ILReader.cs

@ -1147,7 +1147,9 @@ namespace ICSharpCode.Decompiler.IL
private ILInstruction Stloc(int v) private ILInstruction Stloc(int v)
{ {
return new StLoc(localVariables[v], Pop(localVariables[v].StackType)); return new StLoc(localVariables[v], Pop(localVariables[v].StackType)) {
ILStackWasEmpty = currentStack.IsEmpty
};
} }
private ILInstruction LdElem(IType type) private ILInstruction LdElem(IType type)

7
ICSharpCode.Decompiler/IL/Instructions/StLoc.cs

@ -27,6 +27,13 @@ namespace ICSharpCode.Decompiler.IL
/// This field is only used in ILReader and BlockBuilder, and should be ignored by ILAst transforms. /// This field is only used in ILReader and BlockBuilder, and should be ignored by ILAst transforms.
/// </summary> /// </summary>
internal bool IsStackAdjustment; internal bool IsStackAdjustment;
/// <summary>
/// Gets whether the IL stack was empty after this store.
/// Only set for store instructions from the IL; not for stores to the stack
/// or other stores generated by transforms.
/// </summary>
internal bool ILStackWasEmpty;
internal override void CheckInvariant(ILPhase phase) internal override void CheckInvariant(ILPhase phase)
{ {

5
ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs

@ -235,6 +235,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return true; return true;
} else if (r == FindResult.NamedArgument && (options & InliningOptions.IntroduceNamedArguments) != 0) { } else if (r == FindResult.NamedArgument && (options & InliningOptions.IntroduceNamedArguments) != 0) {
Debug.Assert(loadInst.OpCode == OpCode.LdLoc); Debug.Assert(loadInst.OpCode == OpCode.LdLoc);
StLoc originalStore = (StLoc)inlinedExpression.Parent;
if ((options & InliningOptions.Aggressive) == 0 && originalStore.ILStackWasEmpty)
return false;
context.Step($"Introduce named argument '{v.Name}'", inlinedExpression); context.Step($"Introduce named argument '{v.Name}'", inlinedExpression);
var call = (CallInstruction)loadInst.Parent; var call = (CallInstruction)loadInst.Parent;
if (!(call.Parent is Block namedArgBlock) || namedArgBlock.Kind != BlockKind.CallWithNamedArgs) { if (!(call.Parent is Block namedArgBlock) || namedArgBlock.Kind != BlockKind.CallWithNamedArgs) {
@ -254,7 +257,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
} }
} }
v.Kind = VariableKind.NamedArgument; v.Kind = VariableKind.NamedArgument;
namedArgBlock.Instructions.Insert(call.IsInstanceCall ? 1 : 0, new StLoc(v, inlinedExpression)); namedArgBlock.Instructions.Insert(call.IsInstanceCall ? 1 : 0, originalStore);
return true; return true;
} }
return false; return false;

Loading…
Cancel
Save