GetIConvertible() 정적인 개인적인 메소드

static private GetIConvertible ( Object ob ) : IConvertible
ob Object
리턴 IConvertible
예제 #1
0
 private static Object DoOp(Object v1, Object v2, IConvertible ic1, IConvertible ic2, JSToken operatorTok)
 {
     if (operatorTok == JSToken.Minus)
     {
         IConvertible ic1a = ic1;
         Object       p1   = Convert.ToPrimitive(v1, PreferredType.Either, ref ic1a);
         TypeCode     t1   = Convert.GetTypeCode(p1, ic1a);
         if (t1 == TypeCode.Char)
         {
             IConvertible ic2a = ic2;
             Object       p2   = Convert.ToPrimitive(v2, PreferredType.Either, ref ic2a);
             TypeCode     t2   = Convert.GetTypeCode(p2, ic2a);
             if (t2 == TypeCode.String)
             {
                 String str2 = ic2a.ToString(null);
                 if (str2.Length == 1)
                 {
                     t2   = TypeCode.Char;
                     p2   = str2[0];
                     ic2a = Convert.GetIConvertible(p2);
                 }
             }
             Object result = NumericBinary.DoOp(Convert.ToNumber(p1, ic1a), Convert.ToNumber(p2, ic2a), operatorTok);
             if (t2 != TypeCode.Char)
             {
                 result = Convert.Coerce2(result, TypeCode.Char, false);
             }
             return(result);
         }
     }
     return(NumericBinary.DoOp(Convert.ToNumber(v1, ic1), Convert.ToNumber(v2, ic2), operatorTok));
 }
        internal static long Array_index_for(Object index)
        {
            if (index is Int32)
            {
                return((int)index);
            }
            IConvertible ic = Convert.GetIConvertible(index);

            switch (Convert.GetTypeCode(index, ic))
            {
            case TypeCode.Char:
            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.Decimal:
            case TypeCode.Single:
            case TypeCode.Double:
                double d = ic.ToDouble(null);
                long   l = (long)d;
                if (l >= 0 && (double)l == d)
                {
                    return(l);
                }
                break;
            }
            return(-1);
        }
예제 #3
0
        public static bool JScriptEquals(Object v1, Object v2)
        {
            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))
            {
                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);

            return(Equality.JScriptEquals(v1, v2, ic1, ic2, t1, t2, false));
        }
        public new ArrayObject CreateInstance(params Object[] args)
        {
            ArrayObject arrayObj = new ArrayObject(this.originalPrototype, typeof(ArrayObject));

            if (args.Length != 0)
            {
                if (args.Length == 1)
                {
                    Object       arg0 = args[0];
                    IConvertible ic   = Convert.GetIConvertible(arg0);
                    switch (Convert.GetTypeCode(arg0, ic))
                    {
                    case TypeCode.Char:
                    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:
                        double d   = Convert.ToNumber(arg0, ic);
                        uint   len = Convert.ToUint32(arg0, ic);
                        if (d != (double)len)
                        {
                            throw new JScriptException(JSError.ArrayLengthConstructIncorrect);
                        }
                        arrayObj.length = len;
                        return(arrayObj);
                    }
                }
                if (args.Length == 1 && args[0] is Array)
                {
                    Array array = (Array)args[0];
                    if (array.Rank != 1)
                    {
                        throw new JScriptException(JSError.TypeMismatch);
                    }
                    arrayObj.length = array.Length;
                    for (int i = 0; i < array.Length; i++)
                    {
                        arrayObj.SetValueAtIndex((uint)i, array.GetValue(i));
                    }
                }
                else
                {
                    arrayObj.length = args.Length;
                    for (int i = 0; i < args.Length; i++)
                    {
                        arrayObj.SetValueAtIndex((uint)i, args[i]);
                    }
                }
            }
            return(arrayObj);
        }
