private static void ExtractIfBlock(DoStatement loop, IfStatement ifstat) { Statement target = ifstat.GetIfstat(); StatEdge ifedge = ifstat.GetIfEdge(); ifstat.SetIfstat(null); ifedge.GetSource().ChangeEdgeType(Statement.Direction_Forward, ifedge, StatEdge.Type_Break ); ifedge.closure = loop; ifstat.GetStats().RemoveWithKey(target.id); loop.AddLabeledEdge(ifedge); SequenceStatement block = new SequenceStatement(Sharpen.Arrays.AsList(loop, target )); loop.GetParent().ReplaceStatement(loop, block); block.SetAllParent(); loop.AddSuccessor(new StatEdge(StatEdge.Type_Regular, loop, target)); foreach (StatEdge edge in new List <StatEdge>(block.GetLabelEdges())) { if (edge.GetType() == StatEdge.Type_Continue || edge == ifedge) { loop.AddLabeledEdge(edge); } } foreach (StatEdge edge in block.GetPredecessorEdges(StatEdge.Type_Continue)) { if (loop.ContainsStatementStrict(edge.GetSource())) { block.RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, loop); loop.AddPredecessor(edge); } } }
private static void InlineBlock(SequenceStatement seq, int index) { Statement first = seq.GetStats()[index]; Statement pre = seq.GetStats()[index - 1]; pre.RemoveSuccessor(pre.GetAllSuccessorEdges()[0]); // single regular edge StatEdge edge = first.GetPredecessorEdges(StatEdge.Type_Break)[0]; Statement source = edge.GetSource(); Statement parent = source.GetParent(); source.RemoveSuccessor(edge); List <Statement> lst = new List <Statement>(); for (int i = seq.GetStats().Count - 1; i >= index; i--) { lst.Add(0, seq.GetStats().RemoveAtReturningValue(i)); } if (parent.type == Statement.Type_If && ((IfStatement)parent).iftype == IfStatement .Iftype_If && source == parent.GetFirst()) { IfStatement ifparent = (IfStatement)parent; SequenceStatement block = new SequenceStatement(lst); block.SetAllParent(); StatEdge newedge = new StatEdge(StatEdge.Type_Regular, source, block); source.AddSuccessor(newedge); ifparent.SetIfEdge(newedge); ifparent.SetIfstat(block); ifparent.GetStats().AddWithKey(block, block.id); block.SetParent(ifparent); } else { lst.Add(0, source); SequenceStatement block = new SequenceStatement(lst); block.SetAllParent(); parent.ReplaceStatement(source, 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, source ); source.AddPredecessor(prededge); source.AddLabeledEdge(prededge); } if (parent.type == Statement.Type_Switch) { ((SwitchStatement)parent).SortEdgesAndNodes(); } source.AddSuccessor(new StatEdge(StatEdge.Type_Regular, source, first)); } }
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 static void CondenseSequencesRec(Statement stat) { if (stat.type == Statement.Type_Sequence) { List <Statement> lst = new List <Statement>(stat.GetStats()); bool unfolded = false; // unfold blocks for (int i = 0; i < lst.Count; i++) { Statement st = lst[i]; if (st.type == Statement.Type_Sequence) { RemoveEmptyStatements((SequenceStatement)st); if (i == lst.Count - 1 || IsSequenceDisbandable(st, lst[i + 1])) { // move predecessors Statement first = st.GetFirst(); foreach (StatEdge edge in st.GetAllPredecessorEdges()) { st.RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, first); first.AddPredecessor(edge); } // move successors Statement last = st.GetStats().GetLast(); if ((last.GetAllSuccessorEdges().Count == 0) && i < lst.Count - 1) { last.AddSuccessor(new StatEdge(StatEdge.Type_Regular, last, lst[i + 1])); } else { foreach (StatEdge edge in last.GetAllSuccessorEdges()) { if (i == lst.Count - 1) { if (edge.closure == st) { stat.AddLabeledEdge(edge); } } else { edge.GetSource().ChangeEdgeType(Statement.Direction_Forward, edge, StatEdge.Type_Regular ); edge.closure.GetLabelEdges().Remove(edge); edge.closure = null; } } } foreach (StatEdge edge in st.GetAllSuccessorEdges()) { st.RemoveSuccessor(edge); } foreach (StatEdge edge in new HashSet <StatEdge>(st.GetLabelEdges())) { if (edge.GetSource() != last) { last.AddLabeledEdge(edge); } } lst.RemoveAtReturningValue(i); lst.InsertRange(i, st.GetStats()); i--; unfolded = true; } } } if (unfolded) { SequenceStatement sequence = new SequenceStatement(lst); sequence.SetAllParent(); stat.GetParent().ReplaceStatement(stat, sequence); stat = sequence; } } // sequence consisting of one statement -> disband if (stat.type == Statement.Type_Sequence) { RemoveEmptyStatements((SequenceStatement)stat); if (stat.GetStats().Count == 1) { Statement st = stat.GetFirst(); bool ok = (st.GetAllSuccessorEdges().Count == 0); if (!ok) { StatEdge edge = st.GetAllSuccessorEdges()[0]; ok = (stat.GetAllSuccessorEdges().Count == 0); if (!ok) { StatEdge statedge = stat.GetAllSuccessorEdges()[0]; ok = (edge.GetDestination() == statedge.GetDestination()); if (ok) { st.RemoveSuccessor(edge); } } } if (ok) { stat.GetParent().ReplaceStatement(stat, st); stat = st; } } } // replace flat statements with synthetic basic blocks while (true) { foreach (Statement st in stat.GetStats()) { if (((st.GetStats().Count == 0) || st.GetExprents() != null) && st.type != Statement .Type_Basicblock) { DestroyAndFlattenStatement(st); goto outer_continue; } } break; outer_continue :; } outer_break :; // recursion for (int i = 0; i < stat.GetStats().Count; i++) { CondenseSequencesRec(stat.GetStats()[i]); } }
// 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 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); }