private static void RemoveLastEmptyStatement(DoStatement dostat, Statement stat) { if (stat == dostat.GetFirst()) { BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter ))); bstat.SetExprents(new List <Exprent>()); dostat.ReplaceStatement(stat, bstat); } else { foreach (StatEdge edge in stat.GetAllPredecessorEdges()) { edge.GetSource().ChangeEdgeType(Statement.Direction_Forward, edge, StatEdge.Type_Continue ); stat.RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, dostat); dostat.AddPredecessor(edge); dostat.AddLabeledEdge(edge); } // parent is a sequence statement stat.GetParent().GetStats().RemoveWithKey(stat.id); } }
public DirectNode(int type, Statement statement, BasicBlockStatement block) { this.type = type; this.statement = statement; this.id = block.id.ToString(); this.block = block; }
public static void DestroyAndFlattenStatement(Statement stat) { DestroyStatementContent(stat, false); BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter ))); if (stat.GetExprents() == null) { bstat.SetExprents(new List <Exprent>()); } else { bstat.SetExprents(DecHelper.CopyExprentList(stat.GetExprents())); } stat.GetParent().ReplaceStatement(stat, bstat); }
private static void MapClassMethods(ClassesProcessor.ClassNode node, Dictionary < ClassWrapper, MethodWrapper> map) { bool noSynthFlag = DecompilerContext.GetOption(IFernflowerPreferences.Synthetic_Not_Set ); ClassWrapper wrapper = node.GetWrapper(); foreach (MethodWrapper method in wrapper.GetMethods()) { StructMethod mt = method.methodStruct; if ((noSynthFlag || mt.IsSynthetic()) && mt.GetDescriptor().Equals("(Ljava/lang/String;)Ljava/lang/Class;" ) && mt.HasModifier(ICodeConstants.Acc_Static)) { RootStatement root = method.root; if (root != null && root.GetFirst().type == Statement.Type_Trycatch) { CatchStatement cst = (CatchStatement)root.GetFirst(); if (cst.GetStats().Count == 2 && cst.GetFirst().type == Statement.Type_Basicblock && cst.GetStats()[1].type == Statement.Type_Basicblock && cst.GetVars()[0].GetVarType ().Equals(new VarType(ICodeConstants.Type_Object, 0, "java/lang/ClassNotFoundException" ))) { BasicBlockStatement body = (BasicBlockStatement)cst.GetFirst(); BasicBlockStatement handler = (BasicBlockStatement)cst.GetStats()[1]; if (body.GetExprents().Count == 1 && handler.GetExprents().Count == 1) { if (Body_Expr.Equals(body.GetExprents()[0]) && Handler_Expr.Equals(handler.GetExprents ()[0])) { Sharpen.Collections.Put(map, wrapper, method); break; } } } } } } // iterate nested classes foreach (ClassesProcessor.ClassNode nd in node.nested) { MapClassMethods(nd, map); } }
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); }
private FinallyProcessor.Record GetFinallyInformation(StructMethod mt, RootStatement root, CatchAllStatement fstat) { Dictionary <BasicBlock, bool> mapLast = new Dictionary <BasicBlock, bool>(); BasicBlockStatement firstBlockStatement = fstat.GetHandler().GetBasichead(); BasicBlock firstBasicBlock = firstBlockStatement.GetBlock(); Instruction instrFirst = firstBasicBlock.GetInstruction(0); int firstcode = 0; switch (instrFirst.opcode) { case ICodeConstants.opc_pop: { firstcode = 1; break; } case ICodeConstants.opc_astore: { firstcode = 2; break; } } ExprProcessor proc = new ExprProcessor(methodDescriptor, varProcessor); proc.ProcessStatement(root, mt.GetClassStruct()); SSAConstructorSparseEx ssa = new SSAConstructorSparseEx(); ssa.SplitVariables(root, mt); List <Exprent> lstExprents = firstBlockStatement.GetExprents(); VarVersionPair varpaar = new VarVersionPair((VarExprent)((AssignmentExprent)lstExprents [firstcode == 2 ? 1 : 0]).GetLeft()); FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); DirectGraph dgraph = flatthelper.BuildDirectGraph(root); LinkedList <DirectNode> stack = new LinkedList <DirectNode>(); stack.AddLast(dgraph.first); HashSet <DirectNode> setVisited = new HashSet <DirectNode>(); while (!(stack.Count == 0)) { DirectNode node = Sharpen.Collections.RemoveFirst(stack); if (setVisited.Contains(node)) { continue; } setVisited.Add(node); BasicBlockStatement blockStatement = null; if (node.block != null) { blockStatement = node.block; } else if (node.preds.Count == 1) { blockStatement = node.preds[0].block; } bool isTrueExit = true; if (firstcode != 1) { isTrueExit = false; for (int i = 0; i < node.exprents.Count; i++) { Exprent exprent = node.exprents[i]; if (firstcode == 0) { List <Exprent> lst = exprent.GetAllExprents(); lst.Add(exprent); bool found = false; foreach (Exprent expr in lst) { if (expr.type == Exprent.Exprent_Var && new VarVersionPair((VarExprent)expr).Equals (varpaar)) { found = true; break; } } if (found) { found = false; if (exprent.type == Exprent.Exprent_Exit) { ExitExprent exexpr = (ExitExprent)exprent; if (exexpr.GetExitType() == ExitExprent.Exit_Throw && exexpr.GetValue().type == Exprent .Exprent_Var) { found = true; } } if (!found) { return(null); } else { isTrueExit = true; } } } else if (firstcode == 2) { // search for a load instruction if (exprent.type == Exprent.Exprent_Assignment) { AssignmentExprent assexpr = (AssignmentExprent)exprent; if (assexpr.GetRight().type == Exprent.Exprent_Var && new VarVersionPair((VarExprent )assexpr.GetRight()).Equals(varpaar)) { Exprent next = null; if (i == node.exprents.Count - 1) { if (node.succs.Count == 1) { DirectNode nd = node.succs[0]; if (!(nd.exprents.Count == 0)) { next = nd.exprents[0]; } } } else { next = node.exprents[i + 1]; } bool found = false; if (next != null && next.type == Exprent.Exprent_Exit) { ExitExprent exexpr = (ExitExprent)next; if (exexpr.GetExitType() == ExitExprent.Exit_Throw && exexpr.GetValue().type == Exprent .Exprent_Var && assexpr.GetLeft().Equals(exexpr.GetValue())) { found = true; } } if (!found) { return(null); } else { isTrueExit = true; } } } } } } // find finally exits if (blockStatement != null && blockStatement.GetBlock() != null) { Statement handler = fstat.GetHandler(); foreach (StatEdge edge in blockStatement.GetSuccessorEdges(Statement.Statedge_Direct_All )) { if (edge.GetType() != StatEdge.Type_Regular && handler.ContainsStatement(blockStatement ) && !handler.ContainsStatement(edge.GetDestination())) { bool?existingFlag = mapLast.GetOrNullable(blockStatement.GetBlock()); // note: the dummy node is also processed! if (existingFlag == null || !existingFlag.Value) { Sharpen.Collections.Put(mapLast, blockStatement.GetBlock(), isTrueExit); break; } } } } Sharpen.Collections.AddAll(stack, node.succs); } // empty finally block? if (fstat.GetHandler().type == Statement.Type_Basicblock) { bool isEmpty = false; bool isFirstLast = mapLast.ContainsKey(firstBasicBlock); InstructionSequence seq = firstBasicBlock.GetSeq(); switch (firstcode) { case 0: { isEmpty = isFirstLast && seq.Length() == 1; break; } case 1: { isEmpty = seq.Length() == 1; break; } case 2: { isEmpty = isFirstLast ? seq.Length() == 3 : seq.Length() == 1; break; } } if (isEmpty) { firstcode = 3; } } return(new FinallyProcessor.Record(firstcode, mapLast)); }
private static bool MatchWhile(DoStatement stat) { // search for an if condition at the entrance of the loop Statement first = stat.GetFirst(); while (first.type == Statement.Type_Sequence) { first = first.GetFirst(); } // found an if statement if (first.type == Statement.Type_If) { IfStatement firstif = (IfStatement)first; if ((firstif.GetFirst().GetExprents().Count == 0)) { if (firstif.iftype == IfStatement.Iftype_If) { if (firstif.GetIfstat() == null) { StatEdge ifedge = firstif.GetIfEdge(); if (IsDirectPath(stat, ifedge.GetDestination())) { // exit condition identified stat.SetLooptype(DoStatement.Loop_While); // negate condition (while header) IfExprent ifexpr = (IfExprent)firstif.GetHeadexprent().Copy(); ifexpr.NegateIf(); stat.SetConditionExprent(ifexpr.GetCondition()); // remove edges firstif.GetFirst().RemoveSuccessor(ifedge); firstif.RemoveSuccessor(firstif.GetAllSuccessorEdges()[0]); if ((stat.GetAllSuccessorEdges().Count == 0)) { ifedge.SetSource(stat); if (ifedge.closure == stat) { ifedge.closure = stat.GetParent(); } stat.AddSuccessor(ifedge); } // remove empty if statement as it is now part of the loop if (firstif == stat.GetFirst()) { BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter ))); bstat.SetExprents(new List <Exprent>()); stat.ReplaceStatement(firstif, bstat); } else { // precondition: sequence must contain more than one statement! Statement sequence = firstif.GetParent(); sequence.GetStats().RemoveWithKey(firstif.id); sequence.SetFirst(sequence.GetStats()[0]); } return(true); } } else { StatEdge elseedge = firstif.GetAllSuccessorEdges()[0]; if (IsDirectPath(stat, elseedge.GetDestination())) { // exit condition identified stat.SetLooptype(DoStatement.Loop_While); // no need to negate the while condition stat.SetConditionExprent(((IfExprent)firstif.GetHeadexprent().Copy()).GetCondition ()); // remove edges StatEdge ifedge = firstif.GetIfEdge(); firstif.GetFirst().RemoveSuccessor(ifedge); firstif.RemoveSuccessor(elseedge); if ((stat.GetAllSuccessorEdges().Count == 0)) { elseedge.SetSource(stat); if (elseedge.closure == stat) { elseedge.closure = stat.GetParent(); } stat.AddSuccessor(elseedge); } if (firstif.GetIfstat() == null) { BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter ))); bstat.SetExprents(new List <Exprent>()); ifedge.SetSource(bstat); bstat.AddSuccessor(ifedge); stat.ReplaceStatement(firstif, bstat); } else { // replace the if statement with its content first.GetParent().ReplaceStatement(first, firstif.GetIfstat()); // lift closures foreach (StatEdge prededge in elseedge.GetDestination().GetPredecessorEdges(StatEdge .Type_Break)) { if (stat.ContainsStatementStrict(prededge.closure)) { stat.AddLabeledEdge(prededge); } } LabelHelper.LowClosures(stat); } return(true); } } } } } return(false); }
private static int IntegrateExits(Statement stat) { int ret = 0; Statement dest; if (stat.GetExprents() == null) { while (true) { int changed = 0; foreach (Statement st in stat.GetStats()) { changed = IntegrateExits(st); if (changed > 0) { ret = 1; break; } } if (changed == 0) { break; } } if (stat.type == Statement.Type_If) { IfStatement ifst = (IfStatement)stat; if (ifst.GetIfstat() == null) { StatEdge ifedge = ifst.GetIfEdge(); dest = IsExitEdge(ifedge); if (dest != null) { BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter ))); bstat.SetExprents(DecHelper.CopyExprentList(dest.GetExprents())); ifst.GetFirst().RemoveSuccessor(ifedge); StatEdge newedge = new StatEdge(StatEdge.Type_Regular, ifst.GetFirst(), bstat); ifst.GetFirst().AddSuccessor(newedge); ifst.SetIfEdge(newedge); ifst.SetIfstat(bstat); ifst.GetStats().AddWithKey(bstat, bstat.id); bstat.SetParent(ifst); StatEdge oldexitedge = dest.GetAllSuccessorEdges()[0]; StatEdge newexitedge = new StatEdge(StatEdge.Type_Break, bstat, oldexitedge.GetDestination ()); bstat.AddSuccessor(newexitedge); oldexitedge.closure.AddLabeledEdge(newexitedge); ret = 1; } } } } if (stat.GetAllSuccessorEdges().Count == 1 && stat.GetAllSuccessorEdges()[0].GetType () == StatEdge.Type_Break && (stat.GetLabelEdges().Count == 0)) { Statement parent = stat.GetParent(); if (stat != parent.GetFirst() || (parent.type != Statement.Type_If && parent.type != Statement.Type_Switch)) { StatEdge destedge = stat.GetAllSuccessorEdges()[0]; dest = IsExitEdge(destedge); if (dest != null) { stat.RemoveSuccessor(destedge); BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter ))); bstat.SetExprents(DecHelper.CopyExprentList(dest.GetExprents())); StatEdge oldexitedge = dest.GetAllSuccessorEdges()[0]; StatEdge newexitedge = new StatEdge(StatEdge.Type_Break, bstat, oldexitedge.GetDestination ()); bstat.AddSuccessor(newexitedge); oldexitedge.closure.AddLabeledEdge(newexitedge); SequenceStatement block = new SequenceStatement(Sharpen.Arrays.AsList(stat, bstat )); block.SetAllParent(); parent.ReplaceStatement(stat, block); // LabelHelper.lowContinueLabels not applicable because of forward continue edges // LabelHelper.lowContinueLabels(block, new HashSet<StatEdge>()); // do it by hand foreach (StatEdge prededge in block.GetPredecessorEdges(StatEdge.Type_Continue)) { block.RemovePredecessor(prededge); prededge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, prededge, stat); stat.AddPredecessor(prededge); stat.AddLabeledEdge(prededge); } stat.AddSuccessor(new StatEdge(StatEdge.Type_Regular, stat, bstat)); foreach (StatEdge edge in dest.GetAllPredecessorEdges()) { if (!edge.@explicit && stat.ContainsStatementStrict(edge.GetSource()) && MergeHelper .IsDirectPath(edge.GetSource().GetParent(), bstat)) { dest.RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, bstat); bstat.AddPredecessor(edge); if (!stat.ContainsStatementStrict(edge.closure)) { stat.AddLabeledEdge(edge); } } } ret = 2; } } } return(ret); }