예제 #5
0
        public double EvaluateRelational(Object v1, Object v2)
        {
            if (v1 is Int32)
            {
                if (v2 is Int32)
                {
                    return(((double)(int)v1) - (double)(int)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);

            if (t1 == TypeCode.Object && t2 == TypeCode.Object)
            {
                MethodInfo oper = this.GetOperator(v1.GetType(), v2.GetType());
                if (oper != null)
                {
                    bool result = Convert.ToBoolean(oper.Invoke(null, (BindingFlags)0, JSBinder.ob, new Object[] { v1, v2 }, null));
                    switch (this.operatorTok)
                    {
                    case JSToken.GreaterThan:
                    case JSToken.GreaterThanEqual:
                        return(result ? 1 : -1);

                    case JSToken.LessThan:
                    case JSToken.LessThanEqual:
                        return(result ? -1 : 1);

                    default:
                        throw new JScriptException(JSError.InternalError, this.context);
                    }
                }
            }
            return(JScriptCompare2(v1, v2, ic1, ic2, t1, t2));
        }
예제 #6
0
        internal static bool JScriptStrictEquals(Object v1, Object v2, bool checkForDebuggerObjects)
        {
            IConvertible ic1 = Convert.GetIConvertible(v1);
            IConvertible ic2 = Convert.GetIConvertible(v2);
            TypeCode     t1  = Convert.GetTypeCode(v1, ic1);
            TypeCode     t2  = Convert.GetTypeCode(v2, ic2);

            return(StrictEquality.JScriptStrictEquals(v1, v2, ic1, ic2, t1, t2, checkForDebuggerObjects));
        }
예제 #7
0
        public new DateObject CreateInstance(params Object[] args)
        {
            if (args.Length == 0)
            {
                return(new DateObject(this.originalPrototype, DateTime.Now.ToUniversalTime().Ticks / DatePrototype.ticksPerMillisecond - DatePrototype.msTo1970));
            }
            if (args.Length == 1)
            {
                Object       arg0  = args[0];
                IConvertible ic    = Convert.GetIConvertible(arg0);
                TypeCode     tcode = Convert.GetTypeCode(arg0, ic);
                if (tcode == TypeCode.DateTime)
                {
                    return(new DateObject(this.originalPrototype, ic.ToDateTime(null).ToUniversalTime().Ticks / DatePrototype.ticksPerMillisecond - DatePrototype.msTo1970));
                }
                Object yv = Convert.ToPrimitive(arg0, PreferredType.Either, ref ic);
                if (Convert.GetTypeCode(yv, ic) == TypeCode.String)
                {
                    return(new DateObject(this.originalPrototype, parse(ic.ToString(null))));
                }
                double d = Convert.ToNumber(yv, ic);
                if (DatePrototype.minDate <= d && d <= DatePrototype.maxDate)
                {
                    return(new DateObject(this.originalPrototype, d));
                }
                return(new DateObject(this.originalPrototype, Double.NaN));
            }
            double dyear    = Convert.ToNumber(args[0]);
            double dmonth   = Convert.ToNumber(args[1]);
            double ddate    = (args.Length > 2) ? Convert.ToNumber(args[2]) : 1;
            double dhours   = (args.Length > 3) ? Convert.ToNumber(args[3]) : 0;
            double dminutes = (args.Length > 4) ? Convert.ToNumber(args[4]) : 0;
            double dseconds = (args.Length > 5) ? Convert.ToNumber(args[5]) : 0;
            double dms      = (args.Length > 6) ? Convert.ToNumber(args[6]) : 0;
            int    y        = (int)dyear;

            if (!Double.IsNaN(dyear) && 0 <= y && y <= 99)
            {
                dyear = y + 1900;
            }
            double day  = DatePrototype.MakeDay(dyear, dmonth, ddate);
            double time = DatePrototype.MakeTime(dhours, dminutes, dseconds, dms);

            return(new DateObject(this.originalPrototype, DatePrototype.TimeClip(DatePrototype.UTC(DatePrototype.MakeDate(day, time)))));
        }
예제 #8
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));
            }
        }
예제 #9
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));
            }
        }
예제 #10
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);
        }
예제 #11
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));
        }
