GetTypeCode() статический приватный Метод

static private GetTypeCode ( Object ob ) : TypeCode
ob Object
Результат TypeCode
Пример #1
0
        internal static String JScriptTypeof(Object value, bool checkForDebuggerObject)
        {
            switch (Convert.GetTypeCode(value))
            {
            case TypeCode.Empty:
                return("undefined");

            case TypeCode.DBNull:
                return("object");

            case TypeCode.Object:
                if (value is Missing || value is System.Reflection.Missing)
                {
                    return("undefined");
                }
                return(value is ScriptFunction ? "function" : "object");

            case TypeCode.Boolean:
                return("boolean");

            case TypeCode.Char:
            case TypeCode.String:
                return("string");

            case TypeCode.SByte:
            case TypeCode.Byte:
            case TypeCode.Int16:
            case TypeCode.UInt16:
            case TypeCode.Int32:
            case TypeCode.UInt32:
            case TypeCode.Int64:
            case TypeCode.UInt64:
            case TypeCode.Single:
            case TypeCode.Double:
            case TypeCode.Decimal:
                return("number");

            case TypeCode.DateTime:
                return("date");
            }
            return("unknown");
        }
Пример #2
0
        internal static bool IsString(object value)
        {
            IConvertible ic = value as IConvertible;
            TypeCode     tc = Convert.GetTypeCode(value, ic);

            switch (tc)
            {
            case TypeCode.String:
                return(true);

            case TypeCode.Object:
                if (value is StringObject)
                {
                    return(true);
                }
                break;
            }

            return(false);
        }
Пример #3
0
        public Object EvaluatePostOrPrefix(ref Object v)
        {
            int          i; uint ui; long l; ulong ul; double d;
            IConvertible ic = Convert.GetIConvertible(v);

            switch (Convert.GetTypeCode(v, ic))
            {
            case TypeCode.Empty:  v = Double.NaN; return(v);

            case TypeCode.DBNull: v = 0; return(this.DoOp(0));

            case TypeCode.Boolean:
            case TypeCode.SByte:
            case TypeCode.Byte:
            case TypeCode.Int16:
            case TypeCode.UInt16:
            case TypeCode.Int32: v = i = ic.ToInt32(null); return(this.DoOp(i));

            case TypeCode.Char: i = ic.ToInt32(null); return(((IConvertible)this.DoOp(i)).ToChar(null));

            case TypeCode.UInt32: v = ui = ic.ToUInt32(null); return(this.DoOp(ui));

            case TypeCode.Int64: v = l = ic.ToInt64(null); return(this.DoOp(l));

            case TypeCode.UInt64: v = ul = ic.ToUInt64(null); return(this.DoOp(ul));

            case TypeCode.Single:
            case TypeCode.Double: v = d = ic.ToDouble(null); return(this.DoOp(d));
            }
            MethodInfo oper = this.GetOperator(v.GetType());

            if (oper != null)
            {
                return(oper.Invoke(null, (BindingFlags)0, JSBinder.ob, new Object[] { v }, null));
            }
            else
            {
                v = d = Convert.ToNumber(v, ic);
                return(this.DoOp(d));
            }
        }
Пример #4
0
 public static Object valueOf(Object thisob)
 {
     if (thisob is NumberObject)
     {
         return(((NumberObject)thisob).value);
     }
     switch (Convert.GetTypeCode(thisob))
     {
     case TypeCode.SByte:
     case TypeCode.Byte:
     case TypeCode.Int16:
     case TypeCode.UInt16:
     case TypeCode.Int32:
     case TypeCode.UInt32:
     case TypeCode.Int64:
     case TypeCode.UInt64:
     case TypeCode.Single:
     case TypeCode.Double: return(thisob);
     }
     throw new JScriptException(JSError.NumberExpected);
 }
Пример #5
0
 public static Object JScriptEvaluate(Object source, VsaEngine engine)
 {
     if (Convert.GetTypeCode(source) != TypeCode.String)
     {
         return(source);
     }
     if (engine.doFast)
     {
         engine.PushScriptObject(new BlockScope(engine.ScriptObjectStackTop()));
     }
     try{
         Context  context = new Context(new DocumentContext("eval code", engine), ((IConvertible)source).ToString());
         JSParser p       = new JSParser(context);
         return(((Completion)p.ParseEvalBody().PartiallyEvaluate().Evaluate()).value);
     }finally{
         if (engine.doFast)
         {
             engine.PopScriptObject();
         }
     }
 }
Пример #6
0
        public static Object DoOp(Object v1, Object v2)
        {
            IConvertible ic1 = Convert.GetIConvertible(v1);
            IConvertible ic2 = Convert.GetIConvertible(v2);

            v1 = Convert.ToPrimitive(v1, PreferredType.Either, ref ic1);
            v2 = Convert.ToPrimitive(v2, PreferredType.Either, ref ic2);
            TypeCode t1 = Convert.GetTypeCode(v1, ic1);
            TypeCode t2 = Convert.GetTypeCode(v2, ic2);

            if (t1 == TypeCode.String)
            {
                if (v1 is ConcatString)
                {
                    return(new ConcatString((ConcatString)v1, Convert.ToString(v2, ic2)));
                }
                else
                {
                    return(new ConcatString(ic1.ToString(null), Convert.ToString(v2, ic2)));
                }
            }
            else if (t2 == TypeCode.String)
            {
                return(Convert.ToString(v1, ic1) + ic2.ToString(null));
            }
            else if (t1 == TypeCode.Char && t2 == TypeCode.Char)
            {
                return(ic1.ToString(null) + ic2.ToString(null));
            }
            else if ((t1 == TypeCode.Char && (Convert.IsPrimitiveNumericTypeCode(t2) || t2 == TypeCode.Boolean)) ||
                     (t2 == TypeCode.Char && (Convert.IsPrimitiveNumericTypeCode(t1) || t1 == TypeCode.Boolean)))
            {
                return((char)(int)Runtime.DoubleToInt64(Convert.ToNumber(v1, ic1) + Convert.ToNumber(v2, ic2)));
            }
            else
            {
                return(Convert.ToNumber(v1, ic1) + Convert.ToNumber(v2, ic2));
            }
        }
Пример #7
0
        public static String toString(Object thisob)
        {
            StringObject strob = thisob as StringObject;

            if (strob != null)
            {
                return(strob.value);
            }
            ConcatString concatStr = thisob as ConcatString;

            if (concatStr != null)
            {
                return(concatStr.ToString());
            }
            IConvertible ic = Convert.GetIConvertible(thisob);

            if (Convert.GetTypeCode(thisob, ic) == TypeCode.String)
            {
                return(ic.ToString(null));
            }
            throw new JScriptException(JSError.StringExpected);
        }
Пример #8
0
        public static double JScriptCompare(Object v1, Object v2)
        {
            if (v1 is Int32)
            {
                if (v2 is Int32)
                {
                    return(((Int32)v1) - (Int32)v2);
                }
                else if (v2 is Double)
                {
                    return(((Int32)v1) - (Double)v2);
                }
            }
            else if (v1 is Double)
            {
                if (v2 is Double)
                {
                    double d1 = (Double)v1;
                    double d2 = (Double)v2;
                    if (d1 == d2)
                    {
                        return(0);  //d1 and d2 could be infinities
                    }
                    return(d1 - d2);
                }
                else if (v2 is Int32)
                {
                    return(((Double)v1) - (Int32)v2);
                }
            }
            IConvertible ic1 = Convert.GetIConvertible(v1);
            IConvertible ic2 = Convert.GetIConvertible(v2);
            TypeCode     t1  = Convert.GetTypeCode(v1, ic1);
            TypeCode     t2  = Convert.GetTypeCode(v2, ic2);

            return(JScriptCompare2(v1, v2, ic1, ic2, t1, t2));
        }
Пример #9
0
        public static string JScriptTypeof(object value)
        {
            IConvertible ic = value as IConvertible;
            TypeCode     tc = Convert.GetTypeCode(value, ic);

            if (Convert.IsNumberTypeCode(tc))
            {
                return("number");
            }

            switch (tc)
            {
            case TypeCode.String:
                return("string");

            case TypeCode.Object:
            case TypeCode.DBNull:
                if (value is ScriptFunction || value is RegExpObject)
                {
                    return("function");
                }

                return("object");

            case TypeCode.Empty:
                return("undefined");

            case TypeCode.Boolean:
                return("boolean");

            default:
                Console.WriteLine("TypeOf, tc = {0}", tc);
                break;
            }
            throw new NotImplementedException();
        }
