Example #1
0
 public static void ReplaceContinueWithBreak(Statement stat)
 {
     if (stat.type == Statement.Type_Do)
     {
         List <StatEdge> lst = stat.GetPredecessorEdges(StatEdge.Type_Continue);
         foreach (StatEdge edge in lst)
         {
             if (edge.@explicit)
             {
                 Statement minclosure = GetMinContinueClosure(edge);
                 if (minclosure != edge.closure && !InlineSingleBlockHelper.IsBreakEdgeLabeled(edge
                                                                                               .GetSource(), minclosure))
                 {
                     edge.GetSource().ChangeEdgeType(Statement.Direction_Forward, edge, StatEdge.Type_Break
                                                     );
                     edge.labeled = false;
                     minclosure.AddLabeledEdge(edge);
                 }
             }
         }
     }
     foreach (Statement st in stat.GetStats())
     {
         ReplaceContinueWithBreak(st);
     }
 }
        private static void InlineBlock(SequenceStatement seq, int index)
        {
            Statement first = seq.GetStats()[index];
            Statement pre   = seq.GetStats()[index - 1];

            pre.RemoveSuccessor(pre.GetAllSuccessorEdges()[0]);
            // single regular edge
            StatEdge  edge   = first.GetPredecessorEdges(StatEdge.Type_Break)[0];
            Statement source = edge.GetSource();
            Statement parent = source.GetParent();

            source.RemoveSuccessor(edge);
            List <Statement> lst = new List <Statement>();

            for (int i = seq.GetStats().Count - 1; i >= index; i--)
            {
                lst.Add(0, seq.GetStats().RemoveAtReturningValue(i));
            }
            if (parent.type == Statement.Type_If && ((IfStatement)parent).iftype == IfStatement
                .Iftype_If && source == parent.GetFirst())
            {
                IfStatement       ifparent = (IfStatement)parent;
                SequenceStatement block    = new SequenceStatement(lst);
                block.SetAllParent();
                StatEdge newedge = new StatEdge(StatEdge.Type_Regular, source, block);
                source.AddSuccessor(newedge);
                ifparent.SetIfEdge(newedge);
                ifparent.SetIfstat(block);
                ifparent.GetStats().AddWithKey(block, block.id);
                block.SetParent(ifparent);
            }
            else
            {
                lst.Add(0, source);
                SequenceStatement block = new SequenceStatement(lst);
                block.SetAllParent();
                parent.ReplaceStatement(source, 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, source
                                                        );
                    source.AddPredecessor(prededge);
                    source.AddLabeledEdge(prededge);
                }
                if (parent.type == Statement.Type_Switch)
                {
                    ((SwitchStatement)parent).SortEdgesAndNodes();
                }
                source.AddSuccessor(new StatEdge(StatEdge.Type_Regular, source, first));
            }
        }
Example #3
0
        public static void LowContinueLabels(Statement stat, HashSet <StatEdge> edges)
        {
            bool ok = (stat.type != Statement.Type_Do);

            if (!ok)
            {
                DoStatement dostat = (DoStatement)stat;
                ok = dostat.GetLooptype() == DoStatement.Loop_Do || dostat.GetLooptype() == DoStatement
                     .Loop_While || (dostat.GetLooptype() == DoStatement.Loop_For && dostat.GetIncExprent
                                         () == null);
            }
            if (ok)
            {
                Sharpen.Collections.AddAll(edges, stat.GetPredecessorEdges(StatEdge.Type_Continue
                                                                           ));
            }
            if (ok && stat.type == Statement.Type_Do)
            {
                foreach (StatEdge edge in edges)
                {
                    if (stat.ContainsStatementStrict(edge.GetSource()))
                    {
                        edge.GetDestination().RemovePredecessor(edge);
                        edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, stat);
                        stat.AddPredecessor(edge);
                        stat.AddLabeledEdge(edge);
                    }
                }
            }
            foreach (Statement st in stat.GetStats())
            {
                if (st == stat.GetFirst())
                {
                    LowContinueLabels(st, edges);
                }
                else
                {
                    LowContinueLabels(st, new HashSet <StatEdge>());
                }
            }
        }
