Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
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.º 3
0
        private static void InsertSemaphore(ControlFlowGraph graph, HashSet <BasicBlock> setTry
                                            , BasicBlock head, BasicBlock handler, int var, FinallyProcessor.Record information
                                            , int bytecode_version)
        {
            HashSet <BasicBlock> setCopy = new HashSet <BasicBlock>(setTry);
            int finallytype = information.firstCode;
            Dictionary <BasicBlock, bool> mapLast = information.mapLast;

            // first and last statements
            RemoveExceptionInstructionsEx(handler, 1, finallytype);
            foreach (KeyValuePair <BasicBlock, bool> entry in mapLast)
            {
                BasicBlock last = entry.Key;
                if (entry.Value)
                {
                    RemoveExceptionInstructionsEx(last, 2, finallytype);
                    graph.GetFinallyExits().Add(last);
                }
            }
            // disable semaphore at statement exit points
            foreach (BasicBlock block in setTry)
            {
                List <BasicBlock> lstSucc = block.GetSuccs();
                foreach (BasicBlock dest in lstSucc)
                {
                    // break out
                    if (dest != graph.GetLast() && !setCopy.Contains(dest))
                    {
                        // disable semaphore
                        SimpleInstructionSequence seq = new SimpleInstructionSequence();
                        seq.AddInstruction(Instruction.Create(ICodeConstants.opc_bipush, false, ICodeConstants
                                                              .Group_General, bytecode_version, new int[] { 0 }), -1);
                        seq.AddInstruction(Instruction.Create(ICodeConstants.opc_istore, false, ICodeConstants
                                                              .Group_General, bytecode_version, new int[] { var }), -1);
                        // build a separate block
                        BasicBlock newblock = new BasicBlock(++graph.last_id);
                        newblock.SetSeq(seq);
                        // insert between block and dest
                        block.ReplaceSuccessor(dest, newblock);
                        newblock.AddSuccessor(dest);
                        setCopy.Add(newblock);
                        graph.GetBlocks().AddWithKey(newblock, newblock.id);
                        // exception ranges
                        // FIXME: special case synchronized
                        // copy exception edges and extend protected ranges
                        for (int j = 0; j < block.GetSuccExceptions().Count; j++)
                        {
                            BasicBlock hd = block.GetSuccExceptions()[j];
                            newblock.AddSuccessorException(hd);
                            ExceptionRangeCFG range = graph.GetExceptionRange(hd, block);
                            range.GetProtectedRange().Add(newblock);
                        }
                    }
                }
            }
            // enable semaphore at the statement entrance
            SimpleInstructionSequence seq_1 = new SimpleInstructionSequence();

            seq_1.AddInstruction(Instruction.Create(ICodeConstants.opc_bipush, false, ICodeConstants
                                                    .Group_General, bytecode_version, new int[] { 1 }), -1);
            seq_1.AddInstruction(Instruction.Create(ICodeConstants.opc_istore, false, ICodeConstants
                                                    .Group_General, bytecode_version, new int[] { var }), -1);
            BasicBlock newhead = new BasicBlock(++graph.last_id);

            newhead.SetSeq(seq_1);
            InsertBlockBefore(graph, head, newhead);
            // initialize semaphor with false
            seq_1 = new SimpleInstructionSequence();
            seq_1.AddInstruction(Instruction.Create(ICodeConstants.opc_bipush, false, ICodeConstants
                                                    .Group_General, bytecode_version, new int[] { 0 }), -1);
            seq_1.AddInstruction(Instruction.Create(ICodeConstants.opc_istore, false, ICodeConstants
                                                    .Group_General, bytecode_version, new int[] { var }), -1);
            BasicBlock newheadinit = new BasicBlock(++graph.last_id);

            newheadinit.SetSeq(seq_1);
            InsertBlockBefore(graph, newhead, newheadinit);
            setCopy.Add(newhead);
            setCopy.Add(newheadinit);
            foreach (BasicBlock hd in new HashSet <BasicBlock>(newheadinit.GetSuccExceptions()
                                                               ))
            {
                ExceptionRangeCFG range = graph.GetExceptionRange(hd, newheadinit);
                if (setCopy.ContainsAll(range.GetProtectedRange()))
                {
                    newheadinit.RemoveSuccessorException(hd);
                    range.GetProtectedRange().Remove(newheadinit);
                }
            }
        }