Пример #1
0
        private SequenceStatement(Statement head, Statement tail)
            : this(Sharpen.Arrays.AsList(head, tail))
        {
            List <StatEdge> lstSuccs = tail.GetSuccessorEdges(Statedge_Direct_All);

            if (!(lstSuccs.Count == 0))
            {
                StatEdge edge = lstSuccs[0];
                if (edge.GetType() == StatEdge.Type_Regular && edge.GetDestination() != head)
                {
                    post = edge.GetDestination();
                }
            }
        }
Пример #2
0
        // *****************************************************************************
        // public methods
        // *****************************************************************************
        public static Statement IsHead2Block(Statement head)
        {
            if (head.GetLastBasicType() != Statement.Lastbasictype_General)
            {
                return(null);
            }
            // at most one outgoing edge
            StatEdge        edge     = null;
            List <StatEdge> lstSuccs = head.GetSuccessorEdges(Statedge_Direct_All);

            if (!(lstSuccs.Count == 0))
            {
                edge = lstSuccs[0];
            }
            if (edge != null && edge.GetType() == StatEdge.Type_Regular)
            {
                Statement stat = edge.GetDestination();
                if (stat != head && stat.GetPredecessorEdges(StatEdge.Type_Regular).Count == 1 &&
                    !stat.IsMonitorEnter())
                {
                    if (stat.GetLastBasicType() == Statement.Lastbasictype_General)
                    {
                        if (DecHelper.CheckStatementExceptions(Sharpen.Arrays.AsList(head, stat)))
                        {
                            return(new SequenceStatement(head, stat));
                        }
                    }
                }
            }
            return(null);
        }
Пример #3
0
        public override void ReplaceStatement(Statement oldstat, Statement newstat)
        {
            base.ReplaceStatement(oldstat, newstat);
            if (ifstat == oldstat)
            {
                ifstat = newstat;
            }
            if (elsestat == oldstat)
            {
                elsestat = newstat;
            }
            List <StatEdge> lstSuccs = first.GetSuccessorEdges(Statedge_Direct_All);

            if (iftype == Iftype_If)
            {
                ifedge   = lstSuccs[0];
                elseedge = null;
            }
            else
            {
                StatEdge edge0 = lstSuccs[0];
                StatEdge edge1 = lstSuccs[1];
                if (edge0.GetDestination() == ifstat)
                {
                    ifedge   = edge0;
                    elseedge = edge1;
                }
                else
                {
                    ifedge   = edge1;
                    elseedge = edge0;
                }
            }
        }
Пример #4
0
 // post is always null!
 // *****************************************************************************
 // public methods
 // *****************************************************************************
 public static Statement IsHead(Statement head)
 {
     if (head.GetLastBasicType() == Lastbasictype_General && !head.IsMonitorEnter())
     {
         // at most one outgoing edge
         StatEdge        edge     = null;
         List <StatEdge> lstSuccs = head.GetSuccessorEdges(Statedge_Direct_All);
         if (!(lstSuccs.Count == 0))
         {
             edge = lstSuccs[0];
         }
         // regular loop
         if (edge != null && edge.GetType() == StatEdge.Type_Regular && edge.GetDestination
                 () == head)
         {
             return(new DoStatement(head));
         }
         // continues
         if (head.type != Type_Do && (edge == null || edge.GetType() != StatEdge.Type_Regular
                                      ) && head.GetContinueSet().Contains(head.GetBasichead()))
         {
             return(new DoStatement(head));
         }
     }
     return(null);
 }
Пример #5
0
 public virtual void RemoveSuccessor(StatEdge edge)
 {
     if (edge == null)
     {
         return;
     }
     RemoveEdgeInternal(Direction_Forward, edge);
     if (edge.closure != null)
     {
         edge.closure.GetLabelEdges().Remove(edge);
     }
     if (edge.GetDestination() != null)
     {
         // TODO: redundant?
         edge.GetDestination().RemovePredecessor(edge);
     }
 }
Пример #6
0
 public virtual void AddSuccessor(StatEdge edge)
 {
     AddEdgeInternal(Direction_Forward, edge);
     if (edge.closure != null)
     {
         edge.closure.GetLabelEdges().Add(edge);
     }
     edge.GetDestination().AddPredecessor(edge);
 }
