/// <summary>
        /// Generate type statistics for given layer of an array
        /// </summary>
        /// <param name="array"></param>
        /// <returns></returns>
        public static Dictionary <ClassNode, int> GetTypeStatisticsForLayer(StackValue array, Core core)
        {
            if (!StackUtils.IsArray(array))
            {
                Dictionary <ClassNode, int> ret = new Dictionary <ClassNode, int>();
                ret.Add(core.DSExecutable.classTable.ClassNodes[(int)array.metaData.type], 1);
                return(ret);
            }

            Dictionary <ClassNode, int> usageFreq = new Dictionary <ClassNode, int>();

            //This is the element on the heap that manages the data structure
            HeapElement heapElement = GetHeapElement(array, core);

            for (int i = 0; i < heapElement.VisibleSize; ++i)
            {
                StackValue sv = heapElement.Stack[i];
                ClassNode  cn = core.DSExecutable.classTable.ClassNodes[(int)sv.metaData.type];
                if (!usageFreq.ContainsKey(cn))
                {
                    usageFreq.Add(cn, 0);
                }

                usageFreq[cn] = usageFreq[cn] + 1;
            }

            return(usageFreq);
        }
        public static Dictionary <int, StackValue> GetTypeExamplesForLayer(StackValue array, Core core)
        {
            if (!StackUtils.IsArray(array))
            {
                Dictionary <int, StackValue> ret = new Dictionary <int, StackValue>();
                ret.Add((int)array.metaData.type, array);
                return(ret);
            }

            Dictionary <int, StackValue> usageFreq = new Dictionary <int, StackValue>();

            //This is the element on the heap that manages the data structure
            HeapElement heapElement = GetHeapElement(array, core);

            for (int i = 0; i < heapElement.VisibleSize; ++i)
            {
                StackValue sv = heapElement.Stack[i];
                if (!usageFreq.ContainsKey((int)sv.metaData.type))
                {
                    usageFreq.Add((int)sv.metaData.type, sv);
                }
            }

            return(usageFreq);
        }
        /// <summary>
        /// array[index] = value. Here index can be any type.
        ///
        /// Note this function doesn't support the replication of array indexing.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="index"></param>
        /// <param name="value"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue SetValueForIndex(StackValue array, StackValue index, StackValue value, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array) || StackUtils.IsString(array));

            if (StackUtils.IsNumeric(index))
            {
                index = index.AsInt();
                return(SetValueForIndex(array, (int)index.opdata, value, core));
            }
            else
            {
                HeapElement he = GetHeapElement(array, core);
                if (he.Dict == null)
                {
                    he.Dict = new Dictionary <StackValue, StackValue>(new StackValueComparer(core));
                }

                StackValue oldValue;
                if (!he.Dict.TryGetValue(index, out oldValue))
                {
                    oldValue = StackUtils.BuildNull();
                }

                GCUtils.GCRetain(index, core);
                GCUtils.GCRetain(value, core);
                he.Dict[index] = value;

                return(oldValue);
            }
        }
        private static int GetMaxRankForArray(StackValue array, Core core, int tracer)
        {
            if (tracer > RECURSION_LIMIT)
            {
                throw new CompilerInternalException("Internal Recursion limit exceeded in Rank Check - Possible heap corruption {3317D4F6-4758-4C19-9680-75B68DA0436D}");
            }

            if (!StackUtils.IsArray(array))
            {
                return(0);
            }
            //throw new ArgumentException("The stack value provided was not an array");

            int ret = 1;

            //This is the element on the heap that manages the data structure
            HeapElement heapElement = GetHeapElement(array, core);


            int largestSub = 0;

            for (int i = 0; i < heapElement.VisibleSize; ++i)
            {
                StackValue sv = heapElement.Stack[i];

                if (sv.optype == AddressType.ArrayPointer)
                {
                    int subArrayRank = GetMaxRankForArray(sv, core, tracer + 1);

                    largestSub = Math.Max(subArrayRank, largestSub);
                }
            }

            return(largestSub + ret);
        }