예제 #12
0
        public virtual Object InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target,
                                           Object[] args, ParameterModifier[] modifiers, CultureInfo locale, String[] namedParameters)
        {
            if (target != this)
            {
                throw new TargetException();
            }

            bool preferredTypeSpecified = name.StartsWith("< JScript-");
            bool dispid0 = (name == null || name == String.Empty || name.Equals("[DISPID=0]") || preferredTypeSpecified);

            if ((invokeAttr & BindingFlags.CreateInstance) != 0)
            {
                if ((invokeAttr & (BindingFlags.InvokeMethod | BindingFlags.GetField | BindingFlags.GetProperty |
                                   BindingFlags.SetField | BindingFlags.SetProperty | BindingFlags.PutDispProperty)) != 0)
                {
                    throw new ArgumentException();
                }
                //js: x = new foo() --> dispid0, create
                if (dispid0)
                {
                    throw new MissingMethodException();
                }

                //js: x = new foo.name() --> dispid0, create
                LateBinding lb = new LateBinding(name, this);
                return(lb.Call(binder, args, modifiers, locale, namedParameters, true, false, this.engine));
            }

            //According to docs, name == null is only valid for CreateInstance
            if (name == null)
            {
                throw new ArgumentException();
            }

            if ((invokeAttr & (BindingFlags.InvokeMethod | BindingFlags.GetField | BindingFlags.GetProperty)) != 0)
            {
                if ((invokeAttr & (BindingFlags.SetField | BindingFlags.SetProperty | BindingFlags.PutDispProperty)) != 0)
                {
                    throw new ArgumentException();
                }

                if (dispid0)
                {
                    //All callable functions inherit from ScriptFunction which overrides this method to handle
                    //the InvokeMethod case.

                    //js,vbs: x = foo() --> dispid0, invoke
                    if ((invokeAttr & (BindingFlags.GetField | BindingFlags.GetProperty)) == 0)
                    {
                        throw new MissingMethodException();
                    }

                    //js: x = foo --> dispid0, propget; vbs: x = foo --> dispid0, invoke|propget
                    if (args == null || args.Length == 0)
                    {
                        if (this is JSObject || this is GlobalScope || this is ClassScope)
                        {
                            PreferredType preferredType = PreferredType.Either;
                            if (preferredTypeSpecified)
                            {
                                if (name.StartsWith("< JScript-Number"))
                                {
                                    preferredType = PreferredType.Number;
                                }
                                else if (name.StartsWith("< JScript-String"))
                                {
                                    preferredType = PreferredType.String;
                                }
                                else if (name.StartsWith("< JScript-LocaleString"))
                                {
                                    preferredType = PreferredType.LocaleString;
                                }
                            }
                            return(this.GetDefaultValue(preferredType));
                        }
                        throw new MissingFieldException();
                    }

                    //We support indexed properties with exactly one index on all script objects.

                    //js,vbs: x = foo(1,2) --> dispid0, invoke|propget
                    if (args.Length > 1)
                    {
                        throw new ArgumentException();
                    }

                    //js,vbs: x = foo(1) --> dispid0, invoke|propget
                    Object val = args[0];
                    if (val is Int32)
                    {
                        return(this[(int)val]);
                    }
                    IConvertible ic = Convert.GetIConvertible(val);
                    if (ic != null && Convert.IsPrimitiveNumericTypeCode(ic.GetTypeCode()))
                    {
                        double d = ic.ToDouble(null);
                        if (d >= 0 && d <= Int32.MaxValue && d == System.Math.Round(d))
                        {
                            return(this[(int)d]);
                        }
                    }
                    return(this[Convert.ToString(val)]);
                }

                //If no arguments are supplied, prefer GetXXXX rather than Invoke.
                //js: x = foo.bar --> name="bar", propget; vbs: x = foo.bar --> name="bar", propget|invoke
                if ((args == null || args.Length == 0) && (invokeAttr & (BindingFlags.GetField | BindingFlags.GetProperty)) != 0)
                {
                    Object member = this.GetMemberValue(name);
                    if (member != Missing.Value)
                    {
                        return(member);
                    }

                    //js: x = foo.bar --> name="bar", propget
                    if ((invokeAttr & BindingFlags.InvokeMethod) == 0)
                    {
                        throw new MissingFieldException();
                    }
                }

                //Use LateBinding to call because arguments have been supplied.
                //vbs: x = foo.bar --> name="bar", propget|invoke
                //js,vbs: x = foo.bar() --> name="bar", invoke
                //js,vbs: x = foo.bar(1) --> name="bar", invoke|propget
                LateBinding lb = new LateBinding(name, this);
                return(lb.Call(binder, args, modifiers, locale, namedParameters, false, false, this.engine));
            }

            if ((invokeAttr & (BindingFlags.SetField | BindingFlags.SetProperty | BindingFlags.PutDispProperty)) != 0)
            {
                if (dispid0)
                {
                    if (args == null || args.Length != 2)
                    {
                        throw new ArgumentException();
                    }
                    Object val = args[0];
                    if (val is Int32)
                    {
                        this[(int)val] = args[1];
                        return(null);
                    }
                    IConvertible ic = Convert.GetIConvertible(val);
                    if (ic != null && Convert.IsPrimitiveNumericTypeCode(ic.GetTypeCode()))
                    {
                        double d = ic.ToDouble(null);
                        if (d >= 0 && d <= Int32.MaxValue && d == System.Math.Round(d))
                        {
                            this[(int)d] = args[1];
                            return(null);
                        }
                    }
                    this[Convert.ToString(val)] = args[1];
                    return(null);
                }
                if (args == null || args.Length > 1)
                {
                    throw new ArgumentException();
                }
                this.SetMemberValue(name, args[0]);
                return(null);
            }

            throw new ArgumentException();
        }
