private void MergeInVarMaps(DirectNode node, DirectGraph dgraph) { SFormsFastMapDirect mapNew = new SFormsFastMapDirect(); foreach (DirectNode pred in node.preds) { SFormsFastMapDirect mapOut = GetFilteredOutMap(node.id, pred.id, dgraph, node.id); if (mapNew.IsEmpty()) { mapNew = mapOut.GetCopy(); } else { MergeMaps(mapNew, mapOut); } } if (extraVarVersions.ContainsKey(node.id)) { SFormsFastMapDirect mapExtra = extraVarVersions.GetOrNull(node.id); if (mapNew.IsEmpty()) { mapNew = mapExtra.GetCopy(); } else { MergeMaps(mapNew, mapExtra); } } Sharpen.Collections.Put(inVarVersions, node.id, mapNew); }
private static void AddToReversePostOrderListIterative(DirectNode root, LinkedList <DirectNode> lst) { LinkedList <DirectNode> stackNode = new LinkedList <DirectNode>(); LinkedList <int> stackIndex = new LinkedList <int>(); HashSet <DirectNode> setVisited = new HashSet <DirectNode>(); stackNode.AddLast(root); stackIndex.AddLast(0); while (!(stackNode.Count == 0)) { DirectNode node = stackNode.Last.Value; int index = Sharpen.Collections.RemoveLast(stackIndex); setVisited.Add(node); for (; index < node.succs.Count; index++) { DirectNode succ = node.succs[index]; if (!setVisited.Contains(succ)) { stackIndex.AddLast(index + 1); stackNode.AddLast(succ); stackIndex.AddLast(0); break; } } if (index == node.succs.Count) { lst.AddFirst(node); Sharpen.Collections.RemoveLast(stackNode); } } }
public virtual bool IterateExprents(Func <Exprent, int> iter) { LinkedList <DirectNode> stack = new LinkedList <DirectNode>(); stack.AddLast(first); HashSet <DirectNode> setVisited = new HashSet <DirectNode>(); while (!(stack.Count == 0)) { DirectNode node = Sharpen.Collections.RemoveFirst(stack); if (setVisited.Contains(node)) { continue; } setVisited.Add(node); for (int i = 0; i < node.exprents.Count; i++) { int res = iter(node.exprents[i]); if (res == 1) { return(false); } if (res == 2) { node.exprents.RemoveAtReturningValue(i); i--; } } Sharpen.Collections.AddAll(stack, node.succs); } return(true); }
private void SetEdges() { foreach (FlattenStatementsHelper.Edge edge in listEdges) { string sourceid = edge.sourceid; int statid = edge.statid; DirectNode source = graph.nodes.GetWithKey(sourceid); DirectNode dest = graph.nodes.GetWithKey(mapDestinationNodes.GetOrNull(statid)[edge .edgetype == StatEdge.Type_Continue ? 1 : 0]); if (!source.succs.Contains(dest)) { source.succs.Add(dest); } if (!dest.preds.Contains(source)) { dest.preds.Add(source); } if (mapPosIfBranch.ContainsKey(sourceid) && !statid.Equals(mapPosIfBranch.GetOrNullable (sourceid))) { Sharpen.Collections.Put(graph.mapNegIfBranch, sourceid, dest.id); } } for (int i = 0; i < 2; i++) { foreach (KeyValuePair <string, List <string[]> > ent in (i == 0 ? mapShortRangeFinallyPathIds : mapLongRangeFinallyPathIds)) { List <FlattenStatementsHelper.FinallyPathWrapper> newLst = new List <FlattenStatementsHelper.FinallyPathWrapper >(); List <string[]> lst = ent.Value; foreach (string[] arr in lst) { bool isContinueEdge = arr[i == 0 ? 4 : 3] != null; DirectNode dest = graph.nodes.GetWithKey(mapDestinationNodes.GetOrNull(System.Convert.ToInt32 (arr[1]))[isContinueEdge ? 1 : 0]); DirectNode enter = graph.nodes.GetWithKey(mapDestinationNodes.GetOrNull(System.Convert.ToInt32 (arr[2]))[0]); newLst.Add(new FlattenStatementsHelper.FinallyPathWrapper(arr[0], dest.id, enter. id)); if (i == 0 && arr[3] != null) { Sharpen.Collections.Put(graph.mapFinallyMonitorExceptionPathExits, ent.Key, dest. id); } } if (!(newLst.Count == 0)) { Sharpen.Collections.Put((i == 0 ? graph.mapShortRangeFinallyPaths : graph.mapLongRangeFinallyPaths ), ent.Key, new List <FlattenStatementsHelper.FinallyPathWrapper>(new HashSet <FlattenStatementsHelper.FinallyPathWrapper >(newLst))); } } } }
internal StackEntry(CatchAllStatement catchstatement, bool state, int edgetype, Statement destination, Statement finallyShortRangeEntry, Statement finallyLongRangeEntry, DirectNode finallyShortRangeSource, DirectNode finallyLongRangeSource, bool isFinallyExceptionPath ) { this.catchstatement = catchstatement; this.state = state; this.edgetype = edgetype; this.isFinallyExceptionPath = isFinallyExceptionPath; this.destination = destination; this.finallyShortRangeEntry = finallyShortRangeEntry; this.finallyLongRangeEntry = finallyLongRangeEntry; this.finallyShortRangeSource = finallyShortRangeSource; this.finallyLongRangeSource = finallyLongRangeSource; }
// statement.id, node.id(direct), node.id(continue) // node.id(source), statement.id(destination), edge type // node.id(exit), [node.id(source), statement.id(destination)] // node.id(exit), [node.id(source), statement.id(destination)] // positive if branches public virtual DirectGraph BuildDirectGraph(RootStatement root) { this.root = root; graph = new DirectGraph(); FlattenStatement(); // dummy exit node Statement dummyexit = root.GetDummyExit(); DirectNode node = new DirectNode(DirectNode.Node_Direct, dummyexit, dummyexit.id. ToString()); node.exprents = new List <Exprent>(); graph.nodes.AddWithKey(node, node.id); Sharpen.Collections.Put(mapDestinationNodes, dummyexit.id, new string[] { node.id , null }); SetEdges(); graph.first = graph.nodes.GetWithKey(mapDestinationNodes.GetOrNull(root.id)[0]); graph.SortReversePostOrder(); return(graph); }
private void SaveEdge(DirectNode sourcenode, Statement destination, int edgetype, DirectNode finallyShortRangeSource, DirectNode finallyLongRangeSource, Statement finallyShortRangeEntry, Statement finallyLongRangeEntry, bool isFinallyMonitorExceptionPath ) { if (edgetype != StatEdge.Type_Finallyexit) { listEdges.Add(new FlattenStatementsHelper.Edge(sourcenode.id, destination.id, edgetype )); } if (finallyShortRangeSource != null) { bool isContinueEdge = (edgetype == StatEdge.Type_Continue); mapShortRangeFinallyPathIds.ComputeIfAbsent(sourcenode.id, (string k) => new List <string[]>()).Add(new string[] { finallyShortRangeSource.id, destination.id.ToString (), finallyShortRangeEntry.id.ToString(), isFinallyMonitorExceptionPath ? "1" : null, isContinueEdge ? "1" : null }); mapLongRangeFinallyPathIds.ComputeIfAbsent(sourcenode.id, (string k) => new List < string[]>()).Add(new string[] { finallyLongRangeSource.id, destination.id.ToString (), finallyLongRangeEntry.id.ToString(), isContinueEdge ? "1" : null }); } }
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 :; }