public static int FindTargetIndexOrThrow(IElement br, IList <IElement> elements) { var targetIndex = FindTargetIndexOrNull(br, elements); if (targetIndex == null) { BranchProcessing.ThrowTargetNotFound(br); } return((int)targetIndex); }
private void ProcessRange(IList <IElement> elements, int startIndex, IList <IElement> results, IDictionary <IElement, IElement> original) { for (var i = startIndex; i < elements.Count; i++) { var element = elements[i]; if (!BranchProcessing.Matches(element, opCodes.Contains)) { results.Add(element); original[element] = element; continue; } var targetIndexOrNull = BranchProcessing.FindTargetIndexOrNull(element, elements); if (targetIndexOrNull == null) { BranchProcessing.ThrowTargetNotFound(element); } var targetIndex = targetIndexOrNull.Value; BranchProcessing.EnsureNotBackward(i, targetIndex); var targetRange = new List <IElement>(); this.ProcessRange(elements, targetIndex, targetRange, original); var followingRange = new List <IElement>(); this.ProcessRange(elements, i + 1, followingRange, original); var convergingRange = new List <IElement>(); while (targetRange.Count > 0 && followingRange.Count > 0) { var lastTarget = targetRange.Last(); var lastFollowing = followingRange.Last(); if (original[lastTarget] != original[lastFollowing]) { break; } convergingRange.Add(lastFollowing); targetRange.RemoveAt(targetRange.Count - 1); followingRange.RemoveAt(followingRange.Count - 1); } convergingRange.Reverse(); if (targetRange.Count > 0 || followingRange.Count > 0) { var branching = new BranchingElement(((InstructionElement)element).OpCode, targetRange, followingRange); original[branching] = element; results.Add(branching); } results.AddRange(convergingRange); break; } }