예제 #13
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);
            }
        }
예제 #14
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));
            }
        }
예제 #15
0
파일: jsobject.cs 프로젝트: ydunk/masters
 internal override Object GetDefaultValue(PreferredType preferred_type)
 {
     if (preferred_type == PreferredType.String)
     {
         ScriptFunction toString = this.GetMemberValue("toString") as ScriptFunction;
         if (toString != null)
         {
             Object result = toString.Call(new Object[0], this);
             if (result == null)
             {
                 return(result);
             }
             IConvertible ic = Convert.GetIConvertible(result);
             if (ic != null && ic.GetTypeCode() != TypeCode.Object)
             {
                 return(result);
             }
         }
         ScriptFunction valueOf = this.GetMemberValue("valueOf") as ScriptFunction;
         if (valueOf != null)
         {
             Object result = valueOf.Call(new Object[0], this);
             if (result == null)
             {
                 return(result);
             }
             IConvertible ic = Convert.GetIConvertible(result);
             if (ic != null && ic.GetTypeCode() != TypeCode.Object)
             {
                 return(result);
             }
         }
     }
     else if (preferred_type == PreferredType.LocaleString)
     {
         ScriptFunction toLocaleString = this.GetMemberValue("toLocaleString") as ScriptFunction;
         if (toLocaleString != null)
         {
             return(toLocaleString.Call(new Object[0], this));
         }
     }
     else
     {
         if (preferred_type == PreferredType.Either && this is DateObject)
         {
             return(this.GetDefaultValue(PreferredType.String));
         }
         ScriptFunction valueOf = this.GetMemberValue("valueOf") as ScriptFunction;
         if (valueOf != null)
         {
             Object result = valueOf.Call(new Object[0], this);
             if (result == null)
             {
                 return(result);
             }
             IConvertible ic = Convert.GetIConvertible(result);
             if (ic != null && ic.GetTypeCode() != TypeCode.Object)
             {
                 return(result);
             }
         }
         ScriptFunction toString = this.GetMemberValue("toString") as ScriptFunction;
         if (toString != null)
         {
             Object result = toString.Call(new Object[0], this);
             if (result == null)
             {
                 return(result);
             }
             IConvertible ic = Convert.GetIConvertible(result);
             if (ic != null && ic.GetTypeCode() != TypeCode.Object)
             {
                 return(result);
             }
         }
     }
     return(this);
 }
예제 #16
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
            }
        }
예제 #17
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));
        }
