示例#1
0
        private static int IntegrateExits(Statement stat)
        {
            int       ret = 0;
            Statement dest;

            if (stat.GetExprents() == null)
            {
                while (true)
                {
                    int changed = 0;
                    foreach (Statement st in stat.GetStats())
                    {
                        changed = IntegrateExits(st);
                        if (changed > 0)
                        {
                            ret = 1;
                            break;
                        }
                    }
                    if (changed == 0)
                    {
                        break;
                    }
                }
                if (stat.type == Statement.Type_If)
                {
                    IfStatement ifst = (IfStatement)stat;
                    if (ifst.GetIfstat() == null)
                    {
                        StatEdge ifedge = ifst.GetIfEdge();
                        dest = IsExitEdge(ifedge);
                        if (dest != null)
                        {
                            BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext
                                                                                               .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter
                                                                                                                                             )));
                            bstat.SetExprents(DecHelper.CopyExprentList(dest.GetExprents()));
                            ifst.GetFirst().RemoveSuccessor(ifedge);
                            StatEdge newedge = new StatEdge(StatEdge.Type_Regular, ifst.GetFirst(), bstat);
                            ifst.GetFirst().AddSuccessor(newedge);
                            ifst.SetIfEdge(newedge);
                            ifst.SetIfstat(bstat);
                            ifst.GetStats().AddWithKey(bstat, bstat.id);
                            bstat.SetParent(ifst);
                            StatEdge oldexitedge = dest.GetAllSuccessorEdges()[0];
                            StatEdge newexitedge = new StatEdge(StatEdge.Type_Break, bstat, oldexitedge.GetDestination
                                                                    ());
                            bstat.AddSuccessor(newexitedge);
                            oldexitedge.closure.AddLabeledEdge(newexitedge);
                            ret = 1;
                        }
                    }
                }
            }
            if (stat.GetAllSuccessorEdges().Count == 1 && stat.GetAllSuccessorEdges()[0].GetType
                    () == StatEdge.Type_Break && (stat.GetLabelEdges().Count == 0))
            {
                Statement parent = stat.GetParent();
                if (stat != parent.GetFirst() || (parent.type != Statement.Type_If && parent.type
                                                  != Statement.Type_Switch))
                {
                    StatEdge destedge = stat.GetAllSuccessorEdges()[0];
                    dest = IsExitEdge(destedge);
                    if (dest != null)
                    {
                        stat.RemoveSuccessor(destedge);
                        BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext
                                                                                           .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter
                                                                                                                                         )));
                        bstat.SetExprents(DecHelper.CopyExprentList(dest.GetExprents()));
                        StatEdge oldexitedge = dest.GetAllSuccessorEdges()[0];
                        StatEdge newexitedge = new StatEdge(StatEdge.Type_Break, bstat, oldexitedge.GetDestination
                                                                ());
                        bstat.AddSuccessor(newexitedge);
                        oldexitedge.closure.AddLabeledEdge(newexitedge);
                        SequenceStatement block = new SequenceStatement(Sharpen.Arrays.AsList(stat, bstat
                                                                                              ));
                        block.SetAllParent();
                        parent.ReplaceStatement(stat, block);
                        // LabelHelper.lowContinueLabels not applicable because of forward continue edges
                        // LabelHelper.lowContinueLabels(block, new HashSet<StatEdge>());
                        // do it by hand
                        foreach (StatEdge prededge in block.GetPredecessorEdges(StatEdge.Type_Continue))
                        {
                            block.RemovePredecessor(prededge);
                            prededge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, prededge, stat);
                            stat.AddPredecessor(prededge);
                            stat.AddLabeledEdge(prededge);
                        }
                        stat.AddSuccessor(new StatEdge(StatEdge.Type_Regular, stat, bstat));
                        foreach (StatEdge edge in dest.GetAllPredecessorEdges())
                        {
                            if (!edge.@explicit && stat.ContainsStatementStrict(edge.GetSource()) && MergeHelper
                                .IsDirectPath(edge.GetSource().GetParent(), bstat))
                            {
                                dest.RemovePredecessor(edge);
                                edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, bstat);
                                bstat.AddPredecessor(edge);
                                if (!stat.ContainsStatementStrict(edge.closure))
                                {
                                    stat.AddLabeledEdge(edge);
                                }
                            }
                        }
                        ret = 2;
                    }
                }
            }
            return(ret);
        }