Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
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;
             }
         }
     }
 }
Ejemplo n.º 3
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);
        }