Пример #7
0
        public virtual void ReplaceStatement(Statement oldstat, Statement newstat)
        {
            foreach (StatEdge edge in oldstat.GetAllPredecessorEdges())
            {
                oldstat.RemovePredecessor(edge);
                edge.GetSource().ChangeEdgeNode(Direction_Forward, edge, newstat);
                newstat.AddPredecessor(edge);
            }
            foreach (StatEdge edge in oldstat.GetAllSuccessorEdges())
            {
                oldstat.RemoveSuccessor(edge);
                edge.SetSource(newstat);
                newstat.AddSuccessor(edge);
            }
            int statindex = stats.GetIndexByKey(oldstat.id);

            stats.RemoveWithKey(oldstat.id);
            stats.AddWithKeyAndIndex(statindex, newstat, newstat.id);
            newstat.SetParent(this);
            newstat.post = oldstat.post;
            if (first == oldstat)
            {
                first = newstat;
            }
            List <StatEdge> lst = new List <StatEdge>(oldstat.GetLabelEdges());

            for (int i = lst.Count - 1; i >= 0; i--)
            {
                StatEdge edge = lst[i];
                if (edge.GetSource() != newstat)
                {
                    newstat.AddLabeledEdge(edge);
                }
                else if (this == edge.GetDestination() || this.ContainsStatementStrict(edge.GetDestination
                                                                                           ()))
                {
                    edge.closure = null;
                }
                else
                {
                    this.AddLabeledEdge(edge);
                }
            }
            oldstat.GetLabelEdges().Clear();
        }
Пример #8
0
        public SynchronizedStatement(Statement head, Statement body, Statement exc)
            : this()
        {
            first = head;
            stats.AddWithKey(head, head.id);
            this.body = body;
            stats.AddWithKey(body, body.id);
            stats.AddWithKey(exc, exc.id);
            List <StatEdge> lstSuccs = body.GetSuccessorEdges(Statedge_Direct_All);

            if (!(lstSuccs.Count == 0))
            {
                StatEdge edge = lstSuccs[0];
                if (edge.GetType() == StatEdge.Type_Regular)
                {
                    post = edge.GetDestination();
                }
            }
        }
Пример #9
0
        public virtual void ChangeEdgeType(int direction, StatEdge edge, int newtype)
        {
            int oldtype = edge.GetType();

            if (oldtype == newtype)
            {
                return;
            }
            if (oldtype == StatEdge.Type_Exception || newtype == StatEdge.Type_Exception)
            {
                throw new Exception("Invalid edge type!");
            }
            RemoveEdgeDirectInternal(direction, edge, oldtype);
            AddEdgeDirectInternal(direction, edge, newtype);
            if (direction == Direction_Forward)
            {
                edge.GetDestination().ChangeEdgeType(Direction_Backward, edge, newtype);
            }
            edge.SetType(newtype);
        }
Пример #10
0
        private CatchAllStatement(Statement head, Statement handler)
            : this()
        {
            first = head;
            stats.AddWithKey(head, head.id);
            this.handler = handler;
            stats.AddWithKey(handler, handler.id);
            List <StatEdge> lstSuccs = head.GetSuccessorEdges(Statedge_Direct_All);

            if (!(lstSuccs.Count == 0))
            {
                StatEdge edge = lstSuccs[0];
                if (edge.GetType() == StatEdge.Type_Regular)
                {
                    post = edge.GetDestination();
                }
            }
            vars.Add(new VarExprent(DecompilerContext.GetCounterContainer().GetCounterAndIncrement
                                        (CounterContainer.Var_Counter), new VarType(ICodeConstants.Type_Object, 0, "java/lang/Throwable"
                                                                                    ), DecompilerContext.GetVarProcessor()));
        }