Beispiel #5
0
        /// <summary>
        /// Gets all array elements in a List of given type using the given converter to
        /// convert the stackValue.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="array"></param>
        /// <param name="core"></param>
        /// <param name="converter"></param>
        /// <returns></returns>
        public static List <T> GetValues <T>(StackValue array, Core core, Func <StackValue, T> converter)
        {
            Validity.Assert(StackUtils.IsArray(array));
            if (!StackUtils.IsArray(array))
            {
                return(null);
            }

            HeapElement he     = GetHeapElement(array, core);
            List <T>    values = new List <T>();

            foreach (var sv in he.Stack)
            {
                values.Add(converter(sv));
            }

            if (he.Dict != null)
            {
                foreach (var sv in he.Dict.Values)
                {
                    values.Add(converter(sv));
                }
            }

            return(values);
        }
        /// <summary>
        /// = array[index1][index2][...][indexN], and
        /// indices = {index1, index2, ..., indexN}
        ///
        /// Note this function doesn't support the replication of array indexing.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="indices"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue GetValueFromIndices(StackValue array, StackValue[] indices, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array) || StackUtils.IsString(array));
            for (int i = 0; i < indices.Length - 1; ++i)
            {
                if (!StackUtils.IsArray(array) && !StackUtils.IsString(array))
                {
                    core.RuntimeStatus.LogWarning(WarningID.kOverIndexing, WarningMessage.kArrayOverIndexed);
                    return(StackUtils.BuildNull());
                }

                StackValue index = indices[i];
                if (StackUtils.IsNumeric(index))
                {
                    index = index.AsInt();
                    array = GetValueFromIndex(array, (int)index.opdata, core);
                }
                else
                {
                    if (array.optype != AddressType.ArrayPointer)
                    {
                        core.RuntimeStatus.LogWarning(WarningID.kOverIndexing, WarningMessage.kArrayOverIndexed);
                        return(StackUtils.BuildNull());
                    }
                    array = GetValueFromIndex(array, index, core);
                }
            }

            return(GetValueFromIndex(array, indices[indices.Length - 1], core));
        }
