diff --git a/ICSharpCode.Decompiler/IL/BlockBuilder.cs b/ICSharpCode.Decompiler/IL/BlockBuilder.cs index 98e8fd287..af02b341a 100644 --- a/ICSharpCode.Decompiler/IL/BlockBuilder.cs +++ b/ICSharpCode.Decompiler/IL/BlockBuilder.cs @@ -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 Block currentBlock; Stack containerStack = new Stack(); - public void CreateBlocks(BlockContainer mainContainer, List instructions, BitArray incomingBranches) + public void CreateBlocks(BlockContainer mainContainer, List 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 } 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 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 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 break; default: foreach (var child in inst.Children) - ConnectBranches(child); + ConnectBranches(child, cancellationToken); break; } } diff --git a/ICSharpCode.Decompiler/IL/ILReader.cs b/ICSharpCode.Decompiler/IL/ILReader.cs index 4e551c45c..0e3e25a8c 100644 --- a/ICSharpCode.Decompiler/IL/ILReader.cs +++ b/ICSharpCode.Decompiler/IL/ILReader.cs @@ -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); diff --git a/ICSharpCode.Decompiler/IL/Transforms/LoopingTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/LoopingTransform.cs index 6d985e8da..2e42d47be 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/LoopingTransform.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/LoopingTransform.cs @@ -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; diff --git a/ILSpy/Languages/ILAstLanguage.cs b/ILSpy/Languages/ILAstLanguage.cs index 5fe52e10b..2ab5ed0dc 100644 --- a/ILSpy/Languages/ILAstLanguage.cs +++ b/ILSpy/Languages/ILAstLanguage.cs @@ -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 {