Exemplo n.º 1
0
        public static StackValue SetDataAtIndices(StackValue array, int[] indices, StackValue data, Core core)
        {
            Validity.Assert(array.optype == AddressType.ArrayPointer || array.optype == AddressType.String);

            StackValue arrayItem = array;

            for (int i = 0; i < indices.Length - 1; ++i)
            {
                HeapElement arrayHeap = core.Heap.Heaplist[(int)arrayItem.opdata];
                int         index     = arrayHeap.ExpandByAcessingAt(indices[i]);
                arrayItem = arrayHeap.Stack[index];

                if (arrayItem.optype == AddressType.String)
                {
                    core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kOverIndexing, ProtoCore.RuntimeData.WarningMessage.kStringOverIndexed);
                    return(StackUtils.BuildNull());
                }
                else if (arrayItem.optype != AddressType.ArrayPointer)
                {
                    StackValue sv = HeapUtils.StoreArray(new StackValue[] { arrayItem }, core);
                    GCUtils.GCRetain(sv, core);
                    arrayHeap.Stack[index] = sv;
                    arrayItem = arrayHeap.Stack[index];
                }
            }

            return(ArrayUtils.SetDataAtIndex(arrayItem, indices[indices.Length - 1], data, core));
        }
Exemplo n.º 2
0
 private void PushFrame(int size)
 {
     for (int n = 0; n < size; ++n)
     {
         Stack.Add(StackUtils.BuildNull());
     }
 }
Exemplo n.º 3
0
        /// <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);
            }
        }
Exemplo n.º 4
0
 public void PushGlobFrame(int globsize)
 {
     for (int n = 0; n < globsize; ++n)
     {
         Stack.Add(StackUtils.BuildNull());
     }
 }
Exemplo n.º 5
0
        /// <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));
        }
Exemplo n.º 6
0
        public static StackValue GetNextKey(StackValue key, Core core)
        {
            if (StackUtils.IsNull(key) ||
                key.optype != AddressType.ArrayKey ||
                key.opdata < 0 ||
                key.metaData.type < 0)
            {
                return(StackUtils.BuildNull());
            }

            int ptr   = key.metaData.type;
            int index = (int)key.opdata;

            HeapElement he = core.Heap.Heaplist[ptr];

            if ((he.VisibleSize > index + 1) ||
                (he.Dict != null && he.Dict.Count + he.VisibleSize > index + 1))
            {
                StackValue newKey = key;
                newKey.opdata = newKey.opdata + 1;
                return(newKey);
            }

            return(StackUtils.BuildNull());
        }
Exemplo n.º 7
0
        /// <summary>
        /// array[index1][index2][...][indexN] = value, and
        /// indices = {index1, index2, ..., indexN}
        /// </summary>
        /// <param name="array"></param>
        /// <param name="indices"></param>
        /// <param name="value"></param>
        /// <param name="t"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public static StackValue SetValueForIndices(StackValue array, List <StackValue> indices, StackValue value, Type t, Core core)
        {
            StackValue[][] zippedIndices = ArrayUtils.GetZippedIndices(indices, core);
            if (zippedIndices == null || zippedIndices.Length == 0)
            {
                return(StackUtils.BuildNull());
            }

            if (zippedIndices.Length == 1)
            {
                StackValue coercedData = TypeSystem.Coerce(value, t, core);
                GCUtils.GCRetain(coercedData, core);
                return(ArrayUtils.SetValueForIndices(array, zippedIndices[0], coercedData, core));
            }
            else if (value.optype == AddressType.ArrayPointer)
            {
                // Replication happens on both side.
                if (t.rank > 0)
                {
                    t.rank = t.rank - 1;
                    if (t.rank == 0)
                    {
                        t.IsIndexable = false;
                    }
                }

                HeapElement dataHeapElement = GetHeapElement(value, core);
                int         length          = Math.Min(zippedIndices.Length, dataHeapElement.VisibleSize);

                StackValue[] oldValues = new StackValue[length];
                for (int i = 0; i < length; ++i)
                {
                    StackValue coercedData = TypeSystem.Coerce(dataHeapElement.Stack[i], t, core);
                    GCUtils.GCRetain(coercedData, core);
                    oldValues[i] = SetValueForIndices(array, zippedIndices[i], coercedData, core);
                }

                // The returned old values shouldn't have any key-value pairs
                return(HeapUtils.StoreArray(oldValues, null, core));
            }
            else
            {
                // Replication is only on the LHS, so collect all old values
                // and return them in an array.
                StackValue coercedData = TypeSystem.Coerce(value, t, core);
                GCUtils.GCRetain(coercedData, core);

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

                // The returned old values shouldn't have any key-value pairs
                return(HeapUtils.StoreArray(oldValues, null, core));
            }
        }
Exemplo n.º 8
0
        /// <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());
                }
            }
        }
Exemplo n.º 9
0
        /// <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));
        }
Exemplo n.º 10
0
 public StackValue BuildNullArray(int size)
 {
     lock (Heap.cslock)
     {
         int ptr = Heap.Allocate(size);
         for (int n = 0; n < size; ++n)
         {
             Heap.Heaplist[ptr].Stack[n] = StackUtils.BuildNull();
         }
         return(StackUtils.BuildArrayPointer(ptr));
     }
 }