Пример #11
0
        // *****************************************************************************
        // private methods
        // *****************************************************************************
        private static void AddToReversePostOrderListIterative(Statement root, IList
                                                               <Statement> lst)
        {
            LinkedList <Statement> stackNode  = new LinkedList <Statement>();
            LinkedList <int>       stackIndex = new LinkedList <int>();
            HashSet <Statement>    setVisited = new HashSet <Statement>();

            stackNode.AddLast(root);
            stackIndex.AddLast(0);
            while (!(stackNode.Count == 0))
            {
                Statement node  = stackNode.Last.Value;
                int       index = Sharpen.Collections.RemoveLast(stackIndex);
                setVisited.Add(node);
                List <StatEdge> lstEdges = node.GetAllSuccessorEdges();
                for (; index < lstEdges.Count; index++)
                {
                    StatEdge  edge = lstEdges[index];
                    Statement succ = edge.GetDestination();
                    if (!setVisited.Contains(succ) && (edge.GetType() == StatEdge.Type_Regular || edge
                                                       .GetType() == StatEdge.Type_Exception))
                    {
                        // TODO: edge filter?
                        stackIndex.AddLast(index + 1);
                        stackNode.AddLast(succ);
                        stackIndex.AddLast(0);
                        break;
                    }
                }
                if (index == lstEdges.Count)
                {
                    lst.Insert(0, node);
                    Sharpen.Collections.RemoveLast(stackNode);
                }
            }
        }
Пример #12
0
        private void AddEdgeDirectInternal(int direction, StatEdge edge, int edgetype)
        {
            Dictionary <int, List <StatEdge> > mapEdges = direction == Direction_Backward ? mapPredEdges
                                 : mapSuccEdges;
            Dictionary <int, List <Statement> > mapStates = direction == Direction_Backward ?
                                                            mapPredStates : mapSuccStates;

            mapEdges.ComputeIfAbsent(edgetype, (int k) => new List <StatEdge>()).Add(edge);
            mapStates.ComputeIfAbsent(edgetype, (int k) => new List <Statement>()).Add(direction
                                                                                       == Direction_Backward ? edge.GetSource() : edge.GetDestination());
        }
