/// <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> /// 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> /// <returns>Array where the input arrays is merged into.</returns> private Value mergeArrays(MergeOperation operation) { ArrayDescriptorBuilder builder = new ArrayDescriptorBuilder(); builder.SetParentVariable(operation.TargetIndex); builder.SetUnknownField(operation.TargetIndex.CreateUnknownIndex()); ContainerOperations collectVariables = new ContainerOperations(this, builder, operation.TargetIndex, builder.UnknownIndex); // Collecting possible indexes of merged array AssociativeArray targetArray = null; foreach (var operationData in operation.Indexes) { MemoryIndex index = operationData.Item1; Snapshot snapshot = operationData.Item2; AssociativeArray arrayValue; if (snapshot.Structure.TryGetArray(index, out arrayValue)) { // Target array value will be the firs one if (targetArray == null) { if (index.Equals(operation.TargetIndex)) { targetArray = arrayValue; } } ArrayDescriptor descriptor = snapshot.Structure.GetDescriptor(arrayValue); collectVariables.CollectIndexes(snapshot, index, descriptor); } else { collectVariables.SetUndefined(); } } if (targetArray == null) { targetArray = targetSnapshot.CreateArray(); } builder.SetArrayValue(targetArray); collectVariables.MergeContainers(); Structure.SetArray(operation.TargetIndex, targetArray); Structure.SetDescriptor(targetArray, builder.Build()); return(targetArray); }
/// <summary> /// Widens the data of given memory index in this data container. /// </summary> /// <param name="oldData">The old data.</param> /// <param name="index">The index.</param> /// <param name="assistant">The assistant.</param> public void DataWiden(SnapshotData oldData, MemoryIndex index, MemoryAssistantBase assistant) { MemoryEntry newEntry = null; if (!this.IndexData.TryGetValue(index, out newEntry)) { newEntry = EmptyEntry; } MemoryEntry oldEntry = null; if (!oldData.IndexData.TryGetValue(index, out oldEntry)) { oldEntry = EmptyEntry; } MemoryIndex testIndex = ControlIndex.Create(".return", 6); if (testIndex.Equals(index)) { } if (!oldEntry.Equals(newEntry)) { MemoryEntry widenedEntry = assistant.Widen(oldEntry, newEntry); CollectComposedValuesVisitor newVisitor = new CollectComposedValuesVisitor(); newVisitor.VisitMemoryEntry(newEntry); CollectComposedValuesVisitor widenedVisitor = new CollectComposedValuesVisitor(); widenedVisitor.VisitMemoryEntry(widenedEntry); if (newVisitor.Arrays.Count != widenedVisitor.Arrays.Count) { snapshot.DestroyArray(index); } if (newVisitor.Objects.Count != widenedVisitor.Objects.Count) { snapshot.Structure.SetObjects(index, null); } SetMemoryEntry(index, assistant.Widen(oldEntry, new MemoryEntry(widenedVisitor.Values))); } }
/// <summary> /// Simplify data of single memory index if exceeds given simplify limit and compares it with the data inside given data container. /// </summary> /// <param name="oldData">The old data.</param> /// <param name="index">The index.</param> /// <param name="simplifyLimit">The simplify limit.</param> /// <param name="assistant">The assistant.</param> /// <returns>True whether compared data are the same.</returns> public bool DataEqualsAndSimplify(SnapshotData oldData, MemoryIndex index, int simplifyLimit, MemoryAssistantBase assistant) { MemoryEntry newEntry = null; if (!this.IndexData.TryGetValue(index, out newEntry)) { newEntry = EmptyEntry; } MemoryEntry oldEntry = null; if (!oldData.IndexData.TryGetValue(index, out oldEntry)) { oldEntry = EmptyEntry; } if (oldEntry.Equals(newEntry)) { return(true); } else if (newEntry.Count > simplifyLimit) { MemoryIndex testIndex = ControlIndex.Create(".return", 6); if (testIndex.Equals(index)) { } MemoryEntry simplifiedEntry = assistant.Simplify(newEntry); SetMemoryEntry(index, simplifiedEntry); return(oldEntry.Equals(simplifiedEntry)); } else { return(false); } }