internal static String JScriptTypeof(Object value, bool checkForDebuggerObject) { switch (Convert.GetTypeCode(value)) { case TypeCode.Empty: return("undefined"); case TypeCode.DBNull: return("object"); case TypeCode.Object: if (value is Missing || value is System.Reflection.Missing) { return("undefined"); } return(value is ScriptFunction ? "function" : "object"); case TypeCode.Boolean: return("boolean"); case TypeCode.Char: case TypeCode.String: return("string"); case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: return("number"); case TypeCode.DateTime: return("date"); } return("unknown"); }
internal static bool IsString(object value) { IConvertible ic = value as IConvertible; TypeCode tc = Convert.GetTypeCode(value, ic); switch (tc) { case TypeCode.String: return(true); case TypeCode.Object: if (value is StringObject) { return(true); } break; } return(false); }
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 valueOf(Object thisob) { if (thisob is NumberObject) { return(((NumberObject)thisob).value); } switch (Convert.GetTypeCode(thisob)) { case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: case TypeCode.Single: case TypeCode.Double: return(thisob); } throw new JScriptException(JSError.NumberExpected); }
public static Object JScriptEvaluate(Object source, VsaEngine engine) { if (Convert.GetTypeCode(source) != TypeCode.String) { return(source); } if (engine.doFast) { engine.PushScriptObject(new BlockScope(engine.ScriptObjectStackTop())); } try{ Context context = new Context(new DocumentContext("eval code", engine), ((IConvertible)source).ToString()); JSParser p = new JSParser(context); return(((Completion)p.ParseEvalBody().PartiallyEvaluate().Evaluate()).value); }finally{ if (engine.doFast) { engine.PopScriptObject(); } } }
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 static string JScriptTypeof(object value) { IConvertible ic = value as IConvertible; TypeCode tc = Convert.GetTypeCode(value, ic); if (Convert.IsNumberTypeCode(tc)) { return("number"); } switch (tc) { case TypeCode.String: return("string"); case TypeCode.Object: case TypeCode.DBNull: if (value is ScriptFunction || value is RegExpObject) { return("function"); } return("object"); case TypeCode.Empty: return("undefined"); case TypeCode.Boolean: return("boolean"); default: Console.WriteLine("TypeOf, tc = {0}", tc); break; } throw new NotImplementedException(); }
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)); }
public static bool JScriptStrictEquals(object v1, object v2) { IConvertible ic1 = v1 as IConvertible; IConvertible ic2 = v2 as IConvertible; TypeCode tc1 = Convert.GetTypeCode(v1, ic1); TypeCode tc2 = Convert.GetTypeCode(v2, ic2); bool both_numbers = Convert.IsNumberTypeCode(tc1) && Convert.IsNumberTypeCode(tc2); if (tc1 != tc2 && !both_numbers) { return(false); } switch (tc1) { case TypeCode.DBNull: case TypeCode.Empty: return(true); case TypeCode.Boolean: return(ic1.ToBoolean(null) == ic2.ToBoolean(null)); case TypeCode.String: return(ic1.ToString(null) == ic2.ToString(null)); case TypeCode.Object: if (v1 is ScriptFunction && v2 is ScriptFunction) { return(v1 == v2 || v1.Equals(v2)); } else { return(v1 == v2); } default: if (both_numbers) { double num1; if (Convert.IsFloatTypeCode(tc1)) { num1 = ic1.ToDouble(null); } else { num1 = (double)ic1.ToInt64(null); } double num2; if (Convert.IsFloatTypeCode(tc2)) { num2 = ic2.ToDouble(null); } else { num2 = (double)ic2.ToInt64(null); } return(num1 == num2); } Console.WriteLine("StrictEquality, tc1 = {0}, tc2 = {1}", tc1, tc2); break; } throw new NotImplementedException(); }
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)); } }
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 } }
public bool EvaluateEquality(object v1, object v2) { IConvertible ic1 = v1 as IConvertible; IConvertible ic2 = v2 as IConvertible; TypeCode tc1 = Convert.GetTypeCode(v1, ic1); TypeCode tc2 = Convert.GetTypeCode(v2, ic2); bool both_numbers = Convert.IsNumberTypeCode(tc1) && Convert.IsNumberTypeCode(tc2); if ((tc1 == tc2) || both_numbers) { switch (tc1) { case TypeCode.DBNull: case TypeCode.Empty: return(true); case TypeCode.Boolean: return(ic1.ToBoolean(null) == ic2.ToBoolean(null)); case TypeCode.String: return(ic1.ToString(null) == ic2.ToString(null)); case TypeCode.Object: if (v1 is ScriptFunction && v2 is ScriptFunction) { return(v1 == v2 || v1.Equals(v2)); } else { return(v1 == v2); } default: if (both_numbers) { double num1; if (Convert.IsFloatTypeCode(tc1)) { num1 = ic1.ToDouble(null); } else { num1 = (double)ic1.ToInt64(null); } double num2; if (Convert.IsFloatTypeCode(tc2)) { num2 = ic2.ToDouble(null); } else { num2 = (double)ic2.ToInt64(null); } return(num1 == num2); } else { return(false); } } } else { bool swapped = false; redo: switch (tc1) { case TypeCode.DBNull: if (tc2 == TypeCode.Empty) { return(true); } break; case TypeCode.String: if (Convert.IsNumberTypeCode(tc2)) { return(EvaluateEquality(Convert.ToNumber(v1), v2)); } break; case TypeCode.Boolean: return(EvaluateEquality(Convert.ToNumber(v1), v2)); case TypeCode.Object: if (tc2 == TypeCode.String || Convert.IsNumberTypeCode(tc2)) { return(EvaluateEquality(Convert.ToPrimitive(v1, null), v2)); } break; } if (!swapped) { swapped = true; object vt = v1; v1 = v2; v2 = vt; ic1 = v1 as IConvertible; ic2 = v2 as IConvertible; tc1 = Convert.GetTypeCode(v1, ic1); tc2 = Convert.GetTypeCode(v2, ic2); goto redo; } else { return(false); } } }
TypeCode IConvertible.GetTypeCode() { return(Convert.GetTypeCode(this.value)); }
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)); } }
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); } }
public static double ToNumber(object value) { IConvertible ic = value as IConvertible; TypeCode tc = Convert.GetTypeCode(value, ic); switch (tc) { case TypeCode.Empty: return(Double.NaN); case TypeCode.DBNull: return(0); case TypeCode.Boolean: if (ic.ToBoolean(null)) { return(1); } return(0); case TypeCode.String: return(ToNumber((string)value)); case TypeCode.Object: if (value is NumberObject) { return(((NumberObject)value).value); } else if (value is BooleanObject) { return(((BooleanObject)value).value ? 1 : 0); } else if (value is StringObject) { return(ToNumber(((StringObject)value).value)); } else if (value is DateObject) { return(((DateObject)value).ms); } else if (value is ArrayObject) { ArrayObject ary = (ArrayObject)value; Hashtable elems = ary.elems; uint n = (uint)ary.length; uint i = n - 1; if (elems.ContainsKey(i)) { return(Convert.ToNumber(elems [i])); } } return(Double.NaN); default: if (IsFloatTypeCode(tc)) { return((double)value); } else if (IsNumberTypeCode(tc)) { return(ic.ToDouble(null)); } break; } Console.WriteLine("\nToNumber: value.GetType = {0}", value.GetType()); throw new NotImplementedException(); }
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 static string ToString(object value, bool explicitOK) { IConvertible ic = value as IConvertible; TypeCode tc = Convert.GetTypeCode(value, ic); switch (tc) { case TypeCode.Empty: return("undefined"); case TypeCode.DBNull: return("null"); case TypeCode.Boolean: bool r = (bool)value; if (r) { return("true"); } else { return("false"); } case TypeCode.Char: return(ic.ToInt16(null).ToString()); case TypeCode.String: return(ic.ToString(null)); case TypeCode.Object: if (value is StringObject) { return(((StringObject)value).value); } else if (value is ScriptObject) { ScriptObject obj_value = (ScriptObject)value; if (obj_value.HasMethod("toString")) { return((string)obj_value.CallMethod("toString")); } else { return((string)ObjectPrototype.smartToString((JSObject)obj_value)); } } Console.WriteLine("value.GetType = {0}", value.GetType()); throw new NotImplementedException(); default: if (IsNumberTypeCode(tc)) { double val = ic.ToDouble(null); return(ToString(val)); } Console.WriteLine("tc = {0}", tc); throw new NotImplementedException(); } }