Beispiel #7
0
        /*
         * [Obsolete]
         * public static StackValue CoerceArray(StackValue array, Type typ, Core core)
         * {
         *  //@TODO(Luke) handle array rank coersions
         *
         *  Validity.Assert(IsArray(array), "Argument needs to be an array {99FB71A6-72AD-4C93-8F1E-0B1F419C1A6D}");
         *
         *  //This is the element on the heap that manages the data structure
         *  HeapElement heapElement = GetHeapElement(array, core);
         *  StackValue[] newSVs = new StackValue[heapElement.VisibleSize];
         *
         *  for (int i = 0; i < heapElement.VisibleSize; ++i)
         *  {
         *      StackValue sv = heapElement.Stack[i];
         *      StackValue coercedValue;
         *
         *      if (IsArray(sv))
         *      {
         *          Type typ2 = new Type();
         *          typ2.UID = typ.UID;
         *          typ2.rank = typ.rank - 1;
         *          typ2.IsIndexable = (typ2.rank == -1 || typ2.rank > 0);
         *
         *          coercedValue = CoerceArray(sv, typ2, core);
         *      }
         *      else
         *      {
         *          coercedValue = TypeSystem.Coerce(sv, typ, core);
         *      }
         *
         *      GCUtils.GCRetain(coercedValue, core);
         *      newSVs[i] = coercedValue;
         *  }
         *
         *  return HeapUtils.StoreArray(newSVs, core);
         * }
         */


        /// <summary>
        /// Retrieve the first non-array element in an array
        /// </summary>
        /// <param name="svArray"></param>
        /// <param name="sv"></param>
        /// <param name="core"></param>
        /// <returns> true if the element was found </returns>
        public static bool GetFirstNonArrayStackValue(StackValue svArray, ref StackValue sv, Core core)
        {
            if (AddressType.ArrayPointer != svArray.optype)
            {
                return(false);
            }

            int ptr = (int)svArray.opdata;


            if (null == core.Rmem.Heap.Heaplist[ptr].Stack || core.Rmem.Heap.Heaplist[ptr].Stack.Length == 0)
            {
                return(false);
            }

            while (StackUtils.IsArray(core.Rmem.Heap.Heaplist[ptr].Stack[0]))
            {
                ptr = (int)core.Rmem.Heap.Heaplist[ptr].Stack[0].opdata;

                // Handle the case where the array is valid but empty
                if (core.Rmem.Heap.Heaplist[ptr].Stack.Length == 0)
                {
                    return(false);
                }
            }

            sv.optype   = core.Rmem.Heap.Heaplist[ptr].Stack[0].optype;
            sv.opdata   = core.Rmem.Heap.Heaplist[ptr].Stack[0].opdata;
            sv.metaData = core.Rmem.Heap.Heaplist[ptr].Stack[0].metaData;
            return(true);
        }
        /// <summary>
        /// array[index1][index2][...][indexN] = value, and
        /// indices = {index1, index2, ..., indexN}
        ///
        /// Note this function doesn't support the replication of array indexing.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="indices"></param>
        /// <param name="value"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue SetValueForIndices(StackValue array, StackValue[] indices, StackValue value, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array) || StackUtils.IsString(array));

            for (int i = 0; i < indices.Length - 1; ++i)
            {
                StackValue  index = indices[i];
                HeapElement he    = GetHeapElement(array, core);

                StackValue subArray;

                if (StackUtils.IsNumeric(index))
                {
                    index = index.AsInt();
                    int absIndex = he.ExpandByAcessingAt((int)index.opdata);
                    subArray = he.Stack[absIndex];
                }
                else
                {
                    subArray = GetValueFromIndex(array, index, core);
                }

                // auto-promotion
                if (!StackUtils.IsArray(subArray))
                {
                    subArray = HeapUtils.StoreArray(new StackValue[] { subArray }, null, core);
                    GCUtils.GCRetain(subArray, core);
                    SetValueForIndex(array, index, subArray, core);
                }

                array = subArray;
            }

            return(SetValueForIndex(array, indices[indices.Length - 1], value, core));
        }
        /// <summary>
        /// Get all keys from an array
        /// </summary>
        /// <param name="array"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue[] GetKeys(StackValue array, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array));
            if (!StackUtils.IsArray(array))
            {
                return(null);
            }

            HeapElement       he   = GetHeapElement(array, core);
            List <StackValue> keys = new List <StackValue>();

            for (int i = 0; i < he.VisibleSize; ++i)
            {
                keys.Add(StackUtils.BuildInt(i));
            }

            if (he.Dict != null)
            {
                foreach (var key in he.Dict.Keys)
                {
                    keys.Add(key);
                }
            }

            return(keys.ToArray());
        }
