/// <summary> /// Write given value at memory represented by snapshot entry /// </summary> /// <param name="context">Context snapshot where operation is proceeded</param> /// <param name="value">Written value</param> /// <param name="forceStrongWrite">Determine that current write should be processed as strong</param> /// <exception cref="System.NotSupportedException">Current mode: + snapshot.CurrentMode</exception> protected override void writeMemory(SnapshotBase context, MemoryEntry value, bool forceStrongWrite) { SnapshotLogger.append(context, "write memory - " + this.ToString()); Snapshot snapshot = SnapshotEntry.ToSnapshot(context); switch (snapshot.CurrentMode) { case SnapshotMode.MemoryLevel: getTemporary(context).WriteMemory(context, value, forceStrongWrite); break; case SnapshotMode.InfoLevel: if (isTemporarySet(context)) { getTemporary(context).WriteMemory(context, value, forceStrongWrite); } else { infoEntry = value; } break; default: throw new NotSupportedException("Current mode: " + snapshot.CurrentMode); } }
/// <summary> /// Set aliases to current snapshot entry. Aliases can be set even to those entries /// that doesn't belongs to any variable, field,.. /// </summary> /// <param name="context">Context snapshot where operation is proceeded</param> /// <param name="aliasedEntry">Snapshot entry which will be aliased from current entry</param> protected override void setAliases(SnapshotBase context, ReadSnapshotEntryBase aliasedEntry) { Snapshot snapshot = ToSnapshot(context); SnapshotLogger.append(context, "set alias: " + this.ToString() + " from: " + aliasedEntry.ToString()); if (snapshot.CurrentMode == SnapshotMode.InfoLevel) { return; } ICopyModelSnapshotEntry entry = ToEntry(aliasedEntry); AliasData data = entry.CreateAliasToEntry(snapshot); AssignCollector collector = new AssignCollector(snapshot); collector.AliasesProcessing = AliasesProcessing.BeforeCollecting; collector.ProcessPath(path); AssignAliasWorker worker = new AssignAliasWorker(snapshot); worker.AssignAlias(collector, data); data.Release(snapshot); }
/// <summary> /// Read memory represented by current snapshot entry /// </summary> /// <param name="context">Context snapshot where operation is proceeded</param> /// <returns> /// Memory represented by current snapshot entry /// </returns> /// <exception cref="System.NotSupportedException">Current mode: + snapshot.CurrentMode</exception> protected override MemoryEntry readMemory(SnapshotBase context) { SnapshotLogger.append(context, "read memory - " + this.ToString()); if (isTemporarySet(context)) { SnapshotLogger.append(context, "read from temporary location - " + this.ToString()); return(temporaryLocation.ReadMemory(context)); } else { SnapshotLogger.append(context, "read just value - " + this.ToString()); Snapshot snapshot = SnapshotEntry.ToSnapshot(context); switch (snapshot.CurrentMode) { case SnapshotMode.MemoryLevel: return(dataEntry); case SnapshotMode.InfoLevel: return(infoEntry); default: throw new NotSupportedException("Current mode: " + snapshot.CurrentMode); } } }
/// <summary> /// Determine that memory represented by current snapshot entry Is already defined. /// If not, reading memory returns UndefinedValue. But UndefinedValue can be returned /// even for defined memory entries - this can be used to distinct /// between null/undefined semantic of PHP. /// </summary> /// <param name="context">Context snapshot where operation is proceeded</param> /// <returns>True whether memory represented by current snapshot entry Is already defined.</returns> protected override bool isDefined(SnapshotBase context) { Snapshot snapshot = ToSnapshot(context); SnapshotLogger.append(context, "is defined:" + this.ToString()); ReadCollector collector = new ReadCollector(snapshot); collector.ProcessPath(path); return(collector.IsDefined); }
/// <summary> /// Returns aliases that can be used for making alias join /// to current snapshot entry /// </summary> /// <param name="context">Context snapshot where operation is proceeded</param> /// <returns> /// Aliases of current snapshot entry /// </returns> protected override IEnumerable <AliasEntry> aliases(SnapshotBase context) { SnapshotLogger.append(context, "aliases - " + this.ToString()); if (isTemporarySet(context)) { return(temporaryLocation.Aliases(context)); } else { return(new AliasEntry[] { }); } }
/// <summary> /// Determine that memory represented by current snapshot entry Is already defined. /// If not, reading memory returns UndefinedValue. But UndefinedValue can be returned /// even for defined memory entries - this can be used to distinct /// between null/undefined semantic of PHP. /// </summary> /// <param name="context">Context snapshot where operation is proceeded</param> /// <returns>True whether that memory represented by current snapshot entry Is already defined.</returns> protected override bool isDefined(SnapshotBase context) { SnapshotLogger.append(context, "is defined - " + this.ToString()); if (isTemporarySet(context)) { return(temporaryLocation.IsDefined(context)); } else { return(true); } }
/// <summary> /// Write given value at memory represented by snapshot entry and doesn't process any /// array copy. Is needed for correct increment/decrement semantic. /// </summary> /// <param name="context">Context snapshot where operation is proceeded</param> /// <param name="value">Written value</param> protected override void writeMemoryWithoutCopy(SnapshotBase context, MemoryEntry value) { Snapshot snapshot = ToSnapshot(context); SnapshotLogger.append(context, "write without copy:" + this.ToString()); AssignCollector collector = new AssignCollector(snapshot); collector.ProcessPath(path); AssignWithoutCopyWorker worker = new AssignWithoutCopyWorker(snapshot); worker.Assign(collector, value); }
/// <summary> /// Resolve method on current snapshot entry with given methodName /// </summary> /// <param name="context">Context where methods are resolved</param> /// <param name="methodName">Name of resolved method</param> /// <returns> /// Resolved methods /// </returns> protected override IEnumerable <FunctionValue> resolveMethod(SnapshotBase context, PHP.Core.QualifiedName methodName) { SnapshotLogger.append(context, "resolve method - " + this.ToString() + " method: " + methodName); if (isTemporarySet(context)) { return(temporaryLocation.ResolveMethod(context, methodName)); } else { Snapshot snapshot = SnapshotEntry.ToSnapshot(context); return(snapshot.resolveMethod(dataEntry, methodName)); } }
/// <summary> /// Resolve method on current snapshot entry with given methodName /// </summary> /// <param name="context">Context where methods are resolved</param> /// <param name="methodName">Name of resolved method</param> /// <returns> /// Resolved methods /// </returns> protected override IEnumerable <FunctionValue> resolveMethod(SnapshotBase context, QualifiedName methodName) { Snapshot snapshot = ToSnapshot(context); SnapshotLogger.append(context, "resolve method - path: " + this.ToString() + " method: " + methodName); ReadCollector collector = new ReadCollector(snapshot); collector.ProcessPath(path); ReadWorker worker = new ReadWorker(snapshot); MemoryEntry memory = worker.ReadValue(collector); return(snapshot.resolveMethod(memory, methodName)); }
/// <summary> /// Read memory represented by current snapshot entry /// </summary> /// <param name="context">Context snapshot where operation is proceeded</param> /// <returns> /// Memory represented by current snapshot entry /// </returns> protected override MemoryEntry readMemory(SnapshotBase context) { Snapshot snapshot = ToSnapshot(context); SnapshotLogger.append(context, "read: " + this.ToString()); ReadCollector collector = new ReadCollector(snapshot); collector.ProcessPath(path); ReadWorker worker = new ReadWorker(snapshot); MemoryEntry entry = worker.ReadValue(collector); SnapshotLogger.appendToSameLine(" value: " + entry.ToString()); return(entry); }
/// <summary> /// Write given value at memory represented by snapshot entry /// </summary> /// <param name="context">Context snapshot where operation is proceeded</param> /// <param name="value">Written value</param> /// <param name="forceStrongWrite">Determine that current write should be processed as strong</param> /// <exception cref="System.NotSupportedException">Current mode: + snapshot.CurrentMode</exception> protected override void writeMemory(SnapshotBase context, MemoryEntry value, bool forceStrongWrite) { Snapshot snapshot = ToSnapshot(context); SnapshotLogger.append(context, "write: " + this.ToString() + " value: " + value.ToString()); switch (snapshot.CurrentMode) { case SnapshotMode.MemoryLevel: writeMemoryNormal(snapshot, value, forceStrongWrite); break; case SnapshotMode.InfoLevel: writeMemoryInfo(snapshot, value, forceStrongWrite); break; default: throw new NotSupportedException("Current mode: " + snapshot.CurrentMode); } }
/// <summary> /// Set aliases to current snapshot entry. Aliases can be set even to those entries /// that doesn't belongs to any variable, field,.. /// </summary> /// <param name="context">Context snapshot where operation is proceeded</param> /// <param name="aliasedEntry">Snapshot entry which will be aliased from current entry</param> protected override void setAliases(SnapshotBase context, ReadSnapshotEntryBase aliasedEntry) { SnapshotLogger.append(context, "set aliases - " + this.ToString()); getTemporary(context).SetAliases(context, aliasedEntry); }
/// <summary> /// Read memory represented by given field identifier resolved on current /// snapshot entry (resulting snapshot entry can encapsulate merging, alias resolving and /// other stuff based on nondeterminism of identifier and current snapshot entry) /// </summary> /// <param name="context">Context snapshot where operation is proceeded</param> /// <param name="field">Identifier of an field</param> /// <returns> /// Snapshot entry representing field resolving on current entry /// </returns> protected override ReadWriteSnapshotEntryBase readField(SnapshotBase context, AnalysisFramework.VariableIdentifier field) { SnapshotLogger.append(context, "read index - " + this.ToString()); return(getTemporary(context).ReadField(context, field)); }
/// <summary> /// Read memory represented by given index identifier resolved on current /// snapshot entry (resulting snapshot entry can encapsulate merging, alias resolving and /// other stuff based on nondeterminism of identifier and current snapshot entry) /// </summary> /// <param name="context">Context snapshot where operation is proceeded</param> /// <param name="index">Identifier of an index</param> /// <returns> /// Snapshot entry representing index resolving on current entry /// </returns> protected override ReadWriteSnapshotEntryBase readIndex(SnapshotBase context, MemberIdentifier index) { SnapshotLogger.append(context, "read index - " + this.ToString()); return(getTemporary(context).ReadIndex(context, index)); }