/// <summary> /// Sets the array for specified index. /// </summary> /// <param name="index">The index.</param> /// <param name="arrayValue">The array value.</param> internal void SetArray(MemoryIndex index, AssociativeArray arrayValue) { lockedTest(); IndexData data; if (!IndexData.TryGetValue(index, out data)) { data = new IndexData(null, null, null); } IndexDataBuilder builder = data.Builder(); builder.Array = arrayValue; IndexData[index] = builder.Build(); ArrayDescriptor descriptor; if (TryGetDescriptor(arrayValue, out descriptor)) { if (descriptor.ParentVariable != null) { Arrays[descriptor.ParentVariable.CallLevel].Remove(arrayValue); } } Arrays[index.CallLevel].Add(arrayValue); }
/// <summary> /// Processes single merge operation - prepares all valid values and alias informations from the source indexes. /// When the source indexes contains some array values prepares operation for every descendant index and merge the /// array into one which will be stored in the target memory entry. /// </summary> /// <param name="operation">The operation.</param> private void processMergeOperation(MergeOperation operation) { HashSet <Value> values = new HashSet <Value>(); foreach (var operationData in operation.Indexes) { MemoryIndex index = operationData.Item1; Snapshot snapshot = operationData.Item2; MemoryEntry entry = snapshot.Infos.GetMemoryEntry(index); HashSetTools.AddAll(values, entry.PossibleValues); } if (Structure.HasArray(operation.TargetIndex)) { mergeArrays(operation); } if (operation.IsUndefined) { values.Add(targetSnapshot.UndefinedValue); } Structure.SetMemoryEntry(operation.TargetIndex, new MemoryEntry(values)); }
/// <summary> /// Sets the collected aliases to specified index in the given spanshot. /// </summary> /// <param name="memoryIndex">Index of the memory.</param> /// <param name="snapshot">The snapshot.</param> /// <param name="isMust">if set to <c>true</c> uses must and may aliases otherwise all must aliases are invalidated.</param> internal void SetAliases(MemoryIndex memoryIndex, IReferenceHolder snapshot, bool isMust) { if (allReferences.Count == 0) { return; } if (!isMust) { InvalidateMust(); } HashSet <MemoryIndex> mayReferences = new HashSet <MemoryIndex>(); CopyMayReferencesTo(mayReferences); foreach (MemoryIndex mustAlias in mustReferences) { snapshot.AddAlias(mustAlias, memoryIndex, null); } foreach (MemoryIndex mayAlias in mayReferences) { snapshot.AddAlias(mayAlias, null, memoryIndex); } snapshot.AddAliases(memoryIndex, mustReferences, mayReferences); }
/// <summary> /// Adds the aliases to given index. Alias entry of the given alias indexes are not changed. /// If given memory index contains no aliases new alias entry is created. /// </summary> /// <param name="index">The index.</param> /// <param name="mustAliases">The must aliases.</param> /// <param name="mayAliases">The may aliases.</param> public void AddAliases(MemoryIndex index, IEnumerable <MemoryIndex> mustAliases, IEnumerable <MemoryIndex> mayAliases) { MemoryAliasBuilder alias; if (!memoryAliases.TryGetValue(index, out alias)) { alias = new MemoryAliasBuilder(); } if (mustAliases != null) { alias.AddMustAlias(mustAliases); } if (mayAliases != null) { alias.AddMayAlias(mayAliases); } foreach (MemoryIndex mustIndex in alias.MustAliasses) { if (alias.MayAliasses.Contains(mustIndex)) { alias.MayAliasses.Remove(mustIndex); } } memoryAliases[index] = alias; }
/// <summary> /// Adds the aliases to given index. Alias entry of the given alias indexes are not changed. /// If given memory index contains no aliases new alias entry is created. /// </summary> /// <param name="index">The index.</param> /// <param name="mustAlias">The must alias.</param> /// <param name="mayAlias">The may alias.</param> public void AddAlias(MemoryIndex index, MemoryIndex mustAlias, MemoryIndex mayAlias) { MemoryAliasBuilder alias; if (!memoryAliases.TryGetValue(index, out alias)) { alias = new MemoryAliasBuilder(); } if (mustAlias != null) { alias.AddMustAlias(mustAlias); if (alias.MayAliasses.Contains(mustAlias)) { alias.MayAliasses.Remove(mustAlias); } } if (mayAlias != null && !alias.MustAliasses.Contains(mayAlias)) { alias.AddMayAlias(mayAlias); } memoryAliases[index] = alias; }
/// <summary> /// Assigns the specified collector. /// </summary> /// <param name="collector">The collector.</param> /// <param name="sourceIndex">Index of the source.</param> internal void Assign(IIndexCollector collector, MemoryIndex sourceIndex) { foreach (MemoryIndex mustIndex in collector.MustIndexes) { snapshot.DestroyMemory(mustIndex); CopyWithinSnapshotWorker copyWorker = new CopyWithinSnapshotWorker(snapshot, true); copyWorker.Copy(sourceIndex, mustIndex); } foreach (MemoryIndex mayIndex in collector.MayIndexes) { MergeWithinSnapshotWorker mergeWorker = new MergeWithinSnapshotWorker(snapshot); mergeWorker.MergeIndexes(mayIndex, sourceIndex); } MemoryEntry entry = snapshot.Structure.GetMemoryEntry(sourceIndex); LocationVisitor mustVisitor = new LocationVisitor(snapshot, entry, true); foreach (ValueLocation location in collector.MustLocation) { location.Accept(mustVisitor); } LocationVisitor mayVisitor = new LocationVisitor(snapshot, entry, false); foreach (ValueLocation location in collector.MayLocaton) { location.Accept(mayVisitor); } }
/// <summary> /// Stores given collection as the source of indexes and adds its unknown index into unknown operation. /// Also gets all indexes from the source collection and inserts it into target collection. /// /// This method is for the first phase of anaysis. /// </summary> /// <param name="sourceSnapshot">The source snapshot.</param> /// <param name="sourceIndex">Index of the source.</param> /// <param name="sourceContainer">The source container.</param> public void CollectIndexes( Snapshot sourceSnapshot, MemoryIndex sourceIndex, ReadonlyIndexContainer sourceContainer) { sources.Add(new Tuple <ReadonlyIndexContainer, Snapshot>(sourceContainer, sourceSnapshot)); unknownOperation.Add(sourceContainer.UnknownIndex, sourceSnapshot); bool indexEquals = targetIndex.Equals(sourceIndex); foreach (var index in sourceContainer.Indexes) { MemoryIndex containerIndex; if (targetContainer.Indexes.TryGetValue(index.Key, out containerIndex)) { if (containerIndex == null && indexEquals) { targetContainer.Indexes[index.Key] = index.Value; undefinedIndexes.Remove(index.Key); } } else if (indexEquals) { targetContainer.Indexes.Add(index.Key, index.Value); } else { targetContainer.Indexes.Add(index.Key, null); undefinedIndexes.Add(index.Key); } } }
/// <summary> /// Processes the index - traverse thru array or sets path to undefined. When memory location contains /// no array and undefined value new array is created. /// </summary> /// <param name="segment">The segment.</param> /// <param name="parentIndex">Index of the parent.</param> /// <param name="visitor">The visitor to process scalar values.</param> /// <param name="isMust">if set to <c>true</c> [is must].</param> private void processIndex(PathSegment segment, MemoryIndex parentIndex, IndexLocationVisitor visitor, bool isMust) { AssociativeArray arrayValue = null; bool processOtherValues = false; MemoryEntry entry; if (snapshot.Data.TryGetMemoryEntry(parentIndex, out entry)) { if (snapshot.Structure.TryGetArray(parentIndex, out arrayValue)) { processOtherValues = entry.Count > 1; } else if (entry.Count > 0) { processOtherValues = true; } else { entry = snapshot.Data.EmptyEntry; processOtherValues = true; } } else { entry = snapshot.Data.EmptyEntry; processOtherValues = true; snapshot.Structure.TryGetArray(parentIndex, out arrayValue); } if (processOtherValues) { visitor.ProcessValues(parentIndex, entry.PossibleValues, isMust); ReadIndexVisitor valueVisitor = visitor.LastValueVisitor; bool removeUndefined = isMust; if (valueVisitor.ContainsDefinedValue || valueVisitor.ContainsAnyValue) { isMust = false; } if (valueVisitor.ContainsUndefinedValue) { if (arrayValue == null) { arrayValue = snapshot.CreateArray(parentIndex, isMust, removeUndefined); } else if (removeUndefined) { snapshot.Structure.Data.RemoveUndefined(parentIndex); } } } if (arrayValue != null) { ArrayDescriptor descriptor = snapshot.Structure.GetDescriptor(arrayValue); creatorVisitor.ArrayValue = arrayValue; processSegment(segment, descriptor, isMust); } }
private void mergeObjects(MemoryIndex targetIndex, HashSet <ObjectValue> objects, bool mustBeObject, HashSet <Value> values) { if (objects.Count == 1) { ObjectValue objectValue = objects.First(); values.Add(objectValue); if (mustBeObject) { targetSnapshot.MakeMustReferenceObject(objectValue, targetIndex); } else { targetSnapshot.MakeMayReferenceObject(objects, targetIndex); } } else if (objects.Count > 1) { targetSnapshot.MakeMayReferenceObject(objects, targetIndex); foreach (ObjectValue objectValue in objects) { values.Add(objectValue); } } }
/// <summary> /// Prepares operation for every descendant index of target array. /// </summary> /// <param name="operation">The operation.</param> /// <returns>Array where the input arrays is merged into.</returns> private void mergeArrays(MergeOperation operation) { AssociativeArray targetArray = Structure.GetArray(operation.TargetIndex); ArrayDescriptor targetDescriptor = Structure.GetDescriptor(targetArray); ContainerOperations collectIndexes = new ContainerOperations(this, targetDescriptor.Builder(), operation.TargetIndex, targetDescriptor.UnknownIndex); foreach (var operationData in operation.Indexes) { MemoryIndex index = operationData.Item1; Snapshot snapshot = operationData.Item2; AssociativeArray arrayValue; if (snapshot.Structure.TryGetArray(index, out arrayValue)) { ArrayDescriptor descriptor = snapshot.Structure.GetDescriptor(arrayValue); collectIndexes.AddContainer(descriptor, snapshot); } else { collectIndexes.SetUndefined(); } } collectIndexes.MergeContainers(); }
/// <summary> /// Processes the index - traverse thru array or sets path to undefined. /// </summary> /// <param name="parentIndex">Index of the parent.</param> /// <param name="indexSegment">The index segment.</param> /// <param name="visitor">The visitor to process scalar values.</param> private void processIndex(MemoryIndex parentIndex, IndexPathSegment indexSegment, ProcessValueAsLocationVisitor visitor) { MemoryEntry entry; if (snapshot.Data.TryGetMemoryEntry(parentIndex, out entry)) { bool processOtherValues = false; AssociativeArray arrayValue; if (snapshot.Structure.TryGetArray(parentIndex, out arrayValue)) { ArrayDescriptor descriptor = snapshot.Structure.GetDescriptor(arrayValue); process(indexSegment, descriptor); processOtherValues = entry.Count > 1; } else if (entry.Count > 0) { processOtherValues = true; } else { IsDefined = false; } if (processOtherValues) { visitor.ProcessValues(parentIndex, entry.PossibleValues, true); } } else { IsDefined = false; } }
/// <summary> /// Removes the index from structure and data. /// </summary> /// <param name="index">The index.</param> internal void RemoveIndex(MemoryIndex index) { lockedTest(); IndexData.Remove(index); Data.RemoveMemoryEntry(index); }
/// <summary> /// Gets string representation af aliases between memory locations in memory model. /// </summary> /// <returns>String representation af aliases between memory locations in memory model.</returns> internal string GetAliasesRepresentation() { StringBuilder result = new StringBuilder(); foreach (var item in IndexData) { var aliases = item.Value.Aliases; if (aliases != null && (aliases.MayAliasses.Count > 0 || aliases.MustAliasses.Count > 0)) { MemoryIndex index = item.Key; result.AppendFormat("{0}: {{ ", index); result.Append(" MUST: "); foreach (var alias in aliases.MustAliasses) { result.Append(alias); result.Append(", "); } result.Length -= 2; result.Append(" | MAY: "); foreach (var alias in aliases.MayAliasses) { result.Append(alias); result.Append(", "); } result.Length -= 2; result.AppendLine(" }"); } } return(result.ToString()); }
/// <summary> /// Determines whether the specified <see cref="System.Object" />, is equal to this instance. /// </summary> /// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param> /// <returns> /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>. /// </returns> public override bool Equals(object obj) { if (base.Equals(obj)) { return(true); } MemoryIndex otherIndex = obj as MemoryIndex; if (otherIndex == null || otherIndex.Length != this.Length) { return(false); } if (otherIndex.GetType() != this.GetType() || otherIndex.CallLevel != this.CallLevel) { return(false); } for (int x = this.Length - 1; x >= 0; x--) { if (!this.MemoryPath[x].Equals(otherIndex.MemoryPath[x])) { return(false); } } return(true); }
/// <summary> /// Creates the index container object with given unknown object. /// </summary> /// <param name="unknownIndex">Index of the unknown.</param> /// <returns>New index container object with given unknown object.</returns> private IndexContainer createIndexContainer(MemoryIndex unknownIndex) { IndexContainer container = new IndexContainer(unknownIndex); NewIndex(unknownIndex); return(container); }
/// <summary> /// Insert newly created index into structure and data collection. /// </summary> /// <param name="index">The index.</param> internal void NewIndex(MemoryIndex index) { lockedTest(); IndexData data = new IndexData(null, null, null); IndexData[index] = data; Data.SetMemoryEntry(index, new MemoryEntry(Snapshot.UndefinedValue)); }
/// <summary> /// Initializes a new instance of the <see cref="MemoryIndex"/> class from the given parent index and /// adds new index segment at the end of the memory path. /// </summary> /// <param name="parentIndex">Index of the parent.</param> /// <param name="indexSegment">The index segment.</param> protected MemoryIndex(MemoryIndex parentIndex, IndexSegment indexSegment) { CallLevel = parentIndex.CallLevel; List <IndexSegment> path = new List <IndexSegment>(parentIndex.MemoryPath); path.Add(indexSegment); MemoryPath = new ReadOnlyCollection <IndexSegment>(path); }
/// <summary> /// Initializes a new instance of the <see cref="ObjectDescriptor" /> class. /// </summary> /// <param name="objectValue">The object value.</param> /// <param name="type">The type of object.</param> /// <param name="unknownIndex">Index of the unknown.</param> public ObjectDescriptor(ObjectValue objectValue, TypeValue type, MemoryIndex unknownIndex) { Indexes = new ReadOnlyDictionary <string, MemoryIndex>(new Dictionary <string, MemoryIndex>()); Type = type; UnknownIndex = unknownIndex; ObjectValue = objectValue; }
/// <summary> /// Adds the specified memory index into sources for this operation. /// </summary> /// <param name="memoryIndex">Index of the memory.</param> /// <param name="snapshot">The snapshot.</param> /// <exception cref="System.NullReferenceException"></exception> public void Add(MemoryIndex memoryIndex, Snapshot snapshot) { if (memoryIndex == null) { throw new NullReferenceException(); } Indexes.Add(new Tuple <MemoryIndex, Snapshot>(memoryIndex, snapshot)); }
/// <summary> /// Gets the string representation of the collection - dump of all indexes and theirs data. /// </summary> /// <param name="container">The container.</param> /// <param name="data">The data.</param> /// <param name="infos">The infos.</param> /// <param name="result">The result.</param> internal static void GetRepresentation(ReadonlyIndexContainer container, SnapshotData data, SnapshotData infos, StringBuilder result) { GetIndexRepresentation(container.UnknownIndex, data, infos, result); foreach (var item in container.Indexes) { MemoryIndex index = item.Value; GetIndexRepresentation(index, data, infos, result); } }
/// <summary> /// Gets the data of specified index. /// </summary> /// <param name="index">The index.</param> /// <returns>Data of specified index.</returns> /// <exception cref="System.Exception">Missing alias value for given index</exception> internal IndexData GetIndexData(MemoryIndex index) { IndexData data; if (IndexData.TryGetValue(index, out data)) { return(data); } throw new Exception("Missing alias value for " + index); }
/// <summary> /// Adds the index into must collection. /// </summary> /// <param name="index">The index.</param> private void addToMust(MemoryIndex index) { if (!index.ContainsPrefix(mustIndexesProcess)) { index.RemoveIndexesWithPrefix(mustIndexesProcess); index.RemoveIndexesWithPrefix(mayIndexes); mustIndexesProcess.Add(index); } }
/// <summary> /// Gets the data is set in structure or returns given empty data. /// </summary> /// <param name="index">The index.</param> /// <param name="snapshotStructure">The snapshot structure.</param> /// <param name="emptyData">The empty data.</param> /// <returns>Data is set in structure or returns given empty data.</returns> private CopyMemoryModel.IndexData getDataOrUndefined(MemoryIndex index, SnapshotStructure snapshotStructure, IndexData emptyData) { IndexData data = null; if (!snapshotStructure.IndexData.TryGetValue(index, out data)) { data = emptyData; } return(data); }
/// <summary> /// Allews descendant implementation to continue traversing memory by indexing values ar accesing their fields. /// </summary> /// <param name="parentIndex">Index of the parent.</param> /// <param name="values">The values.</param> /// <param name="isMust">if set to <c>true</c> is must.</param> public override void ProcessValues(MemoryIndex parentIndex, IEnumerable <Value> values, bool isMust) { HashSet <ValueLocation> targetSet = mayLocationProcess; if (isMust && values.Count() == 1) { targetSet = mustLocationProcess; } LastValueVisitor = new ReadFieldVisitor(parentIndex, fieldSegment, targetSet); LastValueVisitor.VisitValues(values); }
/// <summary> /// Adds the index into may collection. /// </summary> /// <param name="index">The index.</param> /// <returns>True whether index in not in the collection of must indexes.</returns> private bool addToMay(MemoryIndex index) { if (!mustIndexesProcess.Contains(index) && !index.ContainsPrefix(mustIndexesProcess)) { mayIndexesProcess.Add(index); return(true); } else { return(false); } }
/// <summary> /// Initializes a new instance of the <see cref="ReadIndexVisitor"/> class. /// </summary> /// <param name="containingIndex">Index of the containing.</param> /// <param name="indexSegment">The index segment.</param> /// <param name="locations">The locations.</param> public ReadIndexVisitor(MemoryIndex containingIndex, IndexPathSegment indexSegment, ICollection <ValueLocation> locations) { this.containingIndex = containingIndex; this.locations = locations; ContainsUndefinedValue = false; ContainsDefinedValue = false; ContainsArrayValue = false; ContainsAnyValue = false; index = new MemberIdentifier(indexSegment.Names); }
/// <summary> /// Initializes a new instance of the <see cref="ArrayDescriptor"/> class. /// </summary> /// <param name="arrayValue">The array value.</param> /// <param name="parentVariable">The parent variable.</param> /// <exception cref="System.Exception">Null array in descriptor</exception> public ArrayDescriptor(AssociativeArray arrayValue, MemoryIndex parentVariable) { Indexes = new ReadOnlyDictionary <string, MemoryIndex>(new Dictionary <string, MemoryIndex>()); ParentVariable = parentVariable; UnknownIndex = parentVariable.CreateUnknownIndex(); ArrayValue = arrayValue; if (arrayValue == null) { throw new Exception("Null array in descriptor"); } }
/// <summary> /// Initializes a new instance of the <see cref="ReadFieldVisitor"/> class. /// </summary> /// <param name="containingIndex">Index of the containing.</param> /// <param name="fieldSegment">The field segment.</param> /// <param name="locations">The locations.</param> public ReadFieldVisitor(MemoryIndex containingIndex, FieldPathSegment fieldSegment, ICollection <ValueLocation> locations) { this.containingIndex = containingIndex; this.locations = locations; ContainsUndefinedValue = false; ContainsDefinedValue = false; ContainsObjectValue = false; ContainsAnyValue = false; index = new VariableIdentifier(fieldSegment.Names); }
public void MergeMemoryEntry(MemoryIndex targetIndex, MemoryEntry entry) { CollectComposedValuesVisitor visitor = new CollectComposedValuesVisitor(); visitor.VisitMemoryEntry(entry); arrayCount = visitor.Arrays.Count; HashSet <Value> values = getValues(targetIndex, visitor, false); processMerge(); targetSnapshot.Structure.SetMemoryEntry(targetIndex, new MemoryEntry(values)); }
/// <summary> /// Gets the memory entry. /// </summary> /// <param name="index">The index.</param> /// <returns>Memory entry for the given index.</returns> internal MemoryEntry GetMemoryEntry(MemoryIndex index) { MemoryEntry memoryEntry; if (TryGetMemoryEntry(index, out memoryEntry)) { return(memoryEntry); } else { return(EmptyEntry); } }