Пример #10
0
        private bool EvaluateEquality(Object v1, Object v2, bool checkForDebuggerObjects)
        {
            if (v1 is String && v2 is String)
            {
                return(v1.Equals(v2));
            }
            if (v1 is Int32 && v2 is Int32)
            {
                return(((int)v1) == (int)v2);
            }
            if (v1 is Double && v2 is Double)
            {
                return(((double)v1) == (double)v2);
            }
            if ((v2 == null || v2 is DBNull || v2 is Missing) && !checkForDebuggerObjects)
            {
                return(v1 == null || v1 is DBNull || v1 is Missing);
            }
            IConvertible ic1 = Convert.GetIConvertible(v1);
            IConvertible ic2 = Convert.GetIConvertible(v2);
            TypeCode     t1  = Convert.GetTypeCode(v1, ic1);
            TypeCode     t2  = Convert.GetTypeCode(v2, ic2);

            switch (t1)
            {
            case TypeCode.Empty:
            case TypeCode.DBNull:
                break;

            case TypeCode.Object:
                switch (t2)
                {
                case TypeCode.Empty:
                case TypeCode.DBNull:
                    break;

                default:
                    MethodInfo oper = this.GetOperator(v1.GetType(), v2.GetType());
                    if (oper != null)
                    {
                        bool result = (bool)oper.Invoke(null, (BindingFlags)0, JSBinder.ob, new Object[] { v1, v2 }, null);
                        if (this.operatorTok == JSToken.NotEqual)
                        {
                            return(!result);
                        }
                        return(result);
                    }
                    break;
                }
                break;

            default:
                switch (t2)
                {
                case TypeCode.Object:
                    MethodInfo oper = this.GetOperator(v1.GetType(), v2.GetType());
                    if (oper != null)
                    {
                        bool result = (bool)oper.Invoke(null, (BindingFlags)0, JSBinder.ob, new Object[] { v1, v2 }, null);
                        if (this.operatorTok == JSToken.NotEqual)
                        {
                            return(!result);
                        }
                        return(result);
                    }
                    break;
                }
                break;
            }
            return(Equality.JScriptEquals(v1, v2, ic1, ic2, t1, t2, checkForDebuggerObjects));
        }
Пример #11
0
        public static bool JScriptStrictEquals(object v1, object v2)
        {
            IConvertible ic1 = v1 as IConvertible;
            IConvertible ic2 = v2 as IConvertible;

            TypeCode tc1 = Convert.GetTypeCode(v1, ic1);
            TypeCode tc2 = Convert.GetTypeCode(v2, ic2);

            bool both_numbers = Convert.IsNumberTypeCode(tc1) && Convert.IsNumberTypeCode(tc2);

            if (tc1 != tc2 && !both_numbers)
            {
                return(false);
            }

            switch (tc1)
            {
            case TypeCode.DBNull:
            case TypeCode.Empty:
                return(true);

            case TypeCode.Boolean:
                return(ic1.ToBoolean(null) == ic2.ToBoolean(null));

            case TypeCode.String:
                return(ic1.ToString(null) == ic2.ToString(null));

            case TypeCode.Object:
                if (v1 is ScriptFunction && v2 is ScriptFunction)
                {
                    return(v1 == v2 || v1.Equals(v2));
                }
                else
                {
                    return(v1 == v2);
                }

            default:
                if (both_numbers)
                {
                    double num1;
                    if (Convert.IsFloatTypeCode(tc1))
                    {
                        num1 = ic1.ToDouble(null);
                    }
                    else
                    {
                        num1 = (double)ic1.ToInt64(null);
                    }

                    double num2;
                    if (Convert.IsFloatTypeCode(tc2))
                    {
                        num2 = ic2.ToDouble(null);
                    }
                    else
                    {
                        num2 = (double)ic2.ToInt64(null);
                    }

                    return(num1 == num2);
                }
                Console.WriteLine("StrictEquality, tc1 = {0}, tc2 = {1}", tc1, tc2);
                break;
            }
            throw new NotImplementedException();
        }
Пример #12
0
        private Object EvaluateBitwiseBinary(Object v1, Object v2, JSToken operatorTok)
        {
            IConvertible ic1 = Convert.GetIConvertible(v1);
            IConvertible ic2 = Convert.GetIConvertible(v2);
            TypeCode     t1  = Convert.GetTypeCode(v1, ic1);
            TypeCode     t2  = Convert.GetTypeCode(v2, ic2);

            switch (t1)
            {
            case TypeCode.Empty:
            case TypeCode.DBNull:
                return(EvaluateBitwiseBinary(0, v2, operatorTok));

            case TypeCode.Boolean:
            case TypeCode.Char:
            case TypeCode.SByte:
            case TypeCode.Byte:
            case TypeCode.Int16:
            case TypeCode.UInt16:
            case TypeCode.Int32:
                int i = ic1.ToInt32(null);
                switch (t2)
                {
                case TypeCode.Empty:
                case TypeCode.DBNull:
                    return(DoOp(i, 0, operatorTok));

                case TypeCode.Boolean:
                case TypeCode.Char:
                case TypeCode.SByte:
                case TypeCode.Byte:
                case TypeCode.Int16:
                case TypeCode.UInt16:
                case TypeCode.Int32:
                    return(DoOp(i, ic2.ToInt32(null), operatorTok));

                case TypeCode.UInt32:
                case TypeCode.Int64:
                case TypeCode.UInt64:
                case TypeCode.Single:
                case TypeCode.Double:
                    return(DoOp(i, (int)(long)ic2.ToDouble(null), operatorTok));

                case TypeCode.Object:
                case TypeCode.Decimal:
                case TypeCode.DateTime:
                case TypeCode.String:
                    break;
                }
                break;

            case TypeCode.UInt32:
            case TypeCode.Int64:
            case TypeCode.UInt64:
            case TypeCode.Single:
            case TypeCode.Double:
                i = (int)(long)ic1.ToDouble(null);
                switch (t2)
                {
                case TypeCode.Empty:
                case TypeCode.DBNull:
                    return(DoOp(i, 0, operatorTok));

                case TypeCode.Boolean:
                case TypeCode.Char:
                case TypeCode.SByte:
                case TypeCode.Byte:
                case TypeCode.Int16:
                case TypeCode.UInt16:
                case TypeCode.Int32:
                    return(DoOp(i, ic2.ToInt32(null), operatorTok));

                case TypeCode.UInt32:
                case TypeCode.Int64:
                case TypeCode.UInt64:
                case TypeCode.Single:
                case TypeCode.Double:
                    return(DoOp(i, (int)(long)ic2.ToDouble(null), operatorTok));

                case TypeCode.Object:
                case TypeCode.Decimal:
                case TypeCode.DateTime:
                case TypeCode.String:
                    break;
                }
                break;

            case TypeCode.Object:
            case TypeCode.Decimal:
            case TypeCode.DateTime:
            case TypeCode.String:
                break;
            }
            if (v2 == null)
            {
                return(DoOp(Convert.ToInt32(v1), 0, this.operatorTok));
            }
            MethodInfo oper = this.GetOperator(v1.GetType(), v2.GetType());

            if (oper != null)
            {
                return(oper.Invoke(null, (BindingFlags)0, JSBinder.ob, new Object[] { v1, v2 }, null));
            }
            else
            {
                return(DoOp(Convert.ToInt32(v1), Convert.ToInt32(v2), this.operatorTok));
            }
        }
