Example #1
0
        public static int FindTargetIndexOrThrow(IElement br, IList <IElement> elements)
        {
            var targetIndex = FindTargetIndexOrNull(br, elements);

            if (targetIndex == null)
            {
                BranchProcessing.ThrowTargetNotFound(br);
            }

            return((int)targetIndex);
        }
Example #2
0
        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;
            }
        }