예제 #1
0
        /// <summary>
        /// Convert StackValue to boolean typed StackValue. Returns
        /// StackValue.Null if not able to do conversion.
        /// </summary>
        /// <param name="core"></param>
        /// <returns></returns>
        public StackValue ToBoolean(Core core)
        {
            switch (optype)
            {
            case AddressType.Boolean:
                return(this);

            case AddressType.Int:
                return(BuildBoolean(opdata != 0));

            case AddressType.Null:
                return(StackValue.Null);

            case AddressType.Double:
                bool b = !Double.IsNaN(RawDoubleValue) && !RawDoubleValue.Equals(0.0);
                return(BuildBoolean(b));

            case AddressType.Pointer:
                return(StackValue.BuildBoolean(true));

            case AddressType.String:
                string str = core.Heap.GetString(this);
                return(string.IsNullOrEmpty(str) ? StackValue.False : StackValue.True);

            case AddressType.Char:
                char c = EncodingUtils.ConvertInt64ToCharacter(opdata);
                return((c == 0) ? StackValue.False : StackValue.True);

            default:
                return(StackValue.Null);
            }
        }
예제 #2
0
        /// <summary>
        /// Convert StackValue to boolean typed StackValue. Returns
        /// StackValue.Null if not able to do conversion.
        /// </summary>
        /// <param name="core"></param>
        /// <returns></returns>
        public StackValue ToBoolean(Core core)
        {
            switch (optype)
            {
            case AddressType.Boolean:
                return(this);

            case AddressType.Int:
                return(BuildBoolean(opdata != 0));

            case AddressType.Null:
                return(StackValue.Null);

            case AddressType.Double:
                bool b = !Double.IsNaN(RawDoubleValue) && !RawDoubleValue.Equals(0.0);
                return(BuildBoolean(b));

            case AddressType.Pointer:
                return(StackValue.BuildBoolean(true));

            case AddressType.String:
                int size = ArrayUtils.GetElementSize(this, core);
                return((size == 0) ? StackValue.False : StackValue.True);

            case AddressType.Char:
                char c = EncodingUtils.ConvertInt64ToCharacter(opdata);
                return((c == 0) ? StackValue.False : StackValue.True);

            default:
                return(StackValue.Null);
            }
        }
예제 #3
0
        public static StackValue AsBoolean(this StackValue operand, Core core)
        {
            switch (operand.optype)
            {
            case AddressType.Boolean:
            case AddressType.Int:
                return(BuildBoolean(operand.opdata != 0));

            case AddressType.Null:
                return(BuildNull());    //BuildBoolean(false);

            case AddressType.Double:
                bool b = !(Double.IsNaN(operand.opdata_d) || operand.opdata_d.Equals(0.0));
                return(BuildBoolean(b));

            case AddressType.Pointer:
                return(BuildBoolean(true));

            case AddressType.String:
                if (ArrayUtils.GetElementSize(operand, core) == 0)
                {
                    return(BuildBoolean(false));
                }
                return(BuildBoolean(true));

            case AddressType.Char:
                if (EncodingUtils.ConvertInt64ToCharacter(operand.opdata) == 0)
                {
                    return(BuildBoolean(false));
                }
                return(BuildBoolean(true));

            default:
                return(BuildNull());
            }
        }