Пример #13
0
        private void TranslateToIL(ILGenerator il, Object val, Type rtype)
        {
            IConvertible ic = Convert.GetIConvertible(val);

            switch (Convert.GetTypeCode(val, ic))
            {
            case TypeCode.Empty:
                il.Emit(OpCodes.Ldnull);
                if (rtype.IsValueType)
                {
                    Convert.Emit(this, il, Typeob.Object, rtype);
                }
                return;

            case TypeCode.Object:
                break;

            case TypeCode.DBNull:
                il.Emit(OpCodes.Ldsfld, typeof(DBNull).GetField("Value"));
                Convert.Emit(this, il, Typeob.Null, rtype);
                return;

            case TypeCode.Boolean:
                ConstantWrapper.TranslateToILInt(il, ic.ToInt32(null));
                Convert.Emit(this, il, Typeob.Boolean, rtype);
                return;

            case TypeCode.Char:
            case TypeCode.SByte:
            case TypeCode.Byte:
            case TypeCode.Int16:
            case TypeCode.UInt16:
            case TypeCode.Int32:
                ConstantWrapper.TranslateToILInt(il, ic.ToInt32(null));
                if (rtype.IsEnum)
                {
                    return;
                }
                if (val is EnumWrapper)
                {
                    Convert.Emit(this, il, ((EnumWrapper)val).type.GetTypeBuilderOrEnumBuilder(), rtype);
                }
                else
                {
                    Convert.Emit(this, il, val.GetType(), rtype);
                }
                return;

            case TypeCode.UInt32:
                ConstantWrapper.TranslateToILInt(il, (int)ic.ToUInt32(null));
                if (rtype.IsEnum)
                {
                    return;
                }
                if (val is EnumWrapper)
                {
                    Convert.Emit(this, il, ((EnumWrapper)val).type.GetTypeBuilderOrEnumBuilder(), rtype);
                }
                else
                {
                    Convert.Emit(this, il, Typeob.UInt32, rtype);
                }
                return;

            case TypeCode.Int64:
                long l = ic.ToInt64(null);
                if (Int32.MinValue <= l && l <= Int32.MaxValue)
                {
                    ConstantWrapper.TranslateToILInt(il, (int)l);
                    il.Emit(OpCodes.Conv_I8);
                }
                else
                {
                    il.Emit(OpCodes.Ldc_I8, l);
                }
                if (rtype.IsEnum)
                {
                    return;
                }
                if (val is EnumWrapper)
                {
                    Convert.Emit(this, il, ((EnumWrapper)val).type.GetTypeBuilderOrEnumBuilder(), rtype);
                }
                else
                {
                    Convert.Emit(this, il, Typeob.Int64, rtype);
                }
                return;

            case TypeCode.UInt64:
                ulong ul = ic.ToUInt64(null);
                if (ul <= Int32.MaxValue)
                {
                    ConstantWrapper.TranslateToILInt(il, (int)ul);
                    il.Emit(OpCodes.Conv_I8);
                }
                else
                {
                    il.Emit(OpCodes.Ldc_I8, (long)ul);
                }
                if (rtype.IsEnum)
                {
                    return;
                }
                if (val is EnumWrapper)
                {
                    Convert.Emit(this, il, ((EnumWrapper)val).type.GetTypeBuilderOrEnumBuilder(), rtype);
                }
                else
                {
                    Convert.Emit(this, il, Typeob.UInt64, rtype);
                }
                return;

            case TypeCode.Single:
                float f = ic.ToSingle(null);
                if (f == f && (f != 0 || !Single.IsNegativeInfinity(1 / f)))
                {
                    int i = (int)f;
                    if (-128 <= i && i <= 127 && f == (float)i)
                    {
                        ConstantWrapper.TranslateToILInt(il, i);
                        il.Emit(OpCodes.Conv_R4);
                    }
                    else
                    {
                        il.Emit(OpCodes.Ldc_R4, f);
                    }
                }
                else
                {
                    il.Emit(OpCodes.Ldc_R4, f);
                }
                Convert.Emit(this, il, Typeob.Single, rtype);
                return;

            case TypeCode.Double:
                double d = ic.ToDouble(null);
                if (d == d && (d != 0 || !Double.IsNegativeInfinity(1 / d)))
                {
                    int i = (int)d;
                    if (-128 <= i && i <= 127 && d == (double)i)
                    {
                        ConstantWrapper.TranslateToILInt(il, i);
                        il.Emit(OpCodes.Conv_R8);
                    }
                    else
                    {
                        il.Emit(OpCodes.Ldc_R8, d);
                    }
                }
                else
                {
                    il.Emit(OpCodes.Ldc_R8, d);
                }
                Convert.Emit(this, il, Typeob.Double, rtype);
                return;

            case TypeCode.Decimal:
                int[] bits = Decimal.GetBits(ic.ToDecimal(null));
                ConstantWrapper.TranslateToILInt(il, bits[0]);
                ConstantWrapper.TranslateToILInt(il, bits[1]);
                ConstantWrapper.TranslateToILInt(il, bits[2]);
                il.Emit(bits[3] < 0 ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); //bool isNegative
                ConstantWrapper.TranslateToILInt(il, (bits[3] & 0x7FFFFFFF) >> 16);
                il.Emit(OpCodes.Newobj, CompilerGlobals.decimalConstructor);
                Convert.Emit(this, il, Typeob.Decimal, rtype);
                return;

            case TypeCode.DateTime:
                l = ic.ToDateTime(null).Ticks;
                il.Emit(OpCodes.Ldc_I8, l);
                Convert.Emit(this, il, Typeob.Int64, rtype);
                return;

            case TypeCode.String:
                String str = ic.ToString(null);
                if (rtype == Typeob.Char && str.Length == 1)
                {
                    ConstantWrapper.TranslateToILInt(il, (int)str[0]);
                    return;
                }
                il.Emit(OpCodes.Ldstr, str);
                Convert.Emit(this, il, Typeob.String, rtype);
                return;
            }
            if (val is Enum)
            {
                if (rtype == Typeob.String)
                {
                    this.TranslateToIL(il, val.ToString(), rtype);
                }
                else if (rtype.IsPrimitive)
                {
                    this.TranslateToIL(il, System.Convert.ChangeType(val, Enum.GetUnderlyingType(val.GetType())), rtype);
                }
                else
                {
                    Type et = val.GetType();
                    Type ut = Enum.GetUnderlyingType(et);
                    this.TranslateToIL(il, System.Convert.ChangeType(val, ut), ut);
                    il.Emit(OpCodes.Box, et);
                    Convert.Emit(this, il, Typeob.Object, rtype);
                }
                return;
            }
            if (val is EnumWrapper)
            {
                if (rtype == Typeob.String)
                {
                    this.TranslateToIL(il, val.ToString(), rtype);
                }
                else if (rtype.IsPrimitive)
                {
                    this.TranslateToIL(il, ((EnumWrapper)val).ToNumericValue(), rtype);
                }
                else
                {
                    Type et = ((EnumWrapper)val).type.owner.GetTypeBuilderOrEnumBuilder();
                    Type ut = ((EnumWrapper)val).value.GetType();
                    this.TranslateToIL(il, ((EnumWrapper)val).value, ut);
                    il.Emit(OpCodes.Box, et);
                    Convert.Emit(this, il, Typeob.Object, rtype);
                }
                return;
            }
            if (val is Type)
            {
                il.Emit(OpCodes.Ldtoken, (Type)val);
                il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod);
                Convert.Emit(this, il, Typeob.Type, rtype);
            }
            else if (val is Namespace)
            {
                il.Emit(OpCodes.Ldstr, ((Namespace)val).Name);
                this.EmitILToLoadEngine(il);
                il.Emit(OpCodes.Call, CompilerGlobals.getNamespaceMethod);
                Convert.Emit(this, il, typeof(Namespace), rtype);
            }
            else if (val is ClassScope)
            {
                il.Emit(OpCodes.Ldtoken, ((ClassScope)val).GetTypeBuilderOrEnumBuilder());
                il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod);
                Convert.Emit(this, il, Typeob.Type, rtype);
            }
            else if (val is TypedArray)
            {
                il.Emit(OpCodes.Ldtoken, Convert.ToType((TypedArray)val));
                il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod);
                Convert.Emit(this, il, Typeob.Type, rtype);
            }
            else if (val is NumberObject)
            {
                this.TranslateToIL(il, ((NumberObject)val).value, Typeob.Object);
                this.EmitILToLoadEngine(il);
                il.Emit(OpCodes.Call, CompilerGlobals.toObjectMethod);
                Convert.Emit(this, il, Typeob.NumberObject, rtype);
            }
            else if (val is StringObject)
            {
                il.Emit(OpCodes.Ldstr, ((StringObject)val).value);
                this.EmitILToLoadEngine(il);
                il.Emit(OpCodes.Call, CompilerGlobals.toObjectMethod);
                Convert.Emit(this, il, Typeob.StringObject, rtype);
            }
            else if (val is BooleanObject)
            {
                il.Emit(((BooleanObject)val).value ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Box, Typeob.Boolean);
                this.EmitILToLoadEngine(il);
                il.Emit(OpCodes.Call, CompilerGlobals.toObjectMethod);
                Convert.Emit(this, il, Typeob.BooleanObject, rtype);
            }
            else if (val is ActiveXObjectConstructor)
            {
                il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("ActiveXObject").GetGetMethod());
                Convert.Emit(this, il, Typeob.ScriptFunction, rtype);
            }
            else if (val is ArrayConstructor)
            {
                il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Array").GetGetMethod());
                Convert.Emit(this, il, Typeob.ScriptFunction, rtype);
            }
            else if (val is BooleanConstructor)
            {
                il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Boolean").GetGetMethod());
                Convert.Emit(this, il, Typeob.ScriptFunction, rtype);
            }
            else if (val is DateConstructor)
            {
                il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Date").GetGetMethod());
                Convert.Emit(this, il, Typeob.ScriptFunction, rtype);
            }
            else if (val is EnumeratorConstructor)
            {
                il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Enumerator").GetGetMethod());
                Convert.Emit(this, il, Typeob.ScriptFunction, rtype);
            }
            else if (val is ErrorConstructor)
            {
                ErrorConstructor error = (ErrorConstructor)val;
                if (error == ErrorConstructor.evalOb)
                {
                    il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("EvalError").GetGetMethod());
                }
                else if (error == ErrorConstructor.rangeOb)
                {
                    il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("RangeError").GetGetMethod());
                }
                else if (error == ErrorConstructor.referenceOb)
                {
                    il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("ReferenceError").GetGetMethod());
                }
                else if (error == ErrorConstructor.syntaxOb)
                {
                    il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("SyntaxError").GetGetMethod());
                }
                else if (error == ErrorConstructor.typeOb)
                {
                    il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("TypeError").GetGetMethod());
                }
                else if (error == ErrorConstructor.uriOb)
                {
                    il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("URIError").GetGetMethod());
                }
                else
                {
                    il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Error").GetGetMethod());
                }
                Convert.Emit(this, il, Typeob.ScriptFunction, rtype);
            }
            else if (val is FunctionConstructor)
            {
                il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Function").GetGetMethod());
                Convert.Emit(this, il, Typeob.ScriptFunction, rtype);
            }
            else if (val is MathObject)
            {
                il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Math").GetGetMethod());
                Convert.Emit(this, il, Typeob.JSObject, rtype);
            }
            else if (val is NumberConstructor)
            {
                il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Number").GetGetMethod());
                Convert.Emit(this, il, Typeob.ScriptFunction, rtype);
            }
            else if (val is ObjectConstructor)
            {
                il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("Object").GetGetMethod());
                Convert.Emit(this, il, Typeob.ScriptFunction, rtype);
            }
            else if (val is RegExpConstructor)
            {
                il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("RegExp").GetGetMethod());
                Convert.Emit(this, il, Typeob.ScriptFunction, rtype);
            }
            else if (val is StringConstructor)
            {
                il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("String").GetGetMethod());
                Convert.Emit(this, il, Typeob.ScriptFunction, rtype);
            }
            else if (val is VBArrayConstructor)
            {
                il.Emit(OpCodes.Call, Typeob.GlobalObject.GetProperty("VBArray").GetGetMethod());
                Convert.Emit(this, il, Typeob.ScriptFunction, rtype);
            }
            else if (val is IntPtr)
            {
                il.Emit(OpCodes.Ldc_I8, (long)(IntPtr)val);
                il.Emit(OpCodes.Conv_I);
                Convert.Emit(this, il, typeof(IntPtr), rtype);
            }
            else if (val is UIntPtr)
            {
                il.Emit(OpCodes.Ldc_I8, (long)(UIntPtr)val);
                il.Emit(OpCodes.Conv_U);
                Convert.Emit(this, il, typeof(UIntPtr), rtype);
            }
            else if (val is Missing)
            {
                il.Emit(OpCodes.Ldsfld, CompilerGlobals.missingField);
                Convert.Emit(this, il, Typeob.Object, rtype);
            }
            else if (val is System.Reflection.Missing)
            {
                if (rtype.IsPrimitive)
                {
                    this.TranslateToIL(il, Double.NaN, rtype);
                }
                else if (rtype != Typeob.Object && !rtype.IsValueType)
                {
                    il.Emit(OpCodes.Ldnull);
                }
                else
                {
                    il.Emit(OpCodes.Ldsfld, CompilerGlobals.systemReflectionMissingField);
                    Convert.Emit(this, il, Typeob.Object, rtype);
                }
            }
            else if (val != this.value) //Value was coerced to some type we have no compile time knowlegde of
            {
                this.TranslateToIL(il, this.value, rtype);
            }
            else
            {
                throw new JScriptException(JSError.InternalError, this.context); //It should not be possible to wrap any other kind of object
            }
        }
