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 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); }