Пример #13
0
        // *****************************************************************************
        // private methods
        // *****************************************************************************
        public virtual void SortEdgesAndNodes()
        {
            Dictionary <StatEdge, int> mapEdgeIndex  = new Dictionary <StatEdge, int>();
            List <StatEdge>            lstFirstSuccs = first.GetSuccessorEdges(Statedge_Direct_All);

            for (int i = 0; i < lstFirstSuccs.Count; i++)
            {
                Sharpen.Collections.Put(mapEdgeIndex, lstFirstSuccs[i], i == 0 ? lstFirstSuccs.Count
                                         : i);
            }
            // case values
            BasicBlockStatement bbstat = (BasicBlockStatement)first;

            int[] values = ((SwitchInstruction)bbstat.GetBlock().GetLastInstruction()).GetValues
                               ();
            List <Statement>    nodes = new List <Statement>(stats.Count - 1);
            List <List <int?> > edges = new List <List <int?> >(stats.Count - 1);

            // collect regular edges
            for (int i = 1; i < stats.Count; i++)
            {
                Statement   stat = stats[i];
                List <int?> lst  = new List <int?>();
                foreach (StatEdge edge in stat.GetPredecessorEdges(StatEdge.Type_Regular))
                {
                    if (edge.GetSource() == first)
                    {
                        lst.Add(mapEdgeIndex.GetOrNullable(edge));
                    }
                }
                lst.Sort();
                nodes.Add(stat);
                edges.Add(lst);
            }
            // collect exit edges
            List <StatEdge> lstExitEdges = first.GetSuccessorEdges(StatEdge.Type_Break | StatEdge
                                                                   .Type_Continue);

            while (!(lstExitEdges.Count == 0))
            {
                StatEdge    edge = lstExitEdges[0];
                List <int?> lst  = new List <int?>();
                for (int i = lstExitEdges.Count - 1; i >= 0; i--)
                {
                    StatEdge edgeTemp = lstExitEdges[i];
                    if (edgeTemp.GetDestination() == edge.GetDestination() && edgeTemp.GetType() == edge
                        .GetType())
                    {
                        lst.Add(mapEdgeIndex.GetOrNullable(edgeTemp));
                        lstExitEdges.RemoveAtReturningValue(i);
                    }
                }
                lst.Sort();
                nodes.Add(null);
                edges.Add(lst);
            }
            // sort edges (bubblesort)
            for (int i = 0; i < edges.Count - 1; i++)
            {
                for (int j = edges.Count - 1; j > i; j--)
                {
                    if (edges[j - 1][0] > edges[j][0])
                    {
                        edges[j] = edges[j - 1] = edges[j];
                        nodes[j] = nodes[j - 1] = nodes[j];
                    }
                }
            }
            // sort statement cliques
            for (int index = 0; index < nodes.Count; index++)
            {
                Statement stat = nodes[index];
                if (stat != null)
                {
                    HashSet <Statement> setPreds = new HashSet <Statement>(stat.GetNeighbours(StatEdge.
                                                                                              Type_Regular, Direction_Backward));
                    setPreds.Remove(first);
                    if (!(setPreds.Count == 0))
                    {
                        Statement pred = new Sharpen.EnumeratorAdapter <Statement>(setPreds.GetEnumerator()).Next();
                        // assumption: at most one predecessor node besides the head. May not hold true for obfuscated code.
                        for (int j = 0; j < nodes.Count; j++)
                        {
                            if (j != (index - 1) && nodes[j] == pred)
                            {
                                nodes.Add(j + 1, stat);
                                edges.Add(j + 1, edges[index]);
                                if (j > index)
                                {
                                    nodes.RemoveAtReturningValue(index);
                                    edges.RemoveAtReturningValue(index);
                                    index--;
                                }
                                else
                                {
                                    nodes.RemoveAtReturningValue(index + 1);
                                    edges.RemoveAtReturningValue(index + 1);
                                }
                                break;
                            }
                        }
                    }
                }
            }
            // translate indices back into edges
            List <List <StatEdge> > lstEdges  = new List <List <StatEdge> >(edges.Count);
            List <List <Exprent> >  lstValues = new List <List <Exprent> >(edges.Count);

            foreach (List <int?> lst in edges)
            {
                List <StatEdge> lste     = new List <StatEdge>(lst.Count);
                List <Exprent>  lstv     = new List <Exprent>(lst.Count);
                List <StatEdge> lstSuccs = first.GetSuccessorEdges(Statedge_Direct_All);
                foreach (int? @in in lst)
                {
                    int?index = @in == lstSuccs.Count ? 0 : @in;
                    if (!index.HasValue)
                    {
                        continue;
                    }
                    lste.Add(lstSuccs[index.Value]);
                    lstv.Add(index == 0 ? null : new ConstExprent(values[index.Value - 1], false, null));
                }
                lstEdges.Add(lste);
                lstValues.Add(lstv);
            }
            // replace null statements with dummy basic blocks
            for (int i = 0; i < nodes.Count; i++)
            {
                if (nodes[i] == null)
                {
                    BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext
                                                                                       .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter
                                                                                                                                     )));
                    StatEdge sample_edge = lstEdges[i][0];
                    bstat.AddSuccessor(new StatEdge(sample_edge.GetType(), bstat, sample_edge.GetDestination
                                                        (), sample_edge.closure));
                    foreach (StatEdge edge in lstEdges[i])
                    {
                        edge.GetSource().ChangeEdgeType(Direction_Forward, edge, StatEdge.Type_Regular);
                        edge.closure.GetLabelEdges().Remove(edge);
                        edge.GetDestination().RemovePredecessor(edge);
                        edge.GetSource().ChangeEdgeNode(Direction_Forward, edge, bstat);
                        bstat.AddPredecessor(edge);
                    }
                    nodes[i] = bstat;
                    stats.AddWithKey(bstat, bstat.id);
                    bstat.SetParent(this);
                }
            }
            caseStatements = nodes;
            caseEdges      = lstEdges;
            caseValues     = lstValues;
        }