Пример #14
0
        public bool EvaluateEquality(object v1, object v2)
        {
            IConvertible ic1 = v1 as IConvertible;
            IConvertible ic2 = v2 as IConvertible;

            TypeCode tc1 = Convert.GetTypeCode(v1, ic1);
            TypeCode tc2 = Convert.GetTypeCode(v2, ic2);

            bool both_numbers = Convert.IsNumberTypeCode(tc1) && Convert.IsNumberTypeCode(tc2);

            if ((tc1 == tc2) || both_numbers)
            {
                switch (tc1)
                {
                case TypeCode.DBNull:
                case TypeCode.Empty:
                    return(true);

                case TypeCode.Boolean:
                    return(ic1.ToBoolean(null) == ic2.ToBoolean(null));

                case TypeCode.String:
                    return(ic1.ToString(null) == ic2.ToString(null));

                case TypeCode.Object:
                    if (v1 is ScriptFunction && v2 is ScriptFunction)
                    {
                        return(v1 == v2 || v1.Equals(v2));
                    }
                    else
                    {
                        return(v1 == v2);
                    }

                default:
                    if (both_numbers)
                    {
                        double num1;
                        if (Convert.IsFloatTypeCode(tc1))
                        {
                            num1 = ic1.ToDouble(null);
                        }
                        else
                        {
                            num1 = (double)ic1.ToInt64(null);
                        }

                        double num2;
                        if (Convert.IsFloatTypeCode(tc2))
                        {
                            num2 = ic2.ToDouble(null);
                        }
                        else
                        {
                            num2 = (double)ic2.ToInt64(null);
                        }

                        return(num1 == num2);
                    }
                    else
                    {
                        return(false);
                    }
                }
            }
            else
            {
                bool swapped = false;

redo:
                switch (tc1)
                {
                case TypeCode.DBNull:
                    if (tc2 == TypeCode.Empty)
                    {
                        return(true);
                    }
                    break;

                case TypeCode.String:
                    if (Convert.IsNumberTypeCode(tc2))
                    {
                        return(EvaluateEquality(Convert.ToNumber(v1), v2));
                    }
                    break;

                case TypeCode.Boolean:
                    return(EvaluateEquality(Convert.ToNumber(v1), v2));

                case TypeCode.Object:
                    if (tc2 == TypeCode.String || Convert.IsNumberTypeCode(tc2))
                    {
                        return(EvaluateEquality(Convert.ToPrimitive(v1, null), v2));
                    }
                    break;
                }

                if (!swapped)
                {
                    swapped = true;

                    object vt = v1;
                    v1 = v2;
                    v2 = vt;

                    ic1 = v1 as IConvertible;
                    ic2 = v2 as IConvertible;

                    tc1 = Convert.GetTypeCode(v1, ic1);
                    tc2 = Convert.GetTypeCode(v2, ic2);

                    goto redo;
                }
                else
                {
                    return(false);
                }
            }
        }
