private static bool CollapseIfElse(IfHelper.IfNode rtnode) { if (rtnode.edgetypes[0] == 0) { IfHelper.IfNode ifbranch = rtnode.succs[0]; if (ifbranch.succs.Count == 2) { // if-else branch if (ifbranch.succs[0].value == rtnode.succs[1].value) { IfStatement ifparent = (IfStatement)rtnode.value; IfStatement ifchild = (IfStatement)ifbranch.value; if ((ifchild.GetFirst().GetExprents().Count == 0)) { ifparent.GetFirst().RemoveSuccessor(ifparent.GetIfEdge()); ifchild.GetFirst().RemoveSuccessor(ifchild.GetIfEdge()); ifparent.GetStats().RemoveWithKey(ifchild.id); if (ifbranch.edgetypes[1] == 1 && ifbranch.edgetypes[0] == 1) { // target null ifparent.SetIfstat(null); StatEdge ifedge = ifchild.GetAllSuccessorEdges()[0]; ifchild.RemoveSuccessor(ifedge); ifedge.SetSource(ifparent.GetFirst()); ifparent.GetFirst().AddSuccessor(ifedge); ifparent.SetIfEdge(ifedge); } else { throw new Exception("inconsistent if structure!"); } // merge if conditions IfExprent statexpr = ifparent.GetHeadexprent(); List <Exprent> lstOperands = new List <Exprent>(); lstOperands.Add(statexpr.GetCondition()); lstOperands.Add(new FunctionExprent(FunctionExprent.Function_Bool_Not, ifchild.GetHeadexprent ().GetCondition(), null)); statexpr.SetCondition(new FunctionExprent(FunctionExprent.Function_Cadd, lstOperands , null)); statexpr.AddBytecodeOffsets(ifchild.GetHeadexprent().bytecode); return(true); } } } } return(false); }
private static void MatchDoWhile(DoStatement stat) { // search for an if condition at the end of the loop Statement last = stat.GetFirst(); while (last.type == Statement.Type_Sequence) { last = last.GetStats().GetLast(); } if (last.type == Statement.Type_If) { IfStatement lastif = (IfStatement)last; if (lastif.iftype == IfStatement.Iftype_If && lastif.GetIfstat() == null) { StatEdge ifedge = lastif.GetIfEdge(); StatEdge elseedge = lastif.GetAllSuccessorEdges()[0]; if ((ifedge.GetType() == StatEdge.Type_Break && elseedge.GetType() == StatEdge.Type_Continue && elseedge.closure == stat && IsDirectPath(stat, ifedge.GetDestination())) || (ifedge.GetType() == StatEdge.Type_Continue && elseedge.GetType() == StatEdge.Type_Break && ifedge.closure == stat && IsDirectPath(stat, elseedge.GetDestination()))) { HashSet <Statement> set = stat.GetNeighboursSet(StatEdge.Type_Continue, Statement. Direction_Backward); set.Remove(last); if (!(set.Count == 0)) { return; } stat.SetLooptype(DoStatement.Loop_Dowhile); IfExprent ifexpr = (IfExprent)lastif.GetHeadexprent().Copy(); if (ifedge.GetType() == StatEdge.Type_Break) { ifexpr.NegateIf(); } stat.SetConditionExprent(ifexpr.GetCondition()); lastif.GetFirst().RemoveSuccessor(ifedge); lastif.RemoveSuccessor(elseedge); // remove empty if if ((lastif.GetFirst().GetExprents().Count == 0)) { RemoveLastEmptyStatement(stat, lastif); } else { lastif.SetExprents(lastif.GetFirst().GetExprents()); StatEdge newedge = new StatEdge(StatEdge.Type_Continue, lastif, stat); lastif.AddSuccessor(newedge); stat.AddLabeledEdge(newedge); } if ((stat.GetAllSuccessorEdges().Count == 0)) { StatEdge edge = elseedge.GetType() == StatEdge.Type_Continue ? ifedge : elseedge; edge.SetSource(stat); if (edge.closure == stat) { edge.closure = stat.GetParent(); } stat.AddSuccessor(edge); } } } } }
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); }
// FIXME: rewrite the entire method!!! keep in mind finally exits!! private static bool ReorderIf(IfStatement ifstat) { if (ifstat.iftype == IfStatement.Iftype_Ifelse) { return(false); } bool ifdirect; bool elsedirect; bool noifstat = false; bool noelsestat; bool ifdirectpath = false; bool elsedirectpath = false; Statement parent = ifstat.GetParent(); Statement from = parent.type == Statement.Type_Sequence ? parent : ifstat; Statement next = GetNextStatement(from); if (ifstat.GetIfstat() == null) { noifstat = true; ifdirect = ifstat.GetIfEdge().GetType() == StatEdge.Type_Finallyexit || MergeHelper .IsDirectPath(from, ifstat.GetIfEdge().GetDestination()); } else { List <StatEdge> lstSuccs = ifstat.GetIfstat().GetAllSuccessorEdges(); ifdirect = !(lstSuccs.Count == 0) && lstSuccs[0].GetType() == StatEdge.Type_Finallyexit || HasDirectEndEdge(ifstat.GetIfstat(), from); } Statement last = parent.type == Statement.Type_Sequence ? parent.GetStats().GetLast () : ifstat; noelsestat = (last == ifstat); elsedirect = !(last.GetAllSuccessorEdges().Count == 0) && last.GetAllSuccessorEdges ()[0].GetType() == StatEdge.Type_Finallyexit || HasDirectEndEdge(last, from); if (!noelsestat && ExistsPath(ifstat, ifstat.GetAllSuccessorEdges()[0].GetDestination ())) { return(false); } if (!ifdirect && !noifstat) { ifdirectpath = ExistsPath(ifstat, next); } if (!elsedirect && !noelsestat) { SequenceStatement sequence = (SequenceStatement)parent; for (int i = sequence.GetStats().Count - 1; i >= 0; i--) { Statement sttemp = sequence.GetStats()[i]; if (sttemp == ifstat) { break; } else if (elsedirectpath = ExistsPath(sttemp, next)) { break; } } } if ((ifdirect || ifdirectpath) && (elsedirect || elsedirectpath) && !noifstat && !noelsestat) { // if - then - else SequenceStatement sequence = (SequenceStatement)parent; // build and cut the new else statement List <Statement> lst = new List <Statement>(); for (int i = sequence.GetStats().Count - 1; i >= 0; i--) { Statement sttemp = sequence.GetStats()[i]; if (sttemp == ifstat) { break; } else { lst.Add(0, sttemp); } } Statement stelse; if (lst.Count == 1) { stelse = lst[0]; } else { stelse = new SequenceStatement(lst); stelse.SetAllParent(); } ifstat.RemoveSuccessor(ifstat.GetAllSuccessorEdges()[0]); foreach (Statement st in lst) { sequence.GetStats().RemoveWithKey(st.id); } StatEdge elseedge = new StatEdge(StatEdge.Type_Regular, ifstat.GetFirst(), stelse ); ifstat.GetFirst().AddSuccessor(elseedge); ifstat.SetElsestat(stelse); ifstat.SetElseEdge(elseedge); ifstat.GetStats().AddWithKey(stelse, stelse.id); stelse.SetParent(ifstat); // if(next.type != Statement.TYPE_DUMMYEXIT && (ifdirect || elsedirect)) { // StatEdge breakedge = new StatEdge(StatEdge.TYPE_BREAK, ifstat, next); // sequence.addLabeledEdge(breakedge); // ifstat.addSuccessor(breakedge); // } ifstat.iftype = IfStatement.Iftype_Ifelse; } else if (ifdirect && (!elsedirect || (noifstat && !noelsestat))) { // if - then // negate the if condition IfExprent statexpr = ifstat.GetHeadexprent(); statexpr.SetCondition(new FunctionExprent(FunctionExprent.Function_Bool_Not, statexpr .GetCondition(), null)); if (noelsestat) { StatEdge ifedge = ifstat.GetIfEdge(); StatEdge elseedge = ifstat.GetAllSuccessorEdges()[0]; if (noifstat) { ifstat.GetFirst().RemoveSuccessor(ifedge); ifstat.RemoveSuccessor(elseedge); ifedge.SetSource(ifstat); elseedge.SetSource(ifstat.GetFirst()); ifstat.AddSuccessor(ifedge); ifstat.GetFirst().AddSuccessor(elseedge); ifstat.SetIfEdge(elseedge); } else { Statement ifbranch = ifstat.GetIfstat(); SequenceStatement newseq = new SequenceStatement(Sharpen.Arrays.AsList(ifstat, ifbranch )); ifstat.GetFirst().RemoveSuccessor(ifedge); ifstat.GetStats().RemoveWithKey(ifbranch.id); ifstat.SetIfstat(null); ifstat.RemoveSuccessor(elseedge); elseedge.SetSource(ifstat.GetFirst()); ifstat.GetFirst().AddSuccessor(elseedge); ifstat.SetIfEdge(elseedge); ifstat.GetParent().ReplaceStatement(ifstat, newseq); newseq.SetAllParent(); ifstat.AddSuccessor(new StatEdge(StatEdge.Type_Regular, ifstat, ifbranch)); } } else { SequenceStatement sequence = (SequenceStatement)parent; // build and cut the new else statement List <Statement> lst = new List <Statement>(); for (int i = sequence.GetStats().Count - 1; i >= 0; i--) { Statement sttemp = sequence.GetStats()[i]; if (sttemp == ifstat) { break; } else { lst.Add(0, sttemp); } } Statement stelse; if (lst.Count == 1) { stelse = lst[0]; } else { stelse = new SequenceStatement(lst); stelse.SetAllParent(); } ifstat.RemoveSuccessor(ifstat.GetAllSuccessorEdges()[0]); foreach (Statement st in lst) { sequence.GetStats().RemoveWithKey(st.id); } if (noifstat) { StatEdge ifedge = ifstat.GetIfEdge(); ifstat.GetFirst().RemoveSuccessor(ifedge); ifedge.SetSource(ifstat); ifstat.AddSuccessor(ifedge); } else { Statement ifbranch = ifstat.GetIfstat(); ifstat.GetFirst().RemoveSuccessor(ifstat.GetIfEdge()); ifstat.GetStats().RemoveWithKey(ifbranch.id); ifstat.AddSuccessor(new StatEdge(StatEdge.Type_Regular, ifstat, ifbranch)); sequence.GetStats().AddWithKey(ifbranch, ifbranch.id); ifbranch.SetParent(sequence); } StatEdge newifedge = new StatEdge(StatEdge.Type_Regular, ifstat.GetFirst(), stelse ); ifstat.GetFirst().AddSuccessor(newifedge); ifstat.SetIfstat(stelse); ifstat.SetIfEdge(newifedge); ifstat.GetStats().AddWithKey(stelse, stelse.id); stelse.SetParent(ifstat); } } else { return(false); } return(true); }
private static bool CollapseElse(IfHelper.IfNode rtnode) { if (rtnode.edgetypes[1] == 0) { IfHelper.IfNode elsebranch = rtnode.succs[1]; if (elsebranch.succs.Count == 2) { // else-if or else-else branch int path = elsebranch.succs[1].value == rtnode.succs[0].value ? 2 : (elsebranch.succs [0].value == rtnode.succs[0].value ? 1 : 0); if (path > 0) { IfStatement firstif = (IfStatement)rtnode.value; IfStatement secondif = (IfStatement)elsebranch.value; Statement parent = firstif.GetParent(); if ((secondif.GetFirst().GetExprents().Count == 0)) { firstif.GetFirst().RemoveSuccessor(firstif.GetIfEdge()); // remove first if firstif.RemoveAllSuccessors(secondif); foreach (StatEdge edge in firstif.GetAllPredecessorEdges()) { if (!firstif.ContainsStatementStrict(edge.GetSource())) { firstif.RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, secondif); secondif.AddPredecessor(edge); } } parent.GetStats().RemoveWithKey(firstif.id); if (parent.GetFirst() == firstif) { parent.SetFirst(secondif); } // merge if conditions IfExprent statexpr = secondif.GetHeadexprent(); List <Exprent> lstOperands = new List <Exprent>(); lstOperands.Add(firstif.GetHeadexprent().GetCondition()); if (path == 2) { lstOperands[0] = new FunctionExprent(FunctionExprent.Function_Bool_Not, lstOperands [0], null); } lstOperands.Add(statexpr.GetCondition()); statexpr.SetCondition(new FunctionExprent(path == 1 ? FunctionExprent.Function_Cor : FunctionExprent.Function_Cadd, lstOperands, null)); if ((secondif.GetFirst().GetExprents().Count == 0) && !(firstif.GetFirst().GetExprents ().Count == 0)) { secondif.ReplaceStatement(secondif.GetFirst(), firstif.GetFirst()); } return(true); } } } else if (elsebranch.succs.Count == 1) { if (elsebranch.succs[0].value == rtnode.succs[0].value) { IfStatement firstif = (IfStatement)rtnode.value; Statement second = elsebranch.value; firstif.RemoveAllSuccessors(second); foreach (StatEdge edge in second.GetAllSuccessorEdges()) { second.RemoveSuccessor(edge); edge.SetSource(firstif); firstif.AddSuccessor(edge); } StatEdge ifedge = firstif.GetIfEdge(); firstif.GetFirst().RemoveSuccessor(ifedge); second.AddSuccessor(new StatEdge(ifedge.GetType(), second, ifedge.GetDestination( ), ifedge.closure)); StatEdge newifedge = new StatEdge(StatEdge.Type_Regular, firstif.GetFirst(), second ); firstif.GetFirst().AddSuccessor(newifedge); firstif.SetIfstat(second); firstif.GetStats().AddWithKey(second, second.id); second.SetParent(firstif); firstif.GetParent().GetStats().RemoveWithKey(second.id); // negate the if condition IfExprent statexpr = firstif.GetHeadexprent(); statexpr.SetCondition(new FunctionExprent(FunctionExprent.Function_Bool_Not, statexpr .GetCondition(), null)); return(true); } } } return(false); }
private static bool CollapseIfIf(IfHelper.IfNode rtnode) { if (rtnode.edgetypes[0] == 0) { IfHelper.IfNode ifbranch = rtnode.succs[0]; if (ifbranch.succs.Count == 2) { // if-if branch if (ifbranch.succs[1].value == rtnode.succs[1].value) { IfStatement ifparent = (IfStatement)rtnode.value; IfStatement ifchild = (IfStatement)ifbranch.value; Statement ifinner = ifbranch.succs[0].value; if ((ifchild.GetFirst().GetExprents().Count == 0)) { ifparent.GetFirst().RemoveSuccessor(ifparent.GetIfEdge()); ifchild.RemoveSuccessor(ifchild.GetAllSuccessorEdges()[0]); ifparent.GetStats().RemoveWithKey(ifchild.id); if (ifbranch.edgetypes[0] == 1) { // target null ifparent.SetIfstat(null); StatEdge ifedge = ifchild.GetIfEdge(); ifchild.GetFirst().RemoveSuccessor(ifedge); ifedge.SetSource(ifparent.GetFirst()); if (ifedge.closure == ifchild) { ifedge.closure = null; } ifparent.GetFirst().AddSuccessor(ifedge); ifparent.SetIfEdge(ifedge); } else { ifchild.GetFirst().RemoveSuccessor(ifchild.GetIfEdge()); StatEdge ifedge = new StatEdge(StatEdge.Type_Regular, ifparent.GetFirst(), ifinner ); ifparent.GetFirst().AddSuccessor(ifedge); ifparent.SetIfEdge(ifedge); ifparent.SetIfstat(ifinner); ifparent.GetStats().AddWithKey(ifinner, ifinner.id); ifinner.SetParent(ifparent); if (!(ifinner.GetAllSuccessorEdges().Count == 0)) { StatEdge edge = ifinner.GetAllSuccessorEdges()[0]; if (edge.closure == ifchild) { edge.closure = null; } } } // merge if conditions IfExprent statexpr = ifparent.GetHeadexprent(); List <Exprent> lstOperands = new List <Exprent>(); lstOperands.Add(statexpr.GetCondition()); lstOperands.Add(ifchild.GetHeadexprent().GetCondition()); statexpr.SetCondition(new FunctionExprent(FunctionExprent.Function_Cadd, lstOperands , null)); statexpr.AddBytecodeOffsets(ifchild.GetHeadexprent().bytecode); return(true); } } } } return(false); }