Inheritance: BasicBlockStatement
コード例 #1
0
ファイル: FunctionDecompiler.cs プロジェクト: yole/Gibbed.RED
        private List<Statement> RestoreControlFlow(List<ExpressionStatement> statements)
        {
            MarkTargetStatements(statements);
            var blocks = BuildBasicBlocks(statements);
            MarkJumpTargets(blocks);
            RemoveRedundantBlocks(blocks);

            int i = 0;
            while(i < blocks.Count)
            {
                var block = blocks[i];
                if (block.Predecessors.Count == 1 && block.Successors.Count == 2)
                {
                    var thenBlock = block.Successors[0];
                    var nextBlock = block.Successors[1];
                    var condition = block.Condition;
                    if (condition != null &&
                        thenBlock.Predecessors.Count == 1 && thenBlock.Successors.Count == 1)
                    {
                        if (nextBlock.HasPredecessors(block, thenBlock))
                        {
                            block.RemoveSelf();
                            thenBlock.RemoveSelf();
                            var ifBlock = new ControlStatement(block.Predecessors[0], "if (" + condition + ")", thenBlock);
                            ifBlock.AddSuccessor(nextBlock);
                            blocks.Remove(block);
                            blocks.Remove(thenBlock);
                            blocks.Insert(i, ifBlock);
                            continue;
                        }
                        var jumpBlock = thenBlock.Successors[0];
                        var elseBlock = nextBlock;
                        if (jumpBlock.Successors.Count == 1)
                        {
                            nextBlock = jumpBlock.Successors[0];
                            if (nextBlock.HasPredecessors(jumpBlock, elseBlock))
                            {
                                block.RemoveSelf();
                                thenBlock.RemoveSelf();
                                jumpBlock.RemoveSelf();
                                elseBlock.RemoveSelf();
                                var ifStmt = new ControlStatement(block.Predecessors[0], "if (" + condition + ")",
                                                                   thenBlock);
                                var elseStmt = new ControlStatement(ifStmt, "else", elseBlock);
                                elseStmt.AddSuccessor(nextBlock);
                                blocks.Remove(block);
                                blocks.Remove(thenBlock);
                                blocks.Remove(jumpBlock);
                                blocks.Remove(elseBlock);
                                blocks.Insert(i, ifStmt);
                                blocks.Insert(i+1, elseStmt);
                                continue;
                            }
                        }
                    }
                }

                if (block.Predecessors.Count == 2 && block.Successors.Count == 2)
                {
                    var loopBody = block.Successors[0];
                    var loopEnd = block.Successors[1];
                    var condition = block.Condition;
                    if (condition != null &&
                        loopBody.Predecessors.Count == 1 && loopBody.Successors.Count == 1 && 
                        loopEnd.Predecessors.Count == 1)
                    {
                        var loopJump = loopBody.Successors[0];
                        if (loopJump.HasSuccessors(block))
                        {
                            block.RemoveSelf();
                            loopBody.RemoveSelf();
                            loopJump.RemoveSelf();
                            var whileBlock = new ControlStatement(block.Predecessors[0], "while (" + condition + ")", loopBody);
                            whileBlock.AddSuccessor(loopEnd);
                            blocks.Remove(block);
                            blocks.Remove(loopBody);
                            blocks.Remove(loopJump);
                            blocks.Insert(i, whileBlock);

                        }
                    }
                }
                i++;


            }

            if (IsControlFlowBuilt(blocks))
            {
                blocks.ForEach(block => block.ControlFlowDone = true);
            }

            return new List<Statement>(blocks);

        }
コード例 #2
0
        private List <Statement> RestoreControlFlow(List <ExpressionStatement> statements)
        {
            MarkTargetStatements(statements);
            var blocks = BuildBasicBlocks(statements);

            MarkJumpTargets(blocks);
            RemoveRedundantBlocks(blocks);

            int i = 0;

            while (i < blocks.Count)
            {
                var block = blocks[i];
                if (block.Predecessors.Count == 1 && block.Successors.Count == 2)
                {
                    var thenBlock = block.Successors[0];
                    var nextBlock = block.Successors[1];
                    var condition = block.Condition;
                    if (condition != null &&
                        thenBlock.Predecessors.Count == 1 && thenBlock.Successors.Count == 1)
                    {
                        if (nextBlock.HasPredecessors(block, thenBlock))
                        {
                            block.RemoveSelf();
                            thenBlock.RemoveSelf();
                            var ifBlock = new ControlStatement(block.Predecessors[0], "if (" + condition + ")", thenBlock);
                            ifBlock.AddSuccessor(nextBlock);
                            blocks.Remove(block);
                            blocks.Remove(thenBlock);
                            blocks.Insert(i, ifBlock);
                            continue;
                        }
                        var jumpBlock = thenBlock.Successors[0];
                        var elseBlock = nextBlock;
                        if (jumpBlock.Successors.Count == 1)
                        {
                            nextBlock = jumpBlock.Successors[0];
                            if (nextBlock.HasPredecessors(jumpBlock, elseBlock))
                            {
                                block.RemoveSelf();
                                thenBlock.RemoveSelf();
                                jumpBlock.RemoveSelf();
                                elseBlock.RemoveSelf();
                                var ifStmt = new ControlStatement(block.Predecessors[0], "if (" + condition + ")",
                                                                  thenBlock);
                                var elseStmt = new ControlStatement(ifStmt, "else", elseBlock);
                                elseStmt.AddSuccessor(nextBlock);
                                blocks.Remove(block);
                                blocks.Remove(thenBlock);
                                blocks.Remove(jumpBlock);
                                blocks.Remove(elseBlock);
                                blocks.Insert(i, ifStmt);
                                blocks.Insert(i + 1, elseStmt);
                                continue;
                            }
                        }
                    }
                }

                if (block.Predecessors.Count == 2 && block.Successors.Count == 2)
                {
                    var loopBody  = block.Successors[0];
                    var loopEnd   = block.Successors[1];
                    var condition = block.Condition;
                    if (condition != null &&
                        loopBody.Predecessors.Count == 1 && loopBody.Successors.Count == 1 &&
                        loopEnd.Predecessors.Count == 1)
                    {
                        var loopJump = loopBody.Successors[0];
                        if (loopJump.HasSuccessors(block))
                        {
                            block.RemoveSelf();
                            loopBody.RemoveSelf();
                            loopJump.RemoveSelf();
                            var whileBlock = new ControlStatement(block.Predecessors[0], "while (" + condition + ")", loopBody);
                            whileBlock.AddSuccessor(loopEnd);
                            blocks.Remove(block);
                            blocks.Remove(loopBody);
                            blocks.Remove(loopJump);
                            blocks.Insert(i, whileBlock);
                        }
                    }
                }
                i++;
            }

            if (IsControlFlowBuilt(blocks))
            {
                blocks.ForEach(block => block.ControlFlowDone = true);
            }

            return(new List <Statement>(blocks));
        }