/// <inheritdoc />
        public void Revert(ControlFlowGraphEditContext <TInstruction> context)
        {
            if (!_isApplied)
            {
                throw new InvalidOperationException("Operation is not applied yet.");
            }

            var node = context.FindNode(BranchOffset);

            // Re-merge node if it was split.
            if (_hasSplit)
            {
                var newNeighbour = node.FallThroughNeighbour;
                node.FallThroughNeighbour = null;
                context.RemoveNodeFromIndex(newNeighbour.Offset);
                newNeighbour.MergeWithPredecessor();
            }

            // Restore original fallthrough neighbour.
            node.FallThroughNeighbour = _oldFallThroughOffset.HasValue
                ? context.FindNode(_oldFallThroughOffset.Value)
                : null;

            _isApplied = false;
        }
Example #2
0
        /// <inheritdoc />
        protected override void OnRevert(ControlFlowGraphEditContext <TInstruction> context)
        {
            var origin = context.FindNode(OriginOffset);
            var target = context.FindNodeOrSplit(TargetOffset, out _);

            origin.ConnectWith(target, EdgeType);
        }
        /// <inheritdoc />
        public void Apply(ControlFlowGraphEditContext <TInstruction> context)
        {
            if (_isApplied)
            {
                throw new InvalidOperationException("Operation is already applied.");
            }

            var node = context.FindNode(BranchOffset);

            // Save original fallthrough node offset.
            _oldFallThroughOffset = node.FallThroughNeighbour?.Offset;

            // Set new fallthrough neighbour.
            node.FallThroughNeighbour = NewFallThroughOffset.HasValue
                ? context.FindNodeOrSplit(NewFallThroughOffset.Value, out _hasSplit)
                : null;

            _isApplied = true;
        }
Example #4
0
        /// <inheritdoc />
        protected override void OnRevert(ControlFlowGraphEditContext <TInstruction> context)
        {
            var origin = context.FindNode(OriginOffset);
            var target = context.Graph.Nodes[TargetOffset];

            var collection = EdgeType switch
            {
                ControlFlowEdgeType.Conditional => origin.ConditionalEdges,
                ControlFlowEdgeType.Abnormal => origin.AbnormalEdges,
                _ => throw new ArgumentOutOfRangeException()
            };

            collection.Remove(collection.GetEdgesToNeighbour(target).First());

            if (_hasSplit)
            {
                context.RemoveNodeFromIndex(target.Offset);
                target.MergeWithPredecessor();
            }
        }
Example #5
0
        /// <inheritdoc />
        protected override void OnApply(ControlFlowGraphEditContext <TInstruction> context)
        {
            var origin = context.FindNode(OriginOffset);
            var target = context.Graph.Nodes[TargetOffset];

            var collection = EdgeType switch
            {
                ControlFlowEdgeType.Conditional => origin.ConditionalEdges,
                ControlFlowEdgeType.Abnormal => origin.AbnormalEdges,
                _ => throw new ArgumentOutOfRangeException()
            };

            collection.Remove(collection.GetEdgesToNeighbour(target).First());

            var incomingEdges = target.GetIncomingEdges().ToArray();

            if (incomingEdges.Length == 1 && incomingEdges[0].Type == ControlFlowEdgeType.FallThrough)
            {
                context.RemoveNodeFromIndex(target.Offset);
                target.MergeWithPredecessor();
            }
        }