diff --git a/ICSharpCode.Decompiler/IL/ControlFlow/SwitchAnalysis.cs b/ICSharpCode.Decompiler/IL/ControlFlow/SwitchAnalysis.cs index 928b934c6..c280faa02 100644 --- a/ICSharpCode.Decompiler/IL/ControlFlow/SwitchAnalysis.cs +++ b/ICSharpCode.Decompiler/IL/ControlFlow/SwitchAnalysis.cs @@ -42,8 +42,18 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow /// public readonly List> Sections = new List>(); + /// + /// Used to de-duplicate sections with a branch instruction. + /// Invariant: (Sections[targetBlockToSectionIndex[branch.TargetBlock]].Instruction as Branch).TargetBlock == branch.TargetBlock + /// readonly Dictionary targetBlockToSectionIndex = new Dictionary(); + /// + /// Used to de-duplicate sections with a value-less leave instruction. + /// Invariant: (Sections[targetBlockToSectionIndex[leave.TargetContainer]].Instruction as Leave).TargetContainer == leave.TargetContainer + /// + readonly Dictionary targetContainerToSectionIndex = new Dictionary(); + /// /// Blocks that can be deleted if the tail of the initial block is replaced with a switch instruction. /// @@ -61,6 +71,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow switchVar = null; rootBlock = block; targetBlockToSectionIndex.Clear(); + targetContainerToSectionIndex.Clear(); Sections.Clear(); InnerBlocks.Clear(); ContainsILSwitch = false; @@ -180,10 +191,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow if (values.IsEmpty) { return; } - Block targetBlock; - if (inst.MatchBranch(out targetBlock)) { - int index; - if (targetBlockToSectionIndex.TryGetValue(targetBlock, out index)) { + if (inst.MatchBranch(out Block targetBlock)) { + if (targetBlockToSectionIndex.TryGetValue(targetBlock, out int index)) { Sections[index] = new KeyValuePair( Sections[index].Key.UnionWith(values), inst @@ -192,6 +201,16 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow targetBlockToSectionIndex.Add(targetBlock, Sections.Count); Sections.Add(new KeyValuePair(values, inst)); } + } else if (inst.MatchLeave(out BlockContainer targetContainer)) { + if (targetContainerToSectionIndex.TryGetValue(targetContainer, out int index)) { + Sections[index] = new KeyValuePair( + Sections[index].Key.UnionWith(values), + inst + ); + } else { + targetContainerToSectionIndex.Add(targetContainer, Sections.Count); + Sections.Add(new KeyValuePair(values, inst)); + } } else { Sections.Add(new KeyValuePair(values, inst)); }