/// <summary> /// Assigns the given memory entry into all collected indexes in the collector. /// Must indexes are strongly updated may indexes weakly. /// </summary> /// <param name="collector">The collector.</param> /// <param name="value">The value.</param> internal void Assign(AssignCollector collector, AnalysisFramework.Memory.MemoryEntry value) { CollectComposedValuesVisitor composedValues = new CollectComposedValuesVisitor(); composedValues.VisitMemoryEntry(value); foreach (MemoryIndex mustIndex in collector.MustIndexes) { assignMust(mustIndex, composedValues); } foreach (MemoryIndex mayIndex in collector.MayIndexes) { assignMay(mayIndex, composedValues); } if (snapshot.CurrentMode == SnapshotMode.InfoLevel) { InfoLocationVisitor mustVisitor = new InfoLocationVisitor(snapshot, value, true); foreach (ValueLocation mustLocation in collector.MustLocation) { mustLocation.Accept(mustVisitor); } InfoLocationVisitor mayVisitor = new InfoLocationVisitor(snapshot, value, false); foreach (ValueLocation mustLocation in collector.MayLocaton) { mustLocation.Accept(mayVisitor); } } }
/// <summary> /// Iterates the indexes of PHP array in entry. /// </summary> /// <param name="context">The context.</param> /// <param name="snapshotEntry">The snapshot entry.</param> /// <returns>The list of indexes in the given snapshot entry.</returns> public static IEnumerable <MemberIdentifier> IterateIndexes(SnapshotBase context, ICopyModelSnapshotEntry snapshotEntry) { Snapshot snapshot = SnapshotEntry.ToSnapshot(context); MemoryEntry entry = snapshotEntry.ReadMemory(snapshot); CollectComposedValuesVisitor visitor = new CollectComposedValuesVisitor(); visitor.VisitMemoryEntry(entry); return(visitor.CollectIndexes(snapshot)); }
/// <summary> /// Resolves the type of PHP objects in the entry. /// </summary> /// <param name="context">The context.</param> /// <param name="snapshotEntry">The snapshot entry.</param> /// <returns>The list of types in the given snapshot entry.</returns> public static IEnumerable <TypeValue> ResolveType(SnapshotBase context, ICopyModelSnapshotEntry snapshotEntry) { Snapshot snapshot = SnapshotEntry.ToSnapshot(context); MemoryEntry entry = snapshotEntry.ReadMemory(snapshot); CollectComposedValuesVisitor visitor = new CollectComposedValuesVisitor(); visitor.VisitMemoryEntry(entry); return(visitor.ResolveObjectsTypes(snapshot)); }
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 all values which can be in target memory entry. If sources contains some arrays merge this arrays together /// and traverse their indexes. /// </summary> /// <param name="operation">The operation.</param> /// <param name="visitor">The visitor.</param> /// <returns>Values for the target memory entry.</returns> private HashSet <Value> getValues(MergeOperation operation, CollectComposedValuesVisitor visitor) { HashSet <Value> values = visitor.Values; bool noScalarValue = visitor.Values.Count == 0; if (visitor.Arrays.Count > 0) { values.Add(mergeArrays(operation)); } foreach (ObjectValue value in visitor.Objects) { values.Add(value); } return(values); }
/// <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> /// Assigns the may memory index. /// </summary> /// <param name="mayIndex">Index of the may.</param> /// <param name="composedValues">The composed values.</param> private void assignMay(MemoryIndex mayIndex, CollectComposedValuesVisitor composedValues) { IndexData data = snapshot.Structure.GetIndexData(mayIndex); HashSet <Value> values = new HashSet <Value>(composedValues.Values); if (composedValues.Objects.Count > 0) { HashSet <ObjectValue> objects = new HashSet <ObjectValue>(data.Objects); HashSetTools.AddAll(objects, composedValues.Objects); snapshot.Structure.SetObjects(mayIndex, new ObjectValueContainer(objects)); //if (data.Objects != null) HashSetTools.AddAll(values, data.Objects); } HashSetTools.AddAll(values, snapshot.Structure.GetMemoryEntry(mayIndex).PossibleValues); snapshot.Structure.SetMemoryEntry(mayIndex, new MemoryEntry(values)); }
/// <summary> /// Assigns the must memory index. /// </summary> /// <param name="mustIndex">Index of the must.</param> /// <param name="composedValues">The composed values.</param> private void assignMust(MemoryIndex mustIndex, CollectComposedValuesVisitor composedValues) { IndexData data = snapshot.Structure.GetIndexData(mustIndex); HashSet <Value> values = new HashSet <Value>(composedValues.Values); if (data.Array != null) { values.Add(data.Array); } if (composedValues.Objects.Count > 0) { snapshot.Structure.SetObjects(mustIndex, new ObjectValueContainer(composedValues.Objects)); if (data.Objects != null) { HashSetTools.AddAll(values, data.Objects); } } snapshot.Structure.SetMemoryEntry(mustIndex, new MemoryEntry(values)); }
/// <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) { CollectComposedValuesVisitor visitor = new CollectComposedValuesVisitor(); ReferenceCollector references = new ReferenceCollector(); // Collect all data from source indexes foreach (var operationData in operation.Indexes) { MemoryIndex index = operationData.Item1; Snapshot snapshot = operationData.Item2; MemoryEntry entry = snapshot.Structure.GetMemoryEntry(index); visitor.VisitMemoryEntry(entry); MemoryAlias aliases; if (snapshot.Structure.TryGetAliases(index, out aliases)) { references.CollectMust(aliases.MustAliasses, targetSnapshot.CallLevel); references.CollectMay(aliases.MayAliasses, targetSnapshot.CallLevel); } else { references.InvalidateMust(); } } references.SetAliases(operation.TargetIndex, this, !operation.IsUndefined); //repares the set of values - array values are traversed HashSet <Value> values = getValues(operation, visitor); // If some index in operation can be undefined add undefined value into result if (operation.IsUndefined) { values.Add(targetSnapshot.UndefinedValue); } Structure.SetMemoryEntry(operation.TargetIndex, new MemoryEntry(values)); Structure.SetObjects(operation.TargetIndex, new ObjectValueContainer(visitor.Objects)); }
private HashSet <Value> getValues(MemoryIndex targetIndex, CollectComposedValuesVisitor visitor, bool includeUndefined) { HashSet <Value> values = visitor.Values; bool noScalarValue = visitor.Values.Count == 0; if (visitor.Arrays.Count > 0) { bool mustBeArray = !includeUndefined && noScalarValue && visitor.Objects.Count == 0 && visitor.Arrays.Count == arrayCount; values.Add(mergeArrays(targetIndex, visitor.Arrays, !mustBeArray)); } if (visitor.Objects.Count > 0) { bool mustBeObject = !includeUndefined && noScalarValue && visitor.Arrays.Count == 0; mergeObjects(targetIndex, visitor.Objects, mustBeObject, values); } return(values); }
private void processMergeOperation(MergeOperation operation) { CollectComposedValuesVisitor visitor = new CollectComposedValuesVisitor(); ReferenceCollector references = new ReferenceCollector(); foreach (var item in operation.Indexes) { Snapshot snapshot = item.Item2; MemoryIndex index = item.Item1; MemoryEntry entry = snapshot.Structure.GetMemoryEntry(index); visitor.VisitMemoryEntry(entry); MemoryAlias aliases; if (snapshot.Structure.TryGetAliases(index, out aliases)) { references.CollectMust(aliases.MustAliasses, snapshot.CallLevel); references.CollectMay(aliases.MayAliasses, snapshot.CallLevel); } else { references.InvalidateMust(); } } if (references.HasAliases && !operation.IsRoot) { if (!operation.IsUndefined && operation.Indexes.Count == 1 && references.HasMustAliases) { if (targetSnapshot == operation.Indexes.First().Item2) { references.AddMustAlias(operation.Indexes.First().Item1); } } else { HashSet <MemoryIndex> referenceIndexes = new HashSet <MemoryIndex>(); foreach (var item in operation.Indexes) { MemoryIndex index = item.Item1; Snapshot snapshot = item.Item2; if (index != operation.TargetIndex && targetSnapshot == snapshot) { referenceIndexes.Add(index); } } references.CollectMay(referenceIndexes, targetSnapshot.CallLevel); } } references.SetAliases(operation.TargetIndex, targetSnapshot, !operation.IsUndefined); HashSet <Value> values = getValues(operation.TargetIndex, visitor, operation.IsUndefined); if (operation.IsUndefined) { values.Add(targetSnapshot.UndefinedValue); } targetSnapshot.Structure.SetMemoryEntry(operation.TargetIndex, new MemoryEntry(values)); }