예제 #4
0
        public static StackValue Coerce(StackValue sv, Type targetType, Core core)
        {
            //@TODO(Jun): FIX ME - abort coersion for default args
            if (sv.IsDefaultArgument)
            {
                return(sv);
            }

            if (!(
                    sv.metaData.type == targetType.UID ||
                    (core.ClassTable.ClassNodes[sv.metaData.type].ConvertibleTo(targetType.UID)) ||
                    sv.IsArray))
            {
                core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kConversionNotPossible, ProtoCore.StringConstants.kConvertNonConvertibleTypes);
                return(StackValue.Null);
            }

            //if it's an array
            if (sv.IsArray && !targetType.IsIndexable)
            {
                //This is an array rank reduction
                //this may only be performed in recursion and is illegal here
                string errorMessage = String.Format(ProtoCore.StringConstants.kConvertArrayToNonArray, core.TypeSystem.GetType(targetType.UID));
                core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kConversionNotPossible, errorMessage);
                return(StackValue.Null);
            }


            if (sv.IsArray &&
                targetType.IsIndexable)
            {
                Validity.Assert(sv.IsArray);

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

                var hpe = core.Heap.GetHeapElement(sv);
#if GC_REFERENCE_COUNTING
                var isTemporary = hpe.Active && hpe.Refcount == 0;
#else
                var isTemporary = false;
#endif

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

                //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 != Constants.kArbitraryRank)
                {
                    newTargetType.rank = targetType.rank - 1;
                }
                else
                {
                    if (ArrayUtils.GetMaxRankForArray(sv, core) == 1)
                    {
                        //Last unpacking
                        newTargetType.rank = 0;
                    }
                    else
                    {
                        newTargetType.rank = Constants.kArbitraryRank;
                    }
                }

                return(ArrayUtils.CopyArray(sv, newTargetType, core));
            }

            if (!sv.IsArray && !sv.IsNull &&
                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.Name = targetType.Name;
                    newTargetType.rank = 0;

                    //Upcast once
                    StackValue coercedValue = Coerce(sv, newTargetType, core);
                    GCUtils.GCRetain(coercedValue, core);
                    StackValue newSv = core.Heap.AllocateArray(new StackValue[] { coercedValue }, null);
                    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.Name = targetType.Name;
                    newTargetType.rank = targetType.rank - 1;

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

            if (sv.IsPointer)
            {
                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.ToBoolean(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.ToDouble());

            case (int)PrimitiveType.kTypeFunctionPointer:
                if (sv.metaData.type != (int)PrimitiveType.kTypeFunctionPointer)
                {
                    core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeMismatch, ProtoCore.StringConstants.kFailToConverToFunction);
                    return(StackValue.Null);
                }
                return(sv);

            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)
                {
                    //TODO(lukechurch): Once the API is improved (MAGN-5174)
                    //Replace this with a log entry notification
                    //core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeConvertionCauseInfoLoss, ProtoCore.StringConstants.kConvertDoubleToInt);
                }
                return(sv.ToInteger());
            }

            case (int)PrimitiveType.kTypeNull:
            {
                if (sv.metaData.type != (int)PrimitiveType.kTypeNull)
                {
                    core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeMismatch, ProtoCore.StringConstants.kFailToConverToNull);
                    return(StackValue.Null);
                }
                return(sv);
            }

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

            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 = EncodingUtils.ConvertInt64ToCharacter(newSV.opdata);
                    newSV = StackValue.BuildString(ch.ToString(), core.Heap);
                }
                return(newSV);
            }

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

            case (int)PrimitiveType.kTypeArray:
            {
                return(ArrayUtils.CopyArray(sv, targetType, core));
            }

            default:
                if (sv.IsNull)
                {
                    return(StackValue.Null);
                }
                else
                {
                    throw new NotImplementedException("Requested coercion not implemented");
                }
            }

            throw new NotImplementedException("Requested coercion not implemented");
        }