Пример #15
0
 TypeCode IConvertible.GetTypeCode()
 {
     return(Convert.GetTypeCode(this.value));
 }
Пример #16
0
        public Object EvaluateUnary(Object v)
        {
            IConvertible ic = Convert.GetIConvertible(v);

            switch (Convert.GetTypeCode(v, ic))
            {
            case TypeCode.Empty:  return(this.EvaluateUnary(Double.NaN));

            case TypeCode.DBNull: return(this.EvaluateUnary(0));

            case TypeCode.Boolean: return(this.EvaluateUnary(ic.ToBoolean(null) ? 1 : 0));

            case TypeCode.Char: return(this.EvaluateUnary((int)ic.ToChar(null)));

            case TypeCode.SByte:
            case TypeCode.Byte:
            case TypeCode.Int16:
            case TypeCode.UInt16:
            case TypeCode.Int32:
                int i = ic.ToInt32(null);
                switch (this.operatorTok)
                {
                case JSToken.BitwiseNot:
                    return(~i);

                case JSToken.LogicalNot:
                    return(i == 0);

                case JSToken.Minus:
                    if (i == 0)
                    {
                        return(-(double)i);
                    }
                    if (i == Int32.MinValue)
                    {
                        return((ulong)-(double)i);
                    }
                    return(-i);

                case JSToken.Plus:
                    return(i);

                default:
                    throw new JScriptException(JSError.InternalError, this.context);
                }

            case TypeCode.UInt32:
                uint ui = ic.ToUInt32(null);
                switch (this.operatorTok)
                {
                case JSToken.BitwiseNot:
                    return(~ui);

                case JSToken.LogicalNot:
                    return(ui == 0);

                case JSToken.Minus:
                    if (ui != 0 && ui <= Int32.MaxValue)
                    {
                        return(-(int)ui);
                    }
                    else
                    {
                        return(-(double)ui);
                    }

                case JSToken.Plus:
                    return(ui);

                default:
                    throw new JScriptException(JSError.InternalError, this.context);
                }

            case TypeCode.Int64:
                long l = ic.ToInt64(null);
                switch (this.operatorTok)
                {
                case JSToken.BitwiseNot:
                    return(~l);

                case JSToken.LogicalNot:
                    return(l == 0);

                case JSToken.Minus:
                    if (l == 0 || l == Int64.MinValue)
                    {
                        return(-(double)l);
                    }
                    return(-l);

                case JSToken.Plus:
                    return(l);

                default:
                    throw new JScriptException(JSError.InternalError, this.context);
                }

            case TypeCode.UInt64:
                ulong ul = ic.ToUInt64(null);
                switch (this.operatorTok)
                {
                case JSToken.BitwiseNot:
                    return(~ul);

                case JSToken.LogicalNot:
                    return(ul == 0);

                case JSToken.Minus:
                    if (ul != 0 && ul <= Int64.MaxValue)
                    {
                        return(-(long)ul);
                    }
                    else
                    {
                        return(-(double)ul);
                    }

                case JSToken.Plus:
                    return(ul);

                default:
                    throw new JScriptException(JSError.InternalError, this.context);
                }

            case TypeCode.Single:
            case TypeCode.Double:
                double d = ic.ToDouble(null);
                switch (this.operatorTok)
                {
                case JSToken.BitwiseNot:
                    return(~(int)Runtime.DoubleToInt64(d));

                case JSToken.LogicalNot:
                    return(!Convert.ToBoolean(d));

                case JSToken.Minus:
                    return(-d);

                case JSToken.Plus:
                    return(d);

                default:
                    throw new JScriptException(JSError.InternalError, this.context);
                }

            case TypeCode.String:
                goto no_overload_case;
            }

            MethodInfo oper = this.GetOperator(v.GetType());

            if (oper != null)
            {
                return(oper.Invoke(null, (BindingFlags)0, JSBinder.ob, new Object[] { v }, null));
            }
no_overload_case:
            switch (this.operatorTok)
            {
            case JSToken.BitwiseNot:
                return(~Convert.ToInt32(v, ic));

            case JSToken.LogicalNot:
                return(!Convert.ToBoolean(v, ic));

            case JSToken.Minus:
                return(-Convert.ToNumber(v, ic));

            case JSToken.Plus:
                return(Convert.ToNumber(v, ic));

            default:
                throw new JScriptException(JSError.InternalError, this.context);
            }
        }
