private static Statement GetNextStatement(Statement stat) { Statement parent = stat.GetParent(); switch (parent.type) { case Statement.Type_Root: { return(((RootStatement)parent).GetDummyExit()); } case Statement.Type_Do: { return(parent); } case Statement.Type_Sequence: { SequenceStatement sequence = (SequenceStatement)parent; if (sequence.GetStats().GetLast() != stat) { for (int i = sequence.GetStats().Count - 1; i >= 0; i--) { if (sequence.GetStats()[i] == stat) { return(sequence.GetStats()[i + 1]); } } } break; } } return(GetNextStatement(parent)); }
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 DetectStatement(Statement head) { Statement res; if ((res = DoStatement.IsHead(head)) != null) { return(res); } if ((res = SwitchStatement.IsHead(head)) != null) { return(res); } if ((res = IfStatement.IsHead(head)) != null) { return(res); } // synchronized statements will be identified later // right now they are recognized as catchall if ((res = SequenceStatement.IsHead2Block(head)) != null) { return(res); } if ((res = CatchStatement.IsHead(head)) != null) { return(res); } if ((res = CatchAllStatement.IsHead(head)) != null) { return(res); } return(null); }
public WhileAST sequenceStatements(WhileAST first, List <WhileAST> next) { var seq = new SequenceStatement(first as Statement); seq.AddRange(next.Cast <Statement>().ToList()); return(seq); }
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); }
public void TestAssignAdd() { var buildResult = buildParser(); Assert.False(buildResult.IsError); var parser = buildResult.Result; ParseResult <WhileToken, WhileAST> result = parser.Parse("(a:=1+1)"); Assert.False(result.IsError); Assert.NotNull(result.Result); Assert.IsType <SequenceStatement>(result.Result); SequenceStatement seq = result.Result as SequenceStatement; Assert.IsType <AssignStatement>(seq.Get(0)); AssignStatement assign = seq.Get(0) as AssignStatement; Assert.Equal("a", assign.VariableName); Expression val = assign.Value; Assert.IsType <BinaryOperation>(val); BinaryOperation bin = val as BinaryOperation; Assert.Equal(BinaryOperator.ADD, bin.Operator); Assert.Equal(1, (bin.Left as IntegerConstant)?.Value); Assert.Equal(1, (bin.Right as IntegerConstant)?.Value); }
public void TestPrintBoolExpression() { var buildResult = buildParser(); Assert.False(buildResult.IsError); var parser = buildResult.Result; ParseResult <WhileToken, WhileAST> result = parser.Parse("print true and false"); Assert.False(result.IsError); Assert.NotNull(result.Result); Assert.IsType <SequenceStatement>(result.Result); SequenceStatement seq = result.Result as SequenceStatement; Assert.IsType <PrintStatement>(seq.Get(0)); PrintStatement print = seq.Get(0) as PrintStatement; Expression expr = print.Value; Assert.IsType <BinaryOperation>(expr); BinaryOperation bin = expr as BinaryOperation; Assert.Equal(BinaryOperator.AND, bin.Operator); Assert.True((bin.Left as BoolConstant)?.Value); Assert.False((bin.Right as BoolConstant)?.Value); }
public void TestInfiniteWhile() { var buildResult = buildParser(); Assert.False(buildResult.IsError); var parser = buildResult.Result; ParseResult <WhileToken, WhileAST> result = parser.Parse("while true do (skip)"); Assert.False(result.IsError); Assert.NotNull(result.Result); Assert.IsType <SequenceStatement>(result.Result); SequenceStatement seq = result.Result as SequenceStatement; Assert.IsType <WhileStatement>(seq.Get(0)); WhileStatement whil = seq.Get(0) as WhileStatement; Expression cond = whil.Condition; Assert.IsType <BoolConstant>(cond); Assert.True((cond as BoolConstant).Value); Statement s = whil.BlockStmt; Assert.IsType <SequenceStatement>(whil.BlockStmt); SequenceStatement seqBlock = whil.BlockStmt as SequenceStatement; Assert.Equal(1, seqBlock.Count); Assert.IsType <SkipStatement>(seqBlock.Get(0)); ; }
public Void Visit(SequenceStatement sequenceStatement, SortedSet <string> free) { sequenceStatement.head.Accept(this, free); sequenceStatement.tail.Accept(this, free); return(null); }
private void Interprete(SequenceStatement ast, InterpreterContext context) { for (var i = 0; i < ast.Count; i++) { var stmt = ast.Get(i); Interprete(stmt, context); } }
public Type Visit(SequenceStatement sequenceStatement) { if (sequenceStatement.head != null) { ((SequenceStatement)sequenceStatement.head).Accept(this); } sequenceStatement.tail.Accept(this); return(null); }
public Type Visit(SequenceStatement sequenceStatement, FunctionGeneratorEnvironment arg) { if (sequenceStatement.head != null) { ((SequenceStatement)sequenceStatement.head).Accept(this, arg); } sequenceStatement.tail.Accept(this, arg); return(null); }
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 void SemanticCheck(SequenceStatement ast, CompilerContext context) { context.OpenNewScope(); ast.CompilerScope = context.CurrentScope; for (int i = 0; i < ast.Count; i++) { Statement stmt = ast.Get(i); SemanticCheck(stmt, context); } context.CloseScope(); }
public Statement Visit(SequenceStatement sequenceStatement) { //State.ScopeStart(); //Console.WriteLine("SEQUENCE STATEMENT TAIL"); if (sequenceStatement.head != null) { sequenceStatement.head.Accept(this); } sequenceStatement.tail.Accept(this); //State.ScopeEnd(); return(null); }
public void TestSkip() { var buildResult = buildParser(); Assert.False(buildResult.IsError); var parser = buildResult.Result; ParseResult <WhileToken, WhileAST> result = parser.Parse("skip"); Assert.False(result.IsError); Assert.NotNull(result.Result); Assert.IsType <SequenceStatement>(result.Result); SequenceStatement seq = result.Result as SequenceStatement; Assert.IsType <SkipStatement>(seq.Get(0)); }
public void TestIfThenElse() { var buildResult = buildParser(); Assert.False(buildResult.IsError); var parser = buildResult.Result; ParseResult <WhileToken, WhileAST> result = parser.Parse("if true then (a := \"hello\") else (b := \"world\")"); Assert.False(result.IsError); Assert.NotNull(result.Result); Assert.IsType <SequenceStatement>(result.Result); SequenceStatement seq = result.Result as SequenceStatement; Assert.IsType <IfStatement>(seq.Get(0)); IfStatement si = seq.Get(0) as IfStatement; Expression cond = si.Condition; Assert.IsType <BoolConstant>(cond); Assert.True((cond as BoolConstant).Value); Statement s = si.ThenStmt; Assert.IsType <SequenceStatement>(si.ThenStmt); SequenceStatement thenBlock = si.ThenStmt as SequenceStatement; Assert.Equal(1, thenBlock.Count); Assert.IsType <AssignStatement>(thenBlock.Get(0)); AssignStatement thenAssign = thenBlock.Get(0) as AssignStatement; Assert.Equal("a", thenAssign.VariableName); Assert.IsType <StringConstant>(thenAssign.Value); Assert.Equal("hello", (thenAssign.Value as StringConstant).Value); ; Assert.IsType <SequenceStatement>(si.ElseStmt); SequenceStatement elseBlock = si.ElseStmt as SequenceStatement; Assert.Equal(1, elseBlock.Count); Assert.IsType <AssignStatement>(elseBlock.Get(0)); AssignStatement elseAssign = elseBlock.Get(0) as AssignStatement; Assert.Equal("b", elseAssign.VariableName); Assert.IsType <StringConstant>(elseAssign.Value); Assert.Equal("world", (elseAssign.Value as StringConstant).Value); }
public IValue Visit(SequenceStatement sequenceStatement) { //Console.WriteLine("SEQUENCE STATEMENT"); if (sequenceStatement.head != null) { if (Environment.ReturnValue != null) { return(null); } ((SequenceStatement)sequenceStatement.head).Accept(this); } if (Environment.ReturnValue != null) { return(null); } //Console.WriteLine("SEQUENCE STATEMENT TAIL"); sequenceStatement.tail.Accept(this); return(null); }
private static bool InlineSingleBlocksRec(Statement stat) { bool res = false; foreach (Statement st in stat.GetStats()) { res |= InlineSingleBlocksRec(st); } if (stat.type == Statement.Type_Sequence) { SequenceStatement seq = (SequenceStatement)stat; for (int i = 1; i < seq.GetStats().Count; i++) { if (IsInlineable(seq, i)) { InlineBlock(seq, i); return(true); } } } return(res); }
private static void MergeFlatStatements(SequenceStatement sequence) { while (true) { Statement next; Statement current = null; bool found = false; for (int i = sequence.GetStats().Count - 1; i >= 0; i--) { next = current; current = sequence.GetStats()[i]; if (next != null && current.GetExprents() != null && !(current.GetExprents().Count == 0)) { if (next.GetExprents() != null) { next.GetExprents().InsertRange(0, current.GetExprents()); current.GetExprents().Clear(); found = true; } else { Statement first = GetFirstExprentlist(next); if (first != null) { first.GetExprents().InsertRange(0, current.GetExprents()); current.GetExprents().Clear(); found = true; } } } } if (!found) { break; } } }
public void TestSkipAssignSequence() { var buildResult = buildParser(); Assert.False(buildResult.IsError); var parser = buildResult.Result; ParseResult <WhileToken, WhileAST> result = parser.Parse("(a:=1; b:=2; c:=3)"); Assert.False(result.IsError); Assert.NotNull(result.Result); Assert.IsType <SequenceStatement>(result.Result); SequenceStatement seq = result.Result as SequenceStatement; Assert.Equal(3, seq.Count); string[] names = new string[] { "a", "b", "c" }; for (int i = 0; i < names.Length; i++) { Assert.IsType <AssignStatement>(seq.Get(i)); AssignStatement assign = seq.Get(i) as AssignStatement; Assert.Equal(names[i], assign.VariableName); Assert.Equal(i + 1, (assign.Value as IntegerConstant).Value); } }
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); }
public override void ExplicitVisit(SequenceStatement node) { this.action(node); }
public override void ExplicitVisit(SequenceStatement fragment) { _fragments.Add(fragment); }
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 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]); } }
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); }