private static bool IsInlineable(SequenceStatement seq, int index) { Statement first = seq.GetStats()[index]; Statement pre = seq.GetStats()[index - 1]; if (pre.HasBasicSuccEdge()) { return(false); } List <StatEdge> lst = first.GetPredecessorEdges(StatEdge.Type_Break); if (lst.Count == 1) { StatEdge edge = lst[0]; if (SameCatchRanges(edge)) { if (!edge.@explicit) { for (int i = index; i < seq.GetStats().Count; i++) { if (!NoExitLabels(seq.GetStats()[i], seq)) { return(false); } } } return(true); } } // FIXME: count labels properly return(false); }
private static bool IsOnlyEdge(StatEdge edge) { Statement stat = edge.GetDestination(); foreach (StatEdge ed in stat.GetAllPredecessorEdges()) { if (ed != edge) { if (ed.GetType() == StatEdge.Type_Regular) { Statement source = ed.GetSource(); if (source.type == Statement.Type_Basicblock || (source.type == Statement.Type_If && ((IfStatement)source).iftype == IfStatement.Iftype_If) || (source.type == Statement .Type_Do && ((DoStatement)source).GetLooptype() != DoStatement.Loop_Do)) { return(false); } } else { return(false); } } } return(true); }
private static void RemoveParameterCheck(Statement stat) { Statement st = stat.GetFirst(); while (st.type == Statement.Type_Sequence) { st = st.GetFirst(); } IfStatement ifstat = (IfStatement)st; if (ifstat.GetElsestat() != null) { // if - else StatEdge ifedge = ifstat.GetIfEdge(); StatEdge elseedge = ifstat.GetElseEdge(); Statement ifbranch = ifstat.GetIfstat(); Statement elsebranch = ifstat.GetElsestat(); ifstat.GetFirst().RemoveSuccessor(ifedge); ifstat.GetFirst().RemoveSuccessor(elseedge); ifstat.GetStats().RemoveWithKey(ifbranch.id); ifstat.GetStats().RemoveWithKey(elsebranch.id); if (!(ifbranch.GetAllSuccessorEdges().Count == 0)) { ifbranch.RemoveSuccessor(ifbranch.GetAllSuccessorEdges()[0]); } ifstat.GetParent().ReplaceStatement(ifstat, elsebranch); ifstat.GetParent().SetAllParent(); } }
private static bool SameCatchRanges(StatEdge edge) { Statement from = edge.GetSource(); Statement to = edge.GetDestination(); while (true) { Statement parent = from.GetParent(); if (parent.ContainsStatementStrict(to)) { break; } if (parent.type == Statement.Type_Trycatch || parent.type == Statement.Type_Catchall) { if (parent.GetFirst() == from) { return(false); } } else if (parent.type == Statement.Type_Syncronized) { if (parent.GetStats()[1] == from) { return(false); } } from = parent; } return(true); }
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 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); }
private static bool ExtractLastIf(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) { Statement ifstat = lastif.GetIfstat(); StatEdge elseedge = lastif.GetAllSuccessorEdges()[0]; if (elseedge.GetType() == StatEdge.Type_Continue && elseedge.closure == stat) { HashSet <Statement> set = stat.GetNeighboursSet(StatEdge.Type_Continue, Statement. Direction_Backward); set.Remove(last); if ((set.Count == 0)) { // no direct continues in a do{}while loop if (IsExternStatement(stat, ifstat, ifstat)) { ExtractIfBlock(stat, lastif); return(true); } } } } } return(false); }
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 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 Statement IsExitEdge(StatEdge edge) { Statement dest = edge.GetDestination(); if (edge.GetType() == StatEdge.Type_Break && dest.type == Statement.Type_Basicblock && edge.@explicit && (edge.labeled || IsOnlyEdge(edge))) { List <Exprent> data = dest.GetExprents(); if (data != null && data.Count == 1) { if (data[0].type == Exprent.Exprent_Exit) { return(dest); } } } return(null); }
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); }
// 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 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); }
private static bool RemoveReturnCheck(Statement stat, StructMethod mt) { Statement parent = stat.GetParent(); if (parent != null && parent.type == Statement.Type_If && stat.type == Statement. Type_Basicblock && stat.GetExprents().Count == 1) { Exprent exprent = stat.GetExprents()[0]; if (exprent.type == Exprent.Exprent_Exit) { ExitExprent exit_exprent = (ExitExprent)exprent; if (exit_exprent.GetExitType() == ExitExprent.Exit_Return) { Exprent exprent_value = exit_exprent.GetValue(); //if(exprent_value.type == Exprent.EXPRENT_VAR) { // VarExprent var_value = (VarExprent)exprent_value; IfStatement ifparent = (IfStatement)parent; Exprent if_condition = ifparent.GetHeadexprent().GetCondition(); if (ifparent.GetElsestat() == stat && if_condition.type == Exprent.Exprent_Function && ((FunctionExprent)if_condition).GetFuncType() == FunctionExprent.Function_Eq) { // TODO: reversed order possible (in theory) FunctionExprent func = (FunctionExprent)if_condition; Exprent first_param = func.GetLstOperands()[0]; Exprent second_param = func.GetLstOperands()[1]; StatEdge ifedge = ifparent.GetIfEdge(); StatEdge elseedge = ifparent.GetElseEdge(); Statement ifbranch = ifparent.GetIfstat(); Statement elsebranch = ifparent.GetElsestat(); if (second_param.type == Exprent.Exprent_Const && second_param.GetExprType().type == ICodeConstants.Type_Null) { // TODO: reversed parameter order //if(first_param.type == Exprent.EXPRENT_VAR && ((VarExprent)first_param).getIndex() == var_value.getIndex()) { if (first_param.Equals(exprent_value)) { // TODO: check for absence of side effects like method invocations etc. if (ifbranch.type == Statement.Type_Basicblock && ifbranch.GetExprents().Count == 1 && ifbranch.GetExprents()[0].type == Exprent.Exprent_Exit) { // TODO: special check for IllegalStateException ifparent.GetFirst().RemoveSuccessor(ifedge); ifparent.GetFirst().RemoveSuccessor(elseedge); ifparent.GetStats().RemoveWithKey(ifbranch.id); ifparent.GetStats().RemoveWithKey(elsebranch.id); if (!(ifbranch.GetAllSuccessorEdges().Count == 0)) { ifbranch.RemoveSuccessor(ifbranch.GetAllSuccessorEdges()[0]); } if (!(ifparent.GetFirst().GetExprents().Count == 0)) { elsebranch.GetExprents().InsertRange(0, ifparent.GetFirst().GetExprents()); } ifparent.GetParent().ReplaceStatement(ifparent, elsebranch); ifparent.GetParent().SetAllParent(); return(true); } } } } } } } else if (parent != null && parent.type == Statement.Type_Sequence && stat.type == Statement.Type_Basicblock && stat.GetExprents().Count == 1) { //} Exprent exprent = stat.GetExprents()[0]; if (exprent.type == Exprent.Exprent_Exit) { ExitExprent exit_exprent = (ExitExprent)exprent; if (exit_exprent.GetExitType() == ExitExprent.Exit_Return) { Exprent exprent_value = exit_exprent.GetValue(); SequenceStatement sequence = (SequenceStatement)parent; int sequence_stats_number = sequence.GetStats().Count; if (sequence_stats_number > 1 && sequence.GetStats().GetLast() == stat && sequence .GetStats()[sequence_stats_number - 2].type == Statement.Type_If) { IfStatement ifstat = (IfStatement)sequence.GetStats()[sequence_stats_number - 2]; Exprent if_condition = ifstat.GetHeadexprent().GetCondition(); if (ifstat.iftype == IfStatement.Iftype_If && if_condition.type == Exprent.Exprent_Function && ((FunctionExprent)if_condition).GetFuncType() == FunctionExprent.Function_Eq) { // TODO: reversed order possible (in theory) FunctionExprent func = (FunctionExprent)if_condition; Exprent first_param = func.GetLstOperands()[0]; Exprent second_param = func.GetLstOperands()[1]; Statement ifbranch = ifstat.GetIfstat(); if (second_param.type == Exprent.Exprent_Const && second_param.GetExprType().type == ICodeConstants.Type_Null) { // TODO: reversed parameter order if (first_param.Equals(exprent_value)) { // TODO: check for absence of side effects like method invocations etc. if (ifbranch.type == Statement.Type_Basicblock && ifbranch.GetExprents().Count == 1 && ifbranch.GetExprents()[0].type == Exprent.Exprent_Exit) { // TODO: special check for IllegalStateException ifstat.RemoveSuccessor(ifstat.GetAllSuccessorEdges()[0]); // remove 'else' edge if (!(ifstat.GetFirst().GetExprents().Count == 0)) { stat.GetExprents().InsertRange(0, ifstat.GetFirst().GetExprents()); } foreach (StatEdge edge in ifstat.GetAllPredecessorEdges()) { ifstat.RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, stat); stat.AddPredecessor(edge); } sequence.GetStats().RemoveWithKey(ifstat.id); sequence.SetFirst(sequence.GetStats()[0]); return(true); } } } } } } } } foreach (Statement st in stat.GetStats()) { if (RemoveReturnCheck(st, mt)) { return(true); } } return(false); }
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]); } }
public static bool IdentifySecondaryFunctions(Statement stat, VarProcessor varProc ) { if (stat.GetExprents() == null) { // if(){;}else{...} -> if(!){...} if (stat.type == Statement.Type_If) { IfStatement ifelsestat = (IfStatement)stat; Statement ifstat = ifelsestat.GetIfstat(); if (ifelsestat.iftype == IfStatement.Iftype_Ifelse && ifstat.GetExprents() != null && (ifstat.GetExprents().Count == 0) && ((ifstat.GetAllSuccessorEdges().Count == 0) || !ifstat.GetAllSuccessorEdges()[0].@explicit)) { // move else to the if position ifelsestat.GetStats().RemoveWithKey(ifstat.id); ifelsestat.iftype = IfStatement.Iftype_If; ifelsestat.SetIfstat(ifelsestat.GetElsestat()); ifelsestat.SetElsestat(null); if ((ifelsestat.GetAllSuccessorEdges().Count == 0) && !(ifstat.GetAllSuccessorEdges ().Count == 0)) { StatEdge endedge = ifstat.GetAllSuccessorEdges()[0]; ifstat.RemoveSuccessor(endedge); endedge.SetSource(ifelsestat); if (endedge.closure != null) { ifelsestat.GetParent().AddLabeledEdge(endedge); } ifelsestat.AddSuccessor(endedge); } ifelsestat.GetFirst().RemoveSuccessor(ifelsestat.GetIfEdge()); ifelsestat.SetIfEdge(ifelsestat.GetElseEdge()); ifelsestat.SetElseEdge(null); // negate head expression ifelsestat.SetNegated(!ifelsestat.IsNegated()); ifelsestat.GetHeadexprentList()[0] = ((IfExprent)ifelsestat.GetHeadexprent().Copy ()).NegateIf(); return(true); } } } bool replaced = true; while (replaced) { replaced = false; List <object> lstObjects = new List <object>(stat.GetExprents() == null ? (IEnumerable <object>)stat.GetSequentialObjects () : stat.GetExprents()); for (int i = 0; i < lstObjects.Count; i++) { object obj = lstObjects[i]; if (obj is Statement) { if (IdentifySecondaryFunctions((Statement)obj, varProc)) { replaced = true; break; } } else if (obj is Exprent) { Exprent retexpr = IdentifySecondaryFunctions((Exprent)obj, true, varProc); if (retexpr != null) { if (stat.GetExprents() == null) { // only head expressions can be replaced! stat.ReplaceExprent((Exprent)obj, retexpr); } else { stat.GetExprents()[i] = retexpr; } replaced = true; break; } } } } return(false); }
private static void RemoveEmptyStatements(SequenceStatement sequence) { if (sequence.GetStats().Count <= 1) { return; } MergeFlatStatements(sequence); while (true) { bool found = false; foreach (Statement st in sequence.GetStats()) { if (st.GetExprents() != null && (st.GetExprents().Count == 0)) { if ((st.GetAllSuccessorEdges().Count == 0)) { List <StatEdge> lstBreaks = st.GetPredecessorEdges(StatEdge.Type_Break); if ((lstBreaks.Count == 0)) { foreach (StatEdge edge in st.GetAllPredecessorEdges()) { edge.GetSource().RemoveSuccessor(edge); } found = true; } } else { StatEdge sucedge = st.GetAllSuccessorEdges()[0]; if (sucedge.GetType() != StatEdge.Type_Finallyexit) { st.RemoveSuccessor(sucedge); foreach (StatEdge edge in st.GetAllPredecessorEdges()) { if (sucedge.GetType() != StatEdge.Type_Regular) { edge.GetSource().ChangeEdgeType(Statement.Direction_Forward, edge, sucedge.GetType ()); } st.RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, sucedge.GetDestination ()); sucedge.GetDestination().AddPredecessor(edge); if (sucedge.closure != null) { sucedge.closure.AddLabeledEdge(edge); } } found = true; } } if (found) { sequence.GetStats().RemoveWithKey(st.id); break; } } } if (!found) { break; } } sequence.SetFirst(sequence.GetStats()[0]); }
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 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 IfHelper.IfNode BuildGraph(IfStatement stat, bool stsingle) { if (stat.iftype == IfStatement.Iftype_Ifelse) { return(null); } IfHelper.IfNode res = new IfHelper.IfNode(stat); // if branch Statement ifchild = stat.GetIfstat(); if (ifchild == null) { StatEdge edge = stat.GetIfEdge(); res.AddChild(new IfHelper.IfNode(edge.GetDestination()), 1); } else { IfHelper.IfNode ifnode = new IfHelper.IfNode(ifchild); res.AddChild(ifnode, 0); if (ifchild.type == Statement.Type_If && ((IfStatement)ifchild).iftype == IfStatement .Iftype_If) { IfStatement stat2 = (IfStatement)ifchild; Statement ifchild2 = stat2.GetIfstat(); if (ifchild2 == null) { StatEdge edge = stat2.GetIfEdge(); ifnode.AddChild(new IfHelper.IfNode(edge.GetDestination()), 1); } else { ifnode.AddChild(new IfHelper.IfNode(ifchild2), 0); } } if (!(ifchild.GetAllSuccessorEdges().Count == 0)) { ifnode.AddChild(new IfHelper.IfNode(ifchild.GetAllSuccessorEdges()[0].GetDestination ()), 1); } } // else branch StatEdge edge_1 = stat.GetAllSuccessorEdges()[0]; Statement elsechild = edge_1.GetDestination(); IfHelper.IfNode elsenode = new IfHelper.IfNode(elsechild); if (stsingle || edge_1.GetType() != StatEdge.Type_Regular) { res.AddChild(elsenode, 1); } else { res.AddChild(elsenode, 0); if (elsechild.type == Statement.Type_If && ((IfStatement)elsechild).iftype == IfStatement .Iftype_If) { IfStatement stat2 = (IfStatement)elsechild; Statement ifchild2 = stat2.GetIfstat(); if (ifchild2 == null) { elsenode.AddChild(new IfHelper.IfNode(stat2.GetIfEdge().GetDestination()), 1); } else { elsenode.AddChild(new IfHelper.IfNode(ifchild2), 0); } } if (!(elsechild.GetAllSuccessorEdges().Count == 0)) { elsenode.AddChild(new IfHelper.IfNode(elsechild.GetAllSuccessorEdges()[0].GetDestination ()), 1); } } return(res); }
private static Dictionary <Statement, List <StatEdge> > SetExplicitEdges(Statement stat) { Dictionary <Statement, List <StatEdge> > mapEdges = new Dictionary <Statement, List <StatEdge> >(); if (stat.GetExprents() != null) { return(mapEdges); } switch (stat.type) { case Statement.Type_Trycatch: case Statement.Type_Catchall: { foreach (Statement st in stat.GetStats()) { Dictionary <Statement, List <StatEdge> > mapEdges1 = SetExplicitEdges(st); ProcessEdgesWithNext(st, mapEdges1, null); if (stat.type == Statement.Type_Trycatch || st == stat.GetFirst()) { // edges leaving a finally catch block are always explicit // merge the maps if (mapEdges1 != null) { foreach (KeyValuePair <Statement, List <StatEdge> > entr in mapEdges1) { if (mapEdges.ContainsKey(entr.Key)) { Sharpen.Collections.AddAll(mapEdges.GetOrNull(entr.Key), entr.Value); } else { Sharpen.Collections.Put(mapEdges, entr.Key, entr.Value); } } } } } break; } case Statement.Type_Do: { mapEdges = SetExplicitEdges(stat.GetFirst()); ProcessEdgesWithNext(stat.GetFirst(), mapEdges, stat); break; } case Statement.Type_If: { IfStatement ifstat = (IfStatement)stat; // head statement is a basic block if (ifstat.GetIfstat() == null) { // empty if ProcessEdgesWithNext(ifstat.GetFirst(), mapEdges, null); } else { mapEdges = SetExplicitEdges(ifstat.GetIfstat()); ProcessEdgesWithNext(ifstat.GetIfstat(), mapEdges, null); Dictionary <Statement, List <StatEdge> > mapEdges1 = null; if (ifstat.GetElsestat() != null) { mapEdges1 = SetExplicitEdges(ifstat.GetElsestat()); ProcessEdgesWithNext(ifstat.GetElsestat(), mapEdges1, null); } // merge the maps if (mapEdges1 != null) { foreach (KeyValuePair <Statement, List <StatEdge> > entr in mapEdges1) { if (mapEdges.ContainsKey(entr.Key)) { Sharpen.Collections.AddAll(mapEdges.GetOrNull(entr.Key), entr.Value); } else { Sharpen.Collections.Put(mapEdges, entr.Key, entr.Value); } } } } break; } case Statement.Type_Root: { mapEdges = SetExplicitEdges(stat.GetFirst()); ProcessEdgesWithNext(stat.GetFirst(), mapEdges, ((RootStatement)stat).GetDummyExit ()); break; } case Statement.Type_Sequence: { int index = 0; while (index < stat.GetStats().Count - 1) { Statement st = stat.GetStats()[index]; ProcessEdgesWithNext(st, SetExplicitEdges(st), stat.GetStats()[index + 1]); index++; } Statement st_1 = stat.GetStats()[index]; mapEdges = SetExplicitEdges(st_1); ProcessEdgesWithNext(st_1, mapEdges, null); break; } case Statement.Type_Switch: { SwitchStatement swst = (SwitchStatement)stat; for (int i = 0; i < swst.GetCaseStatements().Count - 1; i++) { Statement stt = swst.GetCaseStatements()[i]; Statement stnext = swst.GetCaseStatements()[i + 1]; if (stnext.GetExprents() != null && (stnext.GetExprents().Count == 0)) { stnext = stnext.GetAllSuccessorEdges()[0].GetDestination(); } ProcessEdgesWithNext(stt, SetExplicitEdges(stt), stnext); } int last = swst.GetCaseStatements().Count - 1; if (last >= 0) { // empty switch possible Statement stlast = swst.GetCaseStatements()[last]; if (stlast.GetExprents() != null && (stlast.GetExprents().Count == 0)) { StatEdge edge = stlast.GetAllSuccessorEdges()[0]; Sharpen.Collections.Put(mapEdges, edge.GetDestination(), new List <StatEdge>(System.Linq.Enumerable.ToList(new [] { edge }))); } else { mapEdges = SetExplicitEdges(stlast); ProcessEdgesWithNext(stlast, mapEdges, null); } } break; } case Statement.Type_Syncronized: { SynchronizedStatement synstat = (SynchronizedStatement)stat; ProcessEdgesWithNext(synstat.GetFirst(), SetExplicitEdges(stat.GetFirst()), synstat .GetBody()); // FIXME: basic block? mapEdges = SetExplicitEdges(synstat.GetBody()); ProcessEdgesWithNext(synstat.GetBody(), mapEdges, null); break; } } return(mapEdges); }
private static void ProcessEdgesWithNext(Statement stat, Dictionary <Statement, List <StatEdge> > mapEdges, Statement next) { StatEdge statedge = null; List <StatEdge> lstSuccs = stat.GetAllSuccessorEdges(); if (!(lstSuccs.Count == 0)) { statedge = lstSuccs[0]; if (statedge.GetDestination() == next) { statedge.@explicit = false; statedge = null; } else { next = statedge.GetDestination(); } } // no next for a do statement if (stat.type == Statement.Type_Do && ((DoStatement)stat).GetLooptype() == DoStatement .Loop_Do) { next = null; } if (next == null) { if (mapEdges.Count == 1) { List <StatEdge> lstEdges = new Sharpen.EnumeratorAdapter <List <StatEdge> >(mapEdges.Values.GetEnumerator()).Next(); if (lstEdges.Count > 1 && new Sharpen.EnumeratorAdapter <Statement>(mapEdges.Keys.GetEnumerator()).Next().type != Statement .Type_Dummyexit) { StatEdge edge_example = lstEdges[0]; Statement closure = stat.GetParent(); if (!closure.ContainsStatementStrict(edge_example.closure)) { closure = edge_example.closure; } StatEdge newedge = new StatEdge(edge_example.GetType(), stat, edge_example.GetDestination (), closure); stat.AddSuccessor(newedge); foreach (StatEdge edge in lstEdges) { edge.@explicit = false; } Sharpen.Collections.Put(mapEdges, newedge.GetDestination(), new List <StatEdge>(System.Linq.Enumerable.ToList(new [] { newedge }))); } } } else { bool implfound = false; foreach (KeyValuePair <Statement, List <StatEdge> > entr in mapEdges) { if (entr.Key == next) { foreach (StatEdge edge in entr.Value) { edge.@explicit = false; } implfound = true; break; } } if ((stat.GetAllSuccessorEdges().Count == 0) && !implfound) { List <StatEdge> lstEdges = null; foreach (KeyValuePair <Statement, List <StatEdge> > entr in mapEdges) { if (entr.Key.type != Statement.Type_Dummyexit && (lstEdges == null || entr.Value. Count > lstEdges.Count)) { lstEdges = entr.Value; } } if (lstEdges != null && lstEdges.Count > 1) { StatEdge edge_example = lstEdges[0]; Statement closure = stat.GetParent(); if (!closure.ContainsStatementStrict(edge_example.closure)) { closure = edge_example.closure; } StatEdge newedge = new StatEdge(edge_example.GetType(), stat, edge_example.GetDestination (), closure); stat.AddSuccessor(newedge); foreach (StatEdge edge in lstEdges) { edge.@explicit = false; } } } mapEdges.Clear(); } if (statedge != null) { Sharpen.Collections.Put(mapEdges, statedge.GetDestination(), new List <StatEdge>(System.Linq.Enumerable.ToList(new [] { statedge }))); } }
public static bool IsChoiceStatement(Statement head, List <Statement> lst) { Statement post = null; HashSet <Statement> setDest = head.GetNeighboursSet(StatEdge.Type_Regular, Statement .Direction_Forward); if (setDest.Contains(head)) { return(false); } while (true) { lst.Clear(); bool repeat = false; setDest.Remove(post); foreach (Statement stat in setDest) { if (stat.GetLastBasicType() != Statement.Lastbasictype_General) { if (post == null) { post = stat; repeat = true; break; } else { return(false); } } // preds HashSet <Statement> setPred = stat.GetNeighboursSet(StatEdge.Type_Regular, Statement .Direction_Backward); setPred.Remove(head); if (setPred.Contains(stat)) { return(false); } if (!setPred.All(setDest.Contains) || setPred.Count > 1) { if (post == null) { post = stat; repeat = true; break; } else { return(false); } } else if (setPred.Count == 1) { Statement pred = new Sharpen.EnumeratorAdapter <Statement>(setPred.GetEnumerator()).Next(); while (lst.Contains(pred)) { HashSet <Statement> setPredTemp = pred.GetNeighboursSet(StatEdge.Type_Regular, Statement .Direction_Backward); setPredTemp.Remove(head); if (!(setPredTemp.Count == 0)) { // at most 1 predecessor pred = new Sharpen.EnumeratorAdapter <Statement>(setPredTemp.GetEnumerator()).Next(); if (pred == stat) { return(false); } } else { // loop found break; } } } // succs List <StatEdge> lstEdges = stat.GetSuccessorEdges(Statement.Statedge_Direct_All); if (lstEdges.Count > 1) { HashSet <Statement> setSucc = stat.GetNeighboursSet(Statement.Statedge_Direct_All, Statement.Direction_Forward); setSucc.RetainAll(setDest); if (setSucc.Count > 0) { return(false); } else if (post == null) { post = stat; repeat = true; break; } else { return(false); } } else if (lstEdges.Count == 1) { StatEdge edge = lstEdges[0]; if (edge.GetType() == StatEdge.Type_Regular) { Statement statd = edge.GetDestination(); if (head == statd) { return(false); } if (post != statd && !setDest.Contains(statd)) { if (post != null) { return(false); } else { HashSet <Statement> set = statd.GetNeighboursSet(StatEdge.Type_Regular, Statement. Direction_Backward); if (set.Count > 1) { post = statd; repeat = true; break; } else { return(false); } } } } } lst.Add(stat); } if (!repeat) { break; } } lst.Add(head); lst.Remove(post); lst.Add(0, post); return(true); }
private static bool BuildIff(Statement stat, SSAConstructorSparseEx ssa) { if (stat.type == Statement.Type_If && stat.GetExprents() == null) { IfStatement statement = (IfStatement)stat; Exprent ifHeadExpr = statement.GetHeadexprent(); HashSet <int> ifHeadExprBytecode = (ifHeadExpr == null ? null : ifHeadExpr.bytecode ); if (statement.iftype == IfStatement.Iftype_Ifelse) { Statement ifStatement = statement.GetIfstat(); Statement elseStatement = statement.GetElsestat(); if (ifStatement.GetExprents() != null && ifStatement.GetExprents().Count == 1 && elseStatement.GetExprents() != null && elseStatement.GetExprents().Count == 1 && ifStatement.GetAllSuccessorEdges().Count == 1 && elseStatement.GetAllSuccessorEdges ().Count == 1 && ifStatement.GetAllSuccessorEdges()[0].GetDestination() == elseStatement .GetAllSuccessorEdges()[0].GetDestination()) { Exprent ifExpr = ifStatement.GetExprents()[0]; Exprent elseExpr = elseStatement.GetExprents()[0]; if (ifExpr.type == Exprent.Exprent_Assignment && elseExpr.type == Exprent.Exprent_Assignment) { AssignmentExprent ifAssign = (AssignmentExprent)ifExpr; AssignmentExprent elseAssign = (AssignmentExprent)elseExpr; if (ifAssign.GetLeft().type == Exprent.Exprent_Var && elseAssign.GetLeft().type == Exprent.Exprent_Var) { VarExprent ifVar = (VarExprent)ifAssign.GetLeft(); VarExprent elseVar = (VarExprent)elseAssign.GetLeft(); if (ifVar.GetIndex() == elseVar.GetIndex() && ifVar.IsStack()) { // ifVar.getIndex() >= VarExprent.STACK_BASE) { bool found = false; foreach (KeyValuePair <VarVersionPair, FastSparseSetFactory <int> .FastSparseSet <int> > ent in ssa.GetPhi()) { if (ent.Key.var == ifVar.GetIndex()) { if (ent.Value.Contains(ifVar.GetVersion()) && ent.Value.Contains(elseVar.GetVersion ())) { found = true; break; } } } if (found) { List <Exprent> data = new List <Exprent>(statement.GetFirst().GetExprents()); List <Exprent> operands = Sharpen.Arrays.AsList(statement.GetHeadexprent().GetCondition (), ifAssign.GetRight(), elseAssign.GetRight()); data.Add(new AssignmentExprent(ifVar, new FunctionExprent(FunctionExprent.Function_Iif , operands, ifHeadExprBytecode), ifHeadExprBytecode)); statement.SetExprents(data); if ((statement.GetAllSuccessorEdges().Count == 0)) { StatEdge ifEdge = ifStatement.GetAllSuccessorEdges()[0]; StatEdge edge = new StatEdge(ifEdge.GetType(), statement, ifEdge.GetDestination() ); statement.AddSuccessor(edge); if (ifEdge.closure != null) { ifEdge.closure.AddLabeledEdge(edge); } } SequenceHelper.DestroyAndFlattenStatement(statement); return(true); } } } } else if (ifExpr.type == Exprent.Exprent_Exit && elseExpr.type == Exprent.Exprent_Exit) { ExitExprent ifExit = (ExitExprent)ifExpr; ExitExprent elseExit = (ExitExprent)elseExpr; if (ifExit.GetExitType() == elseExit.GetExitType() && ifExit.GetValue() != null && elseExit.GetValue() != null && ifExit.GetExitType() == ExitExprent.Exit_Return) { // throw is dangerous, because of implicit casting to a common superclass // e.g. throws IOException and throw true?new RuntimeException():new IOException(); won't work if (ifExit.GetExitType() == ExitExprent.Exit_Throw && !ifExit.GetValue().GetExprType ().Equals(elseExit.GetValue().GetExprType())) { // note: getExprType unreliable at this point! return(false); } // avoid flattening to 'iff' if any of the branches is an 'iff' already if (IsIff(ifExit.GetValue()) || IsIff(elseExit.GetValue())) { return(false); } List <Exprent> data = new List <Exprent>(statement.GetFirst().GetExprents()); data.Add(new ExitExprent(ifExit.GetExitType(), new FunctionExprent(FunctionExprent .Function_Iif, Sharpen.Arrays.AsList(statement.GetHeadexprent().GetCondition(), ifExit.GetValue(), elseExit.GetValue()), ifHeadExprBytecode), ifExit.GetRetType( ), ifHeadExprBytecode)); statement.SetExprents(data); StatEdge retEdge = ifStatement.GetAllSuccessorEdges()[0]; Statement closure = retEdge.closure == statement?statement.GetParent() : retEdge .closure; statement.AddSuccessor(new StatEdge(StatEdge.Type_Break, statement, retEdge.GetDestination (), closure)); SequenceHelper.DestroyAndFlattenStatement(statement); return(true); } } } } } return(false); }
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); }