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>
        /// Visits foreach statement and creates the foreach contruct in cfg.
        /// </summary>
        /// <param name="x">ForeachStmt</param>
        public override void VisitForeachStmt(ForeachStmt x)
        {
            BasicBlock foreachHead = new BasicBlock();
            BasicBlock foreachBody = new BasicBlock();
            BasicBlock foreachSink = new BasicBlock();

            foreachHead.CreateWorklistSegment(foreachSink);

            //Input edge to the foreach statement
            BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, foreachHead);
            foreachHead.AddElement(x);

            //Conditional edge to the foreach body
            BasicBlockEdge.ConnectForeachEdge(foreachHead, foreachBody);

            //Visits foreach body
            loopData.Push(new LoopData(foreachHead, foreachSink));
            currentBasicBlock = foreachBody;
            x.Body.VisitMe(this);
            loopData.Pop();

            //Connect end of foreach with foreach head
            BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, foreachHead);

            //Output edge to the sink
            BasicBlockEdge.ConnectDirectEdge(foreachHead, foreachSink);
            currentBasicBlock = foreachSink;
        }
Example #3
0
        /// <summary>
        /// Visits IfStmt and constructs if branch basic block.
        ///
        /// Does not decompose the condition expression using logical operations (&&, ||, and xor).
        /// Note that this is no longer supported - analyzer now expects that the expression is decomposed
        /// on the level of CFG and it does not deal with logical operations explicitly.
        /// See <see cref="VisitIfStmt"/>.
        /// </summary>
        /// <param name="x">IfStmt</param>
        public void VisitIfStmtOld(IfStmt x)
        {
            //Merge destination for if and else branch
            BasicBlock bottomBox = new BasicBlock();

            currentBasicBlock.CreateWorklistSegment(bottomBox);

            foreach (var condition in x.Conditions)
            {
                if (condition.Condition != null)
                {
                    //IF or ELSEIF branch
                    currentBasicBlock = constructIfBranch(bottomBox, condition);
                }
                else
                {
                    //ELSE branch
                    condition.Statement.VisitMe(this);
                }
            }

            //Connect 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 #4
0
        /// <summary>
        /// Makes the control flow graph for the function or method declaration.
        /// </summary>
        /// <typeparam name="T">Type of function declaration container</typeparam>
        /// <param name="functionDeclaration">The function declaration.</param>
        /// <param name="functionBody">The function body.</param>
        /// <returns>The first basic block of the function's CFG.</returns>
        public BasicBlock MakeFunctionCFG <T>(T functionDeclaration, List <Statement> functionBody) where T : LangElement
        {
            //Store actual basic block
            BasicBlock current            = currentBasicBlock;
            BasicBlock functionBasicBlock = new BasicBlock();

            currentBasicBlock = functionBasicBlock;

            //Store actual Label data - function has its own label namespace

            labelDictionary = new LabelDataDictionary();

            //Add function sink to the stack for resolving returns
            BasicBlock functionSink = new BasicBlock();

            functionSinkStack.Push(functionSink);

            VisitStatementList(functionBody);

            /* foreach (var block in throwBlocks.ElementAt(0))
             * {
             *   block.Statements.RemoveLast();
             *   DirectEdge.MakeNewAndConnect(block, functionSink);
             * }*/


            //Connects return destination
            functionSinkStack.Pop();
            BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, functionSink);

            //Loads previous labels
            currentBasicBlock = current;

            return(functionBasicBlock);
        }
Example #5
0
        /// <summary>
        /// Visits try catch statement and connects thrown exceptions to catch blocks or function sink.
        /// </summary>
        /// <param name="x">TryStmt</param>
        public override void VisitTryStmt(TryStmt x)
        {
            BasicBlock followingBlock = new BasicBlock();

            TryBasicBlock tryBlock = new TryBasicBlock();

            BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, tryBlock);
            currentBasicBlock = tryBlock;

            //throwBlocks.Push(new List<BasicBlock>());
            VisitStatementList(x.Statements);
            currentBasicBlock.EndIngTryBlocks.Add(tryBlock);
            BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, followingBlock);


            foreach (var catchItem in x.Catches)
            {
                CatchBasicBlock catchBlock = new CatchBasicBlock(catchItem.Variable, catchItem.ClassName);

                tryBlock.catchBlocks.Add(catchBlock);
                currentBasicBlock = catchBlock;
                VisitStatementList(catchItem.Statements);
                BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, followingBlock);
            }


            //throwBlocks.Pop();
            currentBasicBlock = followingBlock;
        }
Example #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BasicBlock"/> class.
 /// </summary>
 public BasicBlock()
 {
     Statements            = new List <LangElement>();
     OutgoingEdges         = new List <BasicBlockEdge>();
     IncommingEdges        = new List <BasicBlockEdge>();
     DefaultBranch         = null;
     _afterWorklistSegment = null;
     EndIngTryBlocks       = new List <TryBasicBlock>();
 }
Example #7
0
        /// <summary>
        /// Visit LabelStmt, stores the label in dictionary and creates new basic block.
        /// </summary>
        /// <param name="x">LabelStmt</param>
        public override void VisitLabelStmt(LabelStmt x)
        {
            BasicBlock labelBlock = new BasicBlock();

            labelDictionary.GetOrCreateLabelData(x.Name, x.Position)
            .AsociateLabel(labelBlock, x.Position);

            BasicBlockEdge.ConnectDirectEdge(currentBasicBlock, labelBlock);
            currentBasicBlock = labelBlock;

            //Next line could be used for label visualization, label statement shouldnt be in resulting cgf
            //labelBlock.AddElement(x);
        }
Example #8
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 #9
0
        /// <summary>
        /// Visits the Globalcode element and solves the uncatch exceptions in globalcode.
        /// </summary>
        /// <param name="x">Globalcode</param>
        public override void VisitGlobalCode(GlobalCode x)
        {
            foreach (Statement statement in x.Statements)
            {
                statement.VisitMe(this);
            }
            var peek = functionSinkStack.Peek();

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

            /*   foreach (var block in throwBlocks.ElementAt(0)) {
             *     block.Statements.RemoveLast();
             *     DirectEdge.MakeNewAndConnect(block, functionSinkStack.Peek());
             * }*/
        }
Example #10
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 #11
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 #12
0
        /// <summary>
        /// Connects goto basic block with the basic block of the label.
        /// </summary>
        /// <param name="gotoBlock">The goto block.</param>
        void _asociateGoto(BasicBlock gotoBlock)
        {
            PHP.Core.Debug.Assert(labelBlock != null);

            BasicBlockEdge.ConnectDirectEdge(gotoBlock, labelBlock);
        }
Example #13
0
 /// <summary>
 /// Sets the default branch.
 /// </summary>
 /// <param name="edge">The edge.</param>
 public void SetDefaultBranch(BasicBlockEdge edge)
 {
     DefaultBranch = edge;
 }
Example #14
0
 /// <summary>
 /// Adds the outgoing edge.
 /// </summary>
 /// <param name="edge">The edge.</param>
 public void AddOutgoingEdge(BasicBlockEdge edge)
 {
     OutgoingEdges.Add(edge);
 }
Example #15
0
 /// <summary>
 /// Adds the incomming edge.
 /// </summary>
 /// <param name="edge">The edge.</param>
 public void AddIncommingEdge(BasicBlockEdge edge)
 {
     IncommingEdges.Add(edge);
 }
Example #16
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;
        }
Example #17
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();
        }