Exemplo n.º 1
0
        private static Statement DetectStatement(Statement head)
        {
            Statement res;

            if ((res = DoStatement.IsHead(head)) != null)
            {
                return(res);
            }
            if ((res = SwitchStatement.IsHead(head)) != null)
            {
                return(res);
            }
            if ((res = IfStatement.IsHead(head)) != null)
            {
                return(res);
            }
            // synchronized statements will be identified later
            // right now they are recognized as catchall
            if ((res = SequenceStatement.IsHead2Block(head)) != null)
            {
                return(res);
            }
            if ((res = CatchStatement.IsHead(head)) != null)
            {
                return(res);
            }
            if ((res = CatchAllStatement.IsHead(head)) != null)
            {
                return(res);
            }
            return(null);
        }
Exemplo n.º 2
0
 internal StackEntry(CatchAllStatement catchstatement, bool state, int edgetype, Statement
                     destination, Statement finallyShortRangeEntry, Statement finallyLongRangeEntry,
                     DirectNode finallyShortRangeSource, DirectNode finallyLongRangeSource, bool isFinallyExceptionPath
                     )
 {
     this.catchstatement          = catchstatement;
     this.state                   = state;
     this.edgetype                = edgetype;
     this.isFinallyExceptionPath  = isFinallyExceptionPath;
     this.destination             = destination;
     this.finallyShortRangeEntry  = finallyShortRangeEntry;
     this.finallyLongRangeEntry   = finallyLongRangeEntry;
     this.finallyShortRangeSource = finallyShortRangeSource;
     this.finallyLongRangeSource  = finallyLongRangeSource;
 }
Exemplo n.º 3
0
 internal StackEntry(CatchAllStatement catchstatement, bool state)
     : this(catchstatement, state, -1, null, null, null, null, null, false)
 {
 }
Exemplo n.º 4
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 :;
        }
Exemplo n.º 5
0
 private static void BuildSynchronized(Statement stat)
 {
     foreach (Statement st in stat.GetStats())
     {
         BuildSynchronized(st);
     }
     if (stat.type == Statement.Type_Sequence)
     {
         while (true)
         {
             bool             found = false;
             List <Statement> lst   = stat.GetStats();
             for (int i = 0; i < lst.Count - 1; i++)
             {
                 Statement current = lst[i];
                 // basic block
                 if (current.IsMonitorEnter())
                 {
                     Statement next       = lst[i + 1];
                     Statement nextDirect = next;
                     while (next.type == Statement.Type_Sequence)
                     {
                         next = next.GetFirst();
                     }
                     if (next.type == Statement.Type_Catchall)
                     {
                         CatchAllStatement ca = (CatchAllStatement)next;
                         if (ca.GetFirst().IsContainsMonitorExit() && ca.GetHandler().IsContainsMonitorExit
                                 ())
                         {
                             // remove the head block from sequence
                             current.RemoveSuccessor(current.GetSuccessorEdges(Statement.Statedge_Direct_All)[
                                                         0]);
                             foreach (StatEdge edge in current.GetPredecessorEdges(Statement.Statedge_Direct_All
                                                                                   ))
                             {
                                 current.RemovePredecessor(edge);
                                 edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, nextDirect);
                                 nextDirect.AddPredecessor(edge);
                             }
                             stat.GetStats().RemoveWithKey(current.id);
                             stat.SetFirst(stat.GetStats()[0]);
                             // new statement
                             SynchronizedStatement sync = new SynchronizedStatement(current, ca.GetFirst(), ca
                                                                                    .GetHandler());
                             sync.SetAllParent();
                             foreach (StatEdge edge in new HashSet <StatEdge>(ca.GetLabelEdges()))
                             {
                                 sync.AddLabeledEdge(edge);
                             }
                             current.AddSuccessor(new StatEdge(StatEdge.Type_Regular, current, ca.GetFirst()));
                             ca.GetParent().ReplaceStatement(ca, sync);
                             found = true;
                             break;
                         }
                     }
                 }
             }
             if (!found)
             {
                 break;
             }
         }
     }
 }
