示例#1
0
 public virtual void InlineJsr(StructMethod mt)
 {
     ProcessJsr();
     RemoveJsr(mt);
     RemoveMarkers();
     DeadCodeHelper.RemoveEmptyBlocks(this);
 }
示例#2
0
        private static BasicBlock GetUniqueNext(ControlFlowGraph graph, HashSet <BasicBlock
                                                                                 []> setNext)
        {
            // precondition: there is at most one true exit path in a finally statement
            BasicBlock next     = null;
            bool       multiple = false;

            foreach (BasicBlock[] arr in setNext)
            {
                if (arr[2] != null)
                {
                    next     = arr[1];
                    multiple = false;
                    break;
                }
                else
                {
                    if (next == null)
                    {
                        next = arr[1];
                    }
                    else if (next != arr[1])
                    {
                        multiple = true;
                    }
                    if (arr[1].GetPreds().Count == 1)
                    {
                        next = arr[1];
                    }
                }
            }
            if (multiple)
            {
                // TODO: generic solution
                foreach (BasicBlock[] arr in setNext)
                {
                    BasicBlock block = arr[1];
                    if (block != next)
                    {
                        if (InterpreterUtil.EqualSets(next.GetSuccs(), block.GetSuccs()))
                        {
                            InstructionSequence seqNext  = next.GetSeq();
                            InstructionSequence seqBlock = block.GetSeq();
                            if (seqNext.Length() == seqBlock.Length())
                            {
                                for (int i = 0; i < seqNext.Length(); i++)
                                {
                                    Instruction instrNext  = seqNext.GetInstr(i);
                                    Instruction instrBlock = seqBlock.GetInstr(i);
                                    if (!Instruction.Equals(instrNext, instrBlock))
                                    {
                                        return(null);
                                    }
                                    for (int j = 0; j < instrNext.OperandsCount(); j++)
                                    {
                                        if (instrNext.Operand(j) != instrBlock.Operand(j))
                                        {
                                            return(null);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                return(null);
                            }
                        }
                        else
                        {
                            return(null);
                        }
                    }
                }
                //			try {
                //				DotExporter.toDotFile(graph, new File("c:\\Temp\\fern5.dot"), true);
                //			} catch(IOException ex) {
                //				ex.printStackTrace();
                //			}
                foreach (BasicBlock[] arr in setNext)
                {
                    if (arr[1] != next)
                    {
                        // FIXME: exception edge possible?
                        arr[0].RemoveSuccessor(arr[1]);
                        arr[0].AddSuccessor(next);
                    }
                }
                DeadCodeHelper.RemoveDeadBlocks(graph);
            }
            return(next);
        }
示例#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);
        }
示例#4
0
        private HashSet <BasicBlock> GetJsrRange(BasicBlock jsr, BasicBlock ret)
        {
            HashSet <BasicBlock> blocks   = new HashSet <BasicBlock>();
            List <BasicBlock>    lstNodes = new List <BasicBlock>();

            lstNodes.Add(jsr);
            BasicBlock dom = jsr.GetSuccs()[0];

            while (!(lstNodes.Count == 0))
            {
                BasicBlock node = lstNodes.RemoveAtReturningValue(0);
                for (int j = 0; j < 2; j++)
                {
                    List <BasicBlock> lst;
                    if (j == 0)
                    {
                        if (node.GetLastInstruction().opcode == ICodeConstants.opc_ret)
                        {
                            if (node.GetSuccs().Contains(ret))
                            {
                                continue;
                            }
                        }
                        lst = node.GetSuccs();
                    }
                    else
                    {
                        if (node == jsr)
                        {
                            continue;
                        }
                        lst = node.GetSuccExceptions();
                    }
                    for (int i = lst.Count - 1; i >= 0; i--)
                    {
                        BasicBlock child = lst[i];
                        if (!blocks.Contains(child))
                        {
                            if (node != jsr)
                            {
                                for (int k = 0; k < child.GetPreds().Count; k++)
                                {
                                    if (!DeadCodeHelper.IsDominator(this, child.GetPreds()[k], dom))
                                    {
                                        goto CHILD_continue;
                                    }
                                }
                                for (int k = 0; k < child.GetPredExceptions().Count; k++)
                                {
                                    if (!DeadCodeHelper.IsDominator(this, child.GetPredExceptions()[k], dom))
                                    {
                                        goto CHILD_continue;
                                    }
                                }
                            }
                            // last block is a dummy one
                            if (child != last)
                            {
                                blocks.Add(child);
                            }
                            lstNodes.Add(child);
                        }
                        CHILD_continue :;
                    }
                    CHILD_break :;
                }
            }
            return(blocks);
        }
        /// <exception cref="System.IO.IOException"/>
        public static RootStatement CodeToJava(StructMethod mt, MethodDescriptor md, VarProcessor
                                               varProc)
        {
            StructClass cl            = mt.GetClassStruct();
            bool        isInitializer = ICodeConstants.Clinit_Name.Equals(mt.GetName());

            // for now static initializer only
            mt.ExpandData();
            InstructionSequence seq   = mt.GetInstructionSequence();
            ControlFlowGraph    graph = new ControlFlowGraph(seq);

            DeadCodeHelper.RemoveDeadBlocks(graph);
            graph.InlineJsr(mt);
            // TODO: move to the start, before jsr inlining
            DeadCodeHelper.ConnectDummyExitBlock(graph);
            DeadCodeHelper.RemoveGotos(graph);
            ExceptionDeobfuscator.RemoveCircularRanges(graph);
            ExceptionDeobfuscator.RestorePopRanges(graph);
            if (DecompilerContext.GetOption(IFernflowerPreferences.Remove_Empty_Ranges))
            {
                ExceptionDeobfuscator.RemoveEmptyRanges(graph);
            }
            if (DecompilerContext.GetOption(IFernflowerPreferences.Ensure_Synchronized_Monitor
                                            ))
            {
                // special case: search for 'synchronized' ranges w/o monitorexit instruction (as generated by Kotlin and Scala)
                DeadCodeHelper.ExtendSynchronizedRangeToMonitorexit(graph);
            }
            if (DecompilerContext.GetOption(IFernflowerPreferences.No_Exceptions_Return))
            {
                // special case: single return instruction outside of a protected range
                DeadCodeHelper.IncorporateValueReturns(graph);
            }
            //		ExceptionDeobfuscator.restorePopRanges(graph);
            ExceptionDeobfuscator.InsertEmptyExceptionHandlerBlocks(graph);
            DeadCodeHelper.MergeBasicBlocks(graph);
            DecompilerContext.GetCounterContainer().SetCounter(CounterContainer.Var_Counter,
                                                               mt.GetLocalVariables());
            if (ExceptionDeobfuscator.HasObfuscatedExceptions(graph))
            {
                DecompilerContext.GetLogger().WriteMessage("Heavily obfuscated exception ranges found!"
                                                           , IFernflowerLogger.Severity.Warn);
                if (!ExceptionDeobfuscator.HandleMultipleEntryExceptionRanges(graph))
                {
                    DecompilerContext.GetLogger().WriteMessage("Found multiple entry exception ranges which could not be splitted"
                                                               , IFernflowerLogger.Severity.Warn);
                }
                ExceptionDeobfuscator.InsertDummyExceptionHandlerBlocks(graph, cl.GetBytecodeVersion
                                                                            ());
            }
            RootStatement    root  = DomHelper.ParseGraph(graph);
            FinallyProcessor fProc = new FinallyProcessor(md, varProc);

            while (fProc.IterateGraph(mt, root, graph))
            {
                root = DomHelper.ParseGraph(graph);
            }
            // remove synchronized exception handler
            // not until now because of comparison between synchronized statements in the finally cycle
            DomHelper.RemoveSynchronizedHandler(root);
            //		LabelHelper.lowContinueLabels(root, new HashSet<StatEdge>());
            SequenceHelper.CondenseSequences(root);
            ClearStructHelper.ClearStatements(root);
            ExprProcessor proc = new ExprProcessor(md, varProc);

            proc.ProcessStatement(root, cl);
            SequenceHelper.CondenseSequences(root);
            StackVarsProcessor stackProc = new StackVarsProcessor();

            do
            {
                stackProc.SimplifyStackVars(root, mt, cl);
                varProc.SetVarVersions(root);
            }while (new PPandMMHelper().FindPPandMM(root));
            while (true)
            {
                LabelHelper.CleanUpEdges(root);
                do
                {
                    MergeHelper.EnhanceLoops(root);
                }while (LoopExtractHelper.ExtractLoops(root) || IfHelper.MergeAllIfs(root));
                if (DecompilerContext.GetOption(IFernflowerPreferences.Idea_Not_Null_Annotation))
                {
                    if (IdeaNotNullHelper.RemoveHardcodedChecks(root, mt))
                    {
                        SequenceHelper.CondenseSequences(root);
                        stackProc.SimplifyStackVars(root, mt, cl);
                        varProc.SetVarVersions(root);
                    }
                }
                LabelHelper.IdentifyLabels(root);
                if (InlineSingleBlockHelper.InlineSingleBlocks(root))
                {
                    continue;
                }
                // initializer may have at most one return point, so no transformation of method exits permitted
                if (isInitializer || !ExitHelper.CondenseExits(root))
                {
                    break;
                }
            }
            // FIXME: !!
            //if(!EliminateLoopsHelper.eliminateLoops(root)) {
            //  break;
            //}
            ExitHelper.RemoveRedundantReturns(root);
            SecondaryFunctionsHelper.IdentifySecondaryFunctions(root, varProc);
            varProc.SetVarDefinitions(root);
            // must be the last invocation, because it makes the statement structure inconsistent
            // FIXME: new edge type needed
            LabelHelper.ReplaceContinueWithBreak(root);
            mt.ReleaseResources();
            return(root);
        }