Exemplo n.º 11
0
        public static StackValue SetDataAtIndices(StackValue array, List <StackValue> indices, StackValue data, Type t, Core core)
        {
            int[][] zippedIndices = ArrayUtils.GetZippedIndices(indices, core);
            if (zippedIndices == null || zippedIndices.Length == 0)
            {
                return(StackUtils.BuildNull());
            }

            if (zippedIndices.Length == 1)
            {
                StackValue coercedData = TypeSystem.Coerce(data, t, core);
                GCUtils.GCRetain(coercedData, core);
                return(ArrayUtils.SetDataAtIndices(array, zippedIndices[0], coercedData, core));
            }
            else if (data.optype == AddressType.ArrayPointer)
            {
                if (t.rank > 0)
                {
                    t.rank = t.rank - 1;
                    if (t.rank == 0)
                    {
                        t.IsIndexable = false;
                    }
                }

                HeapElement dataHeapElement = core.Heap.Heaplist[(int)data.opdata];
                int         length          = Math.Min(zippedIndices.Length, dataHeapElement.VisibleSize);

                StackValue[] oldValues = new StackValue[length];
                for (int i = 0; i < length; ++i)
                {
                    StackValue coercedData = TypeSystem.Coerce(dataHeapElement.Stack[i], t, core);
                    GCUtils.GCRetain(coercedData, core);
                    oldValues[i] = ArrayUtils.SetDataAtIndices(array, zippedIndices[i], coercedData, core);
                }
                return(HeapUtils.StoreArray(oldValues, core));
            }
            else
            {
                StackValue coercedData = TypeSystem.Coerce(data, t, core);
                GCUtils.GCRetain(coercedData, core);

                StackValue[] oldValues = new StackValue[zippedIndices.Length];
                for (int i = 0; i < zippedIndices.Length; ++i)
                {
                    oldValues[i] = ArrayUtils.SetDataAtIndices(array, zippedIndices[i], coercedData, core);
                }
                return(HeapUtils.StoreArray(oldValues, core));
            }
        }
Exemplo n.º 12
0
        public static StackValue SetDataAtIndex(StackValue svArray, int index, StackValue svData, Core core)
        {
            Validity.Assert(svArray.optype == AddressType.ArrayPointer || svArray.optype == AddressType.String);
            if (svArray.optype == AddressType.String && svData.optype != AddressType.Char)
            {
                core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeMismatch, RuntimeData.WarningMessage.kAssignNonCharacterToString);
                return(StackUtils.BuildNull());
            }

            lock (core.Heap.cslock)
            {
                HeapElement arrayHeap = core.Heap.Heaplist[(int)svArray.opdata];
                index = arrayHeap.ExpandByAcessingAt(index);
                StackValue oldValue = arrayHeap.SetValue(index, svData);
                return(oldValue);
            }
        }
Exemplo n.º 13
0
        /// <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);
            }
        }
Exemplo n.º 14
0
            public StackValue GetMemberData(int symbolindex, int scope)
            {
                int thisptr = (int)GetAtRelative(GetStackIndex(ProtoCore.DSASM.StackFrame.kFrameIndexThisPtr)).opdata;

                // Get the heapstck offset
                int offset = ClassTable.ClassNodes[scope].symbols.symbolList[symbolindex].index;

                if (null == Heap.Heaplist[thisptr].Stack || Heap.Heaplist[thisptr].Stack.Length == 0)
                {
                    return(StackUtils.BuildNull());
                }

                StackValue sv = Heap.Heaplist[thisptr].Stack[offset];

                Validity.Assert(AddressType.Pointer == sv.optype || AddressType.ArrayPointer == sv.optype || AddressType.Invalid == sv.optype);

                // Not initialized yet
                if (sv.optype == AddressType.Invalid)
                {
                    sv.optype   = AddressType.Null;
                    sv.opdata_d = sv.opdata = 0;
                    return(sv);
                }
                else if (sv.optype == AddressType.ArrayPointer)
                {
                    return(sv);
                }

                int nextPtr = (int)sv.opdata;

                Validity.Assert(nextPtr >= 0);
                if (null != Heap.Heaplist[nextPtr].Stack && Heap.Heaplist[nextPtr].Stack.Length > 0)
                {
                    bool isActualData =
                        AddressType.Pointer != Heap.Heaplist[nextPtr].Stack[0].optype &&
                        AddressType.ArrayPointer != Heap.Heaplist[nextPtr].Stack[0].optype &&
                        AddressType.Invalid != Heap.Heaplist[nextPtr].Stack[0].optype;    // Invalid is an uninitialized member

                    if (isActualData)
                    {
                        return(Heap.Heaplist[nextPtr].Stack[0]);
                    }
                }
                return(sv);
            }
Exemplo n.º 15
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="context"></param>
        /// <param name="dsi"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public override StackValue Marshal(object obj, ProtoCore.Runtime.Context context, Interpreter dsi, ProtoCore.Type type)
        {
            if (obj == null)
            {
                return(StackUtils.BuildNull());
            }

            FFIObjectMarshler marshaler = null;
            StackValue        retVal;
            Type objType = obj.GetType();

            if (type.IsIndexable)
            {
                if (obj is System.Collections.ICollection)
                {
                    System.Collections.ICollection collection = obj as System.Collections.ICollection;
                    object[] array = new object[collection.Count];
                    collection.CopyTo(array, 0);
                    return(PrimitiveMarshler.ConvertCSArrayToDSArray(this, array, context, dsi, type));
                }
                else if (obj is System.Collections.IEnumerable)
                {
                    System.Collections.IEnumerable enumerable = obj as System.Collections.IEnumerable;
                    return(PrimitiveMarshler.ConvertCSArrayToDSArray(this, enumerable, context, dsi, type));
                }
            }

            Array arr = obj as Array;

            if (null != arr)
            {
                return(PrimitiveMarshler.ConvertCSArrayToDSArray(this, arr, context, dsi, type));
            }
            else if ((PrimitiveMarshler.IsPrimitiveDSType(type) || PrimitiveMarshler.IsPrimitiveObjectType(obj, type)) && mPrimitiveMarshalers.TryGetValue(objType, out marshaler))
            {
                return(marshaler.Marshal(obj, context, dsi, type));
            }
            else if (CLRObjectMap.TryGetValue(obj, out retVal))
            {
                return(retVal);
            }

            return(CreateDSObject(obj, context, dsi));
        }
Exemplo n.º 16
0
        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);
        }
