Example #1
0
        /// <summary>
        /// Visits WhileStmt(do while and while) and builds controlflow graf for while cycle.
        /// </summary>
        /// <param name="x">WhileStmt</param>
        public override void VisitWhileStmt(WhileStmt x)
        {
            BasicBlock aboveLoop = currentBasicBlock;
            BasicBlock startLoop = new BasicBlock();
            BasicBlock underLoop = new BasicBlock();

            aboveLoop.CreateWorklistSegment(underLoop);

            // Connect above loop to start of the loop and under loop
            if (x.LoopType == WhileStmt.Type.While)
            {
                // while => above loop is connected conditionally to start of the loop and under loop
                BasicBlockEdge.ConnectConditionalBranching(DeepCopyAstExpressionCopyVisitor(x.CondExpr), currentBasicBlock, startLoop, underLoop);
            }
            else
            {
                // do ... while => above loop is connected just to the start of the loop
                BasicBlockEdge.ConnectDirectEdge(aboveLoop, startLoop);
            }

            // Generate CFG for loop body
            loopData.Push(new LoopData(startLoop, underLoop));
            currentBasicBlock = startLoop;
            x.Body.VisitMe(this);
            loopData.Pop();

            // Connect the end of loop body to start of the loop and under the loop
            BasicBlockEdge.ConnectConditionalBranching(x.CondExpr, currentBasicBlock, startLoop, underLoop);

            currentBasicBlock = underLoop;
        }
Example #2
0
        /// <summary>
        /// Constructs if branch basic block.
        /// </summary>
        /// <param name="bottomBox">Merge destination for if and else branch.</param>
        /// <param name="condition">The condition of the if branch.</param>
        /// <returns>Empty basic block for the else branch</returns>
        private BasicBlock constructIfBranch(BasicBlock bottomBox, ConditionalStmt condition)
        {
            BasicBlock thenBranchBlock = new BasicBlock();
            BasicBlock elseBranchBlock = new BasicBlock();

            BasicBlockEdge.ConnectConditionalBranching(condition.Condition, currentBasicBlock, thenBranchBlock, elseBranchBlock, false);


            currentBasicBlock = thenBranchBlock;
            condition.Statement.VisitMe(this);
            BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, bottomBox);

            return(elseBranchBlock);
        }
Example #3
0
        /// <summary>
        /// Visits ForStmt and builds controlflow graf for for cycle.
        /// </summary>
        /// <param name="x">ForStmt</param>
        public override void VisitForStmt(ForStmt x)
        {
            BasicBlock forTest      = new BasicBlock();
            BasicBlock forBody      = new BasicBlock();
            BasicBlock forEnd       = new BasicBlock();
            BasicBlock forIncrement = new BasicBlock();

            currentBasicBlock.CreateWorklistSegment(forEnd);

            // Create CFG for initialization of the for cycle
            VisitExpressionList(x.InitExList);

            //Adds initial connection from initialization to the test block
            BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, forTest);

            // Connects test block with body of the for cycle and end of the for cycle
            var forCondition = (x.CondExList.Count > 0) ? constructSimpleCondition(x.CondExList) : new BoolLiteral(Position.Invalid, true);
            var currBl       = currentBasicBlock;

            BasicBlockEdge.ConnectConditionalBranching(forCondition, forTest, forBody, forEnd);

            // Create CFG for Loop body
            loopData.Push(new LoopData(forIncrement, forEnd));
            currentBasicBlock = forBody;
            x.Body.VisitMe(this);
            loopData.Pop();

            // Connect end of the loop body to the increment
            BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, forIncrement);

            // Generate CFG for the loop increment
            currentBasicBlock = forIncrement;
            VisitExpressionList(x.ActionExList);

            // Connect for increment to the test block
            BasicBlockEdge.ConnectDirectEdge(forIncrement, forTest);

            currentBasicBlock = forEnd;
        }
Example #4
0
        /// <summary>
        /// Visits IfStmt and constructs if branch basic block.
        ///
        /// Decomposes the condition expression using logical operations with respect to shortcircuit evaluation.
        /// </summary>
        /// <param name="x">IfStmt</param>
        //public override void VisitIfStmt(IfStmt x)
        public override void VisitIfStmt(IfStmt x)
        {
            //Merge destination for if and else branch
            BasicBlock bottomBox = new BasicBlock();

            currentBasicBlock.CreateWorklistSegment(bottomBox);

            foreach (var cond in x.Conditions)
            {
                if (cond.Condition != null)
                {
                    //IF or ELSEIF branch (then branch)
                    var thenBranchBlock = new BasicBlock();
                    var elseBranchBlock = new BasicBlock();

                    // Decompose the condition
                    BasicBlockEdge.ConnectConditionalBranching(cond.Condition, currentBasicBlock, thenBranchBlock, elseBranchBlock);

                    // Create CFG for then branch
                    currentBasicBlock = thenBranchBlock;
                    cond.Statement.VisitMe(this);

                    // Connect the end of then branch to the bottom box
                    BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, bottomBox);

                    currentBasicBlock = elseBranchBlock;
                }
                else
                {
                    //ELSE branch
                    cond.Statement.VisitMe(this);
                }
            }

            //Connect then end of else branch to bottomBox
            //Must be here becouse in the construc phase we dont know whether the else block would split in the future
            BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, bottomBox);
            currentBasicBlock = bottomBox;
        }