Пример #17
0
        private Object EvaluateNumericBinary(Object v1, Object v2, JSToken operatorTok)
        {
            IConvertible ic1 = Convert.GetIConvertible(v1);
            IConvertible ic2 = Convert.GetIConvertible(v2);
            TypeCode     t1  = Convert.GetTypeCode(v1, ic1);
            TypeCode     t2  = Convert.GetTypeCode(v2, ic2);

            switch (t1)
            {
            case TypeCode.Empty:
                return(Double.NaN);

            case TypeCode.DBNull:
                return(this.EvaluateNumericBinary(0, v2, operatorTok));

            case TypeCode.Char: {
                Object result;
                int    val = ic1.ToInt32(null);
                switch (t2)
                {
                case TypeCode.Empty:
                    return(Double.NaN);

                case TypeCode.DBNull:
                    return(NumericBinary.DoOp(val, 0, operatorTok));

                case TypeCode.Boolean:
                case TypeCode.Char:
                case TypeCode.SByte:
                case TypeCode.Byte:
                case TypeCode.Int16:
                case TypeCode.UInt16:
                case TypeCode.Int32:
                    result = NumericBinary.DoOp(val, ic2.ToInt32(null), operatorTok);
                    break;

                case TypeCode.UInt32:
                case TypeCode.Int64:
                    result = NumericBinary.DoOp((long)val, ic2.ToInt64(null), operatorTok);
                    break;

                case TypeCode.UInt64:
                    result = NumericBinary.DoOp((double)val, ic2.ToDouble(null), operatorTok);
                    break;

                case TypeCode.Single:
                case TypeCode.Double:
                    result = NumericBinary.DoOp((double)ic1.ToInt32(null), ic2.ToDouble(null), operatorTok);
                    break;

                case TypeCode.String:
                    result = NumericBinary.DoOp(val, Convert.ToNumber(v2, ic2), operatorTok);
                    break;

                case TypeCode.Object:
                case TypeCode.Decimal:
                case TypeCode.DateTime:
                default:
                    result = null;
                    break;
                }
                if (this.operatorTok == JSToken.Minus && result != null && t2 != TypeCode.Char)
                {
                    return(Convert.Coerce2(result, TypeCode.Char, false));
                }
                else if (result != null)
                {
                    return(result);
                }
                break;
            }

            case TypeCode.Boolean:
            case TypeCode.SByte:
            case TypeCode.Byte:
            case TypeCode.Int16:
            case TypeCode.UInt16:
            case TypeCode.Int32:
            { int val = ic1.ToInt32(null);
              switch (t2)
              {
              case TypeCode.Empty:
                  return(Double.NaN);

              case TypeCode.DBNull:
                  return(NumericBinary.DoOp(val, 0, operatorTok));

              case TypeCode.Boolean:
              case TypeCode.Char:
              case TypeCode.SByte:
              case TypeCode.Byte:
              case TypeCode.Int16:
              case TypeCode.UInt16:
              case TypeCode.Int32:
                  return(NumericBinary.DoOp(val, ic2.ToInt32(null), operatorTok));

              case TypeCode.UInt32:
              case TypeCode.Int64:
                  return(NumericBinary.DoOp((long)val, ic2.ToInt64(null), operatorTok));

              case TypeCode.UInt64:
                  if (val >= 0)
                  {
                      return(NumericBinary.DoOp((ulong)val, ic2.ToUInt64(null), operatorTok));
                  }
                  else
                  {
                      return(NumericBinary.DoOp((double)val, ic2.ToDouble(null), operatorTok));
                  }

              case TypeCode.Single:
              case TypeCode.Double:
                  return(NumericBinary.DoOp((double)val, ic2.ToDouble(null), operatorTok));

              case TypeCode.Object:
              case TypeCode.Decimal:
              case TypeCode.DateTime:
              case TypeCode.String:
                  break;
              }
              break; }

            case TypeCode.UInt32:
            { uint val = ic1.ToUInt32(null);
              switch (t2)
              {
              case TypeCode.Empty:
                  return(Double.NaN);

              case TypeCode.DBNull:
                  return(NumericBinary.DoOp(val, 0, operatorTok));

              case TypeCode.SByte:
              case TypeCode.Byte:
              case TypeCode.Int16:
              case TypeCode.Int32:
                  int val2 = ic2.ToInt32(null);
                  if (val2 >= 0)
                  {
                      return(NumericBinary.DoOp(val, (uint)val2, operatorTok));
                  }
                  else
                  {
                      return(NumericBinary.DoOp((long)val, (long)val2, operatorTok));
                  }

              case TypeCode.Int64:
                  return(NumericBinary.DoOp((long)val, ic2.ToInt64(null), operatorTok));

              case TypeCode.Boolean:
              case TypeCode.Char:
              case TypeCode.UInt16:
              case TypeCode.UInt32:
                  return(NumericBinary.DoOp(val, ic2.ToUInt32(null), operatorTok));

              case TypeCode.UInt64:
                  return(NumericBinary.DoOp((ulong)val, ic2.ToUInt64(null), operatorTok));

              case TypeCode.Single:
              case TypeCode.Double:
                  return(NumericBinary.DoOp((double)val, ic2.ToDouble(null), operatorTok));

              case TypeCode.Object:
              case TypeCode.Decimal:
              case TypeCode.DateTime:
              case TypeCode.String:
                  break;
              }
              break; }

            case TypeCode.Int64:
            { long val = ic1.ToInt64(null);
              switch (t2)
              {
              case TypeCode.Empty:
                  return(Double.NaN);

              case TypeCode.DBNull:
                  return(NumericBinary.DoOp(val, 0, operatorTok));

              case TypeCode.Boolean:
              case TypeCode.Char:
              case TypeCode.SByte:
              case TypeCode.Byte:
              case TypeCode.Int16:
              case TypeCode.UInt16:
              case TypeCode.Int32:
              case TypeCode.UInt32:
              case TypeCode.Int64:
                  return(NumericBinary.DoOp(val, ic2.ToInt64(null), operatorTok));

              case TypeCode.UInt64:
                  if (val >= 0)
                  {
                      return(NumericBinary.DoOp((ulong)val, ic2.ToUInt64(null), operatorTok));
                  }
                  else
                  {
                      return(NumericBinary.DoOp((double)val, ic2.ToDouble(null), operatorTok));
                  }

              case TypeCode.Single:
              case TypeCode.Double:
                  return(NumericBinary.DoOp((double)val, ic2.ToDouble(null), operatorTok));

              case TypeCode.Object:
              case TypeCode.Decimal:
              case TypeCode.DateTime:
              case TypeCode.String:
                  break;
              }
              break; }


            case TypeCode.UInt64:
            { ulong val = ic1.ToUInt64(null);
              switch (t2)
              {
              case TypeCode.Empty:
                  return(Double.NaN);

              case TypeCode.DBNull:
                  return(NumericBinary.DoOp(val, 0, operatorTok));

              case TypeCode.SByte:
              case TypeCode.Byte:
              case TypeCode.Int16:
              case TypeCode.Int32:
              case TypeCode.Int64:
                  long val2 = ic2.ToInt64(null);
                  if (val2 >= 0)
                  {
                      return(NumericBinary.DoOp(val, (ulong)val2, operatorTok));
                  }
                  else
                  {
                      return(NumericBinary.DoOp((double)val, (double)val2, operatorTok));
                  }

              case TypeCode.Boolean:
              case TypeCode.Char:
              case TypeCode.UInt16:
              case TypeCode.UInt32:
              case TypeCode.UInt64:
                  return(NumericBinary.DoOp(val, ic2.ToUInt64(null), operatorTok));

              case TypeCode.Single:
              case TypeCode.Double:
                  return(NumericBinary.DoOp((double)val, ic2.ToDouble(null), operatorTok));

              case TypeCode.Object:
              case TypeCode.Decimal:
              case TypeCode.DateTime:
              case TypeCode.String:
                  break;
              }
              break; }

            case TypeCode.Single:
            case TypeCode.Double:
            { double d = ic1.ToDouble(null);
              switch (t2)
              {
              case TypeCode.Empty:
                  return(Double.NaN);

              case TypeCode.DBNull:
                  return(NumericBinary.DoOp(d, 0, operatorTok));

              case TypeCode.Boolean:
              case TypeCode.Char:
              case TypeCode.SByte:
              case TypeCode.Byte:
              case TypeCode.Int16:
              case TypeCode.UInt16:
              case TypeCode.Int32:
                  return(NumericBinary.DoOp(d, (double)ic2.ToInt32(null), operatorTok));

              case TypeCode.UInt32:
              case TypeCode.Int64:
              case TypeCode.UInt64:
              case TypeCode.Single:
              case TypeCode.Double:
                  return(NumericBinary.DoOp(d, ic2.ToDouble(null), operatorTok));

              case TypeCode.Object:
              case TypeCode.Decimal:
              case TypeCode.DateTime:
              case TypeCode.String:
                  break;
              }
              break; }

            case TypeCode.Object:
            case TypeCode.Decimal:
            case TypeCode.DateTime:
            case TypeCode.String:
                break;
            }
            if (v2 == null)
            {
                return(Double.NaN);
            }
            MethodInfo oper = this.GetOperator(v1.GetType(), v2.GetType());

            if (oper != null)
            {
                return(oper.Invoke(null, (BindingFlags)0, JSBinder.ob, new Object[] { v1, v2 }, null));
            }
            else
            {
                return(NumericBinary.DoOp(v1, v2, ic1, ic2, operatorTok));
            }
        }
Пример #18
0
        private static double JScriptCompare2(Object v1, Object v2, IConvertible ic1, IConvertible ic2, TypeCode t1, TypeCode t2)
        {
            if (t1 == TypeCode.Object)
            {
                v1 = Convert.ToPrimitive(v1, PreferredType.Number, ref ic1);
                t1 = Convert.GetTypeCode(v1, ic1);
            }
            if (t2 == TypeCode.Object)
            {
                v2 = Convert.ToPrimitive(v2, PreferredType.Number, ref ic2);
                t2 = Convert.GetTypeCode(v2, ic2);
            }
            switch (t1)
            {
            case TypeCode.Char:
                if (t2 == TypeCode.String)
                {
                    return(String.CompareOrdinal(Convert.ToString(v1, ic1), ic2.ToString(null)));
                }
                goto case TypeCode.UInt16;

            case TypeCode.SByte:
            case TypeCode.Byte:
            case TypeCode.Int16:
            case TypeCode.UInt16:
            case TypeCode.Int32:
            case TypeCode.UInt32:
            case TypeCode.Int64:
                long l = ic1.ToInt64(null);
                switch (t2)
                {
                case TypeCode.SByte:
                case TypeCode.Byte:
                case TypeCode.Int16:
                case TypeCode.UInt16:
                case TypeCode.Int32:
                case TypeCode.UInt32:
                case TypeCode.Int64:
                    return(l - ic2.ToInt64(null));

                case TypeCode.UInt64:
                    if (l < 0)
                    {
                        return(-1);
                    }
                    ulong ul2 = ic2.ToUInt64(null);
                    if (((ulong)l) < ul2)
                    {
                        return(-1);
                    }
                    if (((ulong)l) == ul2)
                    {
                        return(0);
                    }
                    return(1);

                case TypeCode.Single:
                case TypeCode.Double:
                    return(((double)l) - ic2.ToDouble(null));

                case TypeCode.Decimal:
                    return((double)(new Decimal(l) - ic2.ToDecimal(null)));

                default:
                    Object bd2 = Convert.ToNumber(v2, ic2);
                    return(JScriptCompare2(v1, bd2, ic1, Convert.GetIConvertible(bd2), t1, TypeCode.Double));
                }

            case TypeCode.UInt64:
                ulong ul = ic1.ToUInt64(null);
                switch (t2)
                {
                case TypeCode.SByte:
                case TypeCode.Byte:
                case TypeCode.Int16:
                case TypeCode.UInt16:
                case TypeCode.Int32:
                case TypeCode.UInt32:
                case TypeCode.Int64:
                    long l2 = ic2.ToInt64(null);
                    if (l2 < 0)
                    {
                        return(1);
                    }
                    if (ul == (ulong)l2)
                    {
                        return(0);
                    }
                    return(-1);

                case TypeCode.UInt64:
                    ulong ul2 = ic2.ToUInt64(null);
                    if (ul < ul2)
                    {
                        return(-1);
                    }
                    if (ul == ul2)
                    {
                        return(0);
                    }
                    return(1);

                case TypeCode.Single:
                case TypeCode.Double:
                    return(((double)ul) - ic2.ToDouble(null));

                case TypeCode.Decimal:
                    return((double)(new Decimal(ul) - ic2.ToDecimal(null)));

                default:
                    Object bd2 = Convert.ToNumber(v2, ic2);
                    return(JScriptCompare2(v1, bd2, ic1, Convert.GetIConvertible(bd2), t1, TypeCode.Double));
                }

            case TypeCode.Decimal:
                Decimal dec1 = ic1.ToDecimal(null);
                switch (t2)
                {
                case TypeCode.SByte:
                case TypeCode.Byte:
                case TypeCode.Int16:
                case TypeCode.UInt16:
                case TypeCode.Int32:
                case TypeCode.UInt32:
                case TypeCode.Int64:
                    return((double)(dec1 - new Decimal(ic2.ToInt64(null))));

                case TypeCode.UInt64:
                    return((double)(dec1 - new Decimal(ic2.ToUInt64(null))));

                case TypeCode.Single:
                case TypeCode.Double:
                    return((double)(dec1 - new Decimal(ic2.ToDouble(null))));

                case TypeCode.Decimal:
                    return((double)(dec1 - ic2.ToDecimal(null)));

                default:
                    return((double)(dec1 - new Decimal(Convert.ToNumber(v2, ic2))));
                }

            case TypeCode.String:
                switch (t2)
                {
                case TypeCode.String: return(String.CompareOrdinal(ic1.ToString(null), ic2.ToString(null)));

                case TypeCode.Char: return(String.CompareOrdinal(ic1.ToString(null), Convert.ToString(v2, ic2)));
                }
                goto default;

            default:
                double d1 = Convert.ToNumber(v1, ic1);
                double d2 = Convert.ToNumber(v2, ic2);
                if (d1 == d2)
                {
                    return(0);      //d1 and d2 could be infinities
                }
                return(d1 - d2);
            }
        }