Exemplo n.º 17
0
        private object ConvertReturnValue(object retVal, ProtoCore.Runtime.Context context, ProtoCore.DSASM.Interpreter dsi)
        {
            object returnValue = retVal;

            //  these are arrays!
            if (mReturnType.IsIndexable)
            {
                //  we have already asserted that these can be of rank 1 only, for now
                //
                IntPtr arrPtr = (IntPtr)retVal;
                if (arrPtr == IntPtr.Zero)
                {
                    return(StackUtils.BuildNull());
                }

                _Array arr  = (_Array)Marshal.PtrToStructure(arrPtr, typeof(_Array));
                var    elem = arr.elements;

                if (mReturnType.Name == "double")
                {
                    double[] elements = new double[arr.numElems];
                    Marshal.Copy(arr.elements, elements, 0, arr.numElems);

                    //  free up the memory
                    Marshal.FreeCoTaskMem(arr.elements);
                    Marshal.FreeCoTaskMem(arrPtr);

                    returnValue = ConvertCSArrayToDSArray(elements, dsi);
                }
                else if (mReturnType.Name == "int")
                {
                    int[] elements = new int[arr.numElems];
                    Marshal.Copy(arr.elements, elements, 0, arr.numElems);
                    return(elements);
                }
                else
                {
                    throw new ArgumentException(string.Format("FFI: unknown type {0} to marshall", mReturnType.Name));
                }
            }

            return(returnValue);
        }
Exemplo n.º 18
0
        /// <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));
        }
Exemplo n.º 19
0
        public static StackValue GetArrayElement(StackValue svPtr, List <StackValue> svDimList, Core core)
        {
            Validity.Assert(IsArray(svPtr));
            HeapElement heapElem = null;

            StackValue svFinal = StackUtils.BuildNull();

            foreach (StackValue sv in svDimList)
            {
                if (svPtr.optype != AddressType.ArrayPointer)
                {
                    core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kOverIndexing, ProtoCore.RuntimeData.WarningMessage.kArrayOverIndexed);
                    return(StackUtils.BuildNull());
                }
                heapElem = core.Heap.Heaplist[(int)svPtr.opdata];
                svPtr    = StackUtils.GetValue(heapElem, (int)sv.opdata, core);
                svFinal  = svPtr;
            }
            return(svFinal);
        }
Exemplo n.º 20
0
        /// <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]);
            }
        }
Exemplo n.º 21
0
            public StackValue GetStackData(int blockId, int symbolindex, int classscope, int offset = 0)
            {
                SymbolNode symbolNode = null;

                if (Constants.kInvalidIndex == classscope)
                {
                    symbolNode = Executable.runtimeSymbols[blockId].symbolList[symbolindex];
                }
                else
                {
                    symbolNode = ClassTable.ClassNodes[classscope].symbols.symbolList[symbolindex];
                }

                Validity.Assert(null != symbolNode);
                int n = GetRelative(offset, GetStackIndex(symbolNode));

                if (n > Stack.Count - 1)
                {
                    return(StackUtils.BuildNull());
                }

                return(Stack[n]);
            }
Exemplo n.º 22
0
        public override object Execute(ProtoCore.Runtime.Context c, Interpreter dsi)
        {
            int nParamCount     = mArgTypes.Length;
            int paramCount      = mArgTypes.Length;
            int envSize         = IsDNI ? 2 : 0;
            int totalParamCount = paramCount + envSize;

            List <Object> parameters            = new List <object>();
            List <ProtoCore.DSASM.StackValue> s = dsi.runtime.rmem.Stack;
            Object            thisObject        = null;
            FFIObjectMarshler marshaller        = Module.GetMarshaller(dsi.runtime.Core);

            if (!ReflectionInfo.IsStatic)
            {
                try
                {
                    thisObject = marshaller.UnMarshal(s.Last(), c, dsi, ReflectionInfo.DeclaringType);
                }
                catch (InvalidOperationException)
                {
                    string message = String.Format(ProtoCore.RuntimeData.WarningMessage.kFFIFailedToObtainThisObject, ReflectionInfo.DeclaringType.Name, ReflectionInfo.Name);
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, message);
                    return(null);
                }

                if (thisObject == null)
                {
                    return(null); //Can't call a method on null object.
                }
            }

            ParameterInfo[] paraminfos = ReflectionInfo.GetParameters();
            for (int i = 0; i < mArgTypes.Length; ++i)
            {
                // Comment Jun: FFI function stack frames do not contain locals
                int locals   = 0;
                int relative = 0 - ProtoCore.DSASM.StackFrame.kStackFrameSize - locals - i - 1;
                ProtoCore.DSASM.StackValue opArg = dsi.runtime.rmem.GetAtRelative(relative);
                try
                {
                    Type   paramType = paraminfos[i].ParameterType;
                    object param     = marshaller.UnMarshal(opArg, c, dsi, paramType);


                    //null is passed for a value type, so we must return null
                    //rather than interpreting any value from null. fix defect 1462014
                    if (!paramType.IsGenericType && paramType.IsValueType && param == null)
                    {
                        throw new System.InvalidCastException(string.Format("Null value cannot be cast to {0}", paraminfos[i].ParameterType.Name));
                    }

                    parameters.Add(param);
                }
                catch (System.InvalidCastException ex)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
                    return(null);
                }
                catch (InvalidOperationException)
                {
                    string message = String.Format(ProtoCore.RuntimeData.WarningMessage.kFFIFailedToObtainObject, paraminfos[i].ParameterType.Name, ReflectionInfo.DeclaringType.Name, ReflectionInfo.Name);
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, message);
                    return(null);
                }
            }

            object     ret        = null;
            StackValue dsRetValue = StackUtils.BuildNull();

            try
            {
                ret = InvokeFunctionPointer(thisObject, parameters.Count > 0 ? parameters.ToArray() : null);
                //Reduce to singleton if the attribute is specified.
                ret        = ReflectionInfo.ReduceReturnedCollectionToSingleton(ret);
                dsRetValue = marshaller.Marshal(ret, c, dsi, mReturnType);
            }
            catch (DllNotFoundException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogSemanticError(ex.InnerException.Message);
                }
                dsi.LogSemanticError(ex.Message);
            }
            catch (System.Reflection.TargetException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.Reflection.TargetInvocationException ex)
            {
                if (ex.InnerException != null)
                {
                    System.Exception exc = ex.InnerException;
                    if (exc is System.ArgumentException)
                    {
                        dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kInvalidArguments, ErrorString(exc));
                    }
                    else if (exc is System.NullReferenceException)
                    {
                        dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ErrorString(null));
                    }
                    else
                    {
                        dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ErrorString(exc));
                    }
                }
                else
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ErrorString(ex));
                }
            }
            catch (System.Reflection.TargetParameterCountException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.MethodAccessException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.InvalidOperationException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.NotSupportedException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.ArgumentException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kInvalidArguments, ErrorString(ex.InnerException));
                }
                else
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kInvalidArguments, ErrorString(ex));
                }
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogSemanticError(ErrorString(ex.InnerException));
                }
                dsi.LogSemanticError(ErrorString(ex));
            }

            return(dsRetValue);
        }
