private void FlattenStatement() { LinkedList <_T2081736913> lstStackStatements = new LinkedList <_T2081736913>(); lstStackStatements.AddLast(new _T2081736913(this, root, new LinkedList <FlattenStatementsHelper.StackEntry >(), null)); while (!(lstStackStatements.Count == 0)) { _T2081736913 statEntry = Sharpen.Collections.RemoveFirst(lstStackStatements); Statement stat = statEntry.statement; LinkedList <FlattenStatementsHelper.StackEntry> stackFinally = statEntry.stackFinally; int statementBreakIndex = statEntry.statementIndex; DirectNode node; DirectNode nd; List <StatEdge> lstSuccEdges = new List <StatEdge>(); DirectNode sourcenode = null; if (statEntry.succEdges == null) { switch (stat.type) { case Statement.Type_Basicblock: { node = new DirectNode(DirectNode.Node_Direct, stat, (BasicBlockStatement)stat); if (stat.GetExprents() != null) { node.exprents = stat.GetExprents(); } graph.nodes.PutWithKey(node, node.id); Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { node.id, null }); Sharpen.Collections.AddAll(lstSuccEdges, stat.GetSuccessorEdges(Statement.Statedge_Direct_All )); sourcenode = node; List <Exprent> tailExprentList = statEntry.tailExprents; if (tailExprentList != null) { DirectNode tail = new DirectNode(DirectNode.Node_Tail, stat, stat.id + "_tail"); tail.exprents = tailExprentList; graph.nodes.PutWithKey(tail, tail.id); Sharpen.Collections.Put(mapDestinationNodes, -stat.id, new string[] { tail.id, null }); listEdges.Add(new FlattenStatementsHelper.Edge(node.id, -stat.id, StatEdge.Type_Regular )); sourcenode = tail; } // 'if' statement: record positive branch if (stat.GetLastBasicType() == Statement.Lastbasictype_If) { Sharpen.Collections.Put(mapPosIfBranch, sourcenode.id, lstSuccEdges[0].GetDestination ().id); } break; } case Statement.Type_Catchall: case Statement.Type_Trycatch: { DirectNode firstnd = new DirectNode(DirectNode.Node_Try, stat, stat.id + "_try"); Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { firstnd.id, null }); graph.nodes.PutWithKey(firstnd, firstnd.id); LinkedList <_T2081736913> lst = new LinkedList <_T2081736913>(); foreach (Statement st in stat.GetStats()) { listEdges.Add(new FlattenStatementsHelper.Edge(firstnd.id, st.id, StatEdge.Type_Regular )); LinkedList <FlattenStatementsHelper.StackEntry> stack = stackFinally; if (stat.type == Statement.Type_Catchall && ((CatchAllStatement)stat).IsFinally()) { stack = new LinkedList <FlattenStatementsHelper.StackEntry>(stackFinally); if (st == stat.GetFirst()) { // catch head stack.AddLast(new FlattenStatementsHelper.StackEntry((CatchAllStatement)stat, false)); } else { // handler stack.AddLast(new FlattenStatementsHelper.StackEntry((CatchAllStatement)stat, true, StatEdge .Type_Break, root.GetDummyExit(), st, st, firstnd, firstnd, true)); } } lst.AddLast(new _T2081736913(this, st, stack, null)); } lstStackStatements = new LinkedList <_T2081736913>(lst.Concat(lstStackStatements)); break; } case Statement.Type_Do: { if (statementBreakIndex == 0) { statEntry.statementIndex = 1; lstStackStatements.AddFirst(statEntry); lstStackStatements.AddFirst(new _T2081736913(this, stat.GetFirst(), stackFinally, null)); goto mainloop_continue; } nd = graph.nodes.GetWithKey(mapDestinationNodes.GetOrNull(stat.GetFirst().id)[0]); DoStatement dostat = (DoStatement)stat; int looptype = dostat.GetLooptype(); if (looptype == DoStatement.Loop_Do) { Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { nd.id, nd.id }); break; } lstSuccEdges.Add(stat.GetSuccessorEdges(Statement.Statedge_Direct_All)[0]); switch (looptype) { case DoStatement.Loop_While: case DoStatement.Loop_Dowhile: { // exactly one edge node = new DirectNode(DirectNode.Node_Condition, stat, stat.id + "_cond"); node.exprents = dostat.GetConditionExprentList(); graph.nodes.PutWithKey(node, node.id); listEdges.Add(new FlattenStatementsHelper.Edge(node.id, stat.GetFirst().id, StatEdge .Type_Regular)); if (looptype == DoStatement.Loop_While) { Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { node.id, node .id }); } else { Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { nd.id, node. id }); bool found = false; foreach (FlattenStatementsHelper.Edge edge in listEdges) { if (edge.statid.Equals(stat.id) && edge.edgetype == StatEdge.Type_Continue) { found = true; break; } } if (!found) { listEdges.Add(new FlattenStatementsHelper.Edge(nd.id, stat.id, StatEdge.Type_Continue )); } } sourcenode = node; break; } case DoStatement.Loop_For: { DirectNode nodeinit = new DirectNode(DirectNode.Node_Init, stat, stat.id + "_init" ); if (dostat.GetInitExprent() != null) { nodeinit.exprents = dostat.GetInitExprentList(); } graph.nodes.PutWithKey(nodeinit, nodeinit.id); DirectNode nodecond = new DirectNode(DirectNode.Node_Condition, stat, stat.id + "_cond" ); nodecond.exprents = dostat.GetConditionExprentList(); graph.nodes.PutWithKey(nodecond, nodecond.id); DirectNode nodeinc = new DirectNode(DirectNode.Node_Increment, stat, stat.id + "_inc" ); nodeinc.exprents = dostat.GetIncExprentList(); graph.nodes.PutWithKey(nodeinc, nodeinc.id); Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { nodeinit.id, nodeinc.id }); Sharpen.Collections.Put(mapDestinationNodes, -stat.id, new string[] { nodecond.id , null }); listEdges.Add(new FlattenStatementsHelper.Edge(nodecond.id, stat.GetFirst().id, StatEdge .Type_Regular)); listEdges.Add(new FlattenStatementsHelper.Edge(nodeinit.id, -stat.id, StatEdge.Type_Regular )); listEdges.Add(new FlattenStatementsHelper.Edge(nodeinc.id, -stat.id, StatEdge.Type_Regular )); bool found_1 = false; foreach (FlattenStatementsHelper.Edge edge in listEdges) { if (edge.statid.Equals(stat.id) && edge.edgetype == StatEdge.Type_Continue) { found_1 = true; break; } } if (!found_1) { listEdges.Add(new FlattenStatementsHelper.Edge(nd.id, stat.id, StatEdge.Type_Continue )); } sourcenode = nodecond; break; } } break; } case Statement.Type_Syncronized: case Statement.Type_Switch: case Statement.Type_If: case Statement.Type_Sequence: case Statement.Type_Root: { int statsize = stat.GetStats().Count; if (stat.type == Statement.Type_Syncronized) { statsize = 2; } // exclude the handler if synchronized if (statementBreakIndex <= statsize) { List <Exprent> tailexprlst = null; switch (stat.type) { case Statement.Type_Syncronized: { tailexprlst = ((SynchronizedStatement)stat).GetHeadexprentList(); break; } case Statement.Type_Switch: { tailexprlst = ((SwitchStatement)stat).GetHeadexprentList(); break; } case Statement.Type_If: { tailexprlst = ((IfStatement)stat).GetHeadexprentList(); break; } } for (int i = statementBreakIndex; i < statsize; i++) { statEntry.statementIndex = i + 1; lstStackStatements.AddFirst(statEntry); lstStackStatements.AddFirst(new _T2081736913(this, stat.GetStats()[i], stackFinally , (i == 0 && tailexprlst != null && tailexprlst[0] != null) ? tailexprlst : null )); goto mainloop_continue; } node = graph.nodes.GetWithKey(mapDestinationNodes.GetOrNull(stat.GetFirst().id)[0 ]); Sharpen.Collections.Put(mapDestinationNodes, stat.id, new string[] { node.id, null }); if (stat.type == Statement.Type_If && ((IfStatement)stat).iftype == IfStatement.Iftype_If) { lstSuccEdges.Add(stat.GetSuccessorEdges(Statement.Statedge_Direct_All)[0]); // exactly one edge sourcenode = tailexprlst[0] == null ? node : graph.nodes.GetWithKey(node.id + "_tail" ); } } break; } } } // no successor edges if (sourcenode != null) { if (statEntry.succEdges != null) { lstSuccEdges = statEntry.succEdges; } for (int edgeindex = statEntry.edgeIndex; edgeindex < lstSuccEdges.Count; edgeindex ++) { StatEdge edge = lstSuccEdges[edgeindex]; LinkedList <FlattenStatementsHelper.StackEntry> stack = new LinkedList <FlattenStatementsHelper.StackEntry >(stackFinally); int edgetype = edge.GetType(); Statement destination = edge.GetDestination(); DirectNode finallyShortRangeSource = sourcenode; DirectNode finallyLongRangeSource = sourcenode; Statement finallyShortRangeEntry = null; Statement finallyLongRangeEntry = null; bool isFinallyMonitorExceptionPath = false; bool isFinallyExit = false; while (true) { FlattenStatementsHelper.StackEntry entry = null; if (!(stack.Count == 0)) { entry = stack.Last(); } bool created = true; if (entry == null) { SaveEdge(sourcenode, destination, edgetype, isFinallyExit ? finallyShortRangeSource : null, finallyLongRangeSource, finallyShortRangeEntry, finallyLongRangeEntry, isFinallyMonitorExceptionPath); } else { CatchAllStatement catchall = entry.catchstatement; if (entry.state) { // finally handler statement if (edgetype == StatEdge.Type_Finallyexit) { Sharpen.Collections.RemoveLast(stack); destination = entry.destination; edgetype = entry.edgetype; finallyShortRangeSource = entry.finallyShortRangeSource; finallyLongRangeSource = entry.finallyLongRangeSource; finallyShortRangeEntry = entry.finallyShortRangeEntry; finallyLongRangeEntry = entry.finallyLongRangeEntry; isFinallyExit = true; isFinallyMonitorExceptionPath = (catchall.GetMonitor() != null) & entry.isFinallyExceptionPath; created = false; } else if (!catchall.ContainsStatementStrict(destination)) { Sharpen.Collections.RemoveLast(stack); created = false; } else { SaveEdge(sourcenode, destination, edgetype, isFinallyExit ? finallyShortRangeSource : null, finallyLongRangeSource, finallyShortRangeEntry, finallyLongRangeEntry, isFinallyMonitorExceptionPath); } } else if (!catchall.ContainsStatementStrict(destination)) { // finally protected try statement SaveEdge(sourcenode, catchall.GetHandler(), StatEdge.Type_Regular, isFinallyExit ? finallyShortRangeSource : null, finallyLongRangeSource, finallyShortRangeEntry, finallyLongRangeEntry, isFinallyMonitorExceptionPath); Sharpen.Collections.RemoveLast(stack); stack.AddLast(new FlattenStatementsHelper.StackEntry(catchall, true, edgetype, destination , catchall.GetHandler(), finallyLongRangeEntry == null ? catchall.GetHandler() : finallyLongRangeEntry, sourcenode, finallyLongRangeSource, false)); statEntry.edgeIndex = edgeindex + 1; statEntry.succEdges = lstSuccEdges; lstStackStatements.AddFirst(statEntry); lstStackStatements.AddFirst(new _T2081736913(this, catchall.GetHandler(), stack, null)); goto mainloop_continue; } else { SaveEdge(sourcenode, destination, edgetype, isFinallyExit ? finallyShortRangeSource : null, finallyLongRangeSource, finallyShortRangeEntry, finallyLongRangeEntry, isFinallyMonitorExceptionPath); } } if (created) { break; } } } } mainloop_continue :; } mainloop_break :; }
private bool IterateStatements(RootStatement root, SSAUConstructorSparseEx ssa) { FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); DirectGraph dgraph = flatthelper.BuildDirectGraph(root); bool res = false; HashSet <DirectNode> setVisited = new HashSet <DirectNode>(); LinkedList <DirectNode> stack = new LinkedList <DirectNode>(); LinkedList <Dictionary <VarVersionPair, Exprent> > stackMaps = new LinkedList <Dictionary <VarVersionPair, Exprent> >(); stack.AddLast(dgraph.first); stackMaps.AddLast(new Dictionary <VarVersionPair, Exprent>()); while (!(stack.Count == 0)) { DirectNode nd = Sharpen.Collections.RemoveFirst(stack); Dictionary <VarVersionPair, Exprent> mapVarValues = Sharpen.Collections.RemoveFirst (stackMaps); if (setVisited.Contains(nd)) { continue; } setVisited.Add(nd); List <List <Exprent> > lstLists = new List <List <Exprent> >(); if (!(nd.exprents.Count == 0)) { lstLists.Add(nd.exprents); } if (nd.succs.Count == 1) { DirectNode ndsucc = nd.succs[0]; if (ndsucc.type == DirectNode.Node_Tail && !(ndsucc.exprents.Count == 0)) { lstLists.Add(nd.succs[0].exprents); nd = ndsucc; } } for (int i = 0; i < lstLists.Count; i++) { List <Exprent> lst = lstLists[i]; int index = 0; while (index < lst.Count) { Exprent next = null; if (index == lst.Count - 1) { if (i < lstLists.Count - 1) { next = lstLists[i + 1][0]; } } else { next = lst[index + 1]; } int[] ret = IterateExprent(lst, index, next, mapVarValues, ssa); if (ret[0] >= 0) { index = ret[0]; } else { index++; } res |= (ret[1] == 1); } } foreach (DirectNode ndx in nd.succs) { stack.AddLast(ndx); stackMaps.AddLast(new Dictionary <VarVersionPair, Exprent>(mapVarValues)); } // make sure the 3 special exprent lists in a loop (init, condition, increment) are not empty // change loop type if necessary if ((nd.exprents.Count == 0) && (nd.type == DirectNode.Node_Init || nd.type == DirectNode .Node_Condition || nd.type == DirectNode.Node_Increment)) { nd.exprents.Add(null); if (nd.statement.type == Statement.Type_Do) { DoStatement loop = (DoStatement)nd.statement; if (loop.GetLooptype() == DoStatement.Loop_For && loop.GetInitExprent() == null && loop.GetIncExprent() == null) { // "downgrade" loop to 'while' loop.SetLooptype(DoStatement.Loop_While); } } } } return(res); }
public virtual void SetVarDefinitions() { VarNamesCollector vc = varproc.GetVarNamesCollector(); foreach (KeyValuePair <int, Statement> en in mapVarDefStatements) { Statement stat = en.Value; int index = en.Key; if (implDefVars.Contains(index)) { // already implicitly defined continue; } varproc.SetVarName(new VarVersionPair(index, 0), vc.GetFreeName(index)); // special case for if (stat.type == Statement.Type_Do) { DoStatement dstat = (DoStatement)stat; if (dstat.GetLooptype() == DoStatement.Loop_For) { if (dstat.GetInitExprent() != null && SetDefinition(dstat.GetInitExprent(), index )) { continue; } else { List <Exprent> lstSpecial = Sharpen.Arrays.AsList(dstat.GetConditionExprent(), dstat .GetIncExprent()); foreach (VarExprent var in GetAllVars(lstSpecial)) { if (var.GetIndex() == index) { stat = stat.GetParent(); break; } } } } } Statement first = FindFirstBlock(stat, index); List <Exprent> lst; if (first == null) { lst = stat.GetVarDefinitions(); } else if (first.GetExprents() == null) { lst = first.GetVarDefinitions(); } else { lst = first.GetExprents(); } bool defset = false; // search for the first assignment to var [index] int addindex = 0; foreach (Exprent expr in lst) { if (SetDefinition(expr, index)) { defset = true; break; } else { bool foundvar = false; foreach (Exprent exp in expr.GetAllExprents(true)) { if (exp.type == Exprent.Exprent_Var && ((VarExprent)exp).GetIndex() == index) { foundvar = true; break; } } if (foundvar) { break; } } addindex++; } if (!defset) { VarExprent var = new VarExprent(index, varproc.GetVarType(new VarVersionPair(index , 0)), varproc); var.SetDefinition(true); lst.Add(addindex, var); } } }