Exemplo n.º 6
0
        private bool VerifyFinallyEx(ControlFlowGraph graph, CatchAllStatement fstat, FinallyProcessor.Record
                                     information)
        {
            HashSet <BasicBlock> tryBlocks   = GetAllBasicBlocks(fstat.GetFirst());
            HashSet <BasicBlock> catchBlocks = GetAllBasicBlocks(fstat.GetHandler());
            int finallytype = information.firstCode;
            Dictionary <BasicBlock, bool> mapLast = information.mapLast;
            BasicBlock first        = fstat.GetHandler().GetBasichead().GetBlock();
            bool       skippedFirst = false;

            if (finallytype == 3)
            {
                // empty finally
                RemoveExceptionInstructionsEx(first, 3, finallytype);
                if (mapLast.ContainsKey(first))
                {
                    graph.GetFinallyExits().Add(first);
                }
                return(true);
            }
            else if (first.GetSeq().Length() == 1 && finallytype > 0)
            {
                BasicBlock firstsuc = first.GetSuccs()[0];
                if (catchBlocks.Contains(firstsuc))
                {
                    first        = firstsuc;
                    skippedFirst = true;
                }
            }
            // identify start blocks
            HashSet <BasicBlock> startBlocks = new HashSet <BasicBlock>();

            foreach (BasicBlock block in tryBlocks)
            {
                Sharpen.Collections.AddAll(startBlocks, block.GetSuccs());
            }
            // throw in the try body will point directly to the dummy exit
            // so remove dummy exit
            startBlocks.Remove(graph.GetLast());
            startBlocks.RemoveAll(tryBlocks);
            List <FinallyProcessor.Area> lstAreas = new List <FinallyProcessor.Area>();

            foreach (BasicBlock start in startBlocks)
            {
                FinallyProcessor.Area arr = CompareSubgraphsEx(graph, start, catchBlocks, first,
                                                               finallytype, mapLast, skippedFirst);
                if (arr == null)
                {
                    return(false);
                }
                lstAreas.Add(arr);
            }
            //		try {
            //			DotExporter.toDotFile(graph, new File("c:\\Temp\\fern5.dot"), true);
            //		} catch(Exception ex){ex.printStackTrace();}
            // delete areas
            foreach (FinallyProcessor.Area area in lstAreas)
            {
                DeleteArea(graph, area);
            }
            //		try {
            //			DotExporter.toDotFile(graph, new File("c:\\Temp\\fern5.dot"), true);
            //		} catch(Exception ex){ex.printStackTrace();}
            // INFO: empty basic blocks may remain in the graph!
            foreach (KeyValuePair <BasicBlock, bool> entry in mapLast)
            {
                BasicBlock last = entry.Key;
                if (entry.Value)
                {
                    RemoveExceptionInstructionsEx(last, 2, finallytype);
                    graph.GetFinallyExits().Add(last);
                }
            }
            RemoveExceptionInstructionsEx(fstat.GetHandler().GetBasichead().GetBlock(), 1, finallytype
                                          );
            return(true);
        }
Exemplo n.º 7
0
        private bool ProcessStatementEx(StructMethod mt, RootStatement root, ControlFlowGraph
                                        graph)
        {
            int bytecode_version         = mt.GetClassStruct().GetBytecodeVersion();
            LinkedList <Statement> stack = new LinkedList <Statement>();

            stack.AddLast(root);
            while (!(stack.Count == 0))
            {
                Statement stat   = Sharpen.Collections.RemoveLast(stack);
                Statement parent = stat.GetParent();
                if (parent != null && parent.type == Statement.Type_Catchall && stat == parent.GetFirst
                        () && !parent.IsCopied())
                {
                    CatchAllStatement fin     = (CatchAllStatement)parent;
                    BasicBlock        head    = fin.GetBasichead().GetBlock();
                    BasicBlock        handler = fin.GetHandler().GetBasichead().GetBlock();
                    if (catchallBlockIDs.ContainsKey(handler.id))
                    {
                    }
                    else if (finallyBlockIDs.ContainsKey(handler.id))
                    {
                        // do nothing
                        fin.SetFinally(true);
                        int?var = finallyBlockIDs.GetOrNullable(handler.id);
                        fin.SetMonitor(var == null ? null : new VarExprent(var.Value, VarType.Vartype_Int
                                                                           , varProcessor));
                    }
                    else
                    {
                        FinallyProcessor.Record inf = GetFinallyInformation(mt, root, fin);
                        if (inf == null)
                        {
                            // inconsistent finally
                            Sharpen.Collections.Put(catchallBlockIDs, handler.id, null);
                        }
                        else
                        {
                            if (DecompilerContext.GetOption(IFernflowerPreferences.Finally_Deinline) && VerifyFinallyEx
                                    (graph, fin, inf))
                            {
                                Sharpen.Collections.Put(finallyBlockIDs, handler.id, null);
                            }
                            else
                            {
                                int varindex = DecompilerContext.GetCounterContainer().GetCounterAndIncrement(CounterContainer
                                                                                                              .Var_Counter);
                                InsertSemaphore(graph, GetAllBasicBlocks(fin.GetFirst()), head, handler, varindex
                                                , inf, bytecode_version);
                                Sharpen.Collections.Put(finallyBlockIDs, handler.id, varindex);
                            }
                            DeadCodeHelper.RemoveDeadBlocks(graph);
                            // e.g. multiple return blocks after a nested finally
                            DeadCodeHelper.RemoveEmptyBlocks(graph);
                            DeadCodeHelper.MergeBasicBlocks(graph);
                        }
                        return(true);
                    }
                }
                Sharpen.Collections.AddAll(stack, stat.GetStats());
            }
            return(false);
        }