Пример #19
0
        public static double ToNumber(object value)
        {
            IConvertible ic = value as IConvertible;
            TypeCode     tc = Convert.GetTypeCode(value, ic);

            switch (tc)
            {
            case TypeCode.Empty:
                return(Double.NaN);

            case TypeCode.DBNull:
                return(0);

            case TypeCode.Boolean:
                if (ic.ToBoolean(null))
                {
                    return(1);
                }
                return(0);

            case TypeCode.String:
                return(ToNumber((string)value));

            case TypeCode.Object:
                if (value is NumberObject)
                {
                    return(((NumberObject)value).value);
                }
                else if (value is BooleanObject)
                {
                    return(((BooleanObject)value).value ? 1 : 0);
                }
                else if (value is StringObject)
                {
                    return(ToNumber(((StringObject)value).value));
                }
                else if (value is DateObject)
                {
                    return(((DateObject)value).ms);
                }
                else if (value is ArrayObject)
                {
                    ArrayObject ary   = (ArrayObject)value;
                    Hashtable   elems = ary.elems;
                    uint        n     = (uint)ary.length;
                    uint        i     = n - 1;
                    if (elems.ContainsKey(i))
                    {
                        return(Convert.ToNumber(elems [i]));
                    }
                }
                return(Double.NaN);

            default:
                if (IsFloatTypeCode(tc))
                {
                    return((double)value);
                }
                else if (IsNumberTypeCode(tc))
                {
                    return(ic.ToDouble(null));
                }
                break;
            }

            Console.WriteLine("\nToNumber: value.GetType = {0}", value.GetType());
            throw new NotImplementedException();
        }