Beispiel #10
0
        internal int ComputeCastDistance(List <StackValue> args, ClassTable classTable, Core core)
        {
            //Compute the cost to migrate a class calls argument types to the coresponding base types
            //This cannot be used to determine whether a function can be called as it will ignore anything that doesn't
            //it should only be used to determine which class is closer

            if (args.Count != FormalParams.Length)
            {
                return(int.MaxValue);
            }

            int distance = 0;

            if (0 == args.Count)
            {
                return(distance);
            }
            else
            {
                // Check if all the types match the current function at 'n'
                for (int i = 0; i < args.Count; ++i)
                {
                    int rcvdType = (int)args[i].metaData.type;

                    // If its a default argumnet, then it wasnt provided by the caller
                    // The rcvdType is the type of the argument signature
                    if (args[i].optype == AddressType.DefaultArg)
                    {
                        rcvdType = FormalParams[i].UID;
                    }

                    int expectedType = FormalParams[i].UID;

                    int currentCost = 0;

                    if (FormalParams[i].IsIndexable != StackUtils.IsArray(args[i])) //Replication code will take care of this
                    {
                        continue;
                    }
                    else if (FormalParams[i].IsIndexable && (FormalParams[i].IsIndexable == StackUtils.IsArray(args[i])))
                    {
                        continue;
                    }
                    else if (expectedType == rcvdType && (FormalParams[i].IsIndexable == StackUtils.IsArray(args[i])))
                    {
                        continue;
                    }
                    else if (rcvdType != ProtoCore.DSASM.Constants.kInvalidIndex &&
                             expectedType != ProtoCore.DSASM.Constants.kInvalidIndex)
                    {
                        currentCost += ClassUtils.GetUpcastCountTo(classTable.ClassNodes[rcvdType],
                                                                   classTable.ClassNodes[expectedType], core);
                    }
                    distance += currentCost;
                }
                return(distance);
            }
        }
        /// <summary>
        /// = array[index].
        ///
        /// Note this function doesn't support the replication of array indexing.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="index"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue GetValueFromIndex(StackValue array, StackValue index, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array) || StackUtils.IsString(array));
            if (!StackUtils.IsArray(array) && !StackUtils.IsString(array))
            {
                return(StackUtils.BuildNull());
            }

            if (StackUtils.IsNumeric(index))
            {
                index = index.AsInt();
                return(GetValueFromIndex(array, (int)index.opdata, core));
            }
            else if (index.optype == AddressType.ArrayKey)
            {
                int         fullIndex = (int)index.opdata;
                HeapElement he        = GetHeapElement(array, core);

                if (he.VisibleSize > fullIndex)
                {
                    return(GetValueFromIndex(array, fullIndex, core));
                }
                else
                {
                    fullIndex = fullIndex - he.VisibleSize;
                    if (he.Dict != null && he.Dict.Count > fullIndex)
                    {
                        int count = 0;
                        foreach (var key in he.Dict.Keys)
                        {
                            if (count == fullIndex)
                            {
                                return(he.Dict[key]);
                            }
                            count = count + 1;
                        }
                    }
                }

                return(StackUtils.BuildNull());
            }
            else
            {
                HeapElement he    = GetHeapElement(array, core);
                StackValue  value = StackUtils.BuildNull();

                if (he.Dict != null && he.Dict.TryGetValue(index, out value))
                {
                    return(value);
                }
                else
                {
                    return(StackUtils.BuildNull());
                }
            }
        }
        public static int GetFullSize(StackValue array, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array));
            if (!StackUtils.IsArray(array))
            {
                return(Constants.kInvalidIndex);
            }

            return(GetElementSize(array, core) + GetValueSize(array, core));
        }
        /// <summary>
        /// Return the element size of an array
        /// </summary>
        /// <param name="array"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static int GetElementSize(StackValue array, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array));
            if (!StackUtils.IsArray(array))
            {
                return(Constants.kInvalidIndex);
            }

            return(GetHeapElement(array, core).VisibleSize);
        }
        /// <summary>
        /// = array[index]
        /// </summary>
        /// <param name="array"></param>
        /// <param name="index"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue GetValueFromIndex(StackValue array, int index, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array) || StackUtils.IsString(array));
            if (!StackUtils.IsArray(array) && !StackUtils.IsString(array))
            {
                return(StackUtils.BuildNull());
            }

            HeapElement he = GetHeapElement(array, core);

            return(StackUtils.GetValue(he, index, core));
        }
        public static bool IsUniform(StackValue sv, Core core)
        {
            if (!StackUtils.IsArray(sv))
            {
                return(false);
            }

            if (Utils.ArrayUtils.GetTypeStatisticsForArray(sv, core).Count != 1)
            {
                return(false);
            }

            return(true);
        }
        private static StackValue[] GetFlattenValue(StackValue array, Core core)
        {
            Queue <StackValue> workingSet    = new Queue <StackValue>();
            List <StackValue>  flattenValues = new List <StackValue>();

            if (!StackUtils.IsArray(array))
            {
                return(null);
            }

            workingSet.Enqueue(array);
            while (workingSet.Count > 0)
            {
                array = workingSet.Dequeue();
                HeapElement he = GetHeapElement(array, core);

                for (int i = 0; i < he.VisibleSize; ++i)
                {
                    StackValue value = he.Stack[i];
                    if (StackUtils.IsArray(value))
                    {
                        workingSet.Enqueue(value);
                    }
                    else
                    {
                        flattenValues.Add(value);
                    }
                }

                if (he.Dict != null)
                {
                    foreach (var value in he.Dict.Values)
                    {
                        if (StackUtils.IsArray(value))
                        {
                            workingSet.Enqueue(value);
                        }
                        else
                        {
                            flattenValues.Add(value);
                        }
                    }
                }
            }

            return(flattenValues.ToArray());
        }
        /// <summary>
        /// array[index] = value. The array will be expanded if necessary.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="index"></param>
        /// <param name="value"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue SetValueForIndex(StackValue array, int index, StackValue value, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array) || StackUtils.IsString(array));
            if (StackUtils.IsString(array) && value.optype != AddressType.Char)
            {
                core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeMismatch, RuntimeData.WarningMessage.kAssignNonCharacterToString);
                return(StackUtils.BuildNull());
            }

            lock (core.Heap.cslock)
            {
                HeapElement arrayHeap = GetHeapElement(array, core);
                index = arrayHeap.ExpandByAcessingAt(index);
                StackValue oldValue = arrayHeap.SetValue(index, value);
                return(oldValue);
            }
        }