Exemplo n.º 23
0
        public ExecutionMirror Execute(string code)
        {
            code = string.Format("{0} = {1};", Constants.kWatchResultVar, code);

            // TODO Jun: Move this initaliztion of the exe into a unified function
            //Core.ExprInterpreterExe = new Executable();

            int blockId = ProtoCore.DSASM.Constants.kInvalidIndex;

            Core.Rmem.AlignStackForExprInterpreter();

            //Initialize the watch stack and watchBaseOffset
            //The watchBaseOffset is used to indexing the watch variables and related temporary variables
            Core.watchBaseOffset = 0;
            Core.watchStack.Clear();

            bool succeeded = Compile(code, out blockId);

            //Clear the warnings and errors so they will not continue impact the next compilation.
            //Fix IDE-662
            Core.BuildStatus.Errors.Clear();
            Core.BuildStatus.Warnings.Clear();

            for (int i = 0; i < Core.watchBaseOffset; ++i)
            {
                Core.watchStack.Add(StackUtils.BuildNull());
            }

            //Record the old function call depth
            //Fix IDE-523: part of error for watching non-existing member
            int oldFunctionCallDepth = Core.FunctionCallDepth;

            //Record the old start PC
            int oldStartPC = Core.startPC;

            if (succeeded)
            {
                //a2. Record the old start PC for restore instructions
                Core.startPC = Core.ExprInterpreterExe.instrStreamList[blockId].instrList.Count;
                Core.GenerateExprExeInstructions(blockId);

                //a3. Record the old running block
                int restoreBlock = Core.RunningBlock;
                Core.RunningBlock = blockId;

                //a4. Record the old debug entry PC and stack size of FileFepChosen
                int oldDebugEntryPC = Core.DebugProps.DebugEntryPC;

                //a5. Record the frame pointer for referencing to thisPtr
                Core.watchFramePointer = Core.Rmem.FramePointer;

                // The "Core.Bounce" below is gonna adjust the "FramePointer"
                // based on the current size of "Core.Rmem.Stack". All that is
                // good except that "Bounce" does not restore the previous value
                // of frame pointer after "bouncing back". Here we make a backup
                // of it and restore it right after the "Core.Bounce" call.
                //
                //Core.Executives[Core.CodeBlockList[Core.RunningBlock].language].
                ProtoCore.Runtime.Context context = new ProtoCore.Runtime.Context();

                try
                {
                    ProtoCore.DSASM.StackFrame stackFrame = null;
                    int locals = 0;

                    StackValue sv = Core.Bounce(blockId, Core.startPC, context, stackFrame, locals, EventSink);

                    // As Core.InterpreterProps stack member is pushed to every time the Expression Interpreter begins executing
                    // it needs to be popped off at the end for stack alignment - pratapa
                    Core.InterpreterProps.Pop();
                }
                catch
                { }

                //r5. Restore frame pointer.
                Core.Rmem.FramePointer = Core.watchFramePointer;

                //r4. Restore the debug entry PC and stack size of FileFepChosen
                Core.DebugProps.DebugEntryPC = oldDebugEntryPC;

                //r3. Restore the running block
                Core.RunningBlock = restoreBlock;

                //r2. Restore the instructions in Core.ExprInterpreterExe
                int from  = Core.startPC;
                int elems = Core.ExprInterpreterExe.iStreamCanvas.instrList.Count;
                Core.ExprInterpreterExe.instrStreamList[blockId].instrList.RemoveRange(from, elems);

                //Restore the start PC
                Core.startPC = oldStartPC;

                //Restore the function call depth
                //Fix IDE-523: part of error for watching non-existing member
                Core.FunctionCallDepth = oldFunctionCallDepth;


                //Clear the watchSymbolList
                foreach (SymbolNode node in Core.watchSymbolList)
                {
                    if (ProtoCore.DSASM.Constants.kInvalidIndex == node.classScope)
                    {
                        Core.DSExecutable.runtimeSymbols[node.runtimeTableIndex].Remove(node);
                    }
                    else
                    {
                        Core.ClassTable.ClassNodes[node.classScope].symbols.Remove(node);
                    }
                }
            }
            else
            {
                //Restore the start PC
                Core.startPC = oldStartPC;

                //Restore the function call depth
                //Fix IDE-523: part of error for watching non-existing member
                Core.FunctionCallDepth = oldFunctionCallDepth;

                //Clear the watchSymbolList
                foreach (SymbolNode node in Core.watchSymbolList)
                {
                    if (ProtoCore.DSASM.Constants.kInvalidIndex == node.classScope)
                    {
                        Core.DSExecutable.runtimeSymbols[node.runtimeTableIndex].Remove(node);
                    }
                    else
                    {
                        Core.ClassTable.ClassNodes[node.classScope].symbols.Remove(node);
                    }
                }

                // TODO: investigate why additional elements are added to the stack.
                Core.Rmem.RestoreStackForExprInterpreter();

                throw new ProtoCore.Exceptions.CompileErrorsOccured();
            }

            // TODO: investigate why additional elements are added to the stack.
            Core.Rmem.RestoreStackForExprInterpreter();

            return(new ExecutionMirror(Core.CurrentExecutive.CurrentDSASMExec, Core));
        }