Example #4
0
 private static void CondenseSequencesRec(Statement stat)
 {
     if (stat.type == Statement.Type_Sequence)
     {
         List <Statement> lst      = new List <Statement>(stat.GetStats());
         bool             unfolded = false;
         // unfold blocks
         for (int i = 0; i < lst.Count; i++)
         {
             Statement st = lst[i];
             if (st.type == Statement.Type_Sequence)
             {
                 RemoveEmptyStatements((SequenceStatement)st);
                 if (i == lst.Count - 1 || IsSequenceDisbandable(st, lst[i + 1]))
                 {
                     // move predecessors
                     Statement first = st.GetFirst();
                     foreach (StatEdge edge in st.GetAllPredecessorEdges())
                     {
                         st.RemovePredecessor(edge);
                         edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, first);
                         first.AddPredecessor(edge);
                     }
                     // move successors
                     Statement last = st.GetStats().GetLast();
                     if ((last.GetAllSuccessorEdges().Count == 0) && i < lst.Count - 1)
                     {
                         last.AddSuccessor(new StatEdge(StatEdge.Type_Regular, last, lst[i + 1]));
                     }
                     else
                     {
                         foreach (StatEdge edge in last.GetAllSuccessorEdges())
                         {
                             if (i == lst.Count - 1)
                             {
                                 if (edge.closure == st)
                                 {
                                     stat.AddLabeledEdge(edge);
                                 }
                             }
                             else
                             {
                                 edge.GetSource().ChangeEdgeType(Statement.Direction_Forward, edge, StatEdge.Type_Regular
                                                                 );
                                 edge.closure.GetLabelEdges().Remove(edge);
                                 edge.closure = null;
                             }
                         }
                     }
                     foreach (StatEdge edge in st.GetAllSuccessorEdges())
                     {
                         st.RemoveSuccessor(edge);
                     }
                     foreach (StatEdge edge in new HashSet <StatEdge>(st.GetLabelEdges()))
                     {
                         if (edge.GetSource() != last)
                         {
                             last.AddLabeledEdge(edge);
                         }
                     }
                     lst.RemoveAtReturningValue(i);
                     lst.InsertRange(i, st.GetStats());
                     i--;
                     unfolded = true;
                 }
             }
         }
         if (unfolded)
         {
             SequenceStatement sequence = new SequenceStatement(lst);
             sequence.SetAllParent();
             stat.GetParent().ReplaceStatement(stat, sequence);
             stat = sequence;
         }
     }
     // sequence consisting of one statement -> disband
     if (stat.type == Statement.Type_Sequence)
     {
         RemoveEmptyStatements((SequenceStatement)stat);
         if (stat.GetStats().Count == 1)
         {
             Statement st = stat.GetFirst();
             bool      ok = (st.GetAllSuccessorEdges().Count == 0);
             if (!ok)
             {
                 StatEdge edge = st.GetAllSuccessorEdges()[0];
                 ok = (stat.GetAllSuccessorEdges().Count == 0);
                 if (!ok)
                 {
                     StatEdge statedge = stat.GetAllSuccessorEdges()[0];
                     ok = (edge.GetDestination() == statedge.GetDestination());
                     if (ok)
                     {
                         st.RemoveSuccessor(edge);
                     }
                 }
             }
             if (ok)
             {
                 stat.GetParent().ReplaceStatement(stat, st);
                 stat = st;
             }
         }
     }
     // replace flat statements with synthetic basic blocks
     while (true)
     {
         foreach (Statement st in stat.GetStats())
         {
             if (((st.GetStats().Count == 0) || st.GetExprents() != null) && st.type != Statement
                 .Type_Basicblock)
             {
                 DestroyAndFlattenStatement(st);
                 goto outer_continue;
             }
         }
         break;
         outer_continue :;
     }
     outer_break :;
     // recursion
     for (int i = 0; i < stat.GetStats().Count; i++)
     {
         CondenseSequencesRec(stat.GetStats()[i]);
     }
 }
Example #5
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);
        }