Пример #20
0
        private Object EvaluatePlus2(Object v1, Object v2)
        {
            IConvertible ic1 = Convert.GetIConvertible(v1);
            IConvertible ic2 = Convert.GetIConvertible(v2);
            TypeCode     t1  = Convert.GetTypeCode(v1, ic1);
            TypeCode     t2  = Convert.GetTypeCode(v2, ic2);

            switch (t1)
            {
            case TypeCode.Empty:
                return(Plus.DoOp(v1, v2));

            case TypeCode.DBNull:
                switch (t2)
                {
                case TypeCode.Empty:
                    return(Double.NaN);

                case TypeCode.DBNull:
                    return(0);

                case TypeCode.Boolean:
                case TypeCode.Char:
                case TypeCode.SByte:
                case TypeCode.Byte:
                case TypeCode.Int16:
                case TypeCode.UInt16:
                case TypeCode.Int32:
                    return(ic2.ToInt32(null));

                case TypeCode.UInt32:
                    return(ic2.ToUInt32(null));

                case TypeCode.Int64:
                    return(ic2.ToInt64(null));

                case TypeCode.UInt64:
                    return(ic2.ToUInt64(null));

                case TypeCode.Single:
                case TypeCode.Double:
                    return(ic2.ToDouble(null));

                case TypeCode.Object:
                case TypeCode.Decimal:
                case TypeCode.DateTime:
                    break;

                case TypeCode.String:
                    return("null" + ic2.ToString(null));
                }
                break;

            case TypeCode.Char:
            { int val = ic1.ToInt32(null);
              switch (t2)
              {
              case TypeCode.Empty:
                  return(Double.NaN);

              case TypeCode.DBNull:
                  return(val);

              case TypeCode.Boolean:
              case TypeCode.SByte:
              case TypeCode.Byte:
              case TypeCode.Int16:
              case TypeCode.UInt16:
              case TypeCode.Int32:
                  return(((IConvertible)Plus.DoOp(val, ic2.ToInt32(null))).ToChar(null));

              case TypeCode.UInt32:
              case TypeCode.Int64:
                  return(((IConvertible)Plus.DoOp((long)val, ic2.ToInt64(null))).ToChar(null));

              case TypeCode.UInt64:
                  return(((IConvertible)Plus.DoOp((ulong)val, ic2.ToUInt64(null))).ToChar(null));

              case TypeCode.Single:
              case TypeCode.Double:
                  checked { return((char)(int)(Convert.CheckIfDoubleIsInteger((double)Plus.DoOp((double)val, ic2.ToDouble(null))))); }

              case TypeCode.Object:
              case TypeCode.Decimal:
              case TypeCode.DateTime:
                  return(Plus.DoOp(v1, v2));

              case TypeCode.Char:
              case TypeCode.String:
                  return(ic1.ToString(null) + ic2.ToString(null));
              }
              break; }

            case TypeCode.Boolean:
            case TypeCode.SByte:
            case TypeCode.Byte:
            case TypeCode.Int16:
            case TypeCode.UInt16:
            case TypeCode.Int32:
            { int val = ic1.ToInt32(null);
              switch (t2)
              {
              case TypeCode.Empty:
                  return(Double.NaN);

              case TypeCode.DBNull:
                  return(val);

              case TypeCode.Char:
                  return(((IConvertible)Plus.DoOp(val, ic2.ToInt32(null))).ToChar(null));

              case TypeCode.Boolean:
              case TypeCode.SByte:
              case TypeCode.Byte:
              case TypeCode.Int16:
              case TypeCode.UInt16:
              case TypeCode.Int32:
                  return(Plus.DoOp(val, ic2.ToInt32(null)));

              case TypeCode.UInt32:
              case TypeCode.Int64:
                  return(Plus.DoOp((long)val, ic2.ToInt64(null)));

              case TypeCode.UInt64:
                  if (val >= 0)
                  {
                      return(Plus.DoOp((ulong)val, ic2.ToUInt64(null)));
                  }
                  else
                  {
                      return(Plus.DoOp((double)val, ic2.ToDouble(null)));
                  }

              case TypeCode.Single:
              case TypeCode.Double:
                  return(Plus.DoOp((double)val, ic2.ToDouble(null)));

              case TypeCode.Object:
              case TypeCode.Decimal:
              case TypeCode.DateTime:
                  break;

              case TypeCode.String:
                  return(Convert.ToString(v1) + ic2.ToString(null));
              }
              break; }

            case TypeCode.UInt32:
            { uint val = ic1.ToUInt32(null);
              switch (t2)
              {
              case TypeCode.Empty:
                  return(Double.NaN);

              case TypeCode.DBNull:
                  return(val);

              case TypeCode.SByte:
              case TypeCode.Byte:
              case TypeCode.Int16:
              case TypeCode.Int32:
                  int val2 = ic2.ToInt32(null);
                  if (val2 >= 0)
                  {
                      return(Plus.DoOp(val, (uint)val2));
                  }
                  else
                  {
                      return(Plus.DoOp((long)val, (long)val2));
                  }

              case TypeCode.Int64:
                  return(Plus.DoOp((long)val, ic2.ToInt64(null)));

              case TypeCode.Char:
                  return(((IConvertible)Plus.DoOp(val, ic2.ToUInt32(null))).ToChar(null));

              case TypeCode.Boolean:
              case TypeCode.UInt16:
              case TypeCode.UInt32:
                  return(Plus.DoOp(val, ic2.ToUInt32(null)));

              case TypeCode.UInt64:
                  return(Plus.DoOp((ulong)val, ic2.ToUInt64(null)));

              case TypeCode.Single:
              case TypeCode.Double:
                  return(Plus.DoOp((double)val, ic2.ToDouble(null)));

              case TypeCode.Object:
              case TypeCode.Decimal:
              case TypeCode.DateTime:
                  break;

              case TypeCode.String:
                  return(Convert.ToString(v1) + ic2.ToString(null));
              }
              break; }

            case TypeCode.Int64:
            { long val = ic1.ToInt64(null);
              switch (t2)
              {
              case TypeCode.Empty:
                  return(Double.NaN);

              case TypeCode.DBNull:
                  return(val);

              case TypeCode.Char:
                  return(((IConvertible)Plus.DoOp(val, ic2.ToInt64(null))).ToChar(null));

              case TypeCode.Boolean:
              case TypeCode.SByte:
              case TypeCode.Byte:
              case TypeCode.Int16:
              case TypeCode.UInt16:
              case TypeCode.Int32:
              case TypeCode.UInt32:
              case TypeCode.Int64:
                  return(Plus.DoOp(val, ic2.ToInt64(null)));

              case TypeCode.UInt64:
                  if (val >= 0)
                  {
                      return(Plus.DoOp((ulong)val, ic2.ToUInt64(null)));
                  }
                  else
                  {
                      return(Plus.DoOp((double)val, ic2.ToDouble(null)));
                  }

              case TypeCode.Single:
              case TypeCode.Double:
                  return(Plus.DoOp((double)val, ic2.ToDouble(null)));

              case TypeCode.Object:
              case TypeCode.Decimal:
              case TypeCode.DateTime:
                  break;

              case TypeCode.String:
                  return(Convert.ToString(v1) + ic2.ToString(null));
              }
              break; }

            case TypeCode.UInt64:
            { ulong val = ic1.ToUInt64(null);
              switch (t2)
              {
              case TypeCode.Empty:
                  return(Double.NaN);

              case TypeCode.DBNull:
                  return(val);

              case TypeCode.SByte:
              case TypeCode.Byte:
              case TypeCode.Int16:
              case TypeCode.Int32:
              case TypeCode.Int64:
                  long val2 = ic2.ToInt64(null);
                  if (val2 >= 0)
                  {
                      return(Plus.DoOp(val, (ulong)val2));
                  }
                  else
                  {
                      return(Plus.DoOp((double)val, (double)val2));
                  }

              case TypeCode.Char:
                  return(((IConvertible)Plus.DoOp(val, ic2.ToUInt64(null))).ToChar(null));

              case TypeCode.UInt16:
              case TypeCode.Boolean:
              case TypeCode.UInt32:
              case TypeCode.UInt64:
                  return(Plus.DoOp(val, ic2.ToUInt64(null)));

              case TypeCode.Single:
              case TypeCode.Double:
                  return(Plus.DoOp((double)val, ic2.ToDouble(null)));

              case TypeCode.Object:
              case TypeCode.Decimal:
              case TypeCode.DateTime:
                  break;

              case TypeCode.String:
                  return(Convert.ToString(v1) + ic2.ToString(null));
              }
              break; }

            case TypeCode.Single:
            case TypeCode.Double: {
                double d = ic1.ToDouble(null);
                switch (t2)
                {
                case TypeCode.Empty:
                    return(Double.NaN);

                case TypeCode.DBNull:
                    return(ic1.ToDouble(null));

                case TypeCode.Char:
                    return(System.Convert.ToChar(System.Convert.ToInt32((d + (double)ic2.ToInt32(null)))));

                case TypeCode.Boolean:
                case TypeCode.SByte:
                case TypeCode.Byte:
                case TypeCode.Int16:
                case TypeCode.UInt16:
                case TypeCode.Int32:
                    return(d + (double)ic2.ToInt32(null));

                case TypeCode.UInt32:
                case TypeCode.Int64:
                case TypeCode.UInt64:
                case TypeCode.Single:
                case TypeCode.Double:
                    return(d + ic2.ToDouble(null));

                case TypeCode.Object:
                case TypeCode.Decimal:
                case TypeCode.DateTime:
                    break;

                case TypeCode.String:
                    return(new ConcatString(Convert.ToString(d), ic2.ToString(null)));
                }
                break;
            }

            case TypeCode.Object:
            case TypeCode.Decimal:
            case TypeCode.DateTime:
                break;

            case TypeCode.String:
                switch (t2)
                {
                case TypeCode.Object:
                    break;

                case TypeCode.String:
                    if (v1 is ConcatString)
                    {
                        return(new ConcatString((ConcatString)v1, ic2.ToString(null)));
                    }
                    else
                    {
                        return(new ConcatString(ic1.ToString(null), ic2.ToString(null)));
                    }

                default:
                    if (v1 is ConcatString)
                    {
                        return(new ConcatString((ConcatString)v1, Convert.ToString(v2)));
                    }
                    else
                    {
                        return(new ConcatString(ic1.ToString(null), Convert.ToString(v2)));
                    }
                }
                break;
            }
            MethodInfo oper = this.GetOperator(v1 == null ? Typeob.Empty : v1.GetType(), v2 == null ? Typeob.Empty : v2.GetType());

            if (oper != null)
            {
                return(oper.Invoke(null, (BindingFlags)0, JSBinder.ob, new Object[] { v1, v2 }, null));
            }
            else
            {
                return(Plus.DoOp(v1, v2));
            }
        }
Пример #21
0
        public static string ToString(object value, bool explicitOK)
        {
            IConvertible ic = value as IConvertible;
            TypeCode     tc = Convert.GetTypeCode(value, ic);

            switch (tc)
            {
            case TypeCode.Empty:
                return("undefined");

            case TypeCode.DBNull:
                return("null");

            case TypeCode.Boolean:
                bool r = (bool)value;
                if (r)
                {
                    return("true");
                }
                else
                {
                    return("false");
                }

            case TypeCode.Char:
                return(ic.ToInt16(null).ToString());

            case TypeCode.String:
                return(ic.ToString(null));

            case TypeCode.Object:
                if (value is StringObject)
                {
                    return(((StringObject)value).value);
                }
                else if (value is ScriptObject)
                {
                    ScriptObject obj_value = (ScriptObject)value;
                    if (obj_value.HasMethod("toString"))
                    {
                        return((string)obj_value.CallMethod("toString"));
                    }
                    else
                    {
                        return((string)ObjectPrototype.smartToString((JSObject)obj_value));
                    }
                }

                Console.WriteLine("value.GetType = {0}", value.GetType());
                throw new NotImplementedException();

            default:
                if (IsNumberTypeCode(tc))
                {
                    double val = ic.ToDouble(null);
                    return(ToString(val));
                }

                Console.WriteLine("tc = {0}", tc);
                throw new NotImplementedException();
            }
        }