Exemplo n.º 8
0
        private FinallyProcessor.Record GetFinallyInformation(StructMethod mt, RootStatement
                                                              root, CatchAllStatement fstat)
        {
            Dictionary <BasicBlock, bool> mapLast             = new Dictionary <BasicBlock, bool>();
            BasicBlockStatement           firstBlockStatement = fstat.GetHandler().GetBasichead();
            BasicBlock  firstBasicBlock = firstBlockStatement.GetBlock();
            Instruction instrFirst      = firstBasicBlock.GetInstruction(0);
            int         firstcode       = 0;

            switch (instrFirst.opcode)
            {
            case ICodeConstants.opc_pop:
            {
                firstcode = 1;
                break;
            }

            case ICodeConstants.opc_astore:
            {
                firstcode = 2;
                break;
            }
            }
            ExprProcessor proc = new ExprProcessor(methodDescriptor, varProcessor);

            proc.ProcessStatement(root, mt.GetClassStruct());
            SSAConstructorSparseEx ssa = new SSAConstructorSparseEx();

            ssa.SplitVariables(root, mt);
            List <Exprent> lstExprents = firstBlockStatement.GetExprents();
            VarVersionPair varpaar     = new VarVersionPair((VarExprent)((AssignmentExprent)lstExprents
                                                                         [firstcode == 2 ? 1 : 0]).GetLeft());
            FlattenStatementsHelper flatthelper = new FlattenStatementsHelper();
            DirectGraph             dgraph      = flatthelper.BuildDirectGraph(root);
            LinkedList <DirectNode> stack       = new LinkedList <DirectNode>();

            stack.AddLast(dgraph.first);
            HashSet <DirectNode> setVisited = new HashSet <DirectNode>();

            while (!(stack.Count == 0))
            {
                DirectNode node = Sharpen.Collections.RemoveFirst(stack);
                if (setVisited.Contains(node))
                {
                    continue;
                }
                setVisited.Add(node);
                BasicBlockStatement blockStatement = null;
                if (node.block != null)
                {
                    blockStatement = node.block;
                }
                else if (node.preds.Count == 1)
                {
                    blockStatement = node.preds[0].block;
                }
                bool isTrueExit = true;
                if (firstcode != 1)
                {
                    isTrueExit = false;
                    for (int i = 0; i < node.exprents.Count; i++)
                    {
                        Exprent exprent = node.exprents[i];
                        if (firstcode == 0)
                        {
                            List <Exprent> lst = exprent.GetAllExprents();
                            lst.Add(exprent);
                            bool found = false;
                            foreach (Exprent expr in lst)
                            {
                                if (expr.type == Exprent.Exprent_Var && new VarVersionPair((VarExprent)expr).Equals
                                        (varpaar))
                                {
                                    found = true;
                                    break;
                                }
                            }
                            if (found)
                            {
                                found = false;
                                if (exprent.type == Exprent.Exprent_Exit)
                                {
                                    ExitExprent exexpr = (ExitExprent)exprent;
                                    if (exexpr.GetExitType() == ExitExprent.Exit_Throw && exexpr.GetValue().type == Exprent
                                        .Exprent_Var)
                                    {
                                        found = true;
                                    }
                                }
                                if (!found)
                                {
                                    return(null);
                                }
                                else
                                {
                                    isTrueExit = true;
                                }
                            }
                        }
                        else if (firstcode == 2)
                        {
                            // search for a load instruction
                            if (exprent.type == Exprent.Exprent_Assignment)
                            {
                                AssignmentExprent assexpr = (AssignmentExprent)exprent;
                                if (assexpr.GetRight().type == Exprent.Exprent_Var && new VarVersionPair((VarExprent
                                                                                                          )assexpr.GetRight()).Equals(varpaar))
                                {
                                    Exprent next = null;
                                    if (i == node.exprents.Count - 1)
                                    {
                                        if (node.succs.Count == 1)
                                        {
                                            DirectNode nd = node.succs[0];
                                            if (!(nd.exprents.Count == 0))
                                            {
                                                next = nd.exprents[0];
                                            }
                                        }
                                    }
                                    else
                                    {
                                        next = node.exprents[i + 1];
                                    }
                                    bool found = false;
                                    if (next != null && next.type == Exprent.Exprent_Exit)
                                    {
                                        ExitExprent exexpr = (ExitExprent)next;
                                        if (exexpr.GetExitType() == ExitExprent.Exit_Throw && exexpr.GetValue().type == Exprent
                                            .Exprent_Var && assexpr.GetLeft().Equals(exexpr.GetValue()))
                                        {
                                            found = true;
                                        }
                                    }
                                    if (!found)
                                    {
                                        return(null);
                                    }
                                    else
                                    {
                                        isTrueExit = true;
                                    }
                                }
                            }
                        }
                    }
                }
                // find finally exits
                if (blockStatement != null && blockStatement.GetBlock() != null)
                {
                    Statement handler = fstat.GetHandler();
                    foreach (StatEdge edge in blockStatement.GetSuccessorEdges(Statement.Statedge_Direct_All
                                                                               ))
                    {
                        if (edge.GetType() != StatEdge.Type_Regular && handler.ContainsStatement(blockStatement
                                                                                                 ) && !handler.ContainsStatement(edge.GetDestination()))
                        {
                            bool?existingFlag = mapLast.GetOrNullable(blockStatement.GetBlock());
                            // note: the dummy node is also processed!
                            if (existingFlag == null || !existingFlag.Value)
                            {
                                Sharpen.Collections.Put(mapLast, blockStatement.GetBlock(), isTrueExit);
                                break;
                            }
                        }
                    }
                }
                Sharpen.Collections.AddAll(stack, node.succs);
            }
            // empty finally block?
            if (fstat.GetHandler().type == Statement.Type_Basicblock)
            {
                bool isEmpty            = false;
                bool isFirstLast        = mapLast.ContainsKey(firstBasicBlock);
                InstructionSequence seq = firstBasicBlock.GetSeq();
                switch (firstcode)
                {
                case 0:
                {
                    isEmpty = isFirstLast && seq.Length() == 1;
                    break;
                }

                case 1:
                {
                    isEmpty = seq.Length() == 1;
                    break;
                }

                case 2:
                {
                    isEmpty = isFirstLast ? seq.Length() == 3 : seq.Length() == 1;
                    break;
                }
                }
                if (isEmpty)
                {
                    firstcode = 3;
                }
            }
            return(new FinallyProcessor.Record(firstcode, mapLast));
        }