Example #5
0
        /// <summary>
        /// Visits JumpStmt (break, continue, return).
        /// </summary>
        /// <param name="x">JumpStmt</param>
        public override void VisitJumpStmt(JumpStmt x)
        {
            switch (x.Type)
            {
            case JumpStmt.Types.Break:
            case JumpStmt.Types.Continue:
                if (x.Expression == null)    //break without saying how many loops to break
                {
                    BasicBlock target;
                    //break/continue
                    if (loopData.Count == 0)
                    {
                        if (x.Type == JumpStmt.Types.Break)
                        {
                            throw new ControlFlowException(ControlFlowExceptionCause.BREAK_NOT_IN_CYCLE, x.Position);
                        }
                        else
                        {
                            throw new ControlFlowException(ControlFlowExceptionCause.CONTINUE_NOT_IN_CYCLE, x.Position);
                        }
                    }
                    if (x.Type == JumpStmt.Types.Break)
                    {
                        target = loopData.Peek().BreakTarget;
                    }
                    else
                    {
                        target = loopData.Peek().ContinueTarget;
                    }
                    BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, target);
                }
                else
                {
                    int breakValue = 1;
                    for (int i = loopData.Count - 1; i >= 0; --i)
                    {
                        BasicBlock target;
                        if (x.Type == JumpStmt.Types.Break)
                        {
                            target = loopData.ElementAt(i).BreakTarget;
                        }
                        else
                        {
                            target = loopData.ElementAt(i).ContinueTarget;
                        }
                        BinaryEx condition = new BinaryEx(x.Position, Operations.Equal, new IntLiteral(Position.Invalid, breakValue), x.Expression);
                        graph.cfgAddedElements.Add(condition);
                        BasicBlockEdge.ConnectConditionalBranching(condition, currentBasicBlock, target, new BasicBlock());
                        //BasicBlockEdge.AddConditionalEdge(currentBasicBlock, target, condition);
                        ++breakValue;
                    }
                }
                break;

            case JumpStmt.Types.Return:

                PHP.Core.Debug.Assert(functionSinkStack.Count > 0);

                currentBasicBlock.AddElement(x);
                BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, functionSinkStack.Peek());

                currentBasicBlock = new BasicBlock();

                break;
            }


            currentBasicBlock = new BasicBlock();
        }
Example #6
0
        /// <summary>
        /// Visits switch statement and builds controlflow graf for switch construct.
        ///
        /// </summary>
        /// <param name="x">SwitchStmt</param>
        public override void VisitSwitchStmt(SwitchStmt x)
        {
            var        aboveCurrentCaseBlock = currentBasicBlock;
            BasicBlock lastDefaultStartBlock = null;
            BasicBlock lastDefaultEndBlock   = null;

            currentBasicBlock = new BasicBlock();
            //in case of switch statement, continue and break means the same so we make the edge always to the block under the switch
            BasicBlock underLoop = new BasicBlock();

            loopData.Push(new LoopData(underLoop, underLoop));

            aboveCurrentCaseBlock.CreateWorklistSegment(underLoop);

            for (int j = 0; j < x.SwitchItems.Count; j++)
            {
                var switchItem = x.SwitchItems[j];
                var caseItem   = switchItem as CaseItem;

                // The basic block corresponding to current switch item
                var switchBlock = new BasicBlock();

                // Connect previous switch item (implicitly, subsequent switch items are connected - break must
                // be there to force the flow to not go to subsequent switch item)
                if (j > 0)
                {
                    BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, switchBlock);
                }

                if (caseItem == null)
                {
                    // Default branch

                    // Just mark the last default branch
                    lastDefaultStartBlock = switchBlock;
                }
                else
                {
                    // Case branch

                    // Create condition of the current case branch
                    BinaryEx condition = new BinaryEx(caseItem.CaseVal.Position, Operations.Equal, x.SwitchValue, caseItem.CaseVal);
                    graph.cfgAddedElements.Add(condition);

                    // Create conditional branching: true condition goes to the case, else condition goes above the next switch item
                    var elseBlock = new BasicBlock();
                    BasicBlockEdge.ConnectConditionalBranching(condition, aboveCurrentCaseBlock, switchBlock, elseBlock);
                    aboveCurrentCaseBlock = elseBlock;
                }

                // Builds CFG for the body of the switch element
                currentBasicBlock = switchBlock;
                switchItem.VisitMe(this);

                if (caseItem == null)
                {
                    // Just to mark the last default branch
                    lastDefaultEndBlock = currentBasicBlock;
                }
            }

            loopData.Pop();

            if (lastDefaultStartBlock == null) // No default branch
            {
                // Connect the last case with the code under the switch
                BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, underLoop);
                // Connect the else of the last case with the code under the switch
                BasicBlockEdge.ConnectDirectEdge(aboveCurrentCaseBlock, underLoop);
            }
            else // There is default branch
            {
                // The last default branch is the else of the last case
                BasicBlockEdge.ConnectDirectEdge(aboveCurrentCaseBlock, lastDefaultStartBlock);
                if (lastDefaultEndBlock.DefaultBranch == null) // break/continue in the default branch
                // Connect it with the code under the swithch
                {
                    BasicBlockEdge.ConnectDirectEdge(lastDefaultEndBlock, underLoop);
                }
                else // no break/continue in the default branch
                     // Connect the last case with the code under the switch
                {
                    BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, underLoop);
                }
            }

            currentBasicBlock = underLoop;
        }