Exemplo n.º 24
0
        /// <summary>
        /// Compute the effects of the replication guides on the formal parameter lists
        /// The results of this loose data, and will not be correct on jagged arrays of hetrogenius types
        /// </summary>
        /// <param name="formalParams"></param>
        /// <param name="replicationInstructions"></param>
        /// <returns></returns>
        public static List <StackValue> EstimateReducedParams(List <StackValue> formalParams, List <ReplicationInstruction> replicationInstructions, Core core)
        {
            //Compute the reduced Type args
            List <StackValue> reducedParamTypes = new List <StackValue>();

            //Copy the types so unaffected ones get copied back directly
            foreach (StackValue sv in formalParams)
            {
                reducedParamTypes.Add(sv);
            }


            foreach (ReplicationInstruction ri in replicationInstructions)
            {
                if (ri.Zipped)
                {
                    foreach (int index in ri.ZipIndecies)
                    {
                        //This should generally be a collection, so we need to do a one phase unboxing
                        StackValue target    = reducedParamTypes[index];
                        StackValue reducedSV = StackUtils.BuildNull();

                        if (StackUtils.IsArray(target))
                        {
                            //Array arr = formalParams[index].Payload as Array;
                            HeapElement he = ArrayUtils.GetHeapElement(reducedParamTypes[index], core);



                            //It is a collection, so cast it to an array and pull the type of the first element
                            //@TODO(luke): Deal with sparse arrays, if the first element is null this will explode

                            Validity.Assert(he.Stack != null);

                            //The elements of the array are still type structures
                            if (he.VisibleSize == 0)
                            {
                                reducedSV = StackUtils.BuildNull();
                            }
                            else
                            {
                                reducedSV = he.Stack[0];
                            }
                        }
                        else
                        {
                            System.Console.WriteLine("WARNING: Replication unbox requested on Singleton. Trap: 437AD20D-9422-40A3-BFFD-DA4BAD7F3E5F");
                            reducedSV = target;
                        }

                        //reducedType.IsIndexable = false;
                        reducedParamTypes[index] = reducedSV;
                    }
                }
                else
                {
                    //This should generally be a collection, so we need to do a one phase unboxing
                    int        index     = ri.CartesianIndex;
                    StackValue target    = reducedParamTypes[index];
                    StackValue reducedSV = new StackValue();

                    if (StackUtils.IsArray(target))
                    {
                        //ProtoCore.DSASM.Mirror.DsasmArray arr = formalParams[index].Payload as ProtoCore.DSASM.Mirror.DsasmArray;
                        HeapElement he = ArrayUtils.GetHeapElement(reducedParamTypes[index], core);

                        //It is a collection, so cast it to an array and pull the type of the first element
                        //@TODO(luke): Deal with sparse arrays, if the first element is null this will explode
                        //Validity.Assert(arr != null);
                        //Validity.Assert(arr.members[0] != null);
                        Validity.Assert(he.Stack != null);



                        //The elements of the array are still type structures
                        //reducedType = arr.members[0].Type;
                        if (he.VisibleSize == 0)
                        {
                            reducedSV = StackUtils.BuildNull();
                        }
                        else
                        {
                            reducedSV = he.Stack[0];
                        }
                    }
                    else
                    {
                        System.Console.WriteLine("WARNING: Replication unbox requested on Singleton. Trap: 437AD20D-9422-40A3-BFFD-DA4BAD7F3E5F");
                        reducedSV = target;
                    }

                    //reducedType.IsIndexable = false;
                    reducedParamTypes[index] = reducedSV;
                }
            }

            return(reducedParamTypes);
        }
Exemplo n.º 25
0
        public static List <List <StackValue> > ComputeReducedParamsSuperset(List <StackValue> formalParams, List <ReplicationInstruction> replicationInstructions, Core core)
        {
            //Compute the reduced Type args
            List <List <StackValue> > reducedParams = new List <List <StackValue> >();

            List <StackValue> basicList = new List <StackValue>();

            //Copy the types so unaffected ones get copied back directly
            foreach (StackValue sv in formalParams)
            {
                basicList.Add(sv);
            }

            reducedParams.Add(basicList);


            foreach (ReplicationInstruction ri in replicationInstructions)
            {
                if (ri.Zipped)
                {
                    foreach (int index in ri.ZipIndecies)
                    {
                        //This should generally be a collection, so we need to do a one phase unboxing
                        StackValue target    = basicList[index];
                        StackValue reducedSV = StackUtils.BuildNull();

                        if (StackUtils.IsArray(target))
                        {
                            //Array arr = formalParams[index].Payload as Array;
                            HeapElement he = ArrayUtils.GetHeapElement(basicList[index], core);


                            Validity.Assert(he.Stack != null);

                            //The elements of the array are still type structures
                            if (he.VisibleSize == 0)
                            {
                                reducedSV = StackUtils.BuildNull();
                            }
                            else
                            {
                                var arrayStats = ArrayUtils.GetTypeExamplesForLayer(basicList[index], core).Values;

                                List <List <StackValue> > clonedList = new List <List <StackValue> >();

                                foreach (List <StackValue> list in reducedParams)
                                {
                                    clonedList.Add(list);
                                }

                                reducedParams.Clear();

                                foreach (StackValue sv in arrayStats)
                                {
                                    foreach (List <StackValue> lst in clonedList)
                                    {
                                        List <StackValue> newArgs = new List <StackValue>();

                                        newArgs.AddRange(lst);
                                        newArgs[index] = sv;

                                        reducedParams.Add(newArgs);
                                    }
                                }
                            }
                        }
                        else
                        {
                            System.Console.WriteLine("WARNING: Replication unbox requested on Singleton. Trap: 437AD20D-9422-40A3-BFFD-DA4BAD7F3E5F");
                            reducedSV = target;
                        }

                        //reducedType.IsIndexable = false;
                        //reducedParamTypes[index] = reducedSV;
                    }
                }
                else
                {
                    //This should generally be a collection, so we need to do a one phase unboxing
                    int index = ri.CartesianIndex;
                    //This should generally be a collection, so we need to do a one phase unboxing
                    StackValue target    = basicList[index];
                    StackValue reducedSV = StackUtils.BuildNull();

                    if (StackUtils.IsArray(target))
                    {
                        //Array arr = formalParams[index].Payload as Array;
                        HeapElement he = ArrayUtils.GetHeapElement(basicList[index], core);



                        //It is a collection, so cast it to an array and pull the type of the first element
                        //@TODO(luke): Deal with sparse arrays, if the first element is null this will explode

                        Validity.Assert(he.Stack != null);

                        //The elements of the array are still type structures
                        if (he.VisibleSize == 0)
                        {
                            reducedSV = StackUtils.BuildNull();
                        }
                        else
                        {
                            var arrayStats = ArrayUtils.GetTypeExamplesForLayer(basicList[index], core).Values;

                            List <List <StackValue> > clonedList = new List <List <StackValue> >();

                            foreach (List <StackValue> list in reducedParams)
                            {
                                clonedList.Add(list);
                            }

                            reducedParams.Clear();


                            foreach (StackValue sv in arrayStats)
                            {
                                foreach (List <StackValue> lst in clonedList)
                                {
                                    List <StackValue> newArgs = new List <StackValue>();

                                    newArgs.AddRange(lst);
                                    newArgs[index] = sv;

                                    reducedParams.Add(newArgs);
                                }
                            }
                        }
                    }
                    else
                    {
                        System.Console.WriteLine("WARNING: Replication unbox requested on Singleton. Trap: 437AD20D-9422-40A3-BFFD-DA4BAD7F3E5F");
                        reducedSV = target;
                    }
                }
            }

            return(reducedParams);
        }
