/// <summary> /// Returns identifiers of all indexes of arrays which was found in memory entry. /// </summary> /// <param name="snapshot">The snapshot.</param> /// <returns>Identifiers of all indexes of arrays which was found in memory entry</returns> public IEnumerable <MemberIdentifier> CollectIndexes(Snapshot snapshot) { HashSet <MemberIdentifier> indexes = new HashSet <MemberIdentifier>(); foreach (AssociativeArray arrayValue in Arrays) { IArrayDescriptor descriptor; try { descriptor = snapshot.Structure.Readonly.GetDescriptor(arrayValue); } catch (Exception) { continue; } foreach (var index in descriptor.Indexes) { indexes.Add(new MemberIdentifier(index.Key)); } } indexes.Add(MemberIdentifier.getUnknownMemberIdentifier()); return(indexes); }
/// <inheritdoc /> protected override void flowThrough() { if (Index == null) { // $a[] = value; // Creates new index that is biggest integer index in $a + 1 and writes the value to this index // TODO: // What is should do // Iterate through all arrays in UsedItem // for each array iterate through all indices and find the biggest integer index // for each array resolve the index // LValue should represent all these indices // What it does // Iterate through all indices of all arrays in UsedItem and find the biggest integer index // Resolve this index in all arrays // TODO: causes non-termination: while() $a[] = 1; // Do this only for non-widened arrays. Then write to unknown index // Now arrays are not widened => we use just unknown index /* * IndexIdentifier = new MemberIdentifier (System.Convert.ToString( * UsedItem.Value.BiggestIntegerIndex(OutSnapshot, Services.Evaluator) + 1, * CultureInfo.InvariantCulture)); */ // use the unknown index IndexIdentifier = MemberIdentifier.getUnknownMemberIdentifier(); } else { IndexIdentifier = Services.Evaluator.MemberIdentifier(Index.Value.ReadMemory(OutSnapshot)); } LValue = Services.Evaluator.ResolveIndex(UsedItem.Value, IndexIdentifier); }
/// <summary> /// Base on type function returns AnyTypeValue /// </summary> /// <param name="type">Type to resolve</param> /// <param name="flow">FlowController</param> /// <returns>MemoryEntry containg Abstract Values</returns> public static MemoryEntry ResolveReturnValue(string type, FlowController flow) { var outset = flow.OutSet; List <Value> res = new List <Value>(); switch (type) { case "number": res.Add(outset.AnyIntegerValue); break; case "float": case "double": res.Add(outset.AnyFloatValue); break; case "int": case "integer": res.Add(outset.AnyIntegerValue); break; case "long": res.Add(outset.AnyLongintValue); break; case "string": res.Add(outset.AnyStringValue); break; case "array": res.Add(outset.AnyArrayValue); break; case "void": case "none": res.Add(outset.UndefinedValue); break; case "boolean": case "bool": res.Add(outset.AnyBooleanValue); break; case "object": res.Add(outset.AnyObjectValue); break; case "mixed": case "any": case "ReturnType": res.Add(outset.AnyValue); break; case "NULL": res.Add(outset.UndefinedValue); break; case "resource": res.Add(outset.AnyResourceValue); res.Add(outset.UndefinedValue); break; case "callable": res.Add(outset.AnyStringValue); break; case "bool|string": res.Add(outset.AnyStringValue); res.Add(outset.AnyBooleanValue); break; case "string|array": res.Add(outset.AnyStringValue); res.Add(outset.AnyArrayValue); break; case "bool|array": res.Add(outset.AnyStringValue); res.Add(outset.AnyArrayValue); break; default: if (type.StartsWith("array-")) { // array of objects of the type given by type.Substring(6) // create array var array = flow.OutSet.CreateArray(); var arrayEntry = flow.OutSet.CreateSnapshotEntry(new MemoryEntry(array)); // write object to the unknown field of the array var obj = CreateObject(flow, type.Substring(6)); var index = arrayEntry.ReadIndex(flow.OutSet.Snapshot, MemberIdentifier.getUnknownMemberIdentifier()); index.WriteMemory(flow.OutSet.Snapshot, new MemoryEntry(obj)); res.Add(array); } else { res.Add(CreateObject(flow, type)); } break; } return(new MemoryEntry(res)); }