/// <summary>
 /// Converts any JavaScript value to a primitive value.
 /// </summary>
 /// <param name="value"> The value to convert. </param>
 /// <param name="preferredType"> Specifies whether toString() or valueOf() should be
 /// preferred when converting to a primitive. </param>
 /// <returns> A primitive (non-object) value. </returns>
 public static object ToPrimitive(object value, PrimitiveTypeHint preferredType)
 {
     if (value is ObjectInstance)
     {
         return(((ObjectInstance)value).GetPrimitiveValue(preferredType));
     }
     return(value);
 }
Example #2
0
 /// <summary>
 /// Pops the value on the stack, converts it to a primitive value, then pushes the result
 /// onto the stack.
 /// </summary>
 /// <param name="generator"> The IL generator. </param>
 /// <param name="fromType"> The type to convert from. </param>
 /// <param name="preferredType"> Specifies whether toString() or valueOf() should be
 /// preferred when converting to a primitive. </param>
 public static void ToPrimitive(ILGenerator generator, Type fromType, PrimitiveTypeHint preferredType)
 {
     if (fromType == typeof(Nitrassic.Undefined) || fromType == typeof(Nitrassic.Null) ||
         fromType == typeof(bool) || fromType == typeof(string) || fromType == typeof(ConcatenatedString) ||
         fromType == typeof(int) || fromType == typeof(uint) || fromType == typeof(double))
     {
         return;
     }
     else if (fromType == typeof(object) || fromType == typeof(Library.ObjectInstance))
     {
         // Otherwise, fall back to calling TypeConverter.ToPrimitive()
         if (PrimitiveTypeUtilities.IsValueType(fromType))
         {
             generator.Box(fromType);
         }
         generator.LoadInt32((int)preferredType);
         generator.Call(ReflectionHelpers.TypeConverter_ToPrimitive);
     }
     else
     {
         throw new NotImplementedException("Unsupported primitive type: " + fromType);
     }
 }
        //     JAVASCRIPT INTERNAL FUNCTIONS
        //_________________________________________________________________________________________

        /// <summary>
        /// Returns a primitive value that represents the current object.  Used by the addition and
        /// equality operators.
        /// </summary>
        /// <param name="hint"> Indicates the preferred type of the result. </param>
        /// <returns> A primitive value that represents the current object. </returns>
        protected internal override object GetPrimitiveValue(PrimitiveTypeHint typeHint)
        {
            if (typeHint == PrimitiveTypeHint.None)
                return base.GetPrimitiveValue(PrimitiveTypeHint.String);
            return base.GetPrimitiveValue(typeHint);
        }
Example #4
0
        /// <summary>
        /// Pops the value on the stack, converts it to a primitive value, then pushes the result
        /// onto the stack.
        /// </summary>
        /// <param name="generator"> The IL generator. </param>
        /// <param name="fromType"> The type to convert from. </param>
        /// <param name="preferredType"> Specifies whether toString() or valueOf() should be
        /// preferred when converting to a primitive. </param>
        public static void ToPrimitive(ILGenerator generator, PrimitiveType fromType, PrimitiveTypeHint preferredType)
        {
            switch (fromType)
            {
            case PrimitiveType.Undefined:
            case PrimitiveType.Null:
            case PrimitiveType.Bool:
            case PrimitiveType.String:
            case PrimitiveType.ConcatenatedString:
            case PrimitiveType.Int32:
            case PrimitiveType.UInt32:
            case PrimitiveType.Number:
                // These are primitives already.
                break;

            case PrimitiveType.Any:
            case PrimitiveType.Object:
                // Otherwise, fall back to calling TypeConverter.ToPrimitive()
                generator.LoadEnumValue(preferredType);
                generator.Call(ReflectionHelpers.TypeConverter_ToPrimitive);
                break;

            default:
                throw new NotImplementedException(string.Format("Unsupported primitive type: {0}", fromType));
            }
        }
