Browse Source

More aggressively duplicate return blocks in MoveNext() methods.

This fixes 'yield return' decompilation of debug builds using legacy csc.
pull/832/head
Daniel Grunwald 8 years ago
parent
commit
bcdd34a9d0
  1. 6
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 7
      ICSharpCode.Decompiler/IL/ControlFlow/ControlFlowSimplification.cs
  3. 2
      ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs

6
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -51,10 +51,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -51,10 +51,12 @@ namespace ICSharpCode.Decompiler.CSharp
/// <summary>
/// Pre-yield/await transforms.
/// </summary>
internal static List<IILTransform> EarlyILTransforms()
internal static List<IILTransform> EarlyILTransforms(bool aggressivelyDuplicateReturnBlocks = false)
{
return new List<IILTransform> {
new ControlFlowSimplification(),
new ControlFlowSimplification {
aggressivelyDuplicateReturnBlocks = aggressivelyDuplicateReturnBlocks
},
new SplitVariables(),
new ILInlining(),
};

7
ICSharpCode.Decompiler/IL/ControlFlow/ControlFlowSimplification.cs

@ -36,6 +36,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -36,6 +36,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
/// </remarks>
public class ControlFlowSimplification : IILTransform
{
internal bool aggressivelyDuplicateReturnBlocks;
public void Run(ILFunction function, ILTransformContext context)
{
foreach (var block in function.Descendants.OfType<Block>()) {
@ -129,12 +131,13 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -129,12 +131,13 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
}
}
static bool ShouldSimplifyBranchToReturnBlock(Branch branch)
bool ShouldSimplifyBranchToReturnBlock(Branch branch)
{
var targetBlock = branch.TargetBlock;
if (targetBlock.Instructions.Count != 1 || targetBlock.FinalInstruction.OpCode != OpCode.Nop)
return false;
if (targetBlock.Parent == branch.Ancestors.OfType<BlockContainer>().FirstOrDefault()) {
if (targetBlock.Parent == branch.Ancestors.OfType<BlockContainer>().FirstOrDefault()
&& !aggressivelyDuplicateReturnBlocks) {
// only simplify when jumping out of a try-finally
return false;
}

2
ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs

@ -311,7 +311,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -311,7 +311,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
);
}
var il = new ILReader(typeSystem).ReadIL(method.Body, context.CancellationToken);
il.RunTransforms(CSharpDecompiler.EarlyILTransforms(), new ILTransformContext {
il.RunTransforms(CSharpDecompiler.EarlyILTransforms(true), new ILTransformContext {
Settings = context.Settings,
CancellationToken = context.CancellationToken,
TypeSystem = context.TypeSystem

Loading…
Cancel
Save