/// <summary> /// Iterate indexes defined on array /// </summary> /// <param name="context">Context where indexes are searched</param> /// <returns>Enumeration of available fields</returns> public IEnumerable <MemberIdentifier> IterateIndexes(SnapshotBase context) { //TODO statistics reporting var allIndices = iterateIndexes(context); // filter out unknown field that has just undefined value var returnedIndices = new List <MemberIdentifier> (allIndices.Count()); foreach (var index in allIndices) { if (index.DirectName == null) { var tmp = readIndex(context, index).readMemory(context); if (readIndex(context, index).readMemory(context).PossibleValues.Count() <= 1) { // unknown field that has just undefined value continue; } } returnedIndices.Add(index); } return(returnedIndices); }
internal void ExtendAsCall(SnapshotBase callerContext, ProgramPointGraph callee, MemoryEntry thisObject, MemoryEntry[] arguments) { checkCanUpdate(); _statistics.Report(Statistic.AsCallExtendings); extendAsCall(callerContext, callee, thisObject, arguments); }
/// <summary> /// Initialize context snapshot for current assistant /// </summary> /// <param name="context">Context snapshot for current memory assistant</param> public void InitContext(SnapshotBase context) { if (Context != null) { throw new NotSupportedException("Cannot initialize Context twice"); } Context = context; }
/// <summary> /// Returns true if it is stored an associative array in this entry in given context. /// </summary> /// <returns><c>true</c>, if associative arrray is stored in this entry, <c>false</c> otherwise.</returns> /// <param name="context">Context where the array is searched.</param> public bool isAssociativeArrray(SnapshotBase context) { foreach (var val in this.ReadMemory(context).PossibleValues) { if (val is AssociativeArray) { return(true); } } return(false); }
/// <summary> /// Returns biggest integer index in arrays represented by this entry. /// </summary> /// <returns>The biggest integer index.</returns> /// <param name="context">Context where the index is searched.</param> /// <param name="evaluator">Expression evaluator.</param> public int BiggestIntegerIndex(SnapshotBase context, ExpressionEvaluatorBase evaluator) { int biggestIndex = -1; foreach (var index in iterateIndexes(context)) { int currentIndex; if (evaluator.TryIdentifyInteger(index.DirectName, out currentIndex)) { if (currentIndex > biggestIndex) { biggestIndex = currentIndex; } } } return(biggestIndex); }
/// <summary> /// Write given value at memory represented by snapshot entry /// </summary> /// <param name="value">Written value</param> /// <param name="context">Context snapshot where operation is proceeded</param> /// <param name="forceStrongWrite">Determine that current write should be processed as strong</param> public void WriteMemory(SnapshotBase context, MemoryEntry value, bool forceStrongWrite = false) { //TODO statistics reporting writeMemory(context, value, forceStrongWrite); }
/// <summary> /// Iterate fields defined on object /// </summary> /// <param name="context">Context where fields are searched</param> /// <returns>Enumeration of available fields</returns> public IEnumerable <VariableIdentifier> IterateFields(SnapshotBase context) { //TODO statistics reporting return(iterateFields(context)); }
/// <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="aliasedEntry">Snapshot entry which will be aliased from current entry</param> /// <param name="context">Context snapshot where operation is proceeded</param> public void SetAliases(SnapshotBase context, ReadSnapshotEntryBase aliasedEntry) { //TODO statistics reporting setAliases(context, aliasedEntry); }
/// <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 abstract IEnumerable <FunctionValue> resolveMethod(SnapshotBase context, QualifiedName methodName);
/// <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="index">Identifier of an index</param> /// <param name="context">Context snapshot where operation is proceeded</param> /// <returns>Snapshot entry representing index resolving on current entry</returns> protected abstract ReadWriteSnapshotEntryBase readIndex(SnapshotBase context, MemberIdentifier index);
/// <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 abstract IEnumerable <AliasEntry> aliases(SnapshotBase context);
/// <summary> /// Resolve type of objects in snapshot entry /// </summary> /// <param name="context">Context where types are resolved</param> /// <returns>Resolved types</returns> public IEnumerable <TypeValue> ResolveType(SnapshotBase context) { //TODO statistics reporting return(resolveType(context)); }
/// <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> public IEnumerable <AliasEntry> Aliases(SnapshotBase context) { return(aliases(context)); }
/// <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><c>true</c> if memory is already defined.</returns> public bool IsDefined(SnapshotBase context) { return(isDefined(context)); }
/// <summary> /// Resolve type of objects in snapshot entry /// </summary> /// <param name="context">Context where types are resolved</param> /// <returns>Resolved types</returns> protected abstract IEnumerable <TypeValue> resolveType(SnapshotBase context);
/// <summary> /// Iterate indexes defined on array /// </summary> /// <param name="context">Context where indexes are searched</param> /// <returns>Enumeration of available fields</returns> protected abstract IEnumerable <MemberIdentifier> iterateIndexes(SnapshotBase context);
/// <summary> /// Iterate fields defined on object /// </summary> /// <param name="context">Context where fields are searched</param> /// <returns>Enumeration of available fields</returns> protected abstract IEnumerable <VariableIdentifier> iterateFields(SnapshotBase context);
/// <summary> /// Returns variables corresponding to current snapshot entry /// </summary> /// <param name="context">Context snapshot where operation is proceeded</param> /// <returns>Variable identifier of current snapshot entry or null if entry doesn't belong to variable</returns> protected abstract VariableIdentifier getVariableIdentifier(SnapshotBase context);
/// <summary> /// Returns variables corresponding to current snapshot entry /// </summary> /// <param name="context">Context snapshot where operation is proceeded</param> /// <returns>Variable identifier of current snapshot entry or null if entry doesn't belong to variable</returns> public VariableIdentifier GetVariableIdentifier(SnapshotBase context) { //TODO statistics reporting return(getVariableIdentifier(context)); }
/// <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> public MemoryEntry ReadMemory(SnapshotBase context) { //TODO statistics reporting return(readMemory(context)); }
/// <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><c>true</c> if memory is already defined.</returns> protected abstract bool isDefined(SnapshotBase context);
/// <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 entries representing index resolving on current entry</returns> public ReadWriteSnapshotEntryBase ReadIndex(SnapshotBase context, MemberIdentifier index) { //TODO statistics reporting return(readIndex(context, index)); }
/// <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 abstract MemoryEntry readMemory(SnapshotBase context);
/// <summary> /// Extend snapshot as a call to function/method callee from given callerContext /// </summary> /// <param name="callerContext">The caller context.</param> /// <param name="callee">Program point graph of the callee (identification of function or method that was called).</param> /// <param name="thisObject">The this object.</param> /// <param name="arguments">The arguments.</param> protected abstract void extendAsCall(SnapshotBase callerContext, ProgramPointGraph callee, MemoryEntry thisObject, MemoryEntry[] arguments);
/// <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 abstract ReadWriteSnapshotEntryBase readField(SnapshotBase context, VariableIdentifier field);
/// <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="aliasedEntry">Snapshot entry which will be aliased from current entry</param> /// <param name="context">Context snapshot where operation is proceeded</param> protected abstract void setAliases(SnapshotBase context, ReadSnapshotEntryBase 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 entries representing field resolving on current entry</returns> public ReadWriteSnapshotEntryBase ReadField(SnapshotBase context, VariableIdentifier field) { //TODO statistics reporting return(readField(context, field)); }
/// <summary> /// Write given value at memory represent by snasphot entry. No value copy operations can be proceeded /// </summary> /// <param name="context">Context snapshot where operation is proceeded</param> /// <param name="value">Written value</param> public void WriteMemoryWithoutCopy(SnapshotBase context, MemoryEntry value) { //TODO statistics reporting writeMemoryWithoutCopy(context, 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> public IEnumerable <FunctionValue> ResolveMethod(SnapshotBase context, QualifiedName methodName) { //TODO statistics reporting return(resolveMethod(context, methodName)); }
/// <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="value">Written value</param> /// <param name="context">Context snapshot where operation is proceeded</param> protected abstract void writeMemoryWithoutCopy(SnapshotBase context, MemoryEntry value);