Beispiel #18
0
        /// <summary>
        /// Generate type statistics for the whole array
        /// </summary>
        /// <param name="array"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static Dictionary <ClassNode, int> GetTypeStatisticsForArray(StackValue array, Core core)
        {
            if (!StackUtils.IsArray(array))
            {
                Dictionary <ClassNode, int> ret = new Dictionary <ClassNode, int>();
                ret.Add(core.ClassTable.ClassNodes[(int)array.metaData.type], 1);
                return(ret);
            }

            Dictionary <ClassNode, int> usageFreq = new Dictionary <ClassNode, int>();

            //This is the element on the heap that manages the data structure
            HeapElement heapElement = GetHeapElement(array, core);

            for (int i = 0; i < heapElement.VisibleSize; ++i)
            {
                StackValue sv = heapElement.Stack[i];

                if (sv.optype == AddressType.ArrayPointer)
                {
                    //Recurse
                    Dictionary <ClassNode, int> subLayer = GetTypeStatisticsForArray(sv, core);
                    foreach (ClassNode cn in subLayer.Keys)
                    {
                        if (!usageFreq.ContainsKey(cn))
                        {
                            usageFreq.Add(cn, 0);
                        }

                        usageFreq[cn] = usageFreq[cn] + subLayer[cn];
                    }
                }
                else
                {
                    ClassNode cn = core.ClassTable.ClassNodes[(int)sv.metaData.type];
                    if (!usageFreq.ContainsKey(cn))
                    {
                        usageFreq.Add(cn, 0);
                    }

                    usageFreq[cn] = usageFreq[cn] + 1;
                }
            }

            return(usageFreq);
        }
        /// <summary>
        /// If the passed in value is not an array or an empty array or an array which contains only empty arrays, return false.
        /// Otherwise, return true;
        /// </summary>
        /// <param name="sv"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static bool ContainsNonArrayElement(StackValue sv, Core core)
        {
            if (!StackUtils.IsArray(sv))
            {
                return(true);
            }

            StackValue[] svArray = core.Rmem.GetArrayElements(sv);
            foreach (var item in svArray)
            {
                if (ContainsNonArrayElement(item, core))
                {
                    return(true);
                }
            }

            return(false);
        }
        public static bool RemoveKey(StackValue array, StackValue key, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array));
            if (!StackUtils.IsArray(array))
            {
                return(false);
            }

            HeapElement he = GetHeapElement(array, core);

            if (StackUtils.IsNumeric(key))
            {
                long index = key.AsInt().opdata;
                if (index < 0)
                {
                    index = index + he.VisibleSize;
                }

                if (index >= 0 && index < he.VisibleSize)
                {
                    StackValue oldValue = he.Stack[index];
                    he.Stack[index] = StackUtils.BuildNull();

                    if (index == he.VisibleSize - 1)
                    {
                        he.VisibleSize -= 1;
                    }
                    return(true);
                }
            }
            else
            {
                if (he.Dict != null && he.Dict.ContainsKey(key))
                {
                    StackValue value = he.Dict[key];
                    GCUtils.GCRelease(key, core);
                    GCUtils.GCRelease(value, core);
                    he.Dict.Remove(key);
                    return(true);
                }
            }

            return(false);
        }
        /*
         * [Obsolete]
         * public static StackValue CoerceArray(StackValue array, Type typ, Core core)
         * {
         *  //@TODO(Luke) handle array rank coersions
         *
         *  Validity.Assert(IsArray(array), "Argument needs to be an array {99FB71A6-72AD-4C93-8F1E-0B1F419C1A6D}");
         *
         *  //This is the element on the heap that manages the data structure
         *  HeapElement heapElement = GetHeapElement(array, core);
         *  StackValue[] newSVs = new StackValue[heapElement.VisibleSize];
         *
         *  for (int i = 0; i < heapElement.VisibleSize; ++i)
         *  {
         *      StackValue sv = heapElement.Stack[i];
         *      StackValue coercedValue;
         *
         *      if (IsArray(sv))
         *      {
         *          Type typ2 = new Type();
         *          typ2.UID = typ.UID;
         *          typ2.rank = typ.rank - 1;
         *          typ2.IsIndexable = (typ2.rank == -1 || typ2.rank > 0);
         *
         *          coercedValue = CoerceArray(sv, typ2, core);
         *      }
         *      else
         *      {
         *          coercedValue = TypeSystem.Coerce(sv, typ, core);
         *      }
         *
         *      GCUtils.GCRetain(coercedValue, core);
         *      newSVs[i] = coercedValue;
         *  }
         *
         *  return HeapUtils.StoreArray(newSVs, core);
         * }
         */


        // Retrieve the first non-array element in an array
        public static bool GetFirstNonArrayStackValue(StackValue svArray, ref StackValue sv, Core core)
        {
            if (AddressType.ArrayPointer != svArray.optype)
            {
                return(false);
            }

            int ptr = (int)svArray.opdata;

            while (StackUtils.IsArray(core.Rmem.Heap.Heaplist[ptr].Stack[0]))
            {
                ptr = (int)core.Rmem.Heap.Heaplist[ptr].Stack[0].opdata;
            }

            sv.optype   = core.Rmem.Heap.Heaplist[ptr].Stack[0].optype;
            sv.opdata   = core.Rmem.Heap.Heaplist[ptr].Stack[0].opdata;
            sv.metaData = core.Rmem.Heap.Heaplist[ptr].Stack[0].metaData;
            return(true);
        }
        public static int GetValueSize(StackValue array, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array));
            if (!StackUtils.IsArray(array))
            {
                return(Constants.kInvalidIndex);
            }

            HeapElement he = GetHeapElement(array, core);

            if (null == he)
            {
                return(0);
            }

            var dict = he.Dict as Dictionary <StackValue, StackValue>;

            return((null == dict) ? 0 : dict.Count);
        }
        /// <summary>
        /// Copy an array and coerce its elements/values to target type
        /// </summary>
        /// <param name="array"></param>
        /// <param name="type"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue CopyArray(StackValue array, Type type, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array));
            if (!StackUtils.IsArray(array))
            {
                return(StackUtils.BuildNull());
            }

            HeapElement he = GetHeapElement(array, core);

            Validity.Assert(he != null);

            int elementSize = GetElementSize(array, core);

            StackValue[] elements = new StackValue[elementSize];
            for (int i = 0; i < elementSize; i++)
            {
                StackValue coercedValue = TypeSystem.Coerce(he.Stack[i], type, core);
                GCUtils.GCRetain(coercedValue, core);
                elements[i] = coercedValue;
            }

            Dictionary <StackValue, StackValue> dict = null;

            if (he.Dict != null)
            {
                dict = new Dictionary <StackValue, StackValue>(new StackValueComparer(core));
                foreach (var pair in he.Dict)
                {
                    StackValue key          = pair.Key;
                    StackValue value        = pair.Value;
                    StackValue coercedValue = TypeSystem.Coerce(value, type, core);

                    GCUtils.GCRetain(key, core);
                    GCUtils.GCRetain(coercedValue, core);

                    dict[key] = coercedValue;
                }
            }

            return(HeapUtils.StoreArray(elements, dict, core));
        }
