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); }