예제 #18
0
        private static bool JScriptEquals(Object v1, Object v2, IConvertible ic1, IConvertible ic2, TypeCode t1, TypeCode t2, bool checkForDebuggerObjects)
        {
            if (StrictEquality.JScriptStrictEquals(v1, v2, ic1, ic2, t1, t2, checkForDebuggerObjects))
            {
                return(true);
            }
            if (t2 == TypeCode.Boolean)
            {
                v2  = ic2.ToBoolean(null) ? 1 : 0;
                ic2 = Convert.GetIConvertible(v2);
                return(Equality.JScriptEquals(v1, v2, ic1, ic2, t1, TypeCode.Int32, false));
            }
            switch (t1)
            {
            case TypeCode.Empty: return(t2 == TypeCode.Empty || t2 == TypeCode.DBNull || (t2 == TypeCode.Object && v2 is Missing));

            case TypeCode.Object:
                switch (t2)
                {
                case TypeCode.Empty:
                case TypeCode.DBNull:
                    return(v1 is Missing);

                case TypeCode.Char:
                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:
                case TypeCode.String:
                    IConvertible pvic1 = ic1;
                    Object       pv1   = Convert.ToPrimitive(v1, PreferredType.Either, ref pvic1);
                    if (pvic1 != null && pv1 != v1)
                    {
                        return(Equality.JScriptEquals(pv1, v2, pvic1, ic2, pvic1.GetTypeCode(), t2, false));
                    }
                    else
                    {
                        return(false);
                    }
                }
                return(false);

            case TypeCode.DBNull: return(t2 == TypeCode.DBNull || t2 == TypeCode.Empty || (t2 == TypeCode.Object && v2 is Missing));

            case TypeCode.Boolean:
                v1  = ic1.ToBoolean(null) ? 1 : 0;
                ic1 = Convert.GetIConvertible(v1);
                return(Equality.JScriptEquals(v1, v2, ic1, ic2, TypeCode.Int32, t2, false));

            case TypeCode.Char:
            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:
                if (t2 == TypeCode.Object)
                {
                    IConvertible pvic2 = ic2;
                    Object       pv2   = Convert.ToPrimitive(v2, PreferredType.Either, ref pvic2);
                    if (pvic2 != null && pv2 != v2)
                    {
                        return(Equality.JScriptEquals(v1, pv2, ic1, pvic2, t1, pvic2.GetTypeCode(), false));
                    }
                    else
                    {
                        return(false);
                    }
                }
                if (t2 == TypeCode.String)
                {
                    if (v1 is Enum)
                    {
                        return(Convert.ToString(v1).Equals(ic2.ToString(null)));
                    }
                    v2  = Convert.ToNumber(v2, ic2);
                    ic2 = Convert.GetIConvertible(v2);
                    return(StrictEquality.JScriptStrictEquals(v1, v2, ic1, ic2, t1, TypeCode.Double, false));
                }
                return(false);

            case TypeCode.DateTime:
                if (t2 == TypeCode.Object)
                {
                    IConvertible pvic2 = ic2;
                    Object       pv2   = Convert.ToPrimitive(v2, PreferredType.Either, ref pvic2);
                    if (pv2 != null && pv2 != v2)
                    {
                        return(StrictEquality.JScriptStrictEquals(v1, pv2, ic1, pvic2, t1, pvic2.GetTypeCode(), false));
                    }
                }
                return(false);

            case TypeCode.String:
                switch (t2)
                {
                case TypeCode.Object: {
                    IConvertible pvic2 = ic2;
                    Object       pv2   = Convert.ToPrimitive(v2, PreferredType.Either, ref pvic2);
                    if (pvic2 != null && pv2 != v2)
                    {
                        return(Equality.JScriptEquals(v1, pv2, ic1, pvic2, t1, pvic2.GetTypeCode(), false));
                    }
                    else
                    {
                        return(false);
                    }
                }

                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:
                    if (v2 is Enum)
                    {
                        return(Convert.ToString(v2).Equals(ic1.ToString(null)));
                    }
                    v1  = Convert.ToNumber(v1, ic1);
                    ic1 = Convert.GetIConvertible(v1);
                    return(StrictEquality.JScriptStrictEquals(v1, v2, ic1, ic2, TypeCode.Double, t2, false));
                }
                return(false);
            }
            return(false);
        }
예제 #19
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);
            }
        }
예제 #20
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));
            }
        }
예제 #21
0
 public static Object DoOp(Object v1, Object v2, JSToken operatorTok)
 {
     return(DoOp(v1, v2, Convert.GetIConvertible(v1), Convert.GetIConvertible(v2), operatorTok));
 }
예제 #22
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));
            }
        }
예제 #23
0
 public Object this[params Object[] pars] {
     get{
         int n = pars.Length;
         if (n == 0)
         {
             if (this is ScriptFunction || this == null)
             {
                 throw new JScriptException(JSError.FunctionExpected);
             }
             else
             {
                 throw new JScriptException(JSError.TooFewParameters);
             }
         }
         if (this == null)
         {
             throw new JScriptException(JSError.ObjectExpected);
         }
         Object val = pars[n - 1];
         if (val is Int32)
         {
             return(this[(int)val]);
         }
         IConvertible ic = Convert.GetIConvertible(val);
         if (ic != null && Convert.IsPrimitiveNumericTypeCode(ic.GetTypeCode()))
         {
             double d = ic.ToDouble(null);
             if (d >= 0 && d <= Int32.MaxValue && d == System.Math.Round(d))
             {
                 return(this[(int)d]);
             }
         }
         return(this[Convert.ToString(val)]);
     }
     set{
         int n = pars.Length;
         if (n == 0)
         {
             if (this == null)
             {
                 throw new JScriptException(JSError.FunctionExpected);
             }
             else if (this is ScriptFunction)
             {
                 throw new JScriptException(JSError.CannotAssignToFunctionResult);
             }
             else
             {
                 throw new JScriptException(JSError.TooFewParameters);
             }
         }
         if (this == null)
         {
             throw new JScriptException(JSError.ObjectExpected);
         }
         Object val = pars[n - 1];
         if (val is Int32)
         {
             this[(int)val] = value;
             return;
         }
         IConvertible ic = Convert.GetIConvertible(val);
         if (ic != null && Convert.IsPrimitiveNumericTypeCode(ic.GetTypeCode()))
         {
             double d = ic.ToDouble(null);
             if (d >= 0 && d <= Int32.MaxValue && d == System.Math.Round(d))
             {
                 this[(int)d] = value;
                 return;
             }
         }
         this[Convert.ToString(val)] = value;
     }
 }