Пример #1
0
        private static bool ReplaceAssertion(Statement parent, IfStatement stat, string classname
                                             , string key)
        {
            bool              throwInIf  = true;
            Statement         ifstat     = stat.GetIfstat();
            InvocationExprent throwError = IsAssertionError(ifstat);

            if (throwError == null)
            {
                //check else:
                Statement elsestat = stat.GetElsestat();
                throwError = IsAssertionError(elsestat);
                if (throwError == null)
                {
                    return(false);
                }
                else
                {
                    throwInIf = false;
                }
            }
            object[] exprres = GetAssertionExprent(stat.GetHeadexprent().GetCondition().Copy(
                                                       ), classname, key, throwInIf);
            if (!(bool)exprres[1])
            {
                return(false);
            }
            List <Exprent> lstParams = new List <Exprent>();
            Exprent        ascond    = null;
            Exprent        retcond   = null;

            if (throwInIf)
            {
                if (exprres[0] != null)
                {
                    ascond = new FunctionExprent(FunctionExprent.Function_Bool_Not, (Exprent)exprres[
                                                     0], throwError.bytecode);
                    retcond = SecondaryFunctionsHelper.PropagateBoolNot(ascond);
                }
            }
            else
            {
                ascond  = (Exprent)exprres[0];
                retcond = ascond;
            }
            lstParams.Add(retcond == null ? ascond : retcond);
            if (!(throwError.GetLstParameters().Count == 0))
            {
                lstParams.Add(throwError.GetLstParameters()[0]);
            }
            AssertExprent asexpr  = new AssertExprent(lstParams);
            Statement     newstat = new BasicBlockStatement(new BasicBlock(DecompilerContext.GetCounterContainer
                                                                               ().GetCounterAndIncrement(CounterContainer.Statement_Counter)));

            newstat.SetExprents(Sharpen.Arrays.AsList(new Exprent[] { asexpr }));
            Statement first = stat.GetFirst();

            if (stat.iftype == IfStatement.Iftype_Ifelse || (first.GetExprents() != null && !
                                                             (first.GetExprents().Count == 0)))
            {
                first.RemoveSuccessor(stat.GetIfEdge());
                first.RemoveSuccessor(stat.GetElseEdge());
                List <Statement> lstStatements = new List <Statement>();
                if (first.GetExprents() != null && !(first.GetExprents().Count == 0))
                {
                    lstStatements.Add(first);
                }
                lstStatements.Add(newstat);
                if (stat.iftype == IfStatement.Iftype_Ifelse)
                {
                    if (throwInIf)
                    {
                        lstStatements.Add(stat.GetElsestat());
                    }
                    else
                    {
                        lstStatements.Add(stat.GetIfstat());
                    }
                }
                SequenceStatement sequence = new SequenceStatement(lstStatements);
                sequence.SetAllParent();
                for (int i = 0; i < sequence.GetStats().Count - 1; i++)
                {
                    sequence.GetStats()[i].AddSuccessor(new StatEdge(StatEdge.Type_Regular, sequence.
                                                                     GetStats()[i], sequence.GetStats()[i + 1]));
                }
                if (stat.iftype == IfStatement.Iftype_Ifelse || !throwInIf)
                {
                    Statement stmts;
                    if (throwInIf)
                    {
                        stmts = stat.GetElsestat();
                    }
                    else
                    {
                        stmts = stat.GetIfstat();
                    }
                    List <StatEdge> lstSuccs = stmts.GetAllSuccessorEdges();
                    if (!(lstSuccs.Count == 0))
                    {
                        StatEdge endedge = lstSuccs[0];
                        if (endedge.closure == stat)
                        {
                            sequence.AddLabeledEdge(endedge);
                        }
                    }
                }
                newstat = sequence;
            }
            Sharpen.Collections.AddAll(newstat.GetVarDefinitions(), stat.GetVarDefinitions());
            parent.ReplaceStatement(stat, newstat);
            return(true);
        }
        /// <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);
        }