private static Statement GetMinContinueClosure(StatEdge edge) { Statement closure = edge.closure; while (true) { bool found = false; foreach (Statement st in closure.GetStats()) { if (st.ContainsStatementStrict(edge.GetSource())) { if (MergeHelper.IsDirectPath(st, edge.GetDestination())) { closure = st; found = true; break; } } } if (!found) { break; } } return(closure); }
public static void LowClosures(Statement stat) { foreach (StatEdge edge in new List <StatEdge>(stat.GetLabelEdges())) { if (edge.GetType() == StatEdge.Type_Break) { // FIXME: ? foreach (Statement st in stat.GetStats()) { if (st.ContainsStatementStrict(edge.GetSource())) { if (MergeHelper.IsDirectPath(st, edge.GetDestination())) { st.AddLabeledEdge(edge); } } } } } foreach (Statement st in stat.GetStats()) { LowClosures(st); } }
// 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 HasDirectEndEdge(Statement stat, Statement from) { foreach (StatEdge edge in stat.GetAllSuccessorEdges()) { if (MergeHelper.IsDirectPath(from, edge.GetDestination())) { return(true); } } if (stat.GetExprents() == null) { switch (stat.type) { case Statement.Type_Sequence: { return(HasDirectEndEdge(stat.GetStats().GetLast(), from)); } case Statement.Type_Catchall: case Statement.Type_Trycatch: { foreach (Statement st in stat.GetStats()) { if (HasDirectEndEdge(st, from)) { return(true); } } break; } case Statement.Type_If: { IfStatement ifstat = (IfStatement)stat; if (ifstat.iftype == IfStatement.Iftype_Ifelse) { return(HasDirectEndEdge(ifstat.GetIfstat(), from) || HasDirectEndEdge(ifstat.GetElsestat (), from)); } break; } case Statement.Type_Syncronized: { return(HasDirectEndEdge(stat.GetStats()[1], from)); } case Statement.Type_Switch: { foreach (Statement st in stat.GetStats()) { if (HasDirectEndEdge(st, from)) { return(true); } } break; } } } 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); }