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)); } }
public static void LowContinueLabels(Statement stat, HashSet <StatEdge> edges) { bool ok = (stat.type != Statement.Type_Do); if (!ok) { DoStatement dostat = (DoStatement)stat; ok = dostat.GetLooptype() == DoStatement.Loop_Do || dostat.GetLooptype() == DoStatement .Loop_While || (dostat.GetLooptype() == DoStatement.Loop_For && dostat.GetIncExprent () == null); } if (ok) { Sharpen.Collections.AddAll(edges, stat.GetPredecessorEdges(StatEdge.Type_Continue )); } if (ok && stat.type == Statement.Type_Do) { foreach (StatEdge edge in edges) { if (stat.ContainsStatementStrict(edge.GetSource())) { edge.GetDestination().RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, stat); stat.AddPredecessor(edge); stat.AddLabeledEdge(edge); } } } foreach (Statement st in stat.GetStats()) { if (st == stat.GetFirst()) { LowContinueLabels(st, edges); } else { LowContinueLabels(st, new HashSet <StatEdge>()); } } }
public static bool SplitIrreducibleNode(Statement statement) { Statement splitnode = GetCandidateForSplitting(statement); if (splitnode == null) { return(false); } StatEdge enteredge = splitnode.GetPredecessorEdges(StatEdge.Type_Regular).GetEnumerator ().Current; // copy the smallest statement Statement splitcopy = CopyStatement(splitnode, null, new Dictionary <Statement, Statement >()); InitCopiedStatement(splitcopy); // insert the copy splitcopy.SetParent(statement); statement.GetStats().AddWithKey(splitcopy, splitcopy.id); // switch input edges foreach (StatEdge prededge in splitnode.GetPredecessorEdges(Statement.Statedge_Direct_All )) { if (prededge.GetSource() == enteredge.GetSource() || prededge.closure == enteredge .GetSource()) { splitnode.RemovePredecessor(prededge); prededge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, prededge, splitcopy ); splitcopy.AddPredecessor(prededge); } } // connect successors foreach (StatEdge succ in splitnode.GetSuccessorEdges(Statement.Statedge_Direct_All )) { splitcopy.AddSuccessor(new StatEdge(succ.GetType(), splitcopy, succ.GetDestination (), succ.closure)); } return(true); }
private static void BuildSynchronized(Statement stat) { foreach (Statement st in stat.GetStats()) { BuildSynchronized(st); } if (stat.type == Statement.Type_Sequence) { while (true) { bool found = false; List <Statement> lst = stat.GetStats(); for (int i = 0; i < lst.Count - 1; i++) { Statement current = lst[i]; // basic block if (current.IsMonitorEnter()) { Statement next = lst[i + 1]; Statement nextDirect = next; while (next.type == Statement.Type_Sequence) { next = next.GetFirst(); } if (next.type == Statement.Type_Catchall) { CatchAllStatement ca = (CatchAllStatement)next; if (ca.GetFirst().IsContainsMonitorExit() && ca.GetHandler().IsContainsMonitorExit ()) { // remove the head block from sequence current.RemoveSuccessor(current.GetSuccessorEdges(Statement.Statedge_Direct_All)[ 0]); foreach (StatEdge edge in current.GetPredecessorEdges(Statement.Statedge_Direct_All )) { current.RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, nextDirect); nextDirect.AddPredecessor(edge); } stat.GetStats().RemoveWithKey(current.id); stat.SetFirst(stat.GetStats()[0]); // new statement SynchronizedStatement sync = new SynchronizedStatement(current, ca.GetFirst(), ca .GetHandler()); sync.SetAllParent(); foreach (StatEdge edge in new HashSet <StatEdge>(ca.GetLabelEdges())) { sync.AddLabeledEdge(edge); } current.AddSuccessor(new StatEdge(StatEdge.Type_Regular, current, ca.GetFirst())); ca.GetParent().ReplaceStatement(ca, sync); found = true; break; } } } } if (!found) { break; } } } }
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]); } }
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); }