Beispiel #24
0
        ///// <summary>
        ///// Get the maximum depth to which an object can be reduced
        ///// </summary>
        ///// <param name="obj"></param>
        ///// <returns></returns>
        //[Obsolete]
        //public static int GetMaxReductionDepth(ProtoCore.Lang.Obj obj)
        //{
        //    if (!obj.Type.IsIndexable)
        //        return 0;
        //    else
        //    {
        //        return 1 + GetMaxReductionDepth((Obj)((DSASM.Mirror.DsasmArray)obj.Payload).members[0]);
        //    }
        //}

        /// <summary>
        /// Get the maximum depth to which an element can be reduced
        /// This will include cases where only partial reduction can be performed on jagged arrays
        /// </summary>
        /// <param name="sv"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static int GetMaxReductionDepth(StackValue sv, Core core)
        {
            //PERF(Luke): Could be non-recursive
            if (!StackUtils.IsArray(sv))
            {
                return(0);
            }

            int maxReduction = 0;

            //De-ref the sv
            HeapElement he = ProtoCore.Utils.ArrayUtils.GetHeapElement(sv, core);

            for (int i = 0; i < he.VisibleSize; ++i)
            {
                StackValue subSv = he.Stack[i];
                maxReduction = Math.Max(maxReduction, GetMaxReductionDepth(subSv, core));
            }

            return(1 + maxReduction);
        }
        /// <summary>
        /// Get all values from an array.
        /// </summary>
        /// <param name="array"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue[] GetValues(StackValue array, Core core)
        {
            Validity.Assert(StackUtils.IsArray(array));
            if (!StackUtils.IsArray(array))
            {
                return(null);
            }

            HeapElement       he     = GetHeapElement(array, core);
            List <StackValue> values = new List <StackValue>(he.Stack);

            if (he.Dict != null)
            {
                foreach (var value in he.Dict.Values)
                {
                    values.Add(value);
                }
            }

            return(values.ToArray());
        }