Пример #14
0
        private void FlattenStatement()
        {
            LinkedList <_T2081736913> lstStackStatements = new LinkedList <_T2081736913>();

            lstStackStatements.AddLast(new _T2081736913(this, root, new LinkedList <FlattenStatementsHelper.StackEntry
                                                                                    >(), null));
            while (!(lstStackStatements.Count == 0))
            {
                _T2081736913 statEntry = Sharpen.Collections.RemoveFirst(lstStackStatements);
                Statement    stat      = statEntry.statement;
                LinkedList <FlattenStatementsHelper.StackEntry> stackFinally = statEntry.stackFinally;
                int             statementBreakIndex = statEntry.statementIndex;
                DirectNode      node;
                DirectNode      nd;
                List <StatEdge> lstSuccEdges = new List <StatEdge>();
                DirectNode      sourcenode   = null;
                if (statEntry.succEdges == null)
                {
                    switch (stat.type)
                    {
                    case Statement.Type_Basicblock:
                    {
                        node = new DirectNode(DirectNode.Node_Direct, stat, (BasicBlockStatement)stat);
                        if (stat.GetExprents() != null)
                        {
                            node.exprents = stat.GetExprents();
                        }
                        graph.nodes.PutWithKey(node, node.id);
                        Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { node.id, null });
                        Sharpen.Collections.AddAll(lstSuccEdges, stat.GetSuccessorEdges(Statement.Statedge_Direct_All
                                                                                        ));
                        sourcenode = node;
                        List <Exprent> tailExprentList = statEntry.tailExprents;
                        if (tailExprentList != null)
                        {
                            DirectNode tail = new DirectNode(DirectNode.Node_Tail, stat, stat.id + "_tail");
                            tail.exprents = tailExprentList;
                            graph.nodes.PutWithKey(tail, tail.id);
                            Sharpen.Collections.Put(mapDestinationNodes, -stat.id, new string[] { tail.id, null });
                            listEdges.Add(new FlattenStatementsHelper.Edge(node.id, -stat.id, StatEdge.Type_Regular
                                                                           ));
                            sourcenode = tail;
                        }
                        // 'if' statement: record positive branch
                        if (stat.GetLastBasicType() == Statement.Lastbasictype_If)
                        {
                            Sharpen.Collections.Put(mapPosIfBranch, sourcenode.id, lstSuccEdges[0].GetDestination
                                                        ().id);
                        }
                        break;
                    }

                    case Statement.Type_Catchall:
                    case Statement.Type_Trycatch:
                    {
                        DirectNode firstnd = new DirectNode(DirectNode.Node_Try, stat, stat.id + "_try");
                        Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { firstnd.id,
                                                                                             null });
                        graph.nodes.PutWithKey(firstnd, firstnd.id);
                        LinkedList <_T2081736913> lst = new LinkedList <_T2081736913>();
                        foreach (Statement st in stat.GetStats())
                        {
                            listEdges.Add(new FlattenStatementsHelper.Edge(firstnd.id, st.id, StatEdge.Type_Regular
                                                                           ));
                            LinkedList <FlattenStatementsHelper.StackEntry> stack = stackFinally;
                            if (stat.type == Statement.Type_Catchall && ((CatchAllStatement)stat).IsFinally())
                            {
                                stack = new LinkedList <FlattenStatementsHelper.StackEntry>(stackFinally);
                                if (st == stat.GetFirst())
                                {
                                    // catch head
                                    stack.AddLast(new FlattenStatementsHelper.StackEntry((CatchAllStatement)stat, false));
                                }
                                else
                                {
                                    // handler
                                    stack.AddLast(new FlattenStatementsHelper.StackEntry((CatchAllStatement)stat, true, StatEdge
                                                                                         .Type_Break, root.GetDummyExit(), st, st, firstnd, firstnd, true));
                                }
                            }
                            lst.AddLast(new _T2081736913(this, st, stack, null));
                        }
                        lstStackStatements = new LinkedList <_T2081736913>(lst.Concat(lstStackStatements));
                        break;
                    }

                    case Statement.Type_Do:
                    {
                        if (statementBreakIndex == 0)
                        {
                            statEntry.statementIndex = 1;
                            lstStackStatements.AddFirst(statEntry);
                            lstStackStatements.AddFirst(new _T2081736913(this, stat.GetFirst(), stackFinally,
                                                                         null));
                            goto mainloop_continue;
                        }
                        nd = graph.nodes.GetWithKey(mapDestinationNodes.GetOrNull(stat.GetFirst().id)[0]);
                        DoStatement dostat   = (DoStatement)stat;
                        int         looptype = dostat.GetLooptype();
                        if (looptype == DoStatement.Loop_Do)
                        {
                            Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { nd.id, nd.id });
                            break;
                        }
                        lstSuccEdges.Add(stat.GetSuccessorEdges(Statement.Statedge_Direct_All)[0]);
                        switch (looptype)
                        {
                        case DoStatement.Loop_While:
                        case DoStatement.Loop_Dowhile:
                        {
                            // exactly one edge
                            node          = new DirectNode(DirectNode.Node_Condition, stat, stat.id + "_cond");
                            node.exprents = dostat.GetConditionExprentList();
                            graph.nodes.PutWithKey(node, node.id);
                            listEdges.Add(new FlattenStatementsHelper.Edge(node.id, stat.GetFirst().id, StatEdge
                                                                           .Type_Regular));
                            if (looptype == DoStatement.Loop_While)
                            {
                                Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { node.id, node
                                                                                                     .id });
                            }
                            else
                            {
                                Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { nd.id, node.
                                                                                                     id });
                                bool found = false;
                                foreach (FlattenStatementsHelper.Edge edge in listEdges)
                                {
                                    if (edge.statid.Equals(stat.id) && edge.edgetype == StatEdge.Type_Continue)
                                    {
                                        found = true;
                                        break;
                                    }
                                }
                                if (!found)
                                {
                                    listEdges.Add(new FlattenStatementsHelper.Edge(nd.id, stat.id, StatEdge.Type_Continue
                                                                                   ));
                                }
                            }
                            sourcenode = node;
                            break;
                        }

                        case DoStatement.Loop_For:
                        {
                            DirectNode nodeinit = new DirectNode(DirectNode.Node_Init, stat, stat.id + "_init"
                                                                 );
                            if (dostat.GetInitExprent() != null)
                            {
                                nodeinit.exprents = dostat.GetInitExprentList();
                            }
                            graph.nodes.PutWithKey(nodeinit, nodeinit.id);
                            DirectNode nodecond = new DirectNode(DirectNode.Node_Condition, stat, stat.id + "_cond"
                                                                 );
                            nodecond.exprents = dostat.GetConditionExprentList();
                            graph.nodes.PutWithKey(nodecond, nodecond.id);
                            DirectNode nodeinc = new DirectNode(DirectNode.Node_Increment, stat, stat.id + "_inc"
                                                                );
                            nodeinc.exprents = dostat.GetIncExprentList();
                            graph.nodes.PutWithKey(nodeinc, nodeinc.id);
                            Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { nodeinit.id,
                                                                                                 nodeinc.id });
                            Sharpen.Collections.Put(mapDestinationNodes, -stat.id, new string[] { nodecond.id
                                                                                                  , null });
                            listEdges.Add(new FlattenStatementsHelper.Edge(nodecond.id, stat.GetFirst().id, StatEdge
                                                                           .Type_Regular));
                            listEdges.Add(new FlattenStatementsHelper.Edge(nodeinit.id, -stat.id, StatEdge.Type_Regular
                                                                           ));
                            listEdges.Add(new FlattenStatementsHelper.Edge(nodeinc.id, -stat.id, StatEdge.Type_Regular
                                                                           ));
                            bool found_1 = false;
                            foreach (FlattenStatementsHelper.Edge edge in listEdges)
                            {
                                if (edge.statid.Equals(stat.id) && edge.edgetype == StatEdge.Type_Continue)
                                {
                                    found_1 = true;
                                    break;
                                }
                            }
                            if (!found_1)
                            {
                                listEdges.Add(new FlattenStatementsHelper.Edge(nd.id, stat.id, StatEdge.Type_Continue
                                                                               ));
                            }
                            sourcenode = nodecond;
                            break;
                        }
                        }
                        break;
                    }

                    case Statement.Type_Syncronized:
                    case Statement.Type_Switch:
                    case Statement.Type_If:
                    case Statement.Type_Sequence:
                    case Statement.Type_Root:
                    {
                        int statsize = stat.GetStats().Count;
                        if (stat.type == Statement.Type_Syncronized)
                        {
                            statsize = 2;
                        }
                        // exclude the handler if synchronized
                        if (statementBreakIndex <= statsize)
                        {
                            List <Exprent> tailexprlst = null;
                            switch (stat.type)
                            {
                            case Statement.Type_Syncronized:
                            {
                                tailexprlst = ((SynchronizedStatement)stat).GetHeadexprentList();
                                break;
                            }

                            case Statement.Type_Switch:
                            {
                                tailexprlst = ((SwitchStatement)stat).GetHeadexprentList();
                                break;
                            }

                            case Statement.Type_If:
                            {
                                tailexprlst = ((IfStatement)stat).GetHeadexprentList();
                                break;
                            }
                            }
                            for (int i = statementBreakIndex; i < statsize; i++)
                            {
                                statEntry.statementIndex = i + 1;
                                lstStackStatements.AddFirst(statEntry);
                                lstStackStatements.AddFirst(new _T2081736913(this, stat.GetStats()[i], stackFinally
                                                                             , (i == 0 && tailexprlst != null && tailexprlst[0] != null) ? tailexprlst : null
                                                                             ));
                                goto mainloop_continue;
                            }
                            node = graph.nodes.GetWithKey(mapDestinationNodes.GetOrNull(stat.GetFirst().id)[0
                                                          ]);
                            Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { node.id, null });
                            if (stat.type == Statement.Type_If && ((IfStatement)stat).iftype == IfStatement.Iftype_If)
                            {
                                lstSuccEdges.Add(stat.GetSuccessorEdges(Statement.Statedge_Direct_All)[0]);
                                // exactly one edge
                                sourcenode = tailexprlst[0] == null ? node : graph.nodes.GetWithKey(node.id + "_tail"
                                                                                                    );
                            }
                        }
                        break;
                    }
                    }
                }
                // no successor edges
                if (sourcenode != null)
                {
                    if (statEntry.succEdges != null)
                    {
                        lstSuccEdges = statEntry.succEdges;
                    }
                    for (int edgeindex = statEntry.edgeIndex; edgeindex < lstSuccEdges.Count; edgeindex
                         ++)
                    {
                        StatEdge edge = lstSuccEdges[edgeindex];
                        LinkedList <FlattenStatementsHelper.StackEntry> stack = new LinkedList <FlattenStatementsHelper.StackEntry
                                                                                                >(stackFinally);
                        int        edgetype                      = edge.GetType();
                        Statement  destination                   = edge.GetDestination();
                        DirectNode finallyShortRangeSource       = sourcenode;
                        DirectNode finallyLongRangeSource        = sourcenode;
                        Statement  finallyShortRangeEntry        = null;
                        Statement  finallyLongRangeEntry         = null;
                        bool       isFinallyMonitorExceptionPath = false;
                        bool       isFinallyExit                 = false;
                        while (true)
                        {
                            FlattenStatementsHelper.StackEntry entry = null;
                            if (!(stack.Count == 0))
                            {
                                entry = stack.Last();
                            }
                            bool created = true;
                            if (entry == null)
                            {
                                SaveEdge(sourcenode, destination, edgetype, isFinallyExit ? finallyShortRangeSource
                                                                         : null, finallyLongRangeSource, finallyShortRangeEntry, finallyLongRangeEntry,
                                         isFinallyMonitorExceptionPath);
                            }
                            else
                            {
                                CatchAllStatement catchall = entry.catchstatement;
                                if (entry.state)
                                {
                                    // finally handler statement
                                    if (edgetype == StatEdge.Type_Finallyexit)
                                    {
                                        Sharpen.Collections.RemoveLast(stack);
                                        destination                   = entry.destination;
                                        edgetype                      = entry.edgetype;
                                        finallyShortRangeSource       = entry.finallyShortRangeSource;
                                        finallyLongRangeSource        = entry.finallyLongRangeSource;
                                        finallyShortRangeEntry        = entry.finallyShortRangeEntry;
                                        finallyLongRangeEntry         = entry.finallyLongRangeEntry;
                                        isFinallyExit                 = true;
                                        isFinallyMonitorExceptionPath = (catchall.GetMonitor() != null) & entry.isFinallyExceptionPath;
                                        created = false;
                                    }
                                    else if (!catchall.ContainsStatementStrict(destination))
                                    {
                                        Sharpen.Collections.RemoveLast(stack);
                                        created = false;
                                    }
                                    else
                                    {
                                        SaveEdge(sourcenode, destination, edgetype, isFinallyExit ? finallyShortRangeSource
                                                                                         : null, finallyLongRangeSource, finallyShortRangeEntry, finallyLongRangeEntry,
                                                 isFinallyMonitorExceptionPath);
                                    }
                                }
                                else if (!catchall.ContainsStatementStrict(destination))
                                {
                                    // finally protected try statement
                                    SaveEdge(sourcenode, catchall.GetHandler(), StatEdge.Type_Regular, isFinallyExit ?
                                             finallyShortRangeSource : null, finallyLongRangeSource, finallyShortRangeEntry,
                                             finallyLongRangeEntry, isFinallyMonitorExceptionPath);
                                    Sharpen.Collections.RemoveLast(stack);
                                    stack.AddLast(new FlattenStatementsHelper.StackEntry(catchall, true, edgetype, destination
                                                                                         , catchall.GetHandler(), finallyLongRangeEntry == null ? catchall.GetHandler() :
                                                                                         finallyLongRangeEntry, sourcenode, finallyLongRangeSource, false));
                                    statEntry.edgeIndex = edgeindex + 1;
                                    statEntry.succEdges = lstSuccEdges;
                                    lstStackStatements.AddFirst(statEntry);
                                    lstStackStatements.AddFirst(new _T2081736913(this, catchall.GetHandler(), stack,
                                                                                 null));
                                    goto mainloop_continue;
                                }
                                else
                                {
                                    SaveEdge(sourcenode, destination, edgetype, isFinallyExit ? finallyShortRangeSource
                                                                                 : null, finallyLongRangeSource, finallyShortRangeEntry, finallyLongRangeEntry,
                                             isFinallyMonitorExceptionPath);
                                }
                            }
                            if (created)
                            {
                                break;
                            }
                        }
                    }
                }
                mainloop_continue :;
            }
            mainloop_break :;
        }
