public override void AddChildren(ProgramPointBase work) { foreach (var child in GetOutputPoints(work)) { AddWork(child); } }
public override void AddChildren(ProgramPointBase work) { if (work is RCallPoint) { if (AddPoint(work.Extension.Sink)) { unreachableAfterSegmentPoints.Add(work.Extension.Sink); } // create queue for the branching hQueue = new WorkQueue(hQueue); } if (work.AfterWorklistSegment != null) { // add point after branching if (AddPoint(work.AfterWorklistSegment)) { unreachableAfterSegmentPoints.Add(work.AfterWorklistSegment); } // create queue for the branching hQueue = new WorkQueue(hQueue); } foreach (var child in GetOutputPoints(work)) { unreachableAfterSegmentPoints.Remove(child); AddPoint(child); } }
/// <summary> /// Associate points in given sub graph into log. /// </summary> /// <param name="subgraph">Associated subgraph</param> internal void AssociatePointHierarchy(ProgramPointBase subgraph) { var associated = new HashSet <ProgramPointBase>(); var toAssociate = new Queue <ProgramPointBase>(); toAssociate.Enqueue(subgraph); while (toAssociate.Count > 0) { var point = toAssociate.Dequeue(); if (point.Partial != null) { associatePoint(point); } foreach (var relatedPoint in point.FlowParents.Concat(point.FlowChildren)) { if (associated.Contains(relatedPoint)) { continue; } associated.Add(relatedPoint); toAssociate.Enqueue(relatedPoint); } } }
/// <summary> /// Prepend program point as first of contained points. /// Is connected with flow edge to FirstPoint /// </summary> /// <param name="programPoint">Prepended point</param> internal void PreprendFlowWith(ProgramPointBase programPoint) { var first = FirstPoint; programPoint.AddFlowChild(first); _containedPoints.Insert(0, programPoint); }
private void AddWork(ProgramPointBase work) { if (!_containedPoints.Add(work)) { //don't need to add same work twice return; } // open point if (work.FlowParents.Count() > 0 && work.FlowParents.First().FlowChildrenCount > 1 && work.FlowParents.First() != prevParent) { hQueue = new WorkQueue(hQueue); } if (work.FlowParentsCount > 1 && hQueue._parent != null) // close point { hQueue._parent._queue.Enqueue(work); } else { //normal point hQueue._queue.Enqueue(work); //_workQueue.Enqueue(work); } if (work.FlowParents.Count() > 0) { prevParent = work.FlowParents.First(); } }
/// <summary> /// Visits an extension point /// </summary> /// <param name="p">point to visit</param> public override void VisitExtension(ExtensionPoint p) { _currentPoint = p; if (p.Graph.FunctionName == null) { return; } var declaration = p.Graph.SourceObject; var signature = getSignature(declaration); var callPoint = p.Caller as RCallPoint; if (callPoint != null) { if (signature.HasValue) { // We have names for passed arguments setNamedArguments(OutputSet, callPoint.CallSignature, signature.Value, p.Arguments); } else { // There are no names - use numbered arguments setOrderedArguments(OutputSet, p.Arguments, declaration); } } }
private void extendInput(ProgramPointBase point) { var inputs = GetInputPoints(point); if (!inputs.Any()) { return; } point.SetMode(SnapshotMode.InfoLevel); var inSet = GetInSet(point); switch (Direction) { case AnalysisDirection.Forward: forwardExtend(point, inputs, inSet); break; case AnalysisDirection.Backward: standardExtend(inputs, inSet); break; default: throwUnknownDirection(); break; } }
/// <summary> /// Add work into list /// </summary> /// <param name="work">Added work</param> private void AddWork(ProgramPointBase work) { if (!_containedPoints.Add(work)) { //don't need to add same work twice return; } #if IMPORVEDFIXPOINT if (work.FlowParentsCount > 1) { //close point has been found _closeStack.Push(work); } else if (work.FlowParentsCount == 1 && work.FlowParents.First().FlowChildrenCount > 1) { //open point has been found _openStack.Push(work); } else #endif { //normal point _workQueue.Enqueue(work); } }
/// <summary> /// Creates non-contractable points block for single program point /// </summary> /// <param name="createdPoint">Program points which block is created</param> /// <param name="outgoingBlocks">Outgoing edges from current block</param> /// <returns>Created block</returns> internal static PointsBlock ForPoint(ProgramPointBase createdPoint, IEnumerable <BasicBlock> outgoingBlocks) { var pointsBlock = new PointsBlock(outgoingBlocks, new BasicBlockEdge[0], null); pointsBlock._containedPoints.Add(createdPoint); pointsBlock._needsContraction = false; return(pointsBlock); }
private void commit(ProgramPointBase point) { point.SetMode(SnapshotMode.InfoLevel); var outSet = GetOutSet(point); outSet.CommitTransaction(); }
/// <summary> /// Builds the node visualisation. /// </summary> /// <param name="point">The point.</param> /// <param name="graphVisualizer">The graph visualizer.</param> private static void buildNodeVisualisation(ProgramPointBase point, IGraphVisualizer graphVisualizer) { string id = "pp" + point.ProgramPointID.ToString(); string label = string.Format("{0}\n{1}", point.GetType().Name.ToString(), point.ToString()); graphVisualizer.AddNode(id, label); }
public override void AddEntryPoint(ProgramPointBase entryPoint, ProgramPointBase exitPoint) { if (!_containedPoints.Add(entryPoint)) { //don't need to add same work twice return; } hQueue._queue.Enqueue(entryPoint); }
/// <summary> /// Visits an extension sink point /// </summary> /// <param name="p">point to visit</param> public override void VisitExtensionSink(ExtensionSinkPoint p) { _currentPoint = p; var ends = p.OwningExtension.Branches.Where(c => c.Graph.End.OutSet != null).Select(c => c.Graph.End.OutSet).ToArray(); OutputSet.MergeWithCallLevel(p.Extension.Owner, ends); p.ResolveReturnValue(); }
/// <summary> /// Add work into list /// </summary> /// <param name="work">Added work</param> private void AddWork(ProgramPointBase work) { if (!_containedPoints.Add(work)) { //don't need to add same work twice return; } _workQueue.Enqueue(work); }
/// <summary> /// Creates points block containing just given program point. /// <remarks>Created points block is not contractable</remarks> /// </summary> /// <param name="createdPoint">Program point that will be contained in created block.</param> /// <param name="outgoingBlocks">Blocks used as outcomming edges</param> /// <returns>Created points block</returns> private PointsBlock CreateBlockFromProgramPoint(ProgramPointBase newPoint, params BasicBlock[] outgoingBlocks) { reportCreation(newPoint); var createdBlock = PointsBlock.ForPoint(newPoint, outgoingBlocks); _createdBlocks.Add(createdBlock); return(createdBlock); }
public override void AddChildren(ProgramPointBase work) { foreach (var child in GetOutputPoints(work)) { if (!nextPhase || !unreachable(child)) { AddWork(child); } } }
private void prepare(ProgramPointBase point) { point.SetMode(SnapshotMode.InfoLevel); var outSet = GetOutSet(point); var inSet = GetInSet(point); outSet.StartTransaction(); //default extending outSet.Extend(inSet); }
/// <summary> /// Creates new instance of CatchBlockDescription /// </summary> /// <param name="targetPoint">Point where to jump</param> /// <param name="catchedType">Type of Exception</param> /// <param name="catchVariable">Name of catched variables</param> public CatchBlockDescription(ProgramPointBase targetPoint, GenericQualifiedName catchedType, VariableIdentifier catchVariable) { TargetPoint = targetPoint; CatchedType = catchedType; if (CatchedType.QualifiedName.Name.Value == null) { CatchedType = new GenericQualifiedName(new QualifiedName(new Name("$noname"))); } CatchVariable = catchVariable; }
internal FlowExtension(ProgramPointBase owner) { Owner = owner; if (Owner is ExtensionSinkPoint) { //Because of avoiding recursion - extension sink is also sink for self Sink = owner as ExtensionSinkPoint; } else { Sink = new ExtensionSinkPoint(this); } }
protected IEnumerable <ProgramPointBase> GetOutputPoints(ProgramPointBase point) { switch (Direction) { case AnalysisDirection.Forward: return(point.FlowChildren); case AnalysisDirection.Backward: return(point.FlowParents); default: throwUnknownDirection(); return(null); } }
internal FlowOutputSet GetOutSet(ProgramPointBase point) { switch (Direction) { case AnalysisDirection.Forward: return(point.OutSet); case AnalysisDirection.Backward: return(point.InSet as FlowOutputSet); default: throwUnknownDirection(); return(null); } }
private bool AddPoint(ProgramPointBase work) { if (work == exitPoint) { return(false); } // Do not add program point that is already in the worklist. if ((!nextPhase || !unreachable(work)) && _containedPoints.Add(work)) { hQueue._queue.Enqueue(work); return(true); } return(false); }
private void forwardExtend(ProgramPointBase point, IEnumerable <ProgramPointBase> inputs, FlowOutputSet inSet) { var extensionPoint = point as ExtensionPoint; var sinkPoint = point as ExtensionSinkPoint; if (extensionPoint != null) { extendCallExtension(extensionPoint, inSet); } else if (sinkPoint != null) { extendCallSink(sinkPoint, inSet); } else { standardExtend(inputs, inSet); } }
private void associatePoint(ProgramPointBase point) { var partial = point.Partial; _points[partial] = point; var lValue = point as LValuePoint; if (lValue != null) { _lValues[partial] = lValue; } var rValue = point as ValuePoint; if (rValue != null) { _rValues[partial] = rValue; } }
/// <summary> /// Expand given statements int program point base chain /// </summary> /// <param name="statements">Statements to expand</param> /// <returns>Program points created from statements expanding</returns> private List <ProgramPointBase> expandStatements(IEnumerable <LangElement> statements) { var points = new List <ProgramPointBase>(); ProgramPointBase lastPoint = null; foreach (var statement in statements) { var expanded = ElementExpander.ExpandStatement(statement, reportCreation); if (lastPoint != null) { //connect before expanded points lastPoint.AddFlowChild(expanded[0]); } lastPoint = expanded[expanded.Length - 1]; points.AddRange(expanded); } return(points); }
/// <summary> /// Builds the edges visualisation. /// </summary> /// <param name="point">The point.</param> /// <param name="graphVisualizer">The graph visualizer.</param> /// <param name="skipProgramPoints">The skip program points.</param> private static void buildEdgesVisualisation(ProgramPointBase point, IGraphVisualizer graphVisualizer, Type[] skipProgramPoints) { HashSet <int> processed = new HashSet <int>(); LinkedList <ProgramPointBase> edgeQueue = new LinkedList <ProgramPointBase>(); foreach (var targetPoint in point.FlowChildren) { edgeQueue.AddLast(targetPoint); processed.Add(targetPoint.ProgramPointID); } string id = "pp" + point.ProgramPointID.ToString(); while (edgeQueue.Count > 0) { ProgramPointBase targetPoint = edgeQueue.First.Value; edgeQueue.RemoveFirst(); bool targetSkipped = isTypeOf(targetPoint.GetType(), skipProgramPoints); if (!targetSkipped) { string outId = "pp" + targetPoint.ProgramPointID; graphVisualizer.AddEdge(id, outId, ""); } else { foreach (var p in targetPoint.FlowChildren) { if (!processed.Contains(p.ProgramPointID)) { edgeQueue.AddLast(p); processed.Add(p.ProgramPointID); } } } } }
/// <summary> /// Enques the building extension visualisations recursively. /// </summary> /// <param name="point">The point.</param> /// <param name="graphVisualizer">The graph visualizer.</param> /// <param name="skipProgramPoints">The skip program points.</param> /// <param name="processedGraphs">The processed graphs.</param> private static void enqueBuildingExtensionVisualisations(ProgramPointBase point, IGraphVisualizer graphVisualizer, Type[] skipProgramPoints, HashSet <ProgramPointGraph> processedGraphs) { bool hasBranches = false; foreach (var extension in point.Extension.Branches) { var ppg = extension.Graph; if (!processedGraphs.Contains(ppg)) { processedGraphs.Add(ppg); extension.Graph.BuildGraphVisualisation(graphVisualizer, skipProgramPoints, processedGraphs); } buildNodeVisualisation(extension, graphVisualizer); buildEdgesVisualisation(extension, graphVisualizer, skipProgramPoints); hasBranches = true; } if (hasBranches) { buildNodeVisualisation(point.Extension.Sink, graphVisualizer); buildEdgesVisualisation(point.Extension.Sink, graphVisualizer, skipProgramPoints); } }
/// <inheritdoc /> public override string ToString() { var result = new StringBuilder(); //result.AppendLine(OwningPPGraph.OwningScript.FullName); for (int c = 0; c < _callers.Count; c++) { ProgramPointBase caller = _callers[c]; // If the program point calls itself, continue (this occurs, e.g., in case sharing graphs in recursive calls) if (OwningPPGraph == caller.OwningPPGraph) { continue; } result.Append(" -> "); //result.Append("("); //result.Append(caller.OwningPPGraph.OwningScript.FullName + " at position " + caller.Partial.Position); result.Append(caller.OwningScriptFullName + " at position " + caller.Partial.Position); result.Append(caller.OwningPPGraph.Context); //result.Append(")"); if (c != _callers.Count - 1) { result.Append("or"); } //result.Append("( " + caller.ToString() + " )"); } //result.AppendLine(); return(result.ToString()); }
internal void InitializeNewPoint(ProgramPointBase point, ProgramPointGraph owningGraph) { point.Initialize(Services.CreateEmptySet(), Services.CreateEmptySet()); point.SetServices(Services); point.SetOwningGraph(owningGraph); }
/// <summary> /// Create flow controller for given input and output set /// </summary> internal FlowController(ForwardAnalysisServices services, ProgramPointBase programPoint) { Services = services; CurrentProgramPoint = programPoint; }