Exemplo n.º 26
0
        public static StackValue Coerce(StackValue sv, Type targetType, Core core)
        {
            //@TODO(Jun): FIX ME - abort coersion for default args
            if (sv.optype == AddressType.DefaultArg)
            {
                return(sv);
            }

            if (!(
                    (int)sv.metaData.type == targetType.UID ||
                    (core.DSExecutable.classTable.ClassNodes[(int)sv.metaData.type].ConvertibleTo(targetType.UID)) ||
                    sv.optype == AddressType.ArrayPointer))
            {
                core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kConversionNotPossible, ProtoCore.RuntimeData.WarningMessage.kConvertNonConvertibleTypes);
                return(StackUtils.BuildNull());
            }



            //if it's an array
            if (sv.optype == AddressType.ArrayPointer && !targetType.IsIndexable && targetType.rank != DSASM.Constants.kUndefinedRank)// && targetType.UID != (int)PrimitiveType.kTypeVar)
            {
                //This is an array rank reduction
                //this may only be performed in recursion and is illegal here
                string errorMessage = String.Format(ProtoCore.RuntimeData.WarningMessage.kConvertArrayToNonArray, core.TypeSystem.GetType(targetType.UID));
                core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kConversionNotPossible, errorMessage);
                return(StackUtils.BuildNull());
            }


            if (sv.optype == AddressType.ArrayPointer && targetType.IsIndexable)
            {
                Validity.Assert(ArrayUtils.IsArray(sv));

                //We're being asked to convert an array into an array
                //walk over the structure converting each othe elements

                if (targetType.UID == (int)PrimitiveType.kTypeVar && targetType.rank == DSASM.Constants.kArbitraryRank && core.Heap.IsTemporaryPointer(sv))
                {
                    return(sv);
                }

                HeapElement  he        = core.Heap.Heaplist[(int)sv.opdata];
                StackValue[] newSubSVs = new StackValue[he.VisibleSize];

                //Validity.Assert(targetType.rank != -1, "Arbitrary rank array conversion not yet implemented {2EAF557F-62DE-48F0-9BFA-F750BBCDF2CB}");

                //Decrease level of reductions by one
                Type newTargetType = new Type();
                newTargetType.UID = targetType.UID;
                if (targetType.rank != ProtoCore.DSASM.Constants.kArbitraryRank)
                {
                    newTargetType.rank        = targetType.rank - 1;
                    newTargetType.IsIndexable = newTargetType.rank > 0;
                }
                else
                {
                    if (ArrayUtils.GetMaxRankForArray(sv, core) == 1)
                    {
                        //Last unpacking
                        newTargetType.rank        = 0;
                        newTargetType.IsIndexable = false;
                    }
                    else
                    {
                        newTargetType.rank        = ProtoCore.DSASM.Constants.kArbitraryRank;
                        newTargetType.IsIndexable = true;
                    }
                }


                for (int i = 0; i < he.VisibleSize; i++)
                {
                    StackValue coercedValue = Coerce(he.Stack[i], newTargetType, core);
                    GCUtils.GCRetain(coercedValue, core);
                    newSubSVs[i] = coercedValue;
                }

                StackValue newSV = HeapUtils.StoreArray(newSubSVs, core);
                return(newSV);
            }

            if (sv.optype != AddressType.ArrayPointer && sv.optype != AddressType.Null &&
                targetType.IsIndexable &&
                targetType.rank != DSASM.Constants.kArbitraryRank)
            {
                //We're being asked to promote the value into an array
                if (targetType.rank == 1)
                {
                    Type newTargetType = new Type();
                    newTargetType.UID         = targetType.UID;
                    newTargetType.IsIndexable = false;
                    newTargetType.Name        = targetType.Name;
                    newTargetType.rank        = 0;


                    //Upcast once
                    StackValue coercedValue = Coerce(sv, newTargetType, core);
                    GCUtils.GCRetain(coercedValue, core);
                    StackValue newSv = HeapUtils.StoreArray(new StackValue[] { coercedValue }, core);
                    return(newSv);
                }
                else
                {
                    Validity.Assert(targetType.rank > 1, "Target rank should be greater than one for this clause");

                    Type newTargetType = new Type();
                    newTargetType.UID         = targetType.UID;
                    newTargetType.IsIndexable = true;
                    newTargetType.Name        = targetType.Name;
                    newTargetType.rank        = targetType.rank - 1;


                    //Upcast once
                    StackValue coercedValue = Coerce(sv, newTargetType, core);
                    GCUtils.GCRetain(coercedValue, core);
                    StackValue newSv = HeapUtils.StoreArray(new StackValue[] { coercedValue }, core);
                    return(newSv);
                }
            }


            if (sv.optype == AddressType.Pointer)
            {
                StackValue ret = ClassCoerece(sv, targetType, core);
                return(ret);
            }

            //If it's anything other than array, just create a new copy
            switch (targetType.UID)
            {
            case (int)PrimitiveType.kInvalidType:
                Validity.Assert(false, "Can't convert invalid type");
                break;

            case (int)PrimitiveType.kTypeBool:
                return(sv.AsBoolean(core));

            case (int)PrimitiveType.kTypeChar:
            {
                StackValue newSV = sv.ShallowClone();
                newSV.metaData = new MetaData {
                    type = (int)PrimitiveType.kTypeChar
                };
                return(newSV);
            }

            case (int)PrimitiveType.kTypeDouble:
                return(sv.AsDouble());

            case (int)PrimitiveType.kTypeFunctionPointer:
                if (sv.metaData.type != (int)PrimitiveType.kTypeFunctionPointer)
                {
                    core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeMismatch, ProtoCore.RuntimeData.WarningMessage.kFailToConverToFunction);
                    return(StackUtils.BuildNull());
                }
                return(sv.ShallowClone());

            case (int)PrimitiveType.kTypeHostEntityID:
            {
                StackValue newSV = sv.ShallowClone();
                newSV.metaData = new MetaData {
                    type = (int)PrimitiveType.kTypeHostEntityID
                };
                return(newSV);
            }

            case (int)PrimitiveType.kTypeInt:
            {
                if (sv.metaData.type == (int)PrimitiveType.kTypeDouble)
                {
                    core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeConvertionCauseInfoLoss, ProtoCore.RuntimeData.WarningMessage.kConvertDoubleToInt);
                }
                return(sv.AsInt());
            }

            case (int)PrimitiveType.kTypeNull:
            {
                if (sv.metaData.type != (int)PrimitiveType.kTypeNull)
                {
                    core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeMismatch, ProtoCore.RuntimeData.WarningMessage.kFailToConverToNull);
                    return(StackUtils.BuildNull());
                }
                return(sv.ShallowClone());
            }

            case (int)PrimitiveType.kTypePointer:
            {
                if (sv.metaData.type != (int)PrimitiveType.kTypeNull)
                {
                    core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeMismatch, ProtoCore.RuntimeData.WarningMessage.kFailToConverToPointer);
                    return(StackUtils.BuildNull());
                }
                StackValue ret = sv.ShallowClone();
                return(ret);
            }

            case (int)PrimitiveType.kTypeString:
            {
                StackValue newSV = sv.ShallowClone();
                newSV.metaData = new MetaData {
                    type = (int)PrimitiveType.kTypeString
                };
                if (sv.metaData.type == (int)PrimitiveType.kTypeChar)
                {
                    char ch = ProtoCore.Utils.EncodingUtils.ConvertInt64ToCharacter(newSV.opdata);
                    newSV = StackUtils.BuildString(ch.ToString(), core.Heap);
                }
                return(newSV);
            }

            case (int)PrimitiveType.kTypeVar:
            {
                return(sv);
            }


            case (int)PrimitiveType.kTypeArray:
            {
                HeapElement  he        = core.Heap.Heaplist[(int)sv.opdata];
                StackValue[] newSubSVs = new StackValue[he.VisibleSize];

                for (int i = 0; i < he.VisibleSize; i++)
                {
                    StackValue coercedValue = Coerce(he.Stack[i], targetType, core);
                    GCUtils.GCRetain(coercedValue, core);
                    newSubSVs[i] = coercedValue;
                }

                StackValue newSV = HeapUtils.StoreArray(newSubSVs, core);
                return(newSV);
            }


            default:
                if (sv.optype == AddressType.Null)
                {
                    return(StackUtils.BuildNull());
                }
                else
                {
                    throw new NotImplementedException("Requested coercion not implemented");
                }
            }



            throw new NotImplementedException("Requested coercion not implemented");
        }
        public override StackValue Execute(ProtoCore.Runtime.Context c, List <StackValue> formalParameters, ProtoCore.DSASM.StackFrame stackFrame, Core core)
        {   //  ensure there is no data race, function resolution and execution happens in parallel
            //  but for FFI we want it to be serial cause the code we are calling into may not cope
            //  with parallelism.
            //
            //  we are always looking and putting our function pointers in handler with each lang
            //  so better lock for FFIHandler (being static) it  will be good object to lock
            //
            lock (FFIHandlers)
            {
                ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(core, true);

                StackValue svThisPtr   = stackFrame.GetAt(StackFrame.AbsoluteIndex.kThisPtr);
                StackValue svBlockDecl = stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kFunctionBlock);

                // Setup the stack frame data
                //int thisPtr = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kThisPtr).opdata;
                int ci           = activation.JILRecord.classIndex;
                int fi           = activation.JILRecord.funcIndex;
                int returnAddr   = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kReturnAddress).opdata;
                int blockDecl    = (int)svBlockDecl.opdata;
                int blockCaller  = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kFunctionCallerBlock).opdata;
                int framePointer = core.Rmem.FramePointer;
                int locals       = activation.JILRecord.locals;


                FFIHandler          handler = FFIHandlers[activation.ModuleType];
                FFIActivationRecord r       = activation;
                string className            = "";
                if (activation.JILRecord.classIndex > 0)
                {
                    className = core.DSExecutable.classTable.ClassNodes[activation.JILRecord.classIndex].name;
                }

                bool gcThisPtr = false;
                List <ProtoCore.Type> argTypes = new List <Type>(r.ParameterTypes);

                ProcedureNode fNode = null;
                if (ProtoCore.DSASM.Constants.kInvalidIndex != ci)
                {
                    fNode = interpreter.runtime.exe.classTable.ClassNodes[ci].vtable.procList[fi];
                }

                // Check if this is a 'this' pointer function overload that was generated by the compiler
                if (null != fNode && fNode.isAutoGeneratedThisProc)
                {
                    int  thisPtrIndex = 0;
                    bool isStaticCall = AddressType.Pointer == svThisPtr.optype && ProtoCore.DSASM.Constants.kInvalidPointer == (int)svThisPtr.opdata;
                    if (isStaticCall)
                    {
                        thisPtrIndex = formalParameters.Count - 1;
                    }
                    argTypes.RemoveAt(thisPtrIndex);

                    // Comment Jun: Execute() can handle a null this pointer.
                    // But since we dont even need to to reach there if we dont have a valid this pointer, then just return null
                    if (AddressType.Null == formalParameters[thisPtrIndex].optype)
                    {
                        core.RuntimeStatus.LogWarning(ProtoCore.RuntimeData.WarningID.kDereferencingNonPointer, ProtoCore.RuntimeData.WarningMessage.kDeferencingNonPointer);
                        return(StackUtils.BuildNull());
                    }

                    // These are the op types allowed.
                    Validity.Assert(AddressType.Pointer == formalParameters[thisPtrIndex].optype || AddressType.DefaultArg == formalParameters[thisPtrIndex].optype);

                    svThisPtr = formalParameters[thisPtrIndex];
                    gcThisPtr = true;

                    formalParameters.RemoveAt(thisPtrIndex);
                }

                FFIFunctionPointer functionPointer = handler.GetFunctionPointer(r.ModuleName, className, r.FunctionName, argTypes, r.ReturnType);
                mFunctionPointer       = Validate(functionPointer) ? functionPointer : null;
                mFunctionPointer.IsDNI = activation.IsDNI;


                if (mFunctionPointer == null)
                {
                    return(ProtoCore.DSASM.StackUtils.BuildNull());
                }

                List <object> ps = new List <object>(); //obsolete

                {
                    interpreter.runtime.executingBlock = core.RunningBlock;
                    activation.JILRecord.globs         = core.DSExecutable.runtimeSymbols[core.RunningBlock].GetGlobalSize();

                    // Params
                    formalParameters.Reverse();
                    for (int i = 0; i < formalParameters.Count; i++)
                    {
                        interpreter.Push(formalParameters[i]);
                    }

                    List <ProtoCore.DSASM.StackValue> registers = new List <DSASM.StackValue>();
                    interpreter.runtime.SaveRegisters(registers);

                    // Comment Jun: the depth is always 0 for a function call as we are reseting this for each function call
                    // This is only incremented for every language block bounce
                    int            depth      = 0;
                    StackFrameType callerType = (StackFrameType)stackFrame.GetAt(StackFrame.AbsoluteIndex.kCallerStackFrameType).opdata;

                    // FFI calls do not have execution states
                    core.Rmem.PushStackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, blockCaller, callerType, ProtoCore.DSASM.StackFrameType.kTypeFunction, depth, framePointer, registers, locals, 0);

                    //is there a way the current stack be passed across and back into the managed runtime by FFI calling back into the language?
                    //e.g. DCEnv* carrying all the stack information? look at how vmkit does this.
                    // = jilMain.Run(ActivationRecord.JILRecord.pc, null, true);

                    //double[] tempArray = GetUnderlyingArray<double>(jilMain.runtime.rmem.stack);
                    Object     ret = mFunctionPointer.Execute(c, interpreter);
                    StackValue op;
                    if (ret == null)
                    {
                        op = StackUtils.BuildNull();
                    }
                    else if (ret is StackValue)
                    {
                        op = (StackValue)ret;
                    }
                    else if (ret is Int64 || ret is int)
                    {
                        op        = new StackValue();
                        op.optype = AddressType.Int;
                        op.opdata = (Int64)ret;
                    }
                    else if (ret is double)
                    {
                        op          = new StackValue();
                        op.optype   = AddressType.Double;
                        op.opdata_d = (double)ret;
                    }
                    else
                    {
                        throw new ArgumentException(string.Format("FFI: incorrect return type {0} from external function {1}:{2}", activation.ReturnType.Name,
                                                                  activation.ModuleName, activation.FunctionName));
                    }

                    // gc the parameters
                    if (gcThisPtr)// && core.Options.EnableThisPointerFunctionOverload)
                    {
                        // thisptr is sent as parameter, so need to gc it.
                        // but when running in expression interpreter mode, do not GC because in DSASM.Executive.DecRefCounter() related GC functions,
                        // the reference count will not be changed in expression interpreter mode.
                        if (core.ExecMode != ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
                        {
                            interpreter.runtime.Core.Rmem.Heap.GCRelease(new StackValue[] { svThisPtr }, interpreter.runtime);
                        }
                    }
                    interpreter.runtime.Core.Rmem.Heap.GCRelease(formalParameters.ToArray(), interpreter.runtime);

                    // increment the reference counter of the return value
                    interpreter.runtime.GCRetain(op);
                    // Clear the FFI stack frame
                    // FFI stack frames have no local variables
                    interpreter.runtime.rmem.FramePointer = (int)interpreter.runtime.rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFramePointer).opdata;
                    interpreter.runtime.rmem.PopFrame(ProtoCore.DSASM.StackFrame.kStackFrameSize + formalParameters.Count);

                    return(op); //DSASM.Mirror.ExecutionMirror.Unpack(op, core.heap, core);
                }
            }
        }