Example #5
0
        //     OTHERS
        //_________________________________________________________________________________________

        /// <summary>
        /// Returns a primitive value that represents the current object.  Used by the addition and
        /// equality operators.
        /// </summary>
        /// <param name="hint"> Indicates the preferred type of the result. </param>
        /// <returns> A primitive value that represents the current object. </returns>
        protected internal virtual object GetPrimitiveValue(PrimitiveTypeHint typeHint)
        {
            if (typeHint == PrimitiveTypeHint.None || typeHint == PrimitiveTypeHint.Number)
            {

                // Try calling valueOf().
                object valueOfResult;
                if (TryCallMemberFunction(out valueOfResult, "valueOf") == true)
                {
                    // Return value must be primitive.
                    if (valueOfResult is double || TypeUtilities.IsPrimitive(valueOfResult) == true)
                        return valueOfResult;
                }

                // Try calling toString().
                object toStringResult;
                if (TryCallMemberFunction(out toStringResult, "toString") == true)
                {
                    // Return value must be primitive.
                    if (toStringResult is string || TypeUtilities.IsPrimitive(toStringResult) == true)
                        return toStringResult;
                }

            }
            else
            {

                // Try calling toString().
                object toStringResult;
                if (TryCallMemberFunction(out toStringResult, "toString") == true)
                {
                    // Return value must be primitive.
                    if (toStringResult is string || TypeUtilities.IsPrimitive(toStringResult) == true)
                        return toStringResult;
                }

                // Try calling valueOf().
                object valueOfResult;
                if (TryCallMemberFunction(out valueOfResult, "valueOf") == true)
                {
                    // Return value must be primitive.
                    if (valueOfResult is double || TypeUtilities.IsPrimitive(valueOfResult) == true)
                        return valueOfResult;
                }

            }

            throw new JavaScriptException(this.Engine, "TypeError", "Attempted conversion of the object to a primitive value failed.  Check the toString() and valueOf() functions.");
        }
Example #6
0
        /// <summary>
        /// Pops the value on the stack, converts it to a primitive value, then pushes the result
        /// onto the stack.
        /// </summary>
        /// <param name="generator"> The IL generator. </param>
        /// <param name="fromType"> The type to convert from. </param>
        /// <param name="preferredType"> Specifies whether toString() or valueOf() should be
        /// preferred when converting to a primitive. </param>
        public static void ToPrimitive(ILGenerator generator, PrimitiveType fromType, PrimitiveTypeHint preferredType)
        {
            switch (fromType)
            {
                case PrimitiveType.Undefined:
                case PrimitiveType.Null:
                case PrimitiveType.Bool:
                case PrimitiveType.String:
                case PrimitiveType.ConcatenatedString:
                case PrimitiveType.Int32:
                case PrimitiveType.UInt32:
                case PrimitiveType.Number:
                    // These are primitives already.
                    break;

                case PrimitiveType.Any:
                case PrimitiveType.Object:
                    // Otherwise, fall back to calling TypeConverter.ToPrimitive()
                    generator.LoadInt32((int)preferredType);
                    generator.Call(ReflectionHelpers.TypeConverter_ToPrimitive);
                    break;

                default:
                    throw new NotImplementedException(string.Format("Unsupported primitive type: {0}", fromType));
            }
        }
Example #7
0
        //     OTHERS
        //_________________________________________________________________________________________
        /// <summary>
        /// Returns a primitive value that represents the current object.  Used by the addition and
        /// equality operators.
        /// </summary>
        /// <param name="typeHint"> Indicates the preferred type of the result. </param>
        /// <returns> A primitive value that represents the current object. </returns>
        internal object GetPrimitiveValue(PrimitiveTypeHint typeHint)
        {
            // The first step is to try calling the @@toPrimitive symbol.
            string hintStr;
            switch (typeHint)
            {
                case PrimitiveTypeHint.None:
                    hintStr = "default";
                    break;
                case PrimitiveTypeHint.Number:
                    hintStr = "number";
                    break;
                case PrimitiveTypeHint.String:
                    hintStr = "string";
                    break;
                default:
                    throw new InvalidOperationException($"Unsupported PrimitiveTypeHint value '{typeHint}'.");
            }
            object toPrimitiveResult;
            if (TryCallMemberFunction(out toPrimitiveResult, Engine.Symbol.ToPrimitive, hintStr) == true)
            {
                // Return value must be primitive.
                if (TypeUtilities.IsPrimitive(toPrimitiveResult) == false)
                    throw new JavaScriptException(Engine, ErrorType.TypeError, "Cannot convert object to primitive value.");
                return toPrimitiveResult;
            }

            // If that didn't work.
            return GetPrimitiveValuePreES6(typeHint);
        }