Exemplo n.º 9
0
        private HashSet <int> InitStatement(Statement stat)
        {
            Dictionary <int, int> mapCount = new Dictionary <int, int>();
            List <VarExprent>     condlst;

            if (stat.GetExprents() == null)
            {
                // recurse on children statements
                List <int>     childVars = new List <int>();
                List <Exprent> currVars  = new List <Exprent>();
                foreach (object obj in stat.GetSequentialObjects())
                {
                    if (obj is Statement)
                    {
                        Statement st = (Statement)obj;
                        Sharpen.Collections.AddAll(childVars, InitStatement(st));
                        if (st.type == DoStatement.Type_Do)
                        {
                            DoStatement dost = (DoStatement)st;
                            if (dost.GetLooptype() != DoStatement.Loop_For && dost.GetLooptype() != DoStatement
                                .Loop_Do)
                            {
                                currVars.Add(dost.GetConditionExprent());
                            }
                        }
                        else if (st.type == DoStatement.Type_Catchall)
                        {
                            CatchAllStatement fin = (CatchAllStatement)st;
                            if (fin.IsFinally() && fin.GetMonitor() != null)
                            {
                                currVars.Add(fin.GetMonitor());
                            }
                        }
                    }
                    else if (obj is Exprent)
                    {
                        currVars.Add((Exprent)obj);
                    }
                }
                // children statements
                foreach (int index in childVars)
                {
                    int?count = mapCount.GetOrNullable(index);
                    if (count == null)
                    {
                        count = 0;
                    }
                    Sharpen.Collections.Put(mapCount, index, count.Value + 1);
                }
                condlst = GetAllVars(currVars);
            }
            else
            {
                condlst = GetAllVars(stat.GetExprents());
            }
            // this statement
            foreach (VarExprent var in condlst)
            {
                Sharpen.Collections.Put(mapCount, var.GetIndex(), 2);
            }
            HashSet <int> set = new HashSet <int>(mapCount.Keys);

            // put all variables defined in this statement into the set
            foreach (KeyValuePair <int, int> en in mapCount)
            {
                if (en.Value > 1)
                {
                    Sharpen.Collections.Put(mapVarDefStatements, en.Key, stat);
                }
            }
            Sharpen.Collections.Put(mapStatementVars, stat.id, set);
            return(set);
        }