예제 #5
0
        // Verify for single object
        private static void VerifyInternal(object expectedObject, Obj dsObject, string dsVariable, List <int> indices)
        {
            if (expectedObject == null)
            {
                if (!dsObject.DsasmValue.IsNull)
                {
                    Assert.Fail(String.Format("\t{0}{1} is expected to be null, but it isn't.\n{2}", dsVariable,
                                              TestFrameWork.BuildIndicesString(indices), TestFrameWork.mErrorMessage));
                }
                return;
            }

            Type expectedType = expectedObject.GetType();

            if (dsObject.DsasmValue.IsNull && expectedObject != null)
            {
                Assert.Fail(String.Format("\tThe value of {0} was null, but wasn't expected to be.\n{1}", dsVariable, mErrorMessage));
            }
            else if (expectedObject is Int32 || expectedObject is Int64)
            {
                Int64 expectedValue = Convert.ToInt64(expectedObject);
                if (dsObject.Type.UID != (int)ProtoCore.PrimitiveType.kTypeInt)
                {
                    Assert.Fail(String.Format("\t{0}{1} is expected to be {2}, but its actual value is not an integer. \n{2}", dsVariable,
                                              BuildIndicesString(indices), expectedValue, mErrorMessage));
                }
                else
                {
                    TestFrameWork.VerifyPodType(expectedValue, dsObject, dsVariable, indices);
                }
            }
            else if (expectedObject is Double)
            {
                Double expectedValue = Convert.ToDouble(expectedObject);
                if (dsObject.Type.UID != (int)ProtoCore.PrimitiveType.kTypeDouble)
                {
                    Assert.Fail(String.Format("\t{0}{1} is expected to be {2}, but its actual value is not a double. \n{3}", dsVariable,
                                              BuildIndicesString(indices), expectedValue, mErrorMessage));
                }
                else
                {
                    try
                    {
                        Double dsValue = Convert.ToDouble(dsObject.Payload);

                        if (!MathUtils.Equals(expectedValue, dsValue))
                        {
                            Assert.Fail(String.Format("\t{0}{1} is expected to be {2}, but its actual value is {3}. \n{4}", dsVariable,
                                                      BuildIndicesString(indices), expectedValue, dsValue, mErrorMessage));
                        }
                    }
                    catch (System.InvalidCastException)
                    {
                        Assert.Fail(String.Format("\t{0}{1} is expected to be {2}, but its actual value can't be converted to Double. \n{3}", dsVariable,
                                                  BuildIndicesString(indices), expectedValue, mErrorMessage));
                    }
                }
            }
            else if (expectedObject is Boolean)
            {
                Boolean expectedValue = Convert.ToBoolean(expectedObject);
                if (dsObject.Type.UID != (int)ProtoCore.PrimitiveType.kTypeBool)
                {
                    Assert.Fail(String.Format("\t{0}{1} is expected to be {2}, but its actual type is not bool. \n{3}", dsVariable,
                                              BuildIndicesString(indices), expectedValue, mErrorMessage));
                }
                else
                {
                    TestFrameWork.VerifyPodType(expectedValue, dsObject, dsVariable, indices);
                }
            }
            else if (expectedObject is Char)
            {
                Char expectedValue = Convert.ToChar(expectedObject);

                if (dsObject.Type.UID != (int)ProtoCore.PrimitiveType.kTypeChar)
                {
                    Assert.Fail(String.Format("\t{0}{1} is expected to be {2}, but its actual type is not char. \n{3}", dsVariable, BuildIndicesString(indices), expectedValue, mErrorMessage));
                }
                else
                {
                    try
                    {
                        Int64 utf8Encoding = Convert.ToInt64(dsObject.Payload);
                        Char  dsValue      = EncodingUtils.ConvertInt64ToCharacter(utf8Encoding);

                        if (!expectedObject.Equals(dsValue))
                        {
                            Assert.Fail(String.Format("\t{0}{1} is expected to be {2}, but its actual value is {3}. \n{4}", dsVariable,
                                                      BuildIndicesString(indices), expectedValue, dsValue, mErrorMessage));
                        }
                    }
                    catch (System.InvalidCastException)
                    {
                        Assert.Fail(String.Format("\t{0}{1} is expected to be {2}, but its actual value can't be converted to Char. \n{3}", dsVariable,
                                                  BuildIndicesString(indices), expectedValue, mErrorMessage));
                    }
                }
            }
            else if (expectedObject is String)
            {
                string stringValue = dsObject.Payload as string;
                if (stringValue == null)
                {
                    Assert.Fail(String.Format("\t{0}{1} is expected to be a string, but its actual value is not a string\n{2}", dsVariable,
                                              BuildIndicesString(indices), mErrorMessage));
                }
                else if (!expectedObject.Equals(stringValue))
                {
                    Assert.Fail(String.Format("\t{0}{1} is expected to be a string \"{2}\", but its actual value is \"{3}\".\n{4}", dsVariable,
                                              BuildIndicesString(indices), expectedObject, stringValue, mErrorMessage));
                }
            }
            else if (typeof(IEnumerable).IsAssignableFrom(expectedType))
            {
                IEnumerable collection = expectedObject as IEnumerable;
                int         index      = 0;
                ProtoCore.DSASM.Mirror.DsasmArray dsArray = dsObject.Payload as ProtoCore.DSASM.Mirror.DsasmArray;
                if (dsArray == null)
                {
                    Assert.Fail(String.Format("{0}{1} is expected to be an array, but its actual value isn't an array.\n{2}", dsVariable,
                                              BuildIndicesString(indices), mErrorMessage));
                }
                foreach (var item in collection)
                {
                    indices.Add(index);
                    VerifyInternal(item, dsArray.members[index], dsVariable, indices);
                    indices.RemoveAt(indices.Count - 1);
                    ++index;
                }
            }
            else
            {
                Assert.Fail(string.Format("\tUnexpected object type.\n{0}", mErrorMessage));
            }
        }
