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); }
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); }
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)); }
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)); }
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))))); }
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)); } }
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)); } }
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); }
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)); }
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(); }
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); } }
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)); } }
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); }
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 } }
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)); }
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); }
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); } }
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)); } }
public static Object DoOp(Object v1, Object v2, JSToken operatorTok) { return(DoOp(v1, v2, Convert.GetIConvertible(v1), Convert.GetIConvertible(v2), operatorTok)); }
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)); } }
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; } }