Пример #15
0
        private IfStatement(Statement head, int regedges, Statement postst)
            : this()
        {
            first = head;
            stats.AddWithKey(head, head.id);
            List <StatEdge> lstHeadSuccs = head.GetSuccessorEdges(Statedge_Direct_All);

            switch (regedges)
            {
            case 0:
            {
                ifstat   = null;
                elsestat = null;
                break;
            }

            case 1:
            {
                ifstat   = null;
                elsestat = null;
                StatEdge edgeif = lstHeadSuccs[1];
                if (edgeif.GetType() != StatEdge.Type_Regular)
                {
                    post = lstHeadSuccs[0].GetDestination();
                }
                else
                {
                    post    = edgeif.GetDestination();
                    negated = true;
                }
                break;
            }

            case 2:
            {
                elsestat = lstHeadSuccs[0].GetDestination();
                ifstat   = lstHeadSuccs[1].GetDestination();
                List <StatEdge> lstSucc  = ifstat.GetSuccessorEdges(StatEdge.Type_Regular);
                List <StatEdge> lstSucc1 = elsestat.GetSuccessorEdges(StatEdge.Type_Regular);
                if (ifstat.GetPredecessorEdges(StatEdge.Type_Regular).Count > 1 || lstSucc.Count
                    > 1)
                {
                    post = ifstat;
                }
                else if (elsestat.GetPredecessorEdges(StatEdge.Type_Regular).Count > 1 || lstSucc1
                         .Count > 1)
                {
                    post = elsestat;
                }
                else if (lstSucc.Count == 0)
                {
                    post = elsestat;
                }
                else if (lstSucc1.Count == 0)
                {
                    post = ifstat;
                }
                if (ifstat == post)
                {
                    if (elsestat != post)
                    {
                        ifstat  = elsestat;
                        negated = true;
                    }
                    else
                    {
                        ifstat = null;
                    }
                    elsestat = null;
                }
                else if (elsestat == post)
                {
                    elsestat = null;
                }
                else
                {
                    post = postst;
                }
                if (elsestat == null)
                {
                    regedges = 1;
                }
                break;
            }
            }
            // if without else
            ifedge   = lstHeadSuccs[negated ? 0 : 1];
            elseedge = (regedges == 2) ? lstHeadSuccs[negated ? 1 : 0] : null;
            iftype   = (regedges == 2) ? Iftype_Ifelse : Iftype_If;
            if (iftype == Iftype_If)
            {
                if (regedges == 0)
                {
                    StatEdge edge = lstHeadSuccs[0];
                    head.RemoveSuccessor(edge);
                    edge.SetSource(this);
                    this.AddSuccessor(edge);
                }
                else if (regedges == 1)
                {
                    StatEdge edge = lstHeadSuccs[negated ? 1 : 0];
                    head.RemoveSuccessor(edge);
                }
            }
            if (ifstat != null)
            {
                stats.AddWithKey(ifstat, ifstat.id);
            }
            if (elsestat != null)
            {
                stats.AddWithKey(elsestat, elsestat.id);
            }
            if (post == head)
            {
                post = this;
            }
        }