예제 #6
0
        // Verify for single object
        private static void VerifyInternal(object expectedObject, Obj dsObject, string dsVariable, List <int> indices)
        {
            if (expectedObject == null)
            {
                if (dsObject.DsasmValue.optype != ProtoCore.DSASM.AddressType.Null)
                {
                    Assert.Fail(String.Format("\t{0}{1} is expected to be null, but it isn't.\n{2}", dsVariable, TestFrameWork.BuildIndicesString(indices), TestFrameWork.mErrorMessage));
                }
            }
            else if (dsObject.DsasmValue.optype == ProtoCore.DSASM.AddressType.Null && expectedObject != null)
            {
                Assert.Fail(String.Format("\tThe value of {0} was null, but wasn't expected to be.\n{1}", dsVariable, mErrorMessage));
            }
            else if (expectedObject is Int32 || expectedObject is Int64)
            {
                Int64 expectedValue = Convert.ToInt64(expectedObject);
                if (dsObject.Type.UID != (int)ProtoCore.PrimitiveType.kTypeInt)
                {
                    Assert.Fail(String.Format("\t{0}{1} is expected to be {2}, but its actual value is not an integer. \n{2}", dsVariable, BuildIndicesString(indices), expectedValue, mErrorMessage));
                }
                else
                {
                    TestFrameWork.VerifyPodType(expectedValue, dsObject, dsVariable, indices);
                }
            }
            else if (expectedObject is Double)
            {
                Double expectedValue = Convert.ToDouble(expectedObject);
                if (dsObject.Type.UID != (int)ProtoCore.PrimitiveType.kTypeDouble)
                {
                    Assert.Fail(String.Format("\t{0}{1} is expected to be {2}, but its actual value is not a double. \n{3}", dsVariable, BuildIndicesString(indices), expectedValue, mErrorMessage));
                }
                else
                {
                    try
                    {
                        Double dsValue = Convert.ToDouble(dsObject.Payload);

                        if (!MathUtils.Equals(expectedValue, dsValue))
                        {
                            Assert.Fail(String.Format("\t{0}{1} is expected to be {2}, but its actual value is {3}. \n{4}", dsVariable, BuildIndicesString(indices), expectedValue, dsValue, mErrorMessage));
                        }
                    }
                    catch (System.InvalidCastException)
                    {
                        Assert.Fail(String.Format("\t{0}{1} is expected to be {2}, but its actual value can't be converted to Double. \n{3}", dsVariable, BuildIndicesString(indices), expectedValue, mErrorMessage));
                    }
                }
            }
            else if (expectedObject is Boolean)
            {
                Boolean expectedValue = Convert.ToBoolean(expectedObject);
                if (dsObject.Type.UID != (int)ProtoCore.PrimitiveType.kTypeBool)
                {
                    Assert.Fail(String.Format("\t{0}{1} is expected to be {2}, but its actual type is not bool. \n{3}", dsVariable, BuildIndicesString(indices), expectedValue, mErrorMessage));
                }
                else
                {
                    TestFrameWork.VerifyPodType(expectedValue, dsObject, dsVariable, indices);
                }
            }
            else if (expectedObject is Char)
            {
                Char expectedValue = Convert.ToChar(expectedObject);

                if (dsObject.Type.UID != (int)ProtoCore.PrimitiveType.kTypeChar)
                {
                    Assert.Fail(String.Format("\t{0}{1} is expected to be {2}, but its actual type is not char. \n{3}", dsVariable, BuildIndicesString(indices), expectedValue, mErrorMessage));
                }
                else
                {
                    try
                    {
                        Int64 utf8Encoding = Convert.ToInt64(dsObject.Payload);
                        Char  dsValue      = EncodingUtils.ConvertInt64ToCharacter(utf8Encoding);

                        if (!expectedObject.Equals(dsValue))
                        {
                            Assert.Fail(String.Format("\t{0}{1} is expected to be {2}, but its actual value is {3}. \n{4}", dsVariable, BuildIndicesString(indices), expectedValue, dsValue, mErrorMessage));
                        }
                    }
                    catch (System.InvalidCastException)
                    {
                        Assert.Fail(String.Format("\t{0}{1} is expected to be {2}, but its actual value can't be converted to Char. \n{3}", dsVariable, BuildIndicesString(indices), expectedValue, mErrorMessage));
                    }
                }
            }
            else if (expectedObject is String)
            {
                char[]   chars = (expectedObject as String).ToCharArray();
                object[] objs  = new object[chars.Length];
                Array.Copy(chars, objs, chars.Length);

                ProtoCore.DSASM.Mirror.DsasmArray dsArray = dsObject.Payload as ProtoCore.DSASM.Mirror.DsasmArray;
                if (dsArray == null)
                {
                    Assert.Fail(String.Format("\t{0}{1} is expected to be a string, but its actual value is not a string\n{2}", dsVariable, BuildIndicesString(indices), mErrorMessage));
                }
                else if (chars.Count() != dsArray.members.Count())
                {
                    Assert.Fail(String.Format("\t{0}{1} is expected to be a string of length {2}, but its actual length is {3}.\n{4}", dsVariable, BuildIndicesString(indices), objs.Count(), dsArray.members.Count(), mErrorMessage));
                }
                else
                {
                    for (int i = 0; i < objs.Count(); ++i)
                    {
                        indices.Add(i);
                        TestFrameWork.VerifyInternal(objs[i], dsArray.members[i], dsVariable, indices);
                        indices.RemoveAt(indices.Count - 1);
                    }
                }

                // VerifyInternal(objs, dsObject, dsVariable, indices);
            }
            else if (expectedObject.GetType().IsArray)
            {
                object[] expectedArray = expectedObject as object[];
                ProtoCore.DSASM.Mirror.DsasmArray dsArray = dsObject.Payload as ProtoCore.DSASM.Mirror.DsasmArray;
                if (dsArray == null)
                {
                    Assert.Fail(String.Format("{0}{1} is expected to be an array, but its actual value isn't an array.\n{2}", dsVariable, BuildIndicesString(indices), mErrorMessage));
                }
                else if (expectedArray.Count() != dsArray.members.Count())
                {
                    Assert.Fail(String.Format("{0}{1} is expected to be an array of length {2}, but its actual length is {3}.\n{4}", dsVariable, BuildIndicesString(indices), expectedArray.Count(), dsArray.members.Count(), mErrorMessage));
                }
                else
                {
                    for (int i = 0; i < expectedArray.Count(); ++i)
                    {
                        indices.Add(i);
                        VerifyInternal(expectedArray[i], dsArray.members[i], dsVariable, indices);
                        indices.RemoveAt(indices.Count - 1);
                    }
                }
            }
            else
            {
                Assert.Fail(string.Format("\tUnexpected object type.\n{0}", mErrorMessage));
            }
        }