Beispiel #26
0
        /// <summary>
        /// Tests whether this end point matches the type of the passed arguments
        /// </summary>
        /// <param name="formalParameters">The proposed parameters </param>
        /// <returns></returns>
        public bool DoesTypeMatch(List <StackValue> formalParameters)
        {
            if (formalParameters.Count != FormalParams.Length)
            {
                return(false);
            }

            for (int i = 0; i < FormalParams.Length; i++)
            {
                if (FormalParams[i].IsIndexable && StackUtils.IsArray(formalParameters[i]))
                {
                    continue;
                }

                if (FormalParams[i].UID != (int)formalParameters[i].metaData.type)
                {
                    return(false);
                }
            }
            return(true);
        }
Beispiel #27
0
        public void IsArrayTest()
        {
            String code =
                @"a;b;c;
[Imperative]
{
	a = {1,2,3};
    b = 1;
    c = a;
}
";

            ProtoScript.Runners.ProtoScriptTestRunner fsr = new ProtoScript.Runners.ProtoScriptTestRunner();
            ExecutionMirror mirror = fsr.Execute(code, core);
            StackValue      svA    = mirror.GetRawFirstValue("a");
            StackValue      svB    = mirror.GetRawFirstValue("b");
            StackValue      svC    = mirror.GetRawFirstValue("c");

            Assert.IsTrue(StackUtils.IsArray(svA));
            Assert.IsTrue(!StackUtils.IsArray(svB));
            Assert.IsTrue(StackUtils.IsArray(svC));
        }
        /// <summary>
        /// = array[index1][index2][...][indexN], and
        /// indices = {index1, index2, ..., indexN}
        /// </summary>
        /// <param name="array"></param>
        /// <param name="indices"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue GetValueFromIndices(StackValue array, List <StackValue> indices, Core core)
        {
            if (indices.Count == 0)
            {
                return(array);
            }
            else if (!StackUtils.IsArray(array) && !StackUtils.IsString(array))
            {
                core.RuntimeStatus.LogWarning(WarningID.kOverIndexing, WarningMessage.kArrayOverIndexed);
                return(StackUtils.BuildNull());
            }

            StackValue[][] zippedIndices = ArrayUtils.GetZippedIndices(indices, core);
            if (zippedIndices == null || zippedIndices.Length == 0)
            {
                return(StackUtils.BuildNull());
            }

            StackValue[] values = new StackValue[zippedIndices.Length];
            for (int i = 0; i < zippedIndices.Length; ++i)
            {
                values[i] = GetValueFromIndices(array, zippedIndices[i], core);
            }

            if (zippedIndices.Length > 1)
            {
                for (int i = 0; i < values.Length; ++i)
                {
                    GCUtils.GCRelease(values[i], core);
                }

                return(HeapUtils.StoreArray(values, null, core));
            }
            else
            {
                return(values[0]);
            }
        }
        /// <summary>
        /// Whether sv is double or arrays contains double value.
        /// </summary>
        /// <param name="sv"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static bool ContainsDoubleElement(StackValue sv, Core core)
        {
            if (!StackUtils.IsArray(sv))
            {
                return(core.TypeSystem.GetType(sv) == (int)PrimitiveType.kTypeDouble);
            }

            StackValue[] svArray = core.Rmem.GetArrayElements(sv);
            foreach (var item in svArray)
            {
                if (StackUtils.IsArray(item) && ContainsDoubleElement(item, core))
                {
                    return(true);
                }

                if (core.TypeSystem.GetType(item) == (int)PrimitiveType.kTypeDouble)
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #30
0
        /// <summary>
        /// This computes the max depth to which the element can be reduced
        /// It contains a protected envelope
        /// </summary>
        /// <param name="sv"></param>
        /// <param name="core"></param>
        /// <param name="depthCount"></param>
        /// <returns></returns>
        private static int RecursiveProtectGetMaxReductionDepth(StackValue sv, Core core, int depthCount)
        {
            Validity.Assert(depthCount < 1000,
                            "StackOverflow protection trap. This is almost certainly a VM cycle-in-array bug. {0B530165-2E38-431D-88D9-56B0636364CD}");

            //PERF(Luke): Could be non-recursive
            if (!StackUtils.IsArray(sv))
            {
                return(0);
            }

            int maxReduction = 0;

            //De-ref the sv
            HeapElement he = ProtoCore.Utils.ArrayUtils.GetHeapElement(sv, core);

            for (int i = 0; i < he.VisibleSize; ++i)
            {
                StackValue subSv = he.Stack[i];
                maxReduction = Math.Max(maxReduction, RecursiveProtectGetMaxReductionDepth(subSv, core, depthCount + 1));
            }

            return(1 + maxReduction);
        }