Browse Source

Improve cancellation.

pull/863/head
Daniel Grunwald 8 years ago
parent
commit
71defde402
  1. 14
      ICSharpCode.Decompiler/IL/BlockBuilder.cs
  2. 2
      ICSharpCode.Decompiler/IL/ILReader.cs
  3. 3
      ICSharpCode.Decompiler/IL/Transforms/LoopingTransform.cs
  4. 6
      ILSpy/Languages/ILAstLanguage.cs

14
ICSharpCode.Decompiler/IL/BlockBuilder.cs

@ -21,6 +21,7 @@ using System.Collections; @@ -21,6 +21,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
@ -107,13 +108,14 @@ namespace ICSharpCode.Decompiler.IL @@ -107,13 +108,14 @@ namespace ICSharpCode.Decompiler.IL
Block currentBlock;
Stack<BlockContainer> containerStack = new Stack<BlockContainer>();
public void CreateBlocks(BlockContainer mainContainer, List<ILInstruction> instructions, BitArray incomingBranches)
public void CreateBlocks(BlockContainer mainContainer, List<ILInstruction> instructions, BitArray incomingBranches, CancellationToken cancellationToken)
{
CreateContainerStructure();
mainContainer.ILRange = new Interval(0, body.CodeSize);
currentContainer = mainContainer;
foreach (var inst in instructions) {
cancellationToken.ThrowIfCancellationRequested();
int start = inst.ILRange.Start;
if (currentBlock == null || incomingBranches[start]) {
// Finish up the previous block
@ -153,7 +155,7 @@ namespace ICSharpCode.Decompiler.IL @@ -153,7 +155,7 @@ namespace ICSharpCode.Decompiler.IL
}
FinalizeCurrentBlock(body.CodeSize, fallthrough: false);
containerStack.Clear();
ConnectBranches(mainContainer);
ConnectBranches(mainContainer, cancellationToken);
}
private void FinalizeCurrentBlock(int currentILOffset, bool fallthrough)
@ -166,10 +168,11 @@ namespace ICSharpCode.Decompiler.IL @@ -166,10 +168,11 @@ namespace ICSharpCode.Decompiler.IL
currentBlock = null;
}
void ConnectBranches(ILInstruction inst)
void ConnectBranches(ILInstruction inst, CancellationToken cancellationToken)
{
switch (inst) {
case Branch branch:
cancellationToken.ThrowIfCancellationRequested();
Debug.Assert(branch.TargetBlock == null);
branch.TargetBlock = FindBranchTarget(branch.TargetILOffset);
break;
@ -184,7 +187,8 @@ namespace ICSharpCode.Decompiler.IL @@ -184,7 +187,8 @@ namespace ICSharpCode.Decompiler.IL
case BlockContainer container:
containerStack.Push(container);
foreach (var block in container.Blocks) {
ConnectBranches(block);
cancellationToken.ThrowIfCancellationRequested();
ConnectBranches(block, cancellationToken);
if (block.Instructions.Count == 0 || !block.Instructions.Last().HasFlag(InstructionFlags.EndPointUnreachable)) {
block.Instructions.Add(new InvalidBranch("Unexpected end of block"));
}
@ -193,7 +197,7 @@ namespace ICSharpCode.Decompiler.IL @@ -193,7 +197,7 @@ namespace ICSharpCode.Decompiler.IL
break;
default:
foreach (var child in inst.Children)
ConnectBranches(child);
ConnectBranches(child, cancellationToken);
break;
}
}

2
ICSharpCode.Decompiler/IL/ILReader.cs

@ -306,7 +306,7 @@ namespace ICSharpCode.Decompiler.IL @@ -306,7 +306,7 @@ namespace ICSharpCode.Decompiler.IL
Init(body);
ReadInstructions(cancellationToken);
var blockBuilder = new BlockBuilder(body, typeSystem, variableByExceptionHandler);
blockBuilder.CreateBlocks(mainContainer, instructionBuilder, isBranchTarget);
blockBuilder.CreateBlocks(mainContainer, instructionBuilder, isBranchTarget, cancellationToken);
var function = new ILFunction(body.Method, mainContainer);
CollectionExtensions.AddRange(function.Variables, parameterVariables);
CollectionExtensions.AddRange(function.Variables, localVariables);

3
ICSharpCode.Decompiler/IL/Transforms/LoopingTransform.cs

@ -40,11 +40,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -40,11 +40,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms
throw new InvalidOperationException("LoopingBlockTransform already running. Transforms (and the CSharpDecompiler) are neither neither thread-safe nor re-entrant.");
running = true;
try {
int count = 1;
do {
block.ResetDirty();
block.RunTransforms(children, context);
if (block.IsDirty)
context.Step("Block is dirty; running another loop iteration.", block);
context.Step($"Block is dirty; running loop iteration #{++count}.", block);
} while (block.IsDirty);
} finally {
running = false;

6
ILSpy/Languages/ILAstLanguage.cs

@ -156,7 +156,11 @@ namespace ICSharpCode.ILSpy @@ -156,7 +156,11 @@ namespace ICSharpCode.ILSpy
ILReader reader = new ILReader(typeSystem);
reader.UseDebugSymbols = options.DecompilerSettings.UseDebugSymbols;
ILFunction il = reader.ReadIL(method.Body, options.CancellationToken);
ILTransformContext context = new ILTransformContext { Settings = options.DecompilerSettings, TypeSystem = typeSystem };
ILTransformContext context = new ILTransformContext {
Settings = options.DecompilerSettings,
TypeSystem = typeSystem,
CancellationToken = options.CancellationToken
};
context.Stepper.StepLimit = options.StepLimit;
context.Stepper.IsDebug = options.IsDebug;
try {

Loading…
Cancel
Save