The Labs \ Source Viewer \ SSCLI \ Microsoft.JScript \ PreferredType

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace Microsoft.JScript
  16. {
  17.    
  18.     using Microsoft.JScript.Vsa;
  19.     using System;
  20.     using System.Globalization;
  21.     using System.Reflection;
  22.     using System.Reflection.Emit;
  23.     using System.Security;
  24.     using System.Text;
  25.     using System.Runtime.InteropServices;
  26.     using System.Diagnostics;
  27.    
  28.     enum PreferredType : int
  29.     {
  30.         Either,
  31.         Number,
  32.         String,
  33.         LocaleString
  34.     }
  35.    
  36.     public sealed class Convert
  37.     {
  38.        
  39.         public static bool IsBadIndex(AST ast)
  40.         {
  41.             Int32 i;
  42.             if (!(ast is ConstantWrapper))
  43.                 return false;
  44.             try {
  45.                 i = (Int32)CoerceT(((ConstantWrapper)ast).value, typeof(int));
  46.             }
  47.             catch {
  48.                 return true;
  49.             }
  50.             return i < 0;
  51.         }
  52.        
  53.         public static double CheckIfDoubleIsInteger(double d)
  54.         {
  55.             if (d == System.Math.Round(d))
  56.                 return d;
  57.             throw new JScriptException(JSError.TypeMismatch);
  58.         }
  59.        
  60.         public static float CheckIfSingleIsInteger(float s)
  61.         {
  62.             if (s == System.Math.Round(s))
  63.                 return s;
  64.             throw new JScriptException(JSError.TypeMismatch);
  65.         }
  66.        
  67.         //This routine converts a value to the desired type, if possible.
  68.         //It throws an exception if the conversion has not been provided for, as well as when loss of information will occur.
  69.         //For example, coercing 1.5 to type Int32 will throw an exception.
  70.         public static object Coerce(object value, object type)
  71.         {
  72.             return Convert.Coerce(value, type, false);
  73.         }
  74.        
  75.         static internal object Coerce(object value, object type, bool explicitOK)
  76.         {
  77.             TypeExpression te = type as TypeExpression;
  78.             if (te != null)
  79.                 type = te.ToIReflect();
  80.             TypedArray ta = type as TypedArray;
  81.             if (ta != null) {
  82.                 IReflect eIr = ta.elementType;
  83.                 int rank = ta.rank;
  84.                 Type eTy = eIr is Type ? (Type)eIr : eIr is ClassScope ? ((ClassScope)eIr).GetBakedSuperType() : typeof(object);
  85.                 ArrayObject ao = value as ArrayObject;
  86.                 if (ao != null)
  87.                     return ao.ToNativeArray(eTy);
  88.                 Array arr = value as Array;
  89.                 if (arr != null && arr.Rank == rank)
  90.                     type = Convert.ToType(TypedArray.ToRankString(rank), eTy);
  91.                 if (value == null || value is DBNull)
  92.                     return null;
  93.             }
  94.             ClassScope csc = type as ClassScope;
  95.             if (csc != null) {
  96.                 if (csc.HasInstance(value))
  97.                     return value;
  98.                 else {
  99.                     EnumDeclaration ed = csc.owner as EnumDeclaration;
  100.                     if (ed != null) {
  101.                         EnumWrapper ew = value as EnumWrapper;
  102.                         if (ew != null)
  103.                             if (ew.classScopeOrType == csc)
  104.                                 return value;
  105.                             else
  106.                                 throw new JScriptException(JSError.TypeMismatch);
  107.                         return new DeclaredEnumValue(Coerce(value, ed.baseType), null, csc);
  108.                     }
  109.                     if (value == null || value is DBNull)
  110.                         return null;
  111.                     throw new JScriptException(JSError.TypeMismatch);
  112.                 }
  113.             }
  114.             else if (!(type is Type))
  115.                 type = Convert.ToType(Runtime.TypeRefs, (IReflect)type);
  116.             else if (type == typeof(Type) && value is ClassScope)
  117.                 return value;
  118.             else if (((Type)type).IsEnum) {
  119.                 EnumWrapper ew = value as EnumWrapper;
  120.                 if (ew != null) {
  121.                     if (ew.classScopeOrType == type)
  122.                         return value;
  123.                     else
  124.                         throw new JScriptException(JSError.TypeMismatch);
  125.                 }
  126.                
  127.                 Type t = type as Type;
  128.                 return MetadataEnumValue.GetEnumValue(t, Convert.CoerceT(value, Convert.GetUnderlyingType(t), explicitOK));
  129.             }
  130.             return Convert.CoerceT(value, (Type)type, explicitOK);
  131.         }
  132.        
  133.         //This routine converts a value to the desired type, if possible.
  134.         //It throws an exception if the conversion has not been provided for, as well as when loss of information will occur.
  135.         //For example, coercing 1.5 to type Int32 will throw an exception.
  136.         static internal object CoerceT(object value, Type type)
  137.         {
  138.             return Convert.CoerceT(value, type, false);
  139.         }
  140.        
  141.         public static object CoerceT(object value, Type t, bool explicitOK)
  142.         {
  143.             if (t == typeof(object))
  144.                 return value;
  145.             if (t == typeof(string) && value is string)
  146.                 return value;
  147.             if (t.IsEnum && !(t is EnumBuilder) && !(t is TypeBuilder)) {
  148.                 IConvertible ic = Convert.GetIConvertible(value);
  149.                 TypeCode vc = Convert.GetTypeCode(value, ic);
  150.                 if (vc == TypeCode.String)
  151.                     return Enum.Parse(t, ic.ToString(CultureInfo.InvariantCulture));
  152.                 else {
  153.                     if (!explicitOK && vc != TypeCode.Empty) {
  154.                         Type vty = value.GetType();
  155.                         if (vty.IsEnum)
  156.                             if (vty != t)
  157.                                 throw new JScriptException(JSError.TypeMismatch);
  158.                             else
  159.                                 return value;
  160.                     }
  161.                     return Enum.ToObject(t, Convert.CoerceT(value, Convert.GetUnderlyingType(t), explicitOK));
  162.                 }
  163.             }
  164.             TypeCode c2 = Type.GetTypeCode(t);
  165.             if (c2 != TypeCode.Object)
  166.                 return Convert.Coerce2(value, c2, explicitOK);
  167.             if (value is ConcatString)
  168.                 value = value.ToString();
  169.             if (value == null || (value == DBNull.Value && t != typeof(object)) || value is Missing || value is System.Reflection.Missing)
  170.                 if (t.IsValueType) {
  171.                     // Activator.CreateInstance looks at the immediate caller to check if an internal type can
  172.                     // be created. Only allow public types in this assembly to be created.
  173.                     if (!t.IsPublic && t.Assembly == typeof(ActiveXObjectConstructor).Assembly)
  174.                         throw new JScriptException(JSError.CantCreateObject);
  175.                     return Activator.CreateInstance(t);
  176.                 }
  177.                 else
  178.                     return null;
  179.             else if (t.IsAssignableFrom(value.GetType()))
  180.                 return value;
  181.             else if (typeof(Delegate).IsAssignableFrom(t)) {
  182.                 if (value is Closure)
  183.                     return ((Closure)value).ConvertToDelegate(t);
  184.                 else if (value is FunctionWrapper)
  185.                     return ((FunctionWrapper)value).ConvertToDelegate(t);
  186.                 else if (value is FunctionObject)
  187.                     //called at compile-time from ConstantWrapper
  188.                     return value;
  189.                 //Do nothing, ConstantWrapper will do the right thing.
  190.             }
  191.             else if (value is ArrayObject && typeof(Array).IsAssignableFrom(t))
  192.                 return ((ArrayObject)value).ToNativeArray(t.GetElementType());
  193.             else if (value is Array && t == typeof(ArrayObject) && ((Array)value).Rank == 1) {
  194.                 if (Globals.contextEngine == null) {
  195.                     Globals.contextEngine = new VsaEngine(true);
  196.                     //ASP+ case
  197.                     Globals.contextEngine.InitVsaEngine("JS7://Microsoft.JScript.Vsa.VsaEngine", new DefaultVsaSite());
  198.                 }
  199.                 return Globals.contextEngine.GetOriginalArrayConstructor().ConstructWrapper((Array)value);
  200.             }
  201.             else if (value is ClassScope && t == typeof(Type))
  202.                 return ((ClassScope)value).GetTypeBuilderOrEnumBuilder();
  203.             else if (value is TypedArray && t == typeof(Type))
  204.                 return ((TypedArray)value).ToType();
  205.             //Look for a suitable op_Implicit or op_Explicit conversion
  206.             Type source_type = value.GetType();
  207.             MethodInfo meth = null;
  208.             if (explicitOK) {
  209.                 meth = t.GetMethod("op_Explicit", BindingFlags.ExactBinding | BindingFlags.Public | BindingFlags.Static, null, new Type[] {source_type}, null);
  210.                 if (meth != null && (meth.Attributes & MethodAttributes.SpecialName) != 0) {
  211.                     meth = new JSMethodInfo(meth);
  212.                     return meth.Invoke(null, BindingFlags.SuppressChangeType, null, new object[] {value}, null);
  213.                 }
  214.                 meth = Convert.GetToXXXXMethod(source_type, t, explicitOK);
  215.                 if (meth != null && (meth.Attributes & MethodAttributes.SpecialName) != 0) {
  216.                     meth = new JSMethodInfo(meth);
  217.                     if (meth.IsStatic)
  218.                         return meth.Invoke(null, BindingFlags.SuppressChangeType, null, new object[] {value}, null);
  219.                     else
  220.                         return meth.Invoke(value, BindingFlags.SuppressChangeType, null, new object[] {}, null);
  221.                 }
  222.             }
  223.             meth = t.GetMethod("op_Implicit", BindingFlags.ExactBinding | BindingFlags.Public | BindingFlags.Static, null, new Type[] {source_type}, null);
  224.             if (meth != null && (meth.Attributes & MethodAttributes.SpecialName) != 0) {
  225.                 meth = new JSMethodInfo(meth);
  226.                 return meth.Invoke(null, BindingFlags.SuppressChangeType, null, new object[] {value}, null);
  227.             }
  228.             meth = Convert.GetToXXXXMethod(source_type, t, false);
  229.             if (meth != null && (meth.Attributes & MethodAttributes.SpecialName) != 0) {
  230.                 meth = new JSMethodInfo(meth);
  231.                 if (meth.IsStatic)
  232.                     return meth.Invoke(null, BindingFlags.SuppressChangeType, null, new object[] {value}, null);
  233.                 else
  234.                     return meth.Invoke(value, BindingFlags.SuppressChangeType, null, new object[] {}, null);
  235.             }
  236.             if (t.IsByRef)
  237.                 return Convert.CoerceT(value, t.GetElementType());
  238.             Type vt = value.GetType();
  239.             throw new JScriptException(JSError.TypeMismatch);
  240.         }
  241.        
  242.         //Call this routine only for target TypeTokens other than Object and Empty
  243.         //It special cases the well known types with JScript specific conversion semantics
  244.         public static object Coerce2(object value, TypeCode target, bool truncationPermitted)
  245.         {
  246.             if (truncationPermitted)
  247.                 return Coerce2WithTruncationPermitted(value, target);
  248.             return Coerce2WithNoTrunctation(value, target);
  249.         }
  250.        
  251.         private static object Coerce2WithNoTrunctation(object value, TypeCode target)
  252.         {
  253.             if (value is EnumWrapper)
  254.                 value = ((EnumWrapper)value).value;
  255.             if (value is ConstantWrapper)
  256.                 value = ((ConstantWrapper)value).value;
  257.             try {
  258.                 checked {
  259.                     IConvertible ic = Convert.GetIConvertible(value);
  260.                     switch (Convert.GetTypeCode(value, ic)) {
  261.                         case TypeCode.Empty:
  262.                             switch (target) {
  263.                                 case TypeCode.DBNull:
  264.                                     return DBNull.Value;
  265.                                 case TypeCode.Boolean:
  266.                                     return false;
  267.                                 case TypeCode.Char:
  268.                                     return (char)0;
  269.                                 case TypeCode.SByte:
  270.                                     return (sbyte)0;
  271.                                 case TypeCode.Byte:
  272.                                     return (byte)0;
  273.                                 case TypeCode.Int16:
  274.                                     return (Int16)0;
  275.                                 case TypeCode.UInt16:
  276.                                     return (UInt16)0;
  277.                                 case TypeCode.Int32:
  278.                                     return (Int32)0;
  279.                                 case TypeCode.UInt32:
  280.                                     return (UInt32)0;
  281.                                 case TypeCode.Int64:
  282.                                     return (Int64)0;
  283.                                 case TypeCode.UInt64:
  284.                                     return (UInt64)0;
  285.                                 case TypeCode.Single:
  286.                                     return Single.NaN;
  287.                                 case TypeCode.Double:
  288.                                     return Double.NaN;
  289.                                 case TypeCode.Decimal:
  290.                                     return (decimal)0;
  291.                                 case TypeCode.DateTime:
  292.                                     return new DateTime((Int64)0);
  293.                                 case TypeCode.String:
  294.                                     return null;
  295.                             }
  296.                             break;
  297.                         case TypeCode.Object:
  298.                            
  299.                             if (value is System.Reflection.Missing || (value is Missing && target != TypeCode.Object))
  300.                                 goto case TypeCode.Empty;
  301.                             switch (target) {
  302.                                 case TypeCode.Boolean:
  303.                                     return Convert.ToBoolean(value, false);
  304.                                 case TypeCode.Char:
  305.                                 case TypeCode.SByte:
  306.                                 case TypeCode.Byte:
  307.                                 case TypeCode.Int16:
  308.                                 case TypeCode.UInt16:
  309.                                 case TypeCode.Int32:
  310.                                 case TypeCode.UInt32:
  311.                                 case TypeCode.Int64:
  312.                                 case TypeCode.UInt64:
  313.                                 case TypeCode.Single:
  314.                                 case TypeCode.Double:
  315.                                 case TypeCode.Decimal:
  316.                                     return Coerce2WithNoTrunctation(Convert.ToNumber(value, ic), target);
  317.                                 case TypeCode.DateTime:
  318.                                     if (value is DateObject)
  319.                                         return DatePrototype.getVarDate((DateObject)value);
  320.                                     else
  321.                                         return Coerce2WithNoTrunctation(Convert.ToNumber(value, ic), target);
  322.                                     break;
  323.                                 case TypeCode.String:
  324.                                     return Convert.ToString(value, ic);
  325.                             }
  326.                             break;
  327.                         case TypeCode.DBNull:
  328.                            
  329.                             switch (target) {
  330.                                 case TypeCode.DBNull:
  331.                                     return DBNull.Value;
  332.                                 case TypeCode.Boolean:
  333.                                     return false;
  334.                                 case TypeCode.Char:
  335.                                     return (char)0;
  336.                                 case TypeCode.SByte:
  337.                                     return (sbyte)0;
  338.                                 case TypeCode.Byte:
  339.                                     return (byte)0;
  340.                                 case TypeCode.Int16:
  341.                                     return (Int16)0;
  342.                                 case TypeCode.UInt16:
  343.                                     return (UInt16)0;
  344.                                 case TypeCode.Int32:
  345.                                     return (Int32)0;
  346.                                 case TypeCode.UInt32:
  347.                                     return (UInt32)0;
  348.                                 case TypeCode.Int64:
  349.                                     return (Int64)0;
  350.                                 case TypeCode.UInt64:
  351.                                     return (UInt64)0;
  352.                                 case TypeCode.Single:
  353.                                     return (float)0;
  354.                                 case TypeCode.Double:
  355.                                     return (double)0;
  356.                                 case TypeCode.Decimal:
  357.                                     return (decimal)0;
  358.                                 case TypeCode.DateTime:
  359.                                     return new DateTime((Int64)0);
  360.                                 case TypeCode.String:
  361.                                     return null;
  362.                             }
  363.                             break;
  364.                         case TypeCode.Boolean:
  365.                            
  366.                             bool b = ic.ToBoolean(null);
  367.                             int bi = b ? 1 : 0;
  368.                             switch (target) {
  369.                                 case TypeCode.Boolean:
  370.                                     return b;
  371.                                 case TypeCode.Char:
  372.                                     return (char)bi;
  373.                                 case TypeCode.SByte:
  374.                                     return (sbyte)bi;
  375.                                 case TypeCode.Byte:
  376.                                     return (byte)bi;
  377.                                 case TypeCode.Int16:
  378.                                     return (Int16)bi;
  379.                                 case TypeCode.UInt16:
  380.                                     return (UInt16)bi;
  381.                                 case TypeCode.Int32:
  382.                                     return (Int32)bi;
  383.                                 case TypeCode.UInt32:
  384.                                     return (UInt32)bi;
  385.                                 case TypeCode.Int64:
  386.                                     return (Int64)bi;
  387.                                 case TypeCode.UInt64:
  388.                                     return (UInt64)bi;
  389.                                 case TypeCode.Single:
  390.                                     return (float)bi;
  391.                                 case TypeCode.Double:
  392.                                     return (double)bi;
  393.                                 case TypeCode.Decimal:
  394.                                     return (decimal)bi;
  395.                                 case TypeCode.DateTime:
  396.                                     return new DateTime((Int64)bi);
  397.                                 case TypeCode.String:
  398.                                     return b ? "true" : "false";
  399.                             }
  400.                             break;
  401.                         case TypeCode.Char:
  402.                            
  403.                             char ch = ic.ToChar(null);
  404.                             UInt16 us = (UInt16)ch;
  405.                             switch (target) {
  406.                                 case TypeCode.Boolean:
  407.                                     return us != 0;
  408.                                 case TypeCode.Char:
  409.                                     return ch;
  410.                                 case TypeCode.SByte:
  411.                                     return (sbyte)us;
  412.                                 case TypeCode.Byte:
  413.                                     return (byte)us;
  414.                                 case TypeCode.Int16:
  415.                                     return (Int16)us;
  416.                                 case TypeCode.UInt16:
  417.                                     return us;
  418.                                 case TypeCode.Int32:
  419.                                     return (Int32)us;
  420.                                 case TypeCode.UInt32:
  421.                                     return (UInt32)us;
  422.                                 case TypeCode.Int64:
  423.                                     return (Int64)us;
  424.                                 case TypeCode.UInt64:
  425.                                     return (UInt64)us;
  426.                                 case TypeCode.Single:
  427.                                     return (float)us;
  428.                                 case TypeCode.Double:
  429.                                     return (double)us;
  430.                                 case TypeCode.Decimal:
  431.                                     return (decimal)us;
  432.                                 case TypeCode.DateTime:
  433.                                     return new DateTime((Int64)us);
  434.                                 case TypeCode.String:
  435.                                     return Char.ToString(ch);
  436.                             }
  437.                             break;
  438.                         case TypeCode.SByte:
  439.                            
  440.                             sbyte sb = ic.ToSByte(null);
  441.                             switch (target) {
  442.                                 case TypeCode.Boolean:
  443.                                     return sb != 0;
  444.                                 case TypeCode.Char:
  445.                                     return (char)sb;
  446.                                 case TypeCode.SByte:
  447.                                     return sb;
  448.                                 case TypeCode.Byte:
  449.                                     return (byte)sb;
  450.                                 case TypeCode.Int16:
  451.                                     return (Int16)sb;
  452.                                 case TypeCode.UInt16:
  453.                                     return (UInt16)sb;
  454.                                 case TypeCode.Int32:
  455.                                     return (Int32)sb;
  456.                                 case TypeCode.UInt32:
  457.                                     return (UInt32)sb;
  458.                                 case TypeCode.Int64:
  459.                                     return (Int64)sb;
  460.                                 case TypeCode.UInt64:
  461.                                     return (UInt64)sb;
  462.                                 case TypeCode.Single:
  463.                                     return (float)sb;
  464.                                 case TypeCode.Double:
  465.                                     return (double)sb;
  466.                                 case TypeCode.Decimal:
  467.                                     return (decimal)sb;
  468.                                 case TypeCode.DateTime:
  469.                                     return new DateTime((Int64)sb);
  470.                                 case TypeCode.String:
  471.                                     return sb.ToString(CultureInfo.InvariantCulture);
  472.                             }
  473.                             break;
  474.                         case TypeCode.Byte:
  475.                            
  476.                             byte ub = ic.ToByte(null);
  477.                             switch (target) {
  478.                                 case TypeCode.Boolean:
  479.                                     return ub != 0;
  480.                                 case TypeCode.Char:
  481.                                     return (char)ub;
  482.                                 case TypeCode.SByte:
  483.                                     return (sbyte)ub;
  484.                                 case TypeCode.Byte:
  485.                                     return ub;
  486.                                 case TypeCode.Int16:
  487.                                     return (Int16)ub;
  488.                                 case TypeCode.UInt16:
  489.                                     return (UInt16)ub;
  490.                                 case TypeCode.Int32:
  491.                                     return (Int32)ub;
  492.                                 case TypeCode.UInt32:
  493.                                     return (UInt32)ub;
  494.                                 case TypeCode.Int64:
  495.                                     return (Int64)ub;
  496.                                 case TypeCode.UInt64:
  497.                                     return (UInt64)ub;
  498.                                 case TypeCode.Single:
  499.                                     return (float)ub;
  500.                                 case TypeCode.Double:
  501.                                     return (double)ub;
  502.                                 case TypeCode.Decimal:
  503.                                     return (decimal)ub;
  504.                                 case TypeCode.DateTime:
  505.                                     return new DateTime((Int64)ub);
  506.                                 case TypeCode.String:
  507.                                     return ub.ToString(CultureInfo.InvariantCulture);
  508.                             }
  509.                             break;
  510.                         case TypeCode.Int16:
  511.                            
  512.                             Int16 s = ic.ToInt16(null);
  513.                             switch (target) {
  514.                                 case TypeCode.Boolean:
  515.                                     return s != 0;
  516.                                 case TypeCode.Char:
  517.                                     return (char)s;
  518.                                 case TypeCode.SByte:
  519.                                     return (sbyte)s;
  520.                                 case TypeCode.Byte:
  521.                                     return (byte)s;
  522.                                 case TypeCode.Int16:
  523.                                     return s;
  524.                                 case TypeCode.UInt16:
  525.                                     return (UInt16)s;
  526.                                 case TypeCode.Int32:
  527.                                     return (Int32)s;
  528.                                 case TypeCode.UInt32:
  529.                                     return (UInt32)s;
  530.                                 case TypeCode.Int64:
  531.                                     return (Int64)s;
  532.                                 case TypeCode.UInt64:
  533.                                     return (UInt64)s;
  534.                                 case TypeCode.Single:
  535.                                     return (float)s;
  536.                                 case TypeCode.Double:
  537.                                     return (double)s;
  538.                                 case TypeCode.Decimal:
  539.                                     return (decimal)s;
  540.                                 case TypeCode.DateTime:
  541.                                     return new DateTime((Int64)s);
  542.                                 case TypeCode.String:
  543.                                     return s.ToString(CultureInfo.InvariantCulture);
  544.                             }
  545.                             break;
  546.                         case TypeCode.UInt16:
  547.                            
  548.                             us = ic.ToUInt16(null);
  549.                             switch (target) {
  550.                                 case TypeCode.Boolean:
  551.                                     return us != 0;
  552.                                 case TypeCode.Char:
  553.                                     return (char)us;
  554.                                 case TypeCode.SByte:
  555.                                     return (sbyte)us;
  556.                                 case TypeCode.Byte:
  557.                                     return (byte)us;
  558.                                 case TypeCode.Int16:
  559.                                     return (Int16)us;
  560.                                 case TypeCode.UInt16:
  561.                                     return us;
  562.                                 case TypeCode.Int32:
  563.                                     return (Int32)us;
  564.                                 case TypeCode.UInt32:
  565.                                     return (UInt32)us;
  566.                                 case TypeCode.Int64:
  567.                                     return (Int64)us;
  568.                                 case TypeCode.UInt64:
  569.                                     return (UInt64)us;
  570.                                 case TypeCode.Single:
  571.                                     return (float)us;
  572.                                 case TypeCode.Double:
  573.                                     return (double)us;
  574.                                 case TypeCode.Decimal:
  575.                                     return (decimal)us;
  576.                                 case TypeCode.DateTime:
  577.                                     return new DateTime((Int64)us);
  578.                                 case TypeCode.String:
  579.                                     return us.ToString(CultureInfo.InvariantCulture);
  580.                             }
  581.                             break;
  582.                         case TypeCode.Int32:
  583.                            
  584.                             Int32 i = ic.ToInt32(null);
  585.                             switch (target) {
  586.                                 case TypeCode.Boolean:
  587.                                     return i != 0;
  588.                                 case TypeCode.Char:
  589.                                     return (char)i;
  590.                                 case TypeCode.SByte:
  591.                                     return (sbyte)i;
  592.                                 case TypeCode.Byte:
  593.                                     return (byte)i;
  594.                                 case TypeCode.Int16:
  595.                                     return (Int16)i;
  596.                                 case TypeCode.UInt16:
  597.                                     return (UInt16)i;
  598.                                 case TypeCode.Int32:
  599.                                     return i;
  600.                                 case TypeCode.UInt32:
  601.                                     return (UInt32)i;
  602.                                 case TypeCode.Int64:
  603.                                     return (Int64)i;
  604.                                 case TypeCode.UInt64:
  605.                                     return (UInt64)i;
  606.                                 case TypeCode.Single:
  607.                                     return (float)i;
  608.                                 case TypeCode.Double:
  609.                                     return (double)i;
  610.                                 case TypeCode.Decimal:
  611.                                     return (decimal)i;
  612.                                 case TypeCode.DateTime:
  613.                                     return new DateTime((Int64)i);
  614.                                 case TypeCode.String:
  615.                                     return i.ToString(CultureInfo.InvariantCulture);
  616.                             }
  617.                             break;
  618.                         case TypeCode.UInt32:
  619.                            
  620.                             UInt32 ui = ic.ToUInt32(null);
  621.                             switch (target) {
  622.                                 case TypeCode.Boolean:
  623.                                     return ui != 0;
  624.                                 case TypeCode.Char:
  625.                                     return (char)ui;
  626.                                 case TypeCode.SByte:
  627.                                     return (sbyte)ui;
  628.                                 case TypeCode.Byte:
  629.                                     return (byte)ui;
  630.                                 case TypeCode.Int16:
  631.                                     return (Int16)ui;
  632.                                 case TypeCode.UInt16:
  633.                                     return (UInt16)ui;
  634.                                 case TypeCode.Int32:
  635.                                     return (Int32)ui;
  636.                                 case TypeCode.UInt32:
  637.                                     return ui;
  638.                                 case TypeCode.Int64:
  639.                                     return (Int64)ui;
  640.                                 case TypeCode.UInt64:
  641.                                     return (UInt64)ui;
  642.                                 case TypeCode.Single:
  643.                                     return (float)ui;
  644.                                 case TypeCode.Double:
  645.                                     return (double)ui;
  646.                                 case TypeCode.Decimal:
  647.                                     return (decimal)ui;
  648.                                 case TypeCode.DateTime:
  649.                                     return new DateTime((Int64)ui);
  650.                                 case TypeCode.String:
  651.                                     return ui.ToString(CultureInfo.InvariantCulture);
  652.                             }
  653.                             break;
  654.                         case TypeCode.Int64:
  655.                            
  656.                             Int64 l = ic.ToInt64(null);
  657.                             switch (target) {
  658.                                 case TypeCode.Boolean:
  659.                                     return l != 0;
  660.                                 case TypeCode.Char:
  661.                                     return (char)l;
  662.                                 case TypeCode.SByte:
  663.                                     return (sbyte)l;
  664.                                 case TypeCode.Byte:
  665.                                     return (byte)l;
  666.                                 case TypeCode.Int16:
  667.                                     return (Int16)l;
  668.                                 case TypeCode.UInt16:
  669.                                     return (UInt16)l;
  670.                                 case TypeCode.Int32:
  671.                                     return (Int32)l;
  672.                                 case TypeCode.UInt32:
  673.                                     return (UInt32)l;
  674.                                 case TypeCode.Int64:
  675.                                     return l;
  676.                                 case TypeCode.UInt64:
  677.                                     return (UInt64)l;
  678.                                 case TypeCode.Single:
  679.                                     return (float)l;
  680.                                 case TypeCode.Double:
  681.                                     return (double)l;
  682.                                 case TypeCode.Decimal:
  683.                                     return (decimal)l;
  684.                                 case TypeCode.DateTime:
  685.                                     return new DateTime(l);
  686.                                 case TypeCode.String:
  687.                                     return l.ToString(CultureInfo.InvariantCulture);
  688.                             }
  689.                             break;
  690.                         case TypeCode.UInt64:
  691.                            
  692.                             UInt64 ul = ic.ToUInt64(null);
  693.                             switch (target) {
  694.                                 case TypeCode.Boolean:
  695.                                     return ul != 0;
  696.                                 case TypeCode.Char:
  697.                                     return (char)ul;
  698.                                 case TypeCode.SByte:
  699.                                     return (sbyte)ul;
  700.                                 case TypeCode.Byte:
  701.                                     return (byte)ul;
  702.                                 case TypeCode.Int16:
  703.                                     return (Int16)ul;
  704.                                 case TypeCode.UInt16:
  705.                                     return (UInt16)ul;
  706.                                 case TypeCode.Int32:
  707.                                     return (Int32)ul;
  708.                                 case TypeCode.UInt32:
  709.                                     return (UInt32)ul;
  710.                                 case TypeCode.Int64:
  711.                                     return (Int64)ul;
  712.                                 case TypeCode.UInt64:
  713.                                     return ul;
  714.                                 case TypeCode.Single:
  715.                                     return (float)ul;
  716.                                 case TypeCode.Double:
  717.                                     return (double)ul;
  718.                                 case TypeCode.Decimal:
  719.                                     return (decimal)ul;
  720.                                 case TypeCode.DateTime:
  721.                                     return new DateTime((Int64)ul);
  722.                                 case TypeCode.String:
  723.                                     return ul.ToString(CultureInfo.InvariantCulture);
  724.                             }
  725.                             break;
  726.                         case TypeCode.Single:
  727.                            
  728.                             float f = ic.ToSingle(null);
  729.                             switch (target) {
  730.                                 case TypeCode.Boolean:
  731.                                     if (f != f)
  732.                                         return false;
  733.                                     else
  734.                                         return f != 0;
  735.                                     break;
  736.                                 case TypeCode.Single:
  737.                                     return f;
  738.                                 case TypeCode.Double:
  739.                                     return (double)f;
  740.                                 case TypeCode.Decimal:
  741.                                     return (decimal)f;
  742.                                 case TypeCode.String:
  743.                                     return Convert.ToString((double)f);
  744.                                 default:
  745.                                     if (System.Math.Round(f) == f) {
  746.                                         switch (target) {
  747.                                             case TypeCode.Char:
  748.                                                 return (char)f;
  749.                                             case TypeCode.SByte:
  750.                                                 return (sbyte)f;
  751.                                             case TypeCode.Byte:
  752.                                                 return (byte)f;
  753.                                             case TypeCode.Int16:
  754.                                                 return (Int16)f;
  755.                                             case TypeCode.UInt16:
  756.                                                 return (UInt16)f;
  757.                                             case TypeCode.Int32:
  758.                                                 return (Int32)f;
  759.                                             case TypeCode.UInt32:
  760.                                                 return (UInt32)f;
  761.                                             case TypeCode.Int64:
  762.                                                 return (Int64)f;
  763.                                             case TypeCode.UInt64:
  764.                                                 return (UInt64)f;
  765.                                             case TypeCode.DateTime:
  766.                                                 return new DateTime((Int64)f);
  767.                                         }
  768.                                     }
  769.                                     break;
  770.                             }
  771.                             break;
  772.                         case TypeCode.Double:
  773.                            
  774.                             double d = ic.ToDouble(null);
  775.                             switch (target) {
  776.                                 case TypeCode.Boolean:
  777.                                     return Convert.ToBoolean(d);
  778.                                 case TypeCode.Single:
  779.                                     return (float)d;
  780.                                 case TypeCode.Double:
  781.                                     return d;
  782.                                 case TypeCode.Decimal:
  783.                                     return (decimal)d;
  784.                                 case TypeCode.String:
  785.                                     return Convert.ToString(d);
  786.                                 default:
  787.                                     if (System.Math.Round(d) == d) {
  788.                                         switch (target) {
  789.                                             case TypeCode.Char:
  790.                                                 return (char)d;
  791.                                             case TypeCode.SByte:
  792.                                                 return (sbyte)d;
  793.                                             case TypeCode.Byte:
  794.                                                 return (byte)d;
  795.                                             case TypeCode.Int16:
  796.                                                 return (Int16)d;
  797.                                             case TypeCode.UInt16:
  798.                                                 return (UInt16)d;
  799.                                             case TypeCode.Int32:
  800.                                                 return (Int32)d;
  801.                                             case TypeCode.UInt32:
  802.                                                 return (UInt32)d;
  803.                                             case TypeCode.Int64:
  804.                                                 return (Int64)d;
  805.                                             case TypeCode.UInt64:
  806.                                                 return (UInt64)d;
  807.                                             case TypeCode.DateTime:
  808.                                                 return new DateTime((Int64)d);
  809.                                         }
  810.                                     }
  811.                                     break;
  812.                             }
  813.                             break;
  814.                         case TypeCode.Decimal:
  815.                            
  816.                             decimal dec = ic.ToDecimal(null);
  817.                             switch (target) {
  818.                                 case TypeCode.Boolean:
  819.                                     return dec != 0;
  820.                                 case TypeCode.Char:
  821.                                     return (char)Decimal.ToUInt16(dec);
  822.                                 case TypeCode.SByte:
  823.                                     return Decimal.ToSByte(dec);
  824.                                 case TypeCode.Byte:
  825.                                     return Decimal.ToByte(dec);
  826.                                 case TypeCode.Int16:
  827.                                     return Decimal.ToInt16(dec);
  828.                                 case TypeCode.UInt16:
  829.                                     return Decimal.ToUInt16(dec);
  830.                                 case TypeCode.Int32:
  831.                                     return Decimal.ToInt32(dec);
  832.                                 case TypeCode.UInt32:
  833.                                     return Decimal.ToUInt32(dec);
  834.                                 case TypeCode.Int64:
  835.                                     return Decimal.ToInt64(dec);
  836.                                 case TypeCode.UInt64:
  837.                                     return Decimal.ToUInt64(dec);
  838.                                 case TypeCode.Single:
  839.                                     return Decimal.ToSingle(dec);
  840.                                 case TypeCode.Double:
  841.                                     return Decimal.ToDouble(dec);
  842.                                 case TypeCode.Decimal:
  843.                                     return dec;
  844.                                 case TypeCode.DateTime:
  845.                                     return new DateTime(Decimal.ToInt64(dec));
  846.                                 case TypeCode.String:
  847.                                     return dec.ToString(CultureInfo.InvariantCulture);
  848.                             }
  849.                             break;
  850.                         case TypeCode.DateTime:
  851.                            
  852.                             DateTime dt = ic.ToDateTime(null);
  853.                             switch (target) {
  854.                                 case TypeCode.Boolean:
  855.                                 case TypeCode.Char:
  856.                                 case TypeCode.SByte:
  857.                                 case TypeCode.Byte:
  858.                                 case TypeCode.Int16:
  859.                                 case TypeCode.UInt16:
  860.                                 case TypeCode.Int32:
  861.                                 case TypeCode.UInt32:
  862.                                 case TypeCode.Int64:
  863.                                 case TypeCode.UInt64:
  864.                                 case TypeCode.Single:
  865.                                 case TypeCode.Double:
  866.                                 case TypeCode.Decimal:
  867.                                     return Coerce2WithNoTrunctation(dt.Ticks, target);
  868.                                 case TypeCode.DateTime:
  869.                                     return dt;
  870.                                 case TypeCode.String:
  871.                                     return dt.ToString(CultureInfo.InvariantCulture);
  872.                             }
  873.                             break;
  874.                         case TypeCode.String:
  875.                            
  876.                             string str = ic.ToString(null);
  877.                             switch (target) {
  878.                                 case TypeCode.Boolean:
  879.                                     return Convert.ToBoolean(str, false);
  880.                                 case TypeCode.Char:
  881.                                     if (str.Length == 1)
  882.                                         return str[0];
  883.                                     throw new JScriptException(JSError.TypeMismatch);
  884.                                     break;
  885.                                 case TypeCode.SByte:
  886.                                 case TypeCode.Byte:
  887.                                 case TypeCode.Int16:
  888.                                 case TypeCode.UInt16:
  889.                                 case TypeCode.Int32:
  890.                                 case TypeCode.UInt32:
  891.                                 case TypeCode.Double:
  892.                                     return Coerce2WithNoTrunctation(Convert.ToNumber(str), target);
  893.                                 case TypeCode.Single:
  894.                                     try {
  895.                                         return Single.Parse(str, CultureInfo.InvariantCulture);
  896.                                     }
  897.                                     catch {
  898.                                         goto case TypeCode.Double;
  899.                                     }
  900.                                     break;
  901.                                 case TypeCode.Int64:
  902.                                     try {
  903.                                         return Int64.Parse(str, CultureInfo.InvariantCulture);
  904.                                     }
  905.                                     catch {
  906.                                         goto case TypeCode.Double;
  907.                                     }
  908.                                     break;
  909.                                 case TypeCode.UInt64:
  910.                                     try {
  911.                                         return UInt64.Parse(str, CultureInfo.InvariantCulture);
  912.                                     }
  913.                                     catch {
  914.                                         goto case TypeCode.Double;
  915.                                     }
  916.                                     break;
  917.                                 case TypeCode.Decimal:
  918.                                     try {
  919.                                         return Decimal.Parse(str, CultureInfo.InvariantCulture);
  920.                                     }
  921.                                     catch {
  922.                                         goto case TypeCode.Double;
  923.                                     }
  924.                                     break;
  925.                                 case TypeCode.DateTime:
  926.                                     try {
  927.                                         return DateTime.Parse(str, CultureInfo.InvariantCulture);
  928.                                     }
  929.                                     catch {
  930.                                         return DatePrototype.getVarDate(DateConstructor.ob.CreateInstance(DatePrototype.ParseDate(str)));
  931.                                     }
  932.                                     break;
  933.                                 case TypeCode.String:
  934.                                     return str;
  935.                             }
  936.                             break;
  937.                     }
  938.                 }
  939.             }
  940.             catch (OverflowException) {
  941.             }
  942.             throw new JScriptException(JSError.TypeMismatch);
  943.         }
  944.        
  945.         //Call this routine only for target TypeTokens other than Object and Empty
  946.         //It special cases the well known types with JScript specific conversion semantics
  947.         private static object Coerce2WithTruncationPermitted(object value, TypeCode target)
  948.         {
  949.             if (value is EnumWrapper)
  950.                 value = ((EnumWrapper)value).value;
  951.             if (value is ConstantWrapper)
  952.                 value = ((ConstantWrapper)value).value;
  953.             IConvertible ic = Convert.GetIConvertible(value);
  954.             switch (Convert.GetTypeCode(value, ic)) {
  955.                 case TypeCode.Empty:
  956.                     switch (target) {
  957.                         case TypeCode.DBNull:
  958.                             return DBNull.Value;
  959.                         case TypeCode.Boolean:
  960.                             return false;
  961.                         case TypeCode.Char:
  962.                             return (char)0;
  963.                         case TypeCode.SByte:
  964.                             return (sbyte)0;
  965.                         case TypeCode.Byte:
  966.                             return (byte)0;
  967.                         case TypeCode.Int16:
  968.                             return (Int16)0;
  969.                         case TypeCode.UInt16:
  970.                             return (UInt16)0;
  971.                         case TypeCode.Int32:
  972.                             return (Int32)0;
  973.                         case TypeCode.UInt32:
  974.                             return (UInt32)0;
  975.                         case TypeCode.Int64:
  976.                             return (Int64)0;
  977.                         case TypeCode.UInt64:
  978.                             return (UInt64)0;
  979.                         case TypeCode.Single:
  980.                             return Single.NaN;
  981.                         case TypeCode.Double:
  982.                             return Double.NaN;
  983.                         case TypeCode.Decimal:
  984.                             return (decimal)0;
  985.                         case TypeCode.DateTime:
  986.                             return new DateTime((Int64)0);
  987.                         case TypeCode.String:
  988.                             return "undefined";
  989.                     }
  990.                     break;
  991.                 case TypeCode.Object:
  992.                    
  993.                     if (value is System.Reflection.Missing || (value is Missing && target != TypeCode.Object))
  994.                         goto case TypeCode.Empty;
  995.                     switch (target) {
  996.                         case TypeCode.Boolean:
  997.                             return Convert.ToBoolean(value, ic);
  998.                         case TypeCode.Char:
  999.                         case TypeCode.SByte:
  1000.                         case TypeCode.Byte:
  1001.                         case TypeCode.Int16:
  1002.                         case TypeCode.UInt16:
  1003.                         case TypeCode.Int32:
  1004.                         case TypeCode.UInt32:
  1005.                         case TypeCode.Int64:
  1006.                         case TypeCode.UInt64:
  1007.                         case TypeCode.Single:
  1008.                         case TypeCode.Double:
  1009.                         case TypeCode.Decimal:
  1010.                             return Coerce2WithTruncationPermitted(Convert.ToNumber(value, ic), target);
  1011.                         case TypeCode.DateTime:
  1012.                             if (value is DateObject)
  1013.                                 return DatePrototype.getVarDate((DateObject)value);
  1014.                             else
  1015.                                 return Coerce2WithTruncationPermitted(Convert.ToNumber(value, ic), target);
  1016.                             break;
  1017.                         case TypeCode.String:
  1018.                             return Convert.ToString(value, ic);
  1019.                     }
  1020.                     break;
  1021.                 case TypeCode.DBNull:
  1022.                    
  1023.                     switch (target) {
  1024.                         case TypeCode.DBNull:
  1025.                             return DBNull.Value;
  1026.                         case TypeCode.Boolean:
  1027.                             return false;
  1028.                         case TypeCode.Char:
  1029.                             return (char)0;
  1030.                         case TypeCode.SByte:
  1031.                             return (sbyte)0;
  1032.                         case TypeCode.Byte:
  1033.                             return (byte)0;
  1034.                         case TypeCode.Int16:
  1035.                             return (Int16)0;
  1036.                         case TypeCode.UInt16:
  1037.                             return (UInt16)0;
  1038.                         case TypeCode.Int32:
  1039.                             return (Int32)0;
  1040.                         case TypeCode.UInt32:
  1041.                             return (UInt32)0;
  1042.                         case TypeCode.Int64:
  1043.                             return (Int64)0;
  1044.                         case TypeCode.UInt64:
  1045.                             return (UInt64)0;
  1046.                         case TypeCode.Single:
  1047.                             return (float)0;
  1048.                         case TypeCode.Double:
  1049.                             return (double)0;
  1050.                         case TypeCode.Decimal:
  1051.                             return (decimal)0;
  1052.                         case TypeCode.DateTime:
  1053.                             return new DateTime((Int64)0);
  1054.                         case TypeCode.String:
  1055.                             return "null";
  1056.                     }
  1057.                     break;
  1058.                 case TypeCode.Boolean:
  1059.                    
  1060.                     bool b = ic.ToBoolean(null);
  1061.                     int bi = b ? 1 : 0;
  1062.                     switch (target) {
  1063.                         case TypeCode.Boolean:
  1064.                             return b;
  1065.                         case TypeCode.Char:
  1066.                             return (char)bi;
  1067.                         case TypeCode.SByte:
  1068.                             return (sbyte)bi;
  1069.                         case TypeCode.Byte:
  1070.                             return (byte)bi;
  1071.                         case TypeCode.Int16:
  1072.                             return (Int16)bi;
  1073.                         case TypeCode.UInt16:
  1074.                             return (UInt16)bi;
  1075.                         case TypeCode.Int32:
  1076.                             return (Int32)bi;
  1077.                         case TypeCode.UInt32:
  1078.                             return (UInt32)bi;
  1079.                         case TypeCode.Int64:
  1080.                             return (Int64)bi;
  1081.                         case TypeCode.UInt64:
  1082.                             return (UInt64)bi;
  1083.                         case TypeCode.Single:
  1084.                             return (float)bi;
  1085.                         case TypeCode.Double:
  1086.                             return (double)bi;
  1087.                         case TypeCode.Decimal:
  1088.                             return (decimal)bi;
  1089.                         case TypeCode.DateTime:
  1090.                             return new DateTime((Int64)bi);
  1091.                         case TypeCode.String:
  1092.                             return b ? "true" : "false";
  1093.                     }
  1094.                     break;
  1095.                 case TypeCode.Char:
  1096.                    
  1097.                     char ch = ic.ToChar(null);
  1098.                     UInt16 us = (UInt16)ch;
  1099.                     switch (target) {
  1100.                         case TypeCode.Boolean:
  1101.                             return us != 0;
  1102.                         case TypeCode.Char:
  1103.                             return ch;
  1104.                         case TypeCode.SByte:
  1105.                             return (sbyte)us;
  1106.                         case TypeCode.Byte:
  1107.                             return (byte)us;
  1108.                         case TypeCode.Int16:
  1109.                             return (Int16)us;
  1110.                         case TypeCode.UInt16:
  1111.                             return us;
  1112.                         case TypeCode.Int32:
  1113.                             return (Int32)us;
  1114.                         case TypeCode.UInt32:
  1115.                             return (UInt32)us;
  1116.                         case TypeCode.Int64:
  1117.                             return (Int64)us;
  1118.                         case TypeCode.UInt64:
  1119.                             return (UInt64)us;
  1120.                         case TypeCode.Single:
  1121.                             return (float)us;
  1122.                         case TypeCode.Double:
  1123.                             return (double)us;
  1124.                         case TypeCode.Decimal:
  1125.                             return (decimal)us;
  1126.                         case TypeCode.DateTime:
  1127.                             return new DateTime((Int64)us);
  1128.                         case TypeCode.String:
  1129.                             return Char.ToString(ch);
  1130.                     }
  1131.                     break;
  1132.                 case TypeCode.SByte:
  1133.                    
  1134.                     sbyte sb = ic.ToSByte(null);
  1135.                     switch (target) {
  1136.                         case TypeCode.Boolean:
  1137.                             return sb != 0;
  1138.                         case TypeCode.Char:
  1139.                             return (char)sb;
  1140.                         case TypeCode.SByte:
  1141.                             return sb;
  1142.                         case TypeCode.Byte:
  1143.                             return (byte)sb;
  1144.                         case TypeCode.Int16:
  1145.                             return (Int16)sb;
  1146.                         case TypeCode.UInt16:
  1147.                             return (UInt16)sb;
  1148.                         case TypeCode.Int32:
  1149.                             return (Int32)sb;
  1150.                         case TypeCode.UInt32:
  1151.                             return (UInt32)sb;
  1152.                         case TypeCode.Int64:
  1153.                             return (Int64)sb;
  1154.                         case TypeCode.UInt64:
  1155.                             return (UInt64)sb;
  1156.                         case TypeCode.Single:
  1157.                             return (float)sb;
  1158.                         case TypeCode.Double:
  1159.                             return (double)sb;
  1160.                         case TypeCode.Decimal:
  1161.                             return (decimal)sb;
  1162.                         case TypeCode.DateTime:
  1163.                             return new DateTime((Int64)sb);
  1164.                         case TypeCode.String:
  1165.                             return sb.ToString(CultureInfo.InvariantCulture);
  1166.                     }
  1167.                     break;
  1168.                 case TypeCode.Byte:
  1169.                    
  1170.                     byte ub = ic.ToByte(null);
  1171.                     switch (target) {
  1172.                         case TypeCode.Boolean:
  1173.                             return ub != 0;
  1174.                         case TypeCode.Char:
  1175.                             return (char)ub;
  1176.                         case TypeCode.SByte:
  1177.                             return (sbyte)ub;
  1178.                         case TypeCode.Byte:
  1179.                             return ub;
  1180.                         case TypeCode.Int16:
  1181.                             return (Int16)ub;
  1182.                         case TypeCode.UInt16:
  1183.                             return (UInt16)ub;
  1184.                         case TypeCode.Int32:
  1185.                             return (Int32)ub;
  1186.                         case TypeCode.UInt32:
  1187.                             return (UInt32)ub;
  1188.                         case TypeCode.Int64:
  1189.                             return (Int64)ub;
  1190.                         case TypeCode.UInt64:
  1191.                             return (UInt64)ub;
  1192.                         case TypeCode.Single:
  1193.                             return (float)ub;
  1194.                         case TypeCode.Double:
  1195.                             return (double)ub;
  1196.                         case TypeCode.Decimal:
  1197.                             return (decimal)ub;
  1198.                         case TypeCode.DateTime:
  1199.                             return new DateTime((Int64)ub);
  1200.                         case TypeCode.String:
  1201.                             return ub.ToString(CultureInfo.InvariantCulture);
  1202.                     }
  1203.                     break;
  1204.                 case TypeCode.Int16:
  1205.                    
  1206.                     Int16 s = ic.ToInt16(null);
  1207.                     switch (target) {
  1208.                         case TypeCode.Boolean:
  1209.                             return s != 0;
  1210.                         case TypeCode.Char:
  1211.                             return (char)s;
  1212.                         case TypeCode.SByte:
  1213.                             return (sbyte)s;
  1214.                         case TypeCode.Byte:
  1215.                             return (byte)s;
  1216.                         case TypeCode.Int16:
  1217.                             return s;
  1218.                         case TypeCode.UInt16:
  1219.                             return (UInt16)s;
  1220.                         case TypeCode.Int32:
  1221.                             return (Int32)s;
  1222.                         case TypeCode.UInt32:
  1223.                             return (UInt32)s;
  1224.                         case TypeCode.Int64:
  1225.                             return (Int64)s;
  1226.                         case TypeCode.UInt64:
  1227.                             return (UInt64)s;
  1228.                         case TypeCode.Single:
  1229.                             return (float)s;
  1230.                         case TypeCode.Double:
  1231.                             return (double)s;
  1232.                         case TypeCode.Decimal:
  1233.                             return (decimal)s;
  1234.                         case TypeCode.DateTime:
  1235.                             return new DateTime((Int64)s);
  1236.                         case TypeCode.String:
  1237.                             return s.ToString(CultureInfo.InvariantCulture);
  1238.                     }
  1239.                     break;
  1240.                 case TypeCode.UInt16:
  1241.                    
  1242.                     us = ic.ToUInt16(null);
  1243.                     switch (target) {
  1244.                         case TypeCode.Boolean:
  1245.                             return us != 0;
  1246.                         case TypeCode.Char:
  1247.                             return (char)us;
  1248.                         case TypeCode.SByte:
  1249.                             return (sbyte)us;
  1250.                         case TypeCode.Byte:
  1251.                             return (byte)us;
  1252.                         case TypeCode.Int16:
  1253.                             return (Int16)us;
  1254.                         case TypeCode.UInt16:
  1255.                             return us;
  1256.                         case TypeCode.Int32:
  1257.                             return (Int32)us;
  1258.                         case TypeCode.UInt32:
  1259.                             return (UInt32)us;
  1260.                         case TypeCode.Int64:
  1261.                             return (Int64)us;
  1262.                         case TypeCode.UInt64:
  1263.                             return (UInt64)us;
  1264.                         case TypeCode.Single:
  1265.                             return (float)us;
  1266.                         case TypeCode.Double:
  1267.                             return (double)us;
  1268.                         case TypeCode.Decimal:
  1269.                             return (decimal)us;
  1270.                         case TypeCode.DateTime:
  1271.                             return new DateTime((Int64)us);
  1272.                         case TypeCode.String:
  1273.                             return us.ToString(CultureInfo.InvariantCulture);
  1274.                     }
  1275.                     break;
  1276.                 case TypeCode.Int32:
  1277.                    
  1278.                     Int32 i = ic.ToInt32(null);
  1279.                     switch (target) {
  1280.                         case TypeCode.Boolean:
  1281.                             return i != 0;
  1282.                         case TypeCode.Char:
  1283.                             return (char)i;
  1284.                         case TypeCode.SByte:
  1285.                             return (sbyte)i;
  1286.                         case TypeCode.Byte:
  1287.                             return (byte)i;
  1288.                         case TypeCode.Int16:
  1289.                             return (Int16)i;
  1290.                         case TypeCode.UInt16:
  1291.                             return (UInt16)i;
  1292.                         case TypeCode.Int32:
  1293.                             return i;
  1294.                         case TypeCode.UInt32:
  1295.                             return (UInt32)i;
  1296.                         case TypeCode.Int64:
  1297.                             return (Int64)i;
  1298.                         case TypeCode.UInt64:
  1299.                             return (UInt64)i;
  1300.                         case TypeCode.Single:
  1301.                             return (float)i;
  1302.                         case TypeCode.Double:
  1303.                             return (double)i;
  1304.                         case TypeCode.Decimal:
  1305.                             return (decimal)i;
  1306.                         case TypeCode.DateTime:
  1307.                             return new DateTime((Int64)i);
  1308.                         case TypeCode.String:
  1309.                             return i.ToString(CultureInfo.InvariantCulture);
  1310.                     }
  1311.                     break;
  1312.                 case TypeCode.UInt32:
  1313.                    
  1314.                     UInt32 ui = ic.ToUInt32(null);
  1315.                     switch (target) {
  1316.                         case TypeCode.Boolean:
  1317.                             return ui != 0;
  1318.                         case TypeCode.Char:
  1319.                             return (char)ui;
  1320.                         case TypeCode.SByte:
  1321.                             return (sbyte)ui;
  1322.                         case TypeCode.Byte:
  1323.                             return (byte)ui;
  1324.                         case TypeCode.Int16:
  1325.                             return (Int16)ui;
  1326.                         case TypeCode.UInt16:
  1327.                             return (UInt16)ui;
  1328.                         case TypeCode.Int32:
  1329.                             return (Int32)ui;
  1330.                         case TypeCode.UInt32:
  1331.                             return ui;
  1332.                         case TypeCode.Int64:
  1333.                             return (Int64)ui;
  1334.                         case TypeCode.UInt64:
  1335.                             return (UInt64)ui;
  1336.                         case TypeCode.Single:
  1337.                             return (float)ui;
  1338.                         case TypeCode.Double:
  1339.                             return (double)ui;
  1340.                         case TypeCode.Decimal:
  1341.                             return (decimal)ui;
  1342.                         case TypeCode.DateTime:
  1343.                             return new DateTime((Int64)ui);
  1344.                         case TypeCode.String:
  1345.                             return ui.ToString(CultureInfo.InvariantCulture);
  1346.                     }
  1347.                     break;
  1348.                 case TypeCode.Int64:
  1349.                    
  1350.                     Int64 l = ic.ToInt64(null);
  1351.                     switch (target) {
  1352.                         case TypeCode.Boolean:
  1353.                             return l != 0;
  1354.                         case TypeCode.Char:
  1355.                             return (char)l;
  1356.                         case TypeCode.SByte:
  1357.                             return (sbyte)l;
  1358.                         case TypeCode.Byte:
  1359.                             return (byte)l;
  1360.                         case TypeCode.Int16:
  1361.                             return (Int16)l;
  1362.                         case TypeCode.UInt16:
  1363.                             return (UInt16)l;
  1364.                         case TypeCode.Int32:
  1365.                             return (Int32)l;
  1366.                         case TypeCode.UInt32:
  1367.                             return (UInt32)l;
  1368.                         case TypeCode.Int64:
  1369.                             return l;
  1370.                         case TypeCode.UInt64:
  1371.                             return (UInt64)l;
  1372.                         case TypeCode.Single:
  1373.                             return (float)l;
  1374.                         case TypeCode.Double:
  1375.                             return (double)l;
  1376.                         case TypeCode.Decimal:
  1377.                             return (decimal)l;
  1378.                         case TypeCode.DateTime:
  1379.                             return new DateTime(l);
  1380.                         case TypeCode.String:
  1381.                             return l.ToString(CultureInfo.InvariantCulture);
  1382.                     }
  1383.                     break;
  1384.                 case TypeCode.UInt64:
  1385.                    
  1386.                     UInt64 ul = ic.ToUInt64(null);
  1387.                     switch (target) {
  1388.                         case TypeCode.Boolean:
  1389.                             return ul != 0;
  1390.                         case TypeCode.Char:
  1391.                             return (char)ul;
  1392.                         case TypeCode.SByte:
  1393.                             return (sbyte)ul;
  1394.                         case TypeCode.Byte:
  1395.                             return (byte)ul;
  1396.                         case TypeCode.Int16:
  1397.                             return (Int16)ul;
  1398.                         case TypeCode.UInt16:
  1399.                             return (UInt16)ul;
  1400.                         case TypeCode.Int32:
  1401.                             return (Int32)ul;
  1402.                         case TypeCode.UInt32:
  1403.                             return (UInt32)ul;
  1404.                         case TypeCode.Int64:
  1405.                             return (Int64)ul;
  1406.                         case TypeCode.UInt64:
  1407.                             return ul;
  1408.                         case TypeCode.Single:
  1409.                             return (float)ul;
  1410.                         case TypeCode.Double:
  1411.                             return (double)ul;
  1412.                         case TypeCode.Decimal:
  1413.                             return (decimal)ul;
  1414.                         case TypeCode.DateTime:
  1415.                             return new DateTime((Int64)ul);
  1416.                         case TypeCode.String:
  1417.                             return ul.ToString(CultureInfo.InvariantCulture);
  1418.                     }
  1419.                     break;
  1420.                 case TypeCode.Single:
  1421.                    
  1422.                     float f = ic.ToSingle(null);
  1423.                     switch (target) {
  1424.                         case TypeCode.Boolean:
  1425.                             if (f != f)
  1426.                                 return false;
  1427.                             else
  1428.                                 return f != 0;
  1429.                             break;
  1430.                         case TypeCode.Single:
  1431.                             return f;
  1432.                         case TypeCode.Double:
  1433.                             return (double)f;
  1434.                         case TypeCode.Decimal:
  1435.                             return (decimal)f;
  1436.                         case TypeCode.String:
  1437.                             return Convert.ToString((double)f);
  1438.                     }
  1439.                    
  1440.                     l = Runtime.DoubleToInt64(f);
  1441.                     switch (target) {
  1442.                         case TypeCode.Char:
  1443.                             return (char)l;
  1444.                         case TypeCode.SByte:
  1445.                             return (sbyte)l;
  1446.                         case TypeCode.Byte:
  1447.                             return (byte)l;
  1448.                         case TypeCode.Int16:
  1449.                             return (Int16)l;
  1450.                         case TypeCode.UInt16:
  1451.                             return (UInt16)l;
  1452.                         case TypeCode.Int32:
  1453.                             return (Int32)l;
  1454.                         case TypeCode.UInt32:
  1455.                             return (UInt32)l;
  1456.                         case TypeCode.Int64:
  1457.                             return (Int64)l;
  1458.                         case TypeCode.UInt64:
  1459.                             return (UInt64)l;
  1460.                         case TypeCode.DateTime:
  1461.                             return new DateTime((Int64)l);
  1462.                     }
  1463.                     break;
  1464.                 case TypeCode.Double:
  1465.                    
  1466.                     double d = ic.ToDouble(null);
  1467.                     switch (target) {
  1468.                         case TypeCode.Boolean:
  1469.                             return Convert.ToBoolean(d);
  1470.                         case TypeCode.Single:
  1471.                             return (float)d;
  1472.                         case TypeCode.Double:
  1473.                             return d;
  1474.                         case TypeCode.Decimal:
  1475.                             return (decimal)d;
  1476.                         case TypeCode.String:
  1477.                             return Convert.ToString(d);
  1478.                     }
  1479.                     l = Runtime.DoubleToInt64(d);
  1480.                     switch (target) {
  1481.                         case TypeCode.Char:
  1482.                             return (char)l;
  1483.                         case TypeCode.SByte:
  1484.                             return (sbyte)l;
  1485.                         case TypeCode.Byte:
  1486.                             return (byte)l;
  1487.                         case TypeCode.Int16:
  1488.                             return (Int16)l;
  1489.                         case TypeCode.UInt16:
  1490.                             return (UInt16)l;
  1491.                         case TypeCode.Int32:
  1492.                             return (Int32)l;
  1493.                         case TypeCode.UInt32:
  1494.                             return (UInt32)l;
  1495.                         case TypeCode.Int64:
  1496.                             return (Int64)l;
  1497.                         case TypeCode.UInt64:
  1498.                             return (UInt64)l;
  1499.                         case TypeCode.DateTime:
  1500.                             return new DateTime((Int64)l);
  1501.                     }
  1502.                     break;
  1503.                 case TypeCode.Decimal:
  1504.                    
  1505.                     decimal dec = ic.ToDecimal(null);
  1506.                     switch (target) {
  1507.                         case TypeCode.Boolean:
  1508.                             return dec != 0;
  1509.                         case TypeCode.Char:
  1510.                         case TypeCode.SByte:
  1511.                         case TypeCode.Byte:
  1512.                         case TypeCode.Int16:
  1513.                         case TypeCode.UInt16:
  1514.                         case TypeCode.Int32:
  1515.                         case TypeCode.UInt32:
  1516.                         case TypeCode.Int64:
  1517.                         case TypeCode.UInt64:
  1518.                             return Coerce2WithTruncationPermitted(Runtime.UncheckedDecimalToInt64(dec), target);
  1519.                         case TypeCode.Single:
  1520.                             return Decimal.ToSingle(dec);
  1521.                         case TypeCode.Double:
  1522.                             return Decimal.ToDouble(dec);
  1523.                         case TypeCode.Decimal:
  1524.                             return dec;
  1525.                         case TypeCode.DateTime:
  1526.                             return new DateTime(Runtime.UncheckedDecimalToInt64(dec));
  1527.                         case TypeCode.String:
  1528.                             return dec.ToString(CultureInfo.InvariantCulture);
  1529.                     }
  1530.                     break;
  1531.                 case TypeCode.DateTime:
  1532.                    
  1533.                     DateTime dt = ic.ToDateTime(null);
  1534.                     switch (target) {
  1535.                         case TypeCode.Boolean:
  1536.                         case TypeCode.Char:
  1537.                         case TypeCode.SByte:
  1538.                         case TypeCode.Byte:
  1539.                         case TypeCode.Int16:
  1540.                         case TypeCode.UInt16:
  1541.                         case TypeCode.Int32:
  1542.                         case TypeCode.UInt32:
  1543.                         case TypeCode.Int64:
  1544.                         case TypeCode.UInt64:
  1545.                         case TypeCode.Single:
  1546.                         case TypeCode.Double:
  1547.                         case TypeCode.Decimal:
  1548.                             return Coerce2WithTruncationPermitted(dt.Ticks, target);
  1549.                         case TypeCode.DateTime:
  1550.                             return dt;
  1551.                         case TypeCode.String:
  1552.                             return dt.ToString(CultureInfo.InvariantCulture);
  1553.                     }
  1554.                     break;
  1555.                 case TypeCode.String:
  1556.                    
  1557.                     string str = ic.ToString(null);
  1558.                     switch (target) {
  1559.                         case TypeCode.Boolean:
  1560.                             return Convert.ToBoolean(str, false);
  1561.                         case TypeCode.Char:
  1562.                             if (str.Length == 1)
  1563.                                 return str[0];
  1564.                             throw new JScriptException(JSError.TypeMismatch);
  1565.                             break;
  1566.                         case TypeCode.SByte:
  1567.                         case TypeCode.Byte:
  1568.                         case TypeCode.Int16:
  1569.                         case TypeCode.UInt16:
  1570.                         case TypeCode.Int32:
  1571.                         case TypeCode.UInt32:
  1572.                         case TypeCode.Double:
  1573.                             return Coerce2WithTruncationPermitted(Convert.ToNumber(str), target);
  1574.                         case TypeCode.Single:
  1575.                             try {
  1576.                                 return Single.Parse(str, CultureInfo.InvariantCulture);
  1577.                             }
  1578.                             catch {
  1579.                                 goto case TypeCode.Double;
  1580.                             }
  1581.                             break;
  1582.                         case TypeCode.Int64:
  1583.                             try {
  1584.                                 return Int64.Parse(str, CultureInfo.InvariantCulture);
  1585.                             }
  1586.                             catch {
  1587.                                 try {
  1588.                                     return (long)UInt64.Parse(str, CultureInfo.InvariantCulture);
  1589.                                 }
  1590.                                 catch {
  1591.                                     goto case TypeCode.Double;
  1592.                                 }
  1593.                             }
  1594.                             break;
  1595.                         case TypeCode.UInt64:
  1596.                             try {
  1597.                                 return UInt64.Parse(str, CultureInfo.InvariantCulture);
  1598.                             }
  1599.                             catch {
  1600.                                 goto case TypeCode.Double;
  1601.                             }
  1602.                             break;
  1603.                         case TypeCode.Decimal:
  1604.                             try {
  1605.                                 return Decimal.Parse(str, CultureInfo.InvariantCulture);
  1606.                             }
  1607.                             catch {
  1608.                                 goto case TypeCode.Double;
  1609.                             }
  1610.                             break;
  1611.                         case TypeCode.DateTime:
  1612.                             return DateTime.Parse(str, CultureInfo.InvariantCulture);
  1613.                         case TypeCode.String:
  1614.                             return str;
  1615.                     }
  1616.                     break;
  1617.             }
  1618.             throw new JScriptException(JSError.TypeMismatch);
  1619.         }
  1620.        
  1621.         //This function emits a compiled version of Coerce for a particular (source_type, target_type) pair.
  1622.         //It assumes that an operand of source_type is already on the operand stack. It consumes this operand
  1623.         //and leaves a result of target_type in its place.
  1624.         static internal void Emit(AST ast, ILGenerator il, Type source_type, Type target_type)
  1625.         {
  1626.             Convert.Emit(ast, il, source_type, target_type, false);
  1627.         }
  1628.        
  1629.         static internal void Emit(AST ast, ILGenerator il, Type source_type, Type target_type, bool truncationPermitted)
  1630.         {
  1631.             if (source_type == target_type)
  1632.                 return;
  1633.             if (target_type == Typeob.Void) {
  1634.                 il.Emit(OpCodes.Pop);
  1635.                 return;
  1636.             }
  1637.             if (target_type.IsEnum) {
  1638.                 if (source_type == Typeob.String || source_type == Typeob.Object) {
  1639.                     il.Emit(OpCodes.Ldtoken, target_type);
  1640.                     il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod);
  1641.                     ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
  1642.                     il.Emit(OpCodes.Call, CompilerGlobals.coerceTMethod);
  1643.                     Convert.EmitUnbox(il, target_type, Type.GetTypeCode(Convert.GetUnderlyingType(target_type)));
  1644.                 }
  1645.                 else
  1646.                     Convert.Emit(ast, il, source_type, Convert.GetUnderlyingType(target_type));
  1647.                 return;
  1648.             }
  1649.             if (source_type.IsEnum) {
  1650.                 if (target_type.IsPrimitive) {
  1651.                     Convert.Emit(ast, il, Convert.GetUnderlyingType(source_type), target_type);
  1652.                     return;
  1653.                 }
  1654.                 if (target_type == Typeob.Object || target_type == Typeob.Enum) {
  1655.                     il.Emit(OpCodes.Box, source_type);
  1656.                     return;
  1657.                 }
  1658.                 if (target_type == Typeob.String) {
  1659.                     il.Emit(OpCodes.Box, source_type);
  1660.                     ConstantWrapper.TranslateToILInt(il, 0);
  1661.                     il.Emit(OpCodes.Call, CompilerGlobals.toStringMethod);
  1662.                     return;
  1663.                 }
  1664.             }
  1665.            
  1666.             while (source_type is TypeBuilder) {
  1667.                 source_type = source_type.BaseType;
  1668.                 if (source_type == null)
  1669.                     source_type = Typeob.Object;
  1670.                 //It is an interface
  1671.                 if (source_type == target_type)
  1672.                     return;
  1673.             }
  1674.            
  1675.             if (source_type.IsArray && target_type.IsArray)
  1676.                 //This should only be called if the two types are known to be compatible, so:
  1677.                 return;
  1678.            
  1679.             TypeCode source = Type.GetTypeCode(source_type);
  1680.             TypeCode target = target_type is TypeBuilder ? TypeCode.Object : Type.GetTypeCode(target_type);
  1681.             switch (source) {
  1682.                 case TypeCode.Empty:
  1683.                     //can never occur
  1684.                     return;
  1685.                 case TypeCode.Object:
  1686.                    
  1687.                     if (source_type == Typeob.Void) {
  1688.                         il.Emit(OpCodes.Ldnull);
  1689.                         source_type = Typeob.Object;
  1690.                     }
  1691.                     switch (target) {
  1692.                         case TypeCode.Object:
  1693.                             //The conversion from function object to delegate never happens here. ConstantWrapper takes care of it.
  1694.                             //First check for array target type or TypeBuilder target type. These do not support IsAssignableFrom.
  1695.                             if (target_type.IsArray || target_type == Typeob.Array) {
  1696.                                 if (source_type == Typeob.ArrayObject || source_type == Typeob.Object) {
  1697.                                     if (target_type.IsArray)
  1698.                                         il.Emit(OpCodes.Ldtoken, target_type.GetElementType());
  1699.                                     else
  1700.                                         il.Emit(OpCodes.Ldtoken, Typeob.Object);
  1701.                                     il.Emit(OpCodes.Call, CompilerGlobals.toNativeArrayMethod);
  1702.                                 }
  1703.                                 il.Emit(OpCodes.Castclass, target_type);
  1704.                                 return;
  1705.                             }
  1706.                             else if (target_type is TypeBuilder) {
  1707.                                 il.Emit(OpCodes.Castclass, target_type);
  1708.                                 return;
  1709.                             }
  1710.                             else if (target_type == Typeob.Enum && source_type.BaseType == Typeob.Enum) {
  1711.                                 il.Emit(OpCodes.Box, source_type);
  1712.                                 return;
  1713.                             }
  1714.                             else if (target_type == Typeob.Object || target_type.IsAssignableFrom(source_type)) {
  1715.                                 if (source_type.IsValueType)
  1716.                                     il.Emit(OpCodes.Box, source_type);
  1717.                                 return;
  1718.                             }
  1719.                            
  1720.                             if (Typeob.JSObject.IsAssignableFrom(target_type)) {
  1721.                                 if (source_type.IsValueType)
  1722.                                     il.Emit(OpCodes.Box, source_type);
  1723.                                 ast.EmitILToLoadEngine(il);
  1724.                                 il.Emit(OpCodes.Call, CompilerGlobals.toObject2Method);
  1725.                                 //Do this here so that we need not pass engine to Coerce
  1726.                                 il.Emit(OpCodes.Castclass, target_type);
  1727.                                 return;
  1728.                             }
  1729.                            
  1730.                             if (Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
  1731.                                 return;
  1732.                            
  1733.                             //Either no conversion is possible, or not enough information is available at compile time.
  1734.                             //PartialEvaluator is supposed to give errors when conversions are known to be impossible.
  1735.                             //Defer to run-time type checking
  1736.                             if (target_type.IsValueType || target_type.IsArray) {
  1737.                                 //Some runtime conversions might be possible
  1738.                                 il.Emit(OpCodes.Ldtoken, target_type);
  1739.                                 il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod);
  1740.                                 ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
  1741.                                 il.Emit(OpCodes.Call, CompilerGlobals.coerceTMethod);
  1742.                             }
  1743.                             if (target_type.IsValueType)
  1744.                                 Convert.EmitUnbox(il, target_type, target);
  1745.                             else
  1746.                                 il.Emit(OpCodes.Castclass, target_type);
  1747.                             return;
  1748.                         case TypeCode.Boolean:
  1749.                            
  1750.                             if (source_type.IsValueType)
  1751.                                 il.Emit(OpCodes.Box, source_type);
  1752.                             ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
  1753.                             il.Emit(OpCodes.Call, CompilerGlobals.toBooleanMethod);
  1754.                             return;
  1755.                         case TypeCode.Single:
  1756.                            
  1757.                             if (source_type.IsValueType)
  1758.                                 il.Emit(OpCodes.Box, source_type);
  1759.                             il.Emit(OpCodes.Call, CompilerGlobals.toNumberMethod);
  1760.                             il.Emit(OpCodes.Conv_R4);
  1761.                             return;
  1762.                         case TypeCode.Double:
  1763.                            
  1764.                             if (source_type.IsValueType)
  1765.                                 il.Emit(OpCodes.Box, source_type);
  1766.                             il.Emit(OpCodes.Call, CompilerGlobals.toNumberMethod);
  1767.                             return;
  1768.                         case TypeCode.Char:
  1769.                         case TypeCode.SByte:
  1770.                         case TypeCode.Byte:
  1771.                         case TypeCode.Int16:
  1772.                         case TypeCode.UInt16:
  1773.                         case TypeCode.Int32:
  1774.                         case TypeCode.UInt32:
  1775.                         case TypeCode.Int64:
  1776.                         case TypeCode.UInt64:
  1777.                         case TypeCode.Decimal:
  1778.                         case TypeCode.DateTime:
  1779.                            
  1780.                             if (source_type.IsValueType)
  1781.                                 il.Emit(OpCodes.Box, source_type);
  1782.                             if (truncationPermitted && target == TypeCode.Int32) {
  1783.                                 il.Emit(OpCodes.Call, CompilerGlobals.toInt32Method);
  1784.                                 return;
  1785.                             }
  1786.                             else {
  1787.                                 ConstantWrapper.TranslateToILInt(il, (int)target);
  1788.                                 ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
  1789.                                 il.Emit(OpCodes.Call, CompilerGlobals.coerce2Method);
  1790.                             }
  1791.                             if (target_type.IsValueType)
  1792.                                 Convert.EmitUnbox(il, target_type, target);
  1793.                             return;
  1794.                         case TypeCode.String:
  1795.                            
  1796.                             if (source_type.IsValueType)
  1797.                                 il.Emit(OpCodes.Box, source_type);
  1798.                             if (truncationPermitted)
  1799.                                 il.Emit(OpCodes.Castclass, Typeob.String);
  1800.                             //explict cast to type string
  1801.                             else {
  1802.                                 ConstantWrapper.TranslateToILInt(il, 1);
  1803.                                 il.Emit(OpCodes.Call, CompilerGlobals.toStringMethod);
  1804.                             }
  1805.                             return;
  1806.                     }
  1807.                     return;
  1808.                 case TypeCode.DBNull:
  1809.                    
  1810.                     if (source_type.IsValueType)
  1811.                         //Not likely, but a hacker might cause this to be true.
  1812.                         il.Emit(OpCodes.Box, source_type);
  1813.                     if (target == TypeCode.Object || (target == TypeCode.String && !truncationPermitted)) {
  1814.                         if (target_type == Typeob.Object)
  1815.                             return;
  1816.                         if (!target_type.IsValueType) {
  1817.                             il.Emit(OpCodes.Pop);
  1818.                             il.Emit(OpCodes.Ldnull);
  1819.                             return;
  1820.                         }
  1821.                     }
  1822.                     if (target_type.IsValueType) {
  1823.                         il.Emit(OpCodes.Ldtoken, target_type);
  1824.                         il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod);
  1825.                         ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
  1826.                         il.Emit(OpCodes.Call, CompilerGlobals.coerceTMethod);
  1827.                         Convert.EmitUnbox(il, target_type, target);
  1828.                     }
  1829.                     else {
  1830.                         ConstantWrapper.TranslateToILInt(il, (int)target);
  1831.                         ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
  1832.                         il.Emit(OpCodes.Call, CompilerGlobals.coerce2Method);
  1833.                         //constructs and boxes whatever value is needed
  1834.                     }
  1835.                     return;
  1836.                 case TypeCode.Boolean:
  1837.                    
  1838.                     switch (target) {
  1839.                         case TypeCode.Object:
  1840.                             if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
  1841.                                 return;
  1842.                             il.Emit(OpCodes.Box, source_type);
  1843.                             Convert.Emit(ast, il, Typeob.Object, target_type);
  1844.                             return;
  1845.                         case TypeCode.Boolean:
  1846.                         case TypeCode.Char:
  1847.                         case TypeCode.SByte:
  1848.                         case TypeCode.Int16:
  1849.                         case TypeCode.Int32:
  1850.                         case TypeCode.Byte:
  1851.                         case TypeCode.UInt16:
  1852.                         case TypeCode.UInt32:
  1853.                             return;
  1854.                         case TypeCode.Int64:
  1855.                         case TypeCode.UInt64:
  1856.                             il.Emit(OpCodes.Conv_U8);
  1857.                             return;
  1858.                         case TypeCode.Single:
  1859.                             il.Emit(OpCodes.Conv_R4);
  1860.                             return;
  1861.                         case TypeCode.Double:
  1862.                             il.Emit(OpCodes.Conv_R8);
  1863.                             return;
  1864.                         case TypeCode.Decimal:
  1865.                             il.Emit(OpCodes.Call, CompilerGlobals.int32ToDecimalMethod);
  1866.                             return;
  1867.                         case TypeCode.DateTime:
  1868.                             il.Emit(OpCodes.Conv_I8);
  1869.                             il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
  1870.                             return;
  1871.                         case TypeCode.String:
  1872.                             Label false_label = il.DefineLabel();
  1873.                             Label end_label = il.DefineLabel();
  1874.                             il.Emit(OpCodes.Brfalse, false_label);
  1875.                             il.Emit(OpCodes.Ldstr, "true");
  1876.                             il.Emit(OpCodes.Br, end_label);
  1877.                             il.MarkLabel(false_label);
  1878.                             il.Emit(OpCodes.Ldstr, "false");
  1879.                             il.MarkLabel(end_label);
  1880.                             return;
  1881.                     }
  1882.                     break;
  1883.                 case TypeCode.SByte:
  1884.                    
  1885.                     switch (target) {
  1886.                         case TypeCode.Object:
  1887.                             if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
  1888.                                 return;
  1889.                             il.Emit(OpCodes.Box, source_type);
  1890.                             Convert.Emit(ast, il, Typeob.Object, target_type);
  1891.                             return;
  1892.                         case TypeCode.SByte:
  1893.                         case TypeCode.Int16:
  1894.                         case TypeCode.Int32:
  1895.                             return;
  1896.                         case TypeCode.Byte:
  1897.                             if (truncationPermitted)
  1898.                                 il.Emit(OpCodes.Conv_U1);
  1899.                             else
  1900.                                 il.Emit(OpCodes.Conv_Ovf_U1);
  1901.                             return;
  1902.                         case TypeCode.Char:
  1903.                         case TypeCode.UInt16:
  1904.                             if (truncationPermitted)
  1905.                                 il.Emit(OpCodes.Conv_U2);
  1906.                             else
  1907.                                 il.Emit(OpCodes.Conv_Ovf_U2);
  1908.                             return;
  1909.                         case TypeCode.UInt32:
  1910.                             if (truncationPermitted)
  1911.                                 il.Emit(OpCodes.Conv_U4);
  1912.                             else
  1913.                                 il.Emit(OpCodes.Conv_Ovf_U4);
  1914.                             return;
  1915.                         case TypeCode.Int64:
  1916.                             il.Emit(OpCodes.Conv_I8);
  1917.                             return;
  1918.                         case TypeCode.UInt64:
  1919.                             if (truncationPermitted)
  1920.                                 il.Emit(OpCodes.Conv_I8);
  1921.                             else
  1922.                                 il.Emit(OpCodes.Conv_Ovf_U8);
  1923.                             return;
  1924.                         case TypeCode.Single:
  1925.                         case TypeCode.Double:
  1926.                             il.Emit(OpCodes.Conv_R8);
  1927.                             return;
  1928.                         case TypeCode.Boolean:
  1929.                             il.Emit(OpCodes.Ldc_I4_0);
  1930.                             il.Emit(OpCodes.Ceq);
  1931.                             il.Emit(OpCodes.Ldc_I4_0);
  1932.                             il.Emit(OpCodes.Ceq);
  1933.                             return;
  1934.                         case TypeCode.Decimal:
  1935.                             il.Emit(OpCodes.Call, CompilerGlobals.int32ToDecimalMethod);
  1936.                             return;
  1937.                         case TypeCode.DateTime:
  1938.                             il.Emit(OpCodes.Conv_I8);
  1939.                             il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
  1940.                             return;
  1941.                         case TypeCode.String:
  1942.                             Convert.EmitLdloca(il, Typeob.Int32);
  1943.                             il.Emit(OpCodes.Call, CompilerGlobals.int32ToStringMethod);
  1944.                             return;
  1945.                     }
  1946.                     break;
  1947.                 case TypeCode.Byte:
  1948.                    
  1949.                     switch (target) {
  1950.                         case TypeCode.Object:
  1951.                             if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
  1952.                                 return;
  1953.                             il.Emit(OpCodes.Box, source_type);
  1954.                             Convert.Emit(ast, il, Typeob.Object, target_type);
  1955.                             return;
  1956.                         case TypeCode.SByte:
  1957.                             if (truncationPermitted)
  1958.                                 il.Emit(OpCodes.Conv_I1);
  1959.                             else
  1960.                                 il.Emit(OpCodes.Conv_Ovf_I1_Un);
  1961.                             return;
  1962.                         case TypeCode.Byte:
  1963.                         case TypeCode.Int16:
  1964.                         case TypeCode.Char:
  1965.                         case TypeCode.UInt16:
  1966.                         case TypeCode.Int32:
  1967.                         case TypeCode.UInt32:
  1968.                             return;
  1969.                         case TypeCode.Int64:
  1970.                         case TypeCode.UInt64:
  1971.                             il.Emit(OpCodes.Conv_U8);
  1972.                             return;
  1973.                         case TypeCode.Single:
  1974.                         case TypeCode.Double:
  1975.                             il.Emit(OpCodes.Conv_R_Un);
  1976.                             return;
  1977.                         case TypeCode.Boolean:
  1978.                             il.Emit(OpCodes.Ldc_I4_0);
  1979.                             il.Emit(OpCodes.Ceq);
  1980.                             il.Emit(OpCodes.Ldc_I4_0);
  1981.                             il.Emit(OpCodes.Ceq);
  1982.                             return;
  1983.                         case TypeCode.Decimal:
  1984.                             il.Emit(OpCodes.Call, CompilerGlobals.uint32ToDecimalMethod);
  1985.                             return;
  1986.                         case TypeCode.DateTime:
  1987.                             il.Emit(OpCodes.Conv_I8);
  1988.                             il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
  1989.                             return;
  1990.                         case TypeCode.String:
  1991.                             Convert.EmitLdloca(il, Typeob.UInt32);
  1992.                             il.Emit(OpCodes.Call, CompilerGlobals.uint32ToStringMethod);
  1993.                             return;
  1994.                     }
  1995.                     break;
  1996.                 case TypeCode.Int16:
  1997.                    
  1998.                     switch (target) {
  1999.                         case TypeCode.Object:
  2000.                             if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
  2001.                                 return;
  2002.                             il.Emit(OpCodes.Box, source_type);
  2003.                             Convert.Emit(ast, il, Typeob.Object, target_type);
  2004.                             return;
  2005.                         case TypeCode.SByte:
  2006.                             if (truncationPermitted)
  2007.                                 il.Emit(OpCodes.Conv_I1);
  2008.                             else
  2009.                                 il.Emit(OpCodes.Conv_Ovf_I1);
  2010.                             return;
  2011.                         case TypeCode.Int16:
  2012.                         case TypeCode.Int32:
  2013.                             return;
  2014.                         case TypeCode.Byte:
  2015.                             if (truncationPermitted)
  2016.                                 il.Emit(OpCodes.Conv_U1);
  2017.                             else
  2018.                                 il.Emit(OpCodes.Conv_Ovf_U1);
  2019.                             return;
  2020.                         case TypeCode.Char:
  2021.                         case TypeCode.UInt16:
  2022.                             if (truncationPermitted)
  2023.                                 il.Emit(OpCodes.Conv_U2);
  2024.                             else
  2025.                                 il.Emit(OpCodes.Conv_Ovf_U2);
  2026.                             return;
  2027.                         case TypeCode.UInt32:
  2028.                             if (truncationPermitted)
  2029.                                 il.Emit(OpCodes.Conv_U4);
  2030.                             else
  2031.                                 il.Emit(OpCodes.Conv_Ovf_U4);
  2032.                             return;
  2033.                         case TypeCode.Int64:
  2034.                             il.Emit(OpCodes.Conv_I8);
  2035.                             return;
  2036.                         case TypeCode.UInt64:
  2037.                             if (truncationPermitted)
  2038.                                 il.Emit(OpCodes.Conv_I8);
  2039.                             else
  2040.                                 il.Emit(OpCodes.Conv_Ovf_U8);
  2041.                             return;
  2042.                         case TypeCode.Single:
  2043.                         case TypeCode.Double:
  2044.                             il.Emit(OpCodes.Conv_R8);
  2045.                             return;
  2046.                         case TypeCode.Boolean:
  2047.                             il.Emit(OpCodes.Ldc_I4_0);
  2048.                             il.Emit(OpCodes.Ceq);
  2049.                             il.Emit(OpCodes.Ldc_I4_0);
  2050.                             il.Emit(OpCodes.Ceq);
  2051.                             return;
  2052.                         case TypeCode.Decimal:
  2053.                             il.Emit(OpCodes.Call, CompilerGlobals.int32ToDecimalMethod);
  2054.                             return;
  2055.                         case TypeCode.DateTime:
  2056.                             il.Emit(OpCodes.Conv_I8);
  2057.                             il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
  2058.                             return;
  2059.                         case TypeCode.String:
  2060.                             Convert.EmitLdloca(il, Typeob.Int32);
  2061.                             il.Emit(OpCodes.Call, CompilerGlobals.int32ToStringMethod);
  2062.                             return;
  2063.                     }
  2064.                     break;
  2065.                 case TypeCode.Char:
  2066.                 case TypeCode.UInt16:
  2067.                    
  2068.                     switch (target) {
  2069.                         case TypeCode.Object:
  2070.                             if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
  2071.                                 return;
  2072.                             il.Emit(OpCodes.Box, source_type);
  2073.                             Convert.Emit(ast, il, Typeob.Object, target_type);
  2074.                             return;
  2075.                         case TypeCode.SByte:
  2076.                             if (truncationPermitted)
  2077.                                 il.Emit(OpCodes.Conv_I1);
  2078.                             else
  2079.                                 il.Emit(OpCodes.Conv_Ovf_I1);
  2080.                             return;
  2081.                         case TypeCode.Byte:
  2082.                             if (truncationPermitted)
  2083.                                 il.Emit(OpCodes.Conv_U1);
  2084.                             else
  2085.                                 il.Emit(OpCodes.Conv_Ovf_U1);
  2086.                             return;
  2087.                         case TypeCode.Int16:
  2088.                             if (truncationPermitted)
  2089.                                 il.Emit(OpCodes.Conv_I2);
  2090.                             else
  2091.                                 il.Emit(OpCodes.Conv_Ovf_I2);
  2092.                             return;
  2093.                         case TypeCode.Char:
  2094.                         case TypeCode.UInt16:
  2095.                         case TypeCode.Int32:
  2096.                         case TypeCode.UInt32:
  2097.                             return;
  2098.                         case TypeCode.Int64:
  2099.                             il.Emit(OpCodes.Conv_I8);
  2100.                             return;
  2101.                         case TypeCode.UInt64:
  2102.                             il.Emit(OpCodes.Conv_U8);
  2103.                             return;
  2104.                         case TypeCode.Single:
  2105.                         case TypeCode.Double:
  2106.                             il.Emit(OpCodes.Conv_R_Un);
  2107.                             return;
  2108.                         case TypeCode.Boolean:
  2109.                             il.Emit(OpCodes.Ldc_I4_0);
  2110.                             il.Emit(OpCodes.Ceq);
  2111.                             il.Emit(OpCodes.Ldc_I4_0);
  2112.                             il.Emit(OpCodes.Ceq);
  2113.                             return;
  2114.                         case TypeCode.Decimal:
  2115.                             il.Emit(OpCodes.Call, CompilerGlobals.uint32ToDecimalMethod);
  2116.                             return;
  2117.                         case TypeCode.DateTime:
  2118.                             il.Emit(OpCodes.Conv_I8);
  2119.                             il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
  2120.                             return;
  2121.                         case TypeCode.String:
  2122.                             if (source == TypeCode.Char)
  2123.                                 il.Emit(OpCodes.Call, CompilerGlobals.convertCharToStringMethod);
  2124.                             else {
  2125.                                 Convert.EmitLdloca(il, Typeob.UInt32);
  2126.                                 il.Emit(OpCodes.Call, CompilerGlobals.uint32ToStringMethod);
  2127.                             }
  2128.                             return;
  2129.                     }
  2130.                     break;
  2131.                 case TypeCode.Int32:
  2132.                    
  2133.                     switch (target) {
  2134.                         case TypeCode.Object:
  2135.                             if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
  2136.                                 return;
  2137.                             il.Emit(OpCodes.Box, source_type);
  2138.                             Convert.Emit(ast, il, Typeob.Object, target_type);
  2139.                             return;
  2140.                         case TypeCode.SByte:
  2141.                             if (truncationPermitted)
  2142.                                 il.Emit(OpCodes.Conv_I1);
  2143.                             else
  2144.                                 il.Emit(OpCodes.Conv_Ovf_I1);
  2145.                             return;
  2146.                         case TypeCode.Int16:
  2147.                             if (truncationPermitted)
  2148.                                 il.Emit(OpCodes.Conv_I2);
  2149.                             else
  2150.                                 il.Emit(OpCodes.Conv_Ovf_I2);
  2151.                             return;
  2152.                         case TypeCode.Int32:
  2153.                             return;
  2154.                         case TypeCode.Byte:
  2155.                             if (truncationPermitted)
  2156.                                 il.Emit(OpCodes.Conv_U1);
  2157.                             else
  2158.                                 il.Emit(OpCodes.Conv_Ovf_U1);
  2159.                             return;
  2160.                         case TypeCode.Char:
  2161.                         case TypeCode.UInt16:
  2162.                             if (truncationPermitted)
  2163.                                 il.Emit(OpCodes.Conv_U2);
  2164.                             else
  2165.                                 il.Emit(OpCodes.Conv_Ovf_U2);
  2166.                             return;
  2167.                         case TypeCode.UInt32:
  2168.                             if (truncationPermitted)
  2169.                                 il.Emit(OpCodes.Conv_U4);
  2170.                             else
  2171.                                 il.Emit(OpCodes.Conv_Ovf_U4);
  2172.                             return;
  2173.                         case TypeCode.Int64:
  2174.                             il.Emit(OpCodes.Conv_I8);
  2175.                             return;
  2176.                         case TypeCode.UInt64:
  2177.                             if (truncationPermitted)
  2178.                                 il.Emit(OpCodes.Conv_U8);
  2179.                             else
  2180.                                 il.Emit(OpCodes.Conv_Ovf_U8);
  2181.                             return;
  2182.                         case TypeCode.Single:
  2183.                         case TypeCode.Double:
  2184.                             il.Emit(OpCodes.Conv_R8);
  2185.                             return;
  2186.                         case TypeCode.Boolean:
  2187.                             il.Emit(OpCodes.Ldc_I4_0);
  2188.                             il.Emit(OpCodes.Ceq);
  2189.                             il.Emit(OpCodes.Ldc_I4_0);
  2190.                             il.Emit(OpCodes.Ceq);
  2191.                             return;
  2192.                         case TypeCode.Decimal:
  2193.                             il.Emit(OpCodes.Call, CompilerGlobals.int32ToDecimalMethod);
  2194.                             return;
  2195.                         case TypeCode.DateTime:
  2196.                             il.Emit(OpCodes.Conv_I8);
  2197.                             il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
  2198.                             return;
  2199.                         case TypeCode.String:
  2200.                             Convert.EmitLdloca(il, Typeob.Int32);
  2201.                             il.Emit(OpCodes.Call, CompilerGlobals.int32ToStringMethod);
  2202.                             return;
  2203.                     }
  2204.                     break;
  2205.                 case TypeCode.UInt32:
  2206.                    
  2207.                     switch (target) {
  2208.                         case TypeCode.Object:
  2209.                             if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
  2210.                                 return;
  2211.                             il.Emit(OpCodes.Box, source_type);
  2212.                             Convert.Emit(ast, il, Typeob.Object, target_type);
  2213.                             return;
  2214.                         case TypeCode.SByte:
  2215.                             if (truncationPermitted)
  2216.                                 il.Emit(OpCodes.Conv_I1);
  2217.                             else
  2218.                                 il.Emit(OpCodes.Conv_Ovf_I1);
  2219.                             return;
  2220.                         case TypeCode.Byte:
  2221.                             if (truncationPermitted)
  2222.                                 il.Emit(OpCodes.Conv_U1);
  2223.                             else
  2224.                                 il.Emit(OpCodes.Conv_Ovf_U1);
  2225.                             return;
  2226.                         case TypeCode.Int16:
  2227.                             if (truncationPermitted)
  2228.                                 il.Emit(OpCodes.Conv_I2);
  2229.                             else
  2230.                                 il.Emit(OpCodes.Conv_Ovf_I2);
  2231.                             return;
  2232.                         case TypeCode.Char:
  2233.                         case TypeCode.UInt16:
  2234.                             if (truncationPermitted)
  2235.                                 il.Emit(OpCodes.Conv_U2);
  2236.                             else
  2237.                                 il.Emit(OpCodes.Conv_Ovf_U2);
  2238.                             return;
  2239.                         case TypeCode.Int32:
  2240.                             if (truncationPermitted)
  2241.                                 il.Emit(OpCodes.Conv_I4);
  2242.                             else
  2243.                                 il.Emit(OpCodes.Conv_Ovf_I4_Un);
  2244.                             return;
  2245.                         case TypeCode.UInt32:
  2246.                             return;
  2247.                         case TypeCode.Int64:
  2248.                             il.Emit(OpCodes.Conv_I8);
  2249.                             return;
  2250.                         case TypeCode.UInt64:
  2251.                             il.Emit(OpCodes.Conv_U8);
  2252.                             return;
  2253.                         case TypeCode.Single:
  2254.                         case TypeCode.Double:
  2255.                             il.Emit(OpCodes.Conv_R_Un);
  2256.                             return;
  2257.                         case TypeCode.Boolean:
  2258.                             il.Emit(OpCodes.Ldc_I4_0);
  2259.                             il.Emit(OpCodes.Ceq);
  2260.                             il.Emit(OpCodes.Ldc_I4_0);
  2261.                             il.Emit(OpCodes.Ceq);
  2262.                             return;
  2263.                         case TypeCode.Decimal:
  2264.                             il.Emit(OpCodes.Call, CompilerGlobals.uint32ToDecimalMethod);
  2265.                             return;
  2266.                         case TypeCode.DateTime:
  2267.                             il.Emit(OpCodes.Conv_I8);
  2268.                             il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
  2269.                             return;
  2270.                         case TypeCode.String:
  2271.                             Convert.EmitLdloca(il, Typeob.UInt32);
  2272.                             il.Emit(OpCodes.Call, CompilerGlobals.uint32ToStringMethod);
  2273.                             return;
  2274.                     }
  2275.                     break;
  2276.                 case TypeCode.Int64:
  2277.                    
  2278.                     switch (target) {
  2279.                         case TypeCode.Object:
  2280.                             if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
  2281.                                 return;
  2282.                             il.Emit(OpCodes.Box, source_type);
  2283.                             Convert.Emit(ast, il, Typeob.Object, target_type);
  2284.                             return;
  2285.                         case TypeCode.SByte:
  2286.                             if (truncationPermitted)
  2287.                                 il.Emit(OpCodes.Conv_I1);
  2288.                             else
  2289.                                 il.Emit(OpCodes.Conv_Ovf_I1);
  2290.                             return;
  2291.                         case TypeCode.Int16:
  2292.                             if (truncationPermitted)
  2293.                                 il.Emit(OpCodes.Conv_I2);
  2294.                             else
  2295.                                 il.Emit(OpCodes.Conv_Ovf_I2);
  2296.                             return;
  2297.                         case TypeCode.Int32:
  2298.                             if (truncationPermitted)
  2299.                                 il.Emit(OpCodes.Conv_I4);
  2300.                             else
  2301.                                 il.Emit(OpCodes.Conv_Ovf_I4);
  2302.                             return;
  2303.                         case TypeCode.Byte:
  2304.                             if (truncationPermitted)
  2305.                                 il.Emit(OpCodes.Conv_U1);
  2306.                             else
  2307.                                 il.Emit(OpCodes.Conv_Ovf_U1);
  2308.                             return;
  2309.                         case TypeCode.Char:
  2310.                         case TypeCode.UInt16:
  2311.                             if (truncationPermitted)
  2312.                                 il.Emit(OpCodes.Conv_U2);
  2313.                             else
  2314.                                 il.Emit(OpCodes.Conv_Ovf_U2);
  2315.                             return;
  2316.                         case TypeCode.UInt32:
  2317.                             if (truncationPermitted)
  2318.                                 il.Emit(OpCodes.Conv_U4);
  2319.                             else
  2320.                                 il.Emit(OpCodes.Conv_Ovf_U4);
  2321.                             return;
  2322.                         case TypeCode.Int64:
  2323.                             return;
  2324.                         case TypeCode.UInt64:
  2325.                             if (truncationPermitted)
  2326.                                 il.Emit(OpCodes.Conv_U8);
  2327.                             else
  2328.                                 il.Emit(OpCodes.Conv_Ovf_U8);
  2329.                             return;
  2330.                         case TypeCode.Single:
  2331.                         case TypeCode.Double:
  2332.                             il.Emit(OpCodes.Conv_R8);
  2333.                             return;
  2334.                         case TypeCode.Boolean:
  2335.                             il.Emit(OpCodes.Ldc_I4_0);
  2336.                             il.Emit(OpCodes.Conv_I8);
  2337.                             il.Emit(OpCodes.Ceq);
  2338.                             il.Emit(OpCodes.Ldc_I4_0);
  2339.                             il.Emit(OpCodes.Ceq);
  2340.                             return;
  2341.                         case TypeCode.Decimal:
  2342.                             il.Emit(OpCodes.Call, CompilerGlobals.int64ToDecimalMethod);
  2343.                             return;
  2344.                         case TypeCode.DateTime:
  2345.                             il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
  2346.                             return;
  2347.                         case TypeCode.String:
  2348.                             Convert.EmitLdloca(il, Typeob.Int64);
  2349.                             il.Emit(OpCodes.Call, CompilerGlobals.int64ToStringMethod);
  2350.                             return;
  2351.                     }
  2352.                     break;
  2353.                 case TypeCode.UInt64:
  2354.                    
  2355.                     switch (target) {
  2356.                         case TypeCode.Object:
  2357.                             if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
  2358.                                 return;
  2359.                             il.Emit(OpCodes.Box, source_type);
  2360.                             Convert.Emit(ast, il, Typeob.Object, target_type);
  2361.                             return;
  2362.                         case TypeCode.SByte:
  2363.                             if (truncationPermitted)
  2364.                                 il.Emit(OpCodes.Conv_I1);
  2365.                             else
  2366.                                 il.Emit(OpCodes.Conv_Ovf_I1);
  2367.                             return;
  2368.                         case TypeCode.Byte:
  2369.                             if (truncationPermitted)
  2370.                                 il.Emit(OpCodes.Conv_U1);
  2371.                             else
  2372.                                 il.Emit(OpCodes.Conv_Ovf_U1);
  2373.                             return;
  2374.                         case TypeCode.Int16:
  2375.                             if (truncationPermitted)
  2376.                                 il.Emit(OpCodes.Conv_I2);
  2377.                             else
  2378.                                 il.Emit(OpCodes.Conv_Ovf_I2);
  2379.                             return;
  2380.                         case TypeCode.Char:
  2381.                         case TypeCode.UInt16:
  2382.                             if (truncationPermitted)
  2383.                                 il.Emit(OpCodes.Conv_U2);
  2384.                             else
  2385.                                 il.Emit(OpCodes.Conv_Ovf_U2);
  2386.                             return;
  2387.                         case TypeCode.Int32:
  2388.                             if (truncationPermitted)
  2389.                                 il.Emit(OpCodes.Conv_I4);
  2390.                             else
  2391.                                 il.Emit(OpCodes.Conv_Ovf_I4);
  2392.                             return;
  2393.                         case TypeCode.UInt32:
  2394.                             if (truncationPermitted)
  2395.                                 il.Emit(OpCodes.Conv_U4);
  2396.                             else
  2397.                                 il.Emit(OpCodes.Conv_Ovf_U4);
  2398.                             return;
  2399.                         case TypeCode.Int64:
  2400.                             if (truncationPermitted)
  2401.                                 il.Emit(OpCodes.Conv_I8);
  2402.                             else
  2403.                                 il.Emit(OpCodes.Conv_Ovf_I8_Un);
  2404.                             return;
  2405.                         case TypeCode.UInt64:
  2406.                             return;
  2407.                         case TypeCode.Single:
  2408.                         case TypeCode.Double:
  2409.                             il.Emit(OpCodes.Conv_R_Un);
  2410.                             return;
  2411.                         case TypeCode.Boolean:
  2412.                             il.Emit(OpCodes.Ldc_I4_0);
  2413.                             il.Emit(OpCodes.Conv_I8);
  2414.                             il.Emit(OpCodes.Ceq);
  2415.                             il.Emit(OpCodes.Ldc_I4_0);
  2416.                             il.Emit(OpCodes.Ceq);
  2417.                             return;
  2418.                         case TypeCode.Decimal:
  2419.                             il.Emit(OpCodes.Call, CompilerGlobals.uint64ToDecimalMethod);
  2420.                             return;
  2421.                         case TypeCode.DateTime:
  2422.                             il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
  2423.                             return;
  2424.                         case TypeCode.String:
  2425.                             Convert.EmitLdloca(il, Typeob.UInt64);
  2426.                             il.Emit(OpCodes.Call, CompilerGlobals.uint64ToStringMethod);
  2427.                             return;
  2428.                     }
  2429.                     break;
  2430.                 case TypeCode.Single:
  2431.                    
  2432.                     switch (target) {
  2433.                         case TypeCode.Object:
  2434.                             if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
  2435.                                 return;
  2436.                             il.Emit(OpCodes.Box, source_type);
  2437.                             Convert.Emit(ast, il, Typeob.Object, target_type);
  2438.                             return;
  2439.                         case TypeCode.SByte:
  2440.                             if (truncationPermitted)
  2441.                                 Convert.EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_I1);
  2442.                             else {
  2443.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
  2444.                                 il.Emit(OpCodes.Conv_Ovf_I1);
  2445.                             }
  2446.                             return;
  2447.                         case TypeCode.Int16:
  2448.                             if (truncationPermitted)
  2449.                                 Convert.EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_I2);
  2450.                             else {
  2451.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
  2452.                                 il.Emit(OpCodes.Conv_Ovf_I2);
  2453.                             }
  2454.                             return;
  2455.                         case TypeCode.Int32:
  2456.                             if (truncationPermitted)
  2457.                                 Convert.EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_I4);
  2458.                             else {
  2459.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
  2460.                                 il.Emit(OpCodes.Conv_I4);
  2461.                             }
  2462.                             return;
  2463.                         case TypeCode.Byte:
  2464.                             if (truncationPermitted)
  2465.                                 Convert.EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_U1);
  2466.                             else {
  2467.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
  2468.                                 il.Emit(OpCodes.Conv_Ovf_U1);
  2469.                             }
  2470.                             return;
  2471.                         case TypeCode.Char:
  2472.                         case TypeCode.UInt16:
  2473.                             if (truncationPermitted)
  2474.                                 Convert.EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_U2);
  2475.                             else {
  2476.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
  2477.                                 il.Emit(OpCodes.Conv_Ovf_U2);
  2478.                             }
  2479.                             return;
  2480.                         case TypeCode.UInt32:
  2481.                             if (truncationPermitted)
  2482.                                 Convert.EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_Ovf_U4);
  2483.                             else {
  2484.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
  2485.                                 il.Emit(OpCodes.Conv_Ovf_U4);
  2486.                             }
  2487.                             return;
  2488.                         case TypeCode.Int64:
  2489.                             if (truncationPermitted)
  2490.                                 Convert.EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_I8);
  2491.                             else {
  2492.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
  2493.                                 il.Emit(OpCodes.Conv_I8);
  2494.                             }
  2495.                             return;
  2496.                         case TypeCode.UInt64:
  2497.                             if (truncationPermitted)
  2498.                                 Convert.EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_U8);
  2499.                             else {
  2500.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
  2501.                                 il.Emit(OpCodes.Conv_Ovf_U8);
  2502.                             }
  2503.                             return;
  2504.                         case TypeCode.Single:
  2505.                         case TypeCode.Double:
  2506.                             return;
  2507.                         case TypeCode.DateTime:
  2508.                             if (truncationPermitted)
  2509.                                 Convert.EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_I8);
  2510.                             else {
  2511.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
  2512.                                 il.Emit(OpCodes.Conv_Ovf_I8);
  2513.                             }
  2514.                             il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
  2515.                             return;
  2516.                         case TypeCode.Boolean:
  2517.                         case TypeCode.Decimal:
  2518.                         case TypeCode.String:
  2519.                             il.Emit(OpCodes.Conv_R8);
  2520.                             Convert.Emit(ast, il, Typeob.Double, target_type);
  2521.                             return;
  2522.                     }
  2523.                     break;
  2524.                 case TypeCode.Double:
  2525.                    
  2526.                     switch (target) {
  2527.                         case TypeCode.Object:
  2528.                             if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
  2529.                                 return;
  2530.                             il.Emit(OpCodes.Box, source_type);
  2531.                             Convert.Emit(ast, il, Typeob.Object, target_type);
  2532.                             return;
  2533.                         case TypeCode.SByte:
  2534.                             if (truncationPermitted)
  2535.                                 Convert.EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_I1);
  2536.                             else {
  2537.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
  2538.                                 il.Emit(OpCodes.Conv_Ovf_I1);
  2539.                             }
  2540.                             return;
  2541.                         case TypeCode.Int16:
  2542.                             if (truncationPermitted)
  2543.                                 Convert.EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_I2);
  2544.                             else {
  2545.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
  2546.                                 il.Emit(OpCodes.Conv_Ovf_I2);
  2547.                             }
  2548.                             return;
  2549.                         case TypeCode.Int32:
  2550.                             if (truncationPermitted)
  2551.                                 Convert.EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_I4);
  2552.                             else {
  2553.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
  2554.                                 il.Emit(OpCodes.Conv_Ovf_I4);
  2555.                             }
  2556.                             return;
  2557.                         case TypeCode.Byte:
  2558.                             if (truncationPermitted)
  2559.                                 Convert.EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_U1);
  2560.                             else {
  2561.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
  2562.                                 il.Emit(OpCodes.Conv_Ovf_U1);
  2563.                             }
  2564.                             return;
  2565.                         case TypeCode.Char:
  2566.                         case TypeCode.UInt16:
  2567.                             if (truncationPermitted)
  2568.                                 Convert.EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_U2);
  2569.                             else {
  2570.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
  2571.                                 il.Emit(OpCodes.Conv_Ovf_U2);
  2572.                             }
  2573.                             return;
  2574.                         case TypeCode.UInt32:
  2575.                             if (truncationPermitted)
  2576.                                 Convert.EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_U4);
  2577.                             else {
  2578.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
  2579.                                 il.Emit(OpCodes.Conv_Ovf_U4);
  2580.                             }
  2581.                             return;
  2582.                         case TypeCode.Int64:
  2583.                             if (truncationPermitted)
  2584.                                 Convert.EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_I8);
  2585.                             else {
  2586.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
  2587.                                 il.Emit(OpCodes.Conv_I8);
  2588.                             }
  2589.                             return;
  2590.                         case TypeCode.UInt64:
  2591.                             if (truncationPermitted)
  2592.                                 Convert.EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_U8);
  2593.                             else {
  2594.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
  2595.                                 il.Emit(OpCodes.Conv_Ovf_U8);
  2596.                             }
  2597.                             return;
  2598.                         case TypeCode.Single:
  2599.                         case TypeCode.Double:
  2600.                             return;
  2601.                         case TypeCode.Boolean:
  2602.                             il.Emit(OpCodes.Call, CompilerGlobals.doubleToBooleanMethod);
  2603.                             return;
  2604.                         case TypeCode.Decimal:
  2605.                             il.Emit(OpCodes.Call, CompilerGlobals.doubleToDecimalMethod);
  2606.                             return;
  2607.                         case TypeCode.DateTime:
  2608.                             if (truncationPermitted)
  2609.                                 Convert.EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_I8);
  2610.                             else {
  2611.                                 il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
  2612.                                 il.Emit(OpCodes.Conv_Ovf_I8);
  2613.                             }
  2614.                             il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
  2615.                             return;
  2616.                         case TypeCode.String:
  2617.                             il.Emit(OpCodes.Call, CompilerGlobals.doubleToStringMethod);
  2618.                             return;
  2619.                     }
  2620.                     break;
  2621.                 case TypeCode.Decimal:
  2622.                    
  2623.                     switch (target) {
  2624.                         case TypeCode.Object:
  2625.                             if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
  2626.                                 return;
  2627.                             il.Emit(OpCodes.Box, source_type);
  2628.                             Convert.Emit(ast, il, Typeob.Object, target_type);
  2629.                             return;
  2630.                         case TypeCode.Char:
  2631.                         case TypeCode.SByte:
  2632.                         case TypeCode.Byte:
  2633.                         case TypeCode.Int16:
  2634.                         case TypeCode.UInt16:
  2635.                         case TypeCode.Int32:
  2636.                             if (truncationPermitted) {
  2637.                                 Convert.EmitDecimalToIntegerTruncatedConversion(il, OpCodes.Conv_I4);
  2638.                             }
  2639.                             else
  2640.                                 il.Emit(OpCodes.Call, CompilerGlobals.decimalToInt32Method);
  2641.                             Convert.Emit(ast, il, Typeob.Int32, target_type, truncationPermitted);
  2642.                             return;
  2643.                         case TypeCode.UInt32:
  2644.                             if (truncationPermitted) {
  2645.                                 Convert.EmitDecimalToIntegerTruncatedConversion(il, OpCodes.Conv_U4);
  2646.                             }
  2647.                             else
  2648.                                 il.Emit(OpCodes.Call, CompilerGlobals.decimalToUInt32Method);
  2649.                             return;
  2650.                         case TypeCode.Boolean:
  2651.                             il.Emit(OpCodes.Ldsfld, CompilerGlobals.decimalZeroField);
  2652.                             il.Emit(OpCodes.Call, CompilerGlobals.decimalCompare);
  2653.                             il.Emit(OpCodes.Ldc_I4_0);
  2654.                             il.Emit(OpCodes.Ceq);
  2655.                             il.Emit(OpCodes.Ldc_I4_0);
  2656.                             il.Emit(OpCodes.Ceq);
  2657.                             return;
  2658.                         case TypeCode.Single:
  2659.                         case TypeCode.Double:
  2660.                             il.Emit(OpCodes.Call, CompilerGlobals.decimalToDoubleMethod);
  2661.                             Convert.Emit(ast, il, Typeob.Double, target_type, truncationPermitted);
  2662.                             return;
  2663.                         case TypeCode.Int64:
  2664.                             if (truncationPermitted) {
  2665.                                 Convert.EmitDecimalToIntegerTruncatedConversion(il, OpCodes.Conv_I8);
  2666.                             }
  2667.                             else
  2668.                                 il.Emit(OpCodes.Call, CompilerGlobals.decimalToInt64Method);
  2669.                             return;
  2670.                         case TypeCode.UInt64:
  2671.                             if (truncationPermitted) {
  2672.                                 Convert.EmitDecimalToIntegerTruncatedConversion(il, OpCodes.Conv_U8);
  2673.                             }
  2674.                             else
  2675.                                 il.Emit(OpCodes.Call, CompilerGlobals.decimalToUInt64Method);
  2676.                             return;
  2677.                         case TypeCode.Decimal:
  2678.                             return;
  2679.                         case TypeCode.DateTime:
  2680.                             if (truncationPermitted) {
  2681.                                 Convert.EmitDecimalToIntegerTruncatedConversion(il, OpCodes.Conv_I8);
  2682.                             }
  2683.                             else
  2684.                                 il.Emit(OpCodes.Call, CompilerGlobals.decimalToInt64Method);
  2685.                             Convert.Emit(ast, il, Typeob.Int64, target_type);
  2686.                             return;
  2687.                         case TypeCode.String:
  2688.                             Convert.EmitLdloca(il, source_type);
  2689.                             il.Emit(OpCodes.Call, CompilerGlobals.decimalToStringMethod);
  2690.                             return;
  2691.                     }
  2692.                     break;
  2693.                 case TypeCode.DateTime:
  2694.                    
  2695.                     switch (target) {
  2696.                         case TypeCode.Object:
  2697.                             if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
  2698.                                 return;
  2699.                             il.Emit(OpCodes.Box, source_type);
  2700.                             Convert.Emit(ast, il, Typeob.Object, target_type);
  2701.                             return;
  2702.                         case TypeCode.Boolean:
  2703.                         case TypeCode.Char:
  2704.                         case TypeCode.SByte:
  2705.                         case TypeCode.Byte:
  2706.                         case TypeCode.Int16:
  2707.                         case TypeCode.UInt16:
  2708.                         case TypeCode.Int32:
  2709.                         case TypeCode.UInt32:
  2710.                         case TypeCode.Int64:
  2711.                         case TypeCode.UInt64:
  2712.                         case TypeCode.Single:
  2713.                         case TypeCode.Double:
  2714.                         case TypeCode.Decimal:
  2715.                             Convert.EmitLdloca(il, source_type);
  2716.                             il.Emit(OpCodes.Call, CompilerGlobals.dateTimeToInt64Method);
  2717.                             Convert.Emit(ast, il, Typeob.Int64, target_type, truncationPermitted);
  2718.                             return;
  2719.                         case TypeCode.DateTime:
  2720.                             return;
  2721.                         case TypeCode.String:
  2722.                             Convert.EmitLdloca(il, source_type);
  2723.                             il.Emit(OpCodes.Call, CompilerGlobals.dateTimeToStringMethod);
  2724.                             return;
  2725.                     }
  2726.                     break;
  2727.                 case TypeCode.String:
  2728.                    
  2729.                     switch (target) {
  2730.                         case TypeCode.Object:
  2731.                             if (target_type != Typeob.Object && !(target_type is TypeBuilder) && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
  2732.                                 return;
  2733.                             Convert.Emit(ast, il, Typeob.Object, target_type);
  2734.                             return;
  2735.                         case TypeCode.Boolean:
  2736.                         case TypeCode.Char:
  2737.                         case TypeCode.SByte:
  2738.                         case TypeCode.Byte:
  2739.                         case TypeCode.Int16:
  2740.                         case TypeCode.UInt16:
  2741.                         case TypeCode.Int32:
  2742.                         case TypeCode.UInt32:
  2743.                         case TypeCode.Int64:
  2744.                         case TypeCode.UInt64:
  2745.                         case TypeCode.Single:
  2746.                         case TypeCode.Double:
  2747.                         case TypeCode.Decimal:
  2748.                         case TypeCode.DateTime:
  2749.                             //Resort to calling the Coerce routine. The extra call and the extra box/unbox adds neglible cost to such an expensive conversion.
  2750.                             if (truncationPermitted && target == TypeCode.Int32) {
  2751.                                 il.Emit(OpCodes.Call, CompilerGlobals.toInt32Method);
  2752.                                 return;
  2753.                             }
  2754.                             else {
  2755.                                 ConstantWrapper.TranslateToILInt(il, (int)target);
  2756.                                 ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
  2757.                                 il.Emit(OpCodes.Call, CompilerGlobals.coerce2Method);
  2758.                             }
  2759.                             if (target_type.IsValueType)
  2760.                                 //Should always be true, but may as well check
  2761.                                 Convert.EmitUnbox(il, target_type, target);
  2762.                             return;
  2763.                         case TypeCode.String:
  2764.                             return;
  2765.                     }
  2766.                     break;
  2767.             }
  2768.             Convert.Emit(ast, il, source_type, Typeob.Object);
  2769.             //The thing on the stack cannot be converted to target_type. Arrange for an error message.
  2770.             il.Emit(OpCodes.Call, CompilerGlobals.throwTypeMismatch);
  2771.             LocalBuilder tok = il.DeclareLocal(target_type);
  2772.             //Add dummy code to reassure the verifier.
  2773.             il.Emit(OpCodes.Ldloc, tok);
  2774.         }
  2775.        
  2776.         // Emit code sequence used for explicit casts from floating point numbers to integer values.
  2777.         // A call is needed because the built in opcodes such as Conv.I4 have unspecified behavior
  2778.         // if the value overflows the integer.
  2779.         static internal void EmitSingleToIntegerTruncatedConversion(ILGenerator il, OpCode opConversion)
  2780.         {
  2781.             il.Emit(OpCodes.Conv_R8);
  2782.             EmitDoubleToIntegerTruncatedConversion(il, opConversion);
  2783.         }
  2784.         static internal void EmitDoubleToIntegerTruncatedConversion(ILGenerator il, OpCode opConversion)
  2785.         {
  2786.             il.Emit(OpCodes.Call, CompilerGlobals.doubleToInt64);
  2787.             if (!opConversion.Equals(OpCodes.Conv_I8))
  2788.                 il.Emit(opConversion);
  2789.         }
  2790.         static internal void EmitDecimalToIntegerTruncatedConversion(ILGenerator il, OpCode opConversion)
  2791.         {
  2792.             il.Emit(OpCodes.Call, CompilerGlobals.uncheckedDecimalToInt64Method);
  2793.             if (!opConversion.Equals(OpCodes.Conv_I8))
  2794.                 il.Emit(opConversion);
  2795.         }
  2796.        
  2797.         static internal void EmitUnbox(ILGenerator il, Type target_type, TypeCode target)
  2798.         {
  2799.             il.Emit(OpCodes.Unbox, target_type);
  2800.             switch (target) {
  2801.                 case TypeCode.Boolean:
  2802.                 case TypeCode.Byte:
  2803.                     il.Emit(OpCodes.Ldind_U1);
  2804.                     return;
  2805.                 case TypeCode.Char:
  2806.                 case TypeCode.UInt16:
  2807.                     il.Emit(OpCodes.Ldind_U2);
  2808.                     return;
  2809.                 case TypeCode.SByte:
  2810.                     il.Emit(OpCodes.Ldind_I1);
  2811.                     return;
  2812.                 case TypeCode.Int16:
  2813.                     il.Emit(OpCodes.Ldind_I2);
  2814.                     return;
  2815.                 case TypeCode.Int32:
  2816.                     il.Emit(OpCodes.Ldind_I4);
  2817.                     return;
  2818.                 case TypeCode.UInt32:
  2819.                     il.Emit(OpCodes.Ldind_U4);
  2820.                     return;
  2821.                 case TypeCode.Int64:
  2822.                 case TypeCode.UInt64:
  2823.                     il.Emit(OpCodes.Ldind_I8);
  2824.                     return;
  2825.                 case TypeCode.Single:
  2826.                     il.Emit(OpCodes.Ldind_R4);
  2827.                     return;
  2828.                 case TypeCode.Double:
  2829.                     il.Emit(OpCodes.Ldind_R8);
  2830.                     return;
  2831.                 default:
  2832.                     il.Emit(OpCodes.Ldobj, target_type);
  2833.                     return;
  2834.             }
  2835.         }
  2836.        
  2837.         private static bool EmittedCallToConversionMethod(AST ast, ILGenerator il, Type source_type, Type target_type)
  2838.         {
  2839.             //Look for an explicit conversion, call that if there is one
  2840.             MethodInfo meth = target_type.GetMethod("op_Explicit", BindingFlags.ExactBinding | BindingFlags.Public | BindingFlags.Static, null, new Type[] {source_type}, null);
  2841.             if (meth != null) {
  2842.                 il.Emit(OpCodes.Call, meth);
  2843.                 Convert.Emit(ast, il, meth.ReturnType, target_type);
  2844.                 return true;
  2845.             }
  2846.             meth = Convert.GetToXXXXMethod(source_type, target_type, true);
  2847.             if (meth != null) {
  2848.                 il.Emit(OpCodes.Call, meth);
  2849.                 return true;
  2850.             }
  2851.            
  2852.             //Look for implicit conversion, call that if there is one
  2853.             meth = target_type.GetMethod("op_Implicit", BindingFlags.ExactBinding | BindingFlags.Public | BindingFlags.Static, null, new Type[] {source_type}, null);
  2854.             if (meth != null) {
  2855.                 il.Emit(OpCodes.Call, meth);
  2856.                 Convert.Emit(ast, il, meth.ReturnType, target_type);
  2857.                 return true;
  2858.             }
  2859.             meth = Convert.GetToXXXXMethod(source_type, target_type, false);
  2860.             if (meth != null) {
  2861.                 il.Emit(OpCodes.Call, meth);
  2862.                 return true;
  2863.             }
  2864.             return false;
  2865.         }
  2866.        
  2867.         static internal void EmitLdarg(ILGenerator il, short argNum)
  2868.         {
  2869.             switch (argNum) {
  2870.                 case 0:
  2871.                     il.Emit(OpCodes.Ldarg_0);
  2872.                     return;
  2873.                 case 1:
  2874.                     il.Emit(OpCodes.Ldarg_1);
  2875.                     return;
  2876.                 case 2:
  2877.                     il.Emit(OpCodes.Ldarg_2);
  2878.                     return;
  2879.                 case 3:
  2880.                     il.Emit(OpCodes.Ldarg_3);
  2881.                     return;
  2882.             }
  2883.             if (argNum < 256)
  2884.                 il.Emit(OpCodes.Ldarg_S, (byte)argNum);
  2885.             else
  2886.                 il.Emit(OpCodes.Ldarg, argNum);
  2887.         }
  2888.        
  2889.         static internal void EmitLdloca(ILGenerator il, Type source_type)
  2890.         {
  2891.             LocalBuilder tok = il.DeclareLocal(source_type);
  2892.             il.Emit(OpCodes.Stloc, tok);
  2893.             il.Emit(OpCodes.Ldloca, tok);
  2894.         }
  2895.        
  2896.         private static IReflect GetArrayElementType(IReflect ir)
  2897.         {
  2898.             if (ir is TypedArray)
  2899.                 return ((TypedArray)ir).elementType;
  2900.             else if (ir is Type && ((Type)ir).IsArray)
  2901.                 return ((Type)ir).GetElementType();
  2902.             else if (ir is ArrayObject || ir == Typeob.ArrayObject)
  2903.                 return Typeob.Object;
  2904.             else
  2905.                 return null;
  2906.         }
  2907.        
  2908.         static internal int GetArrayRank(IReflect ir)
  2909.         {
  2910.             if (ir == Typeob.ArrayObject || ir is ArrayObject)
  2911.                 return 1;
  2912.             else if (ir is TypedArray)
  2913.                 return ((TypedArray)ir).rank;
  2914.             else if (ir is Type && ((Type)ir).IsArray)
  2915.                 return ((Type)ir).GetArrayRank();
  2916.             else
  2917.                 return -1;
  2918.         }
  2919.        
  2920.         static internal IConvertible GetIConvertible(object ob)
  2921.         {
  2922.             return ob as IConvertible;
  2923.         }
  2924.        
  2925.         private static MethodInfo GetToXXXXMethod(IReflect ir, Type desiredType, bool explicitOK)
  2926.         {
  2927.             if ((ir is TypeBuilder) || (ir is EnumBuilder))
  2928.                 return null;
  2929.             MemberInfo[] members = ir.GetMember(explicitOK ? "op_Explicit" : "op_Implicit", BindingFlags.Public | BindingFlags.Static);
  2930.             if (members != null)
  2931.                 foreach (MemberInfo mem in members)
  2932.                     if (mem is MethodInfo)
  2933.                         if (((MethodInfo)mem).ReturnType == desiredType)
  2934.                             return (MethodInfo)mem;
  2935.             return null;
  2936.         }
  2937.        
  2938.         static internal TypeCode GetTypeCode(object ob, IConvertible ic)
  2939.         {
  2940.             if (ob == null)
  2941.                 return TypeCode.Empty;
  2942.             if (ic == null)
  2943.                 return TypeCode.Object;
  2944.             return ic.GetTypeCode();
  2945.         }
  2946.        
  2947.         static internal TypeCode GetTypeCode(object ob)
  2948.         {
  2949.             return Convert.GetTypeCode(ob, Convert.GetIConvertible(ob));
  2950.         }
  2951.        
  2952.         static internal Type GetUnderlyingType(Type type)
  2953.         {
  2954.             if (type is TypeBuilder)
  2955.                 return type.UnderlyingSystemType;
  2956.             return Enum.GetUnderlyingType(type);
  2957.         }
  2958.        
  2959.         static internal bool IsArray(IReflect ir)
  2960.         {
  2961.             return ir == Typeob.Array || ir == Typeob.ArrayObject || ir is TypedArray || ir is ArrayObject || (ir is Type && ((Type)ir).IsArray);
  2962.         }
  2963.        
  2964.         private static bool IsArrayElementTypeKnown(IReflect ir)
  2965.         {
  2966.             Debug.PreCondition(IsArray(ir));
  2967.             return ir == Typeob.ArrayObject || ir is TypedArray || ir is ArrayObject || (ir is Type && ((Type)ir).IsArray);
  2968.         }
  2969.        
  2970.         static internal bool IsArrayRankKnown(IReflect ir)
  2971.         {
  2972.             Debug.PreCondition(IsArray(ir));
  2973.             return ir == Typeob.ArrayObject || ir is TypedArray || ir is ArrayObject || (ir is Type && ((Type)ir).IsArray);
  2974.         }
  2975.        
  2976.         static internal bool IsArrayType(IReflect ir)
  2977.         {
  2978.             return ir is TypedArray || ir == Typeob.Array || ir == Typeob.ArrayObject || (ir is Type && ((Type)ir).IsArray);
  2979.         }
  2980.        
  2981.         static internal bool IsJScriptArray(IReflect ir)
  2982.         {
  2983.             return ir is ArrayObject || ir == Typeob.ArrayObject;
  2984.         }
  2985.        
  2986.         static internal bool IsPrimitiveSignedNumericType(Type t)
  2987.         {
  2988.             switch (Type.GetTypeCode(t)) {
  2989.                 case TypeCode.Single:
  2990.                 case TypeCode.Double:
  2991.                 case TypeCode.SByte:
  2992.                 case TypeCode.Int16:
  2993.                 case TypeCode.Int32:
  2994.                 case TypeCode.Int64:
  2995.                     return true;
  2996.             }
  2997.             return false;
  2998.         }
  2999.        
  3000.         static internal bool IsPrimitiveSignedIntegerType(Type t)
  3001.         {
  3002.             switch (Type.GetTypeCode(t)) {
  3003.                 case TypeCode.SByte:
  3004.                 case TypeCode.Int16:
  3005.                 case TypeCode.Int32:
  3006.                 case TypeCode.Int64:
  3007.                     return true;
  3008.             }
  3009.             return false;
  3010.         }
  3011.        
  3012.         static internal bool IsPrimitiveUnsignedIntegerType(Type t)
  3013.         {
  3014.             switch (Type.GetTypeCode(t)) {
  3015.                 case TypeCode.Byte:
  3016.                 case TypeCode.UInt16:
  3017.                 case TypeCode.UInt32:
  3018.                 case TypeCode.UInt64:
  3019.                     return true;
  3020.             }
  3021.             return false;
  3022.         }
  3023.        
  3024.         static internal bool IsPrimitiveIntegerType(Type t)
  3025.         {
  3026.             switch (Type.GetTypeCode(t)) {
  3027.                 case TypeCode.SByte:
  3028.                 case TypeCode.Byte:
  3029.                 case TypeCode.Int16:
  3030.                 case TypeCode.UInt16:
  3031.                 case TypeCode.Int32:
  3032.                 case TypeCode.UInt32:
  3033.                 case TypeCode.Int64:
  3034.                 case TypeCode.UInt64:
  3035.                     return true;
  3036.             }
  3037.             return false;
  3038.         }
  3039.        
  3040.         static internal bool IsPrimitiveNumericTypeCode(TypeCode tc)
  3041.         {
  3042.             switch (tc) {
  3043.                 case TypeCode.SByte:
  3044.                 case TypeCode.Byte:
  3045.                 case TypeCode.Int16:
  3046.                 case TypeCode.UInt16:
  3047.                 case TypeCode.Int32:
  3048.                 case TypeCode.UInt32:
  3049.                 case TypeCode.Int64:
  3050.                 case TypeCode.UInt64:
  3051.                 case TypeCode.Single:
  3052.                 case TypeCode.Double:
  3053.                     return true;
  3054.             }
  3055.             return false;
  3056.         }
  3057.        
  3058.         static internal bool IsPrimitiveNumericType(IReflect ir)
  3059.         {
  3060.             Type t = ir as Type;
  3061.             if (t == null)
  3062.                 return false;
  3063.             return Convert.IsPrimitiveNumericTypeCode(Type.GetTypeCode(t));
  3064.         }
  3065.        
  3066.         static internal bool IsPrimitiveNumericTypeFitForDouble(IReflect ir)
  3067.         {
  3068.             Type t = ir as Type;
  3069.             if (t == null)
  3070.                 return false;
  3071.             switch (Type.GetTypeCode(t)) {
  3072.                 case TypeCode.SByte:
  3073.                 case TypeCode.Byte:
  3074.                 case TypeCode.Int16:
  3075.                 case TypeCode.UInt16:
  3076.                 case TypeCode.Int32:
  3077.                 case TypeCode.UInt32:
  3078.                 case TypeCode.Single:
  3079.                 case TypeCode.Double:
  3080.                     return true;
  3081.             }
  3082.             return false;
  3083.         }
  3084.        
  3085. /* indicates whether all values of source type can be converted to the target type without loss of information */       
  3086.         private static bool[,] promotable = new bool[,] {{true, true, true, true, true, true, true, true, true, true,
  3087.         true, true, true, true, true, true, true, true, true}, {false, false, false, false, false, false, false, false, false, false,
  3088.         false, false, false, false, false, false, false, false, false}, {true, true, true, true, true, true, true, true, true, true,
  3089.         true, true, true, true, true, true, true, true, true}, {false, false, false, true, true, true, true, true, true, true,
  3090.         true, true, true, true, true, true, true, true, false}, {false, false, false, false, true, false, false, false, true, true,
  3091.         true, true, true, true, true, true, true, true, false}, {false, false, false, false, false, true, false, true, false, true,
  3092.         false, true, false, true, true, true, true, true, false}, {false, false, false, false, true, false, true, true, true, true,
  3093.         true, true, true, true, true, true, true, true, false}, {false, false, false, false, false, true, false, true, false, true,
  3094.         false, true, false, true, true, true, true, true, false}, {false, false, false, false, true, false, false, false, true, true,
  3095.         true, true, true, true, true, true, true, true, false}, {false, false, false, false, false, false, false, false, false, true,
  3096.         false, true, false, false, true, true, true, true, false},
  3097.         {false, false, false, false, false, false, false, false, false, false,
  3098.         true, true, true, false, true, true, true, true, false}, {false, false, false, false, false, false, false, false, false, false,
  3099.         false, true, false, false, false, true, true, true, false}, {false, false, false, false, false, false, false, false, false, false,
  3100.         false, false, true, false, false, true, true, true, false}, {false, false, false, false, false, false, false, false, false, false,
  3101.         false, false, false, true, true, true, false, false, false}, {false, false, false, false, false, false, false, false, false, false,
  3102.         false, false, false, false, true, true, false, false, false}, {false, false, false, false, false, false, false, false, false, false,
  3103.         false, false, false, false, false, true, false, false, false}, {false, false, false, false, false, false, false, false, false, false,
  3104.         false, false, false, false, false, false, true, false, false}, {false, false, false, false, false, false, false, false, false, false,
  3105.         false, false, false, false, false, false, false, true, false}, {false, false, false, false, false, false, false, false, false, false,
  3106.             /*target type*/            /*source      Empty  Object DBNull Boolean Char  SByte  Byte  Int16  UInt16 Int32  UInt32 Int64  UInt64 Single Double Decimal DateTime TimeSpan String*/           
  3107.             /*Empty*/            /*Object*/            /*DBNull*/            /*Boolean*/            /*Char*/            /*SByte*/            /*Byte*/            /*Int16*/            /*UInt16*/            /*Int32*/            /*UInt32*/            /*Int64*/            /*UInt64*/            /*Single*/            /*Double*/            /*Decimal*/            /*DateTime*/            /*TimeSpan*/            /*String*/        false, false, false, false, false, false, false, false, true}};
  3108.         // By "promotable" we mean that:
  3109.         // * value types may be promoted to other value types if there is no possible loss of data
  3110.         // (Int16 is promotable to Double, but Double is not promotable to Int16.)
  3111.         // * value types may be promoted to their wrapper reference types
  3112.         // (A boolean is promotable to a Boolean object.)
  3113.         // * reference types may be promoted to reference types they inherit from, but not vice-versa.
  3114.         // (A Derived is promotable to a Base, but a Base is not promotable to a Derived.)
  3115.        
  3116.         private static bool IsPromotableTo(Type source_type, Type target_type)
  3117.         {
  3118.             TypeCode source = Type.GetTypeCode(source_type);
  3119.             TypeCode target = Type.GetTypeCode(target_type);
  3120.             if (Convert.promotable[(int)source, (int)target])
  3121.                 return true;
  3122.             if ((source == TypeCode.Object || source == TypeCode.String) && target == TypeCode.Object) {
  3123.                 if (target_type.IsAssignableFrom(source_type))
  3124.                     return true;
  3125.                 if (target_type == Typeob.BooleanObject && source_type == Typeob.Boolean)
  3126.                     return true;
  3127.                 if (target_type == Typeob.StringObject && source_type == Typeob.String)
  3128.                     return true;
  3129.                 if (target_type == Typeob.NumberObject && Convert.IsPromotableTo(source_type, Typeob.Double))
  3130.                     return true;
  3131.                 if (target_type == Typeob.Array || source_type == Typeob.Array || target_type.IsArray || source_type.IsArray)
  3132.                     return Convert.IsPromotableToArray(source_type, target_type);
  3133.             }
  3134.             if (source_type == Typeob.BooleanObject && target_type == Typeob.Boolean)
  3135.                 return true;
  3136.             if (source_type == Typeob.StringObject && target_type == Typeob.String)
  3137.                 return true;
  3138.             if (source_type == Typeob.DateObject && target_type == Typeob.DateTime)
  3139.                 return true;
  3140.             if (source_type == Typeob.NumberObject)
  3141.                 return Convert.IsPrimitiveNumericType(target_type);
  3142.             if (source_type.IsEnum)
  3143.                 return !target_type.IsEnum && Convert.IsPromotableTo(Convert.GetUnderlyingType(source_type), target_type);
  3144.             if (target_type.IsEnum)
  3145.                 return !source_type.IsEnum && Convert.IsPromotableTo(source_type, Convert.GetUnderlyingType(target_type));
  3146.             //Look for implicit conversions.
  3147.             MethodInfo meth = target_type.GetMethod("op_Implicit", BindingFlags.ExactBinding | BindingFlags.Public | BindingFlags.Static, null, new Type[] {source_type}, null);
  3148.             if (meth != null && (meth.Attributes & MethodAttributes.SpecialName) != 0)
  3149.                 return true;
  3150.             meth = Convert.GetToXXXXMethod(source_type, target_type, false);
  3151.             if (meth != null && (meth.Attributes & MethodAttributes.SpecialName) != 0)
  3152.                 return true;
  3153.             return false;
  3154.         }
  3155.        
  3156.         static internal bool IsPromotableTo(IReflect source_ir, IReflect target_ir)
  3157.         {
  3158.             Type target_type;
  3159.             if (source_ir is TypedArray || target_ir is TypedArray || source_ir is ArrayObject || target_ir is ArrayObject || source_ir == Typeob.ArrayObject || target_ir == Typeob.ArrayObject)
  3160.                 return Convert.IsPromotableToArray(source_ir, target_ir);
  3161.             if (target_ir is ClassScope) {
  3162.                 if (((ClassScope)target_ir).owner is EnumDeclaration) {
  3163.                     if (Convert.IsPrimitiveNumericType(source_ir))
  3164.                         return IsPromotableTo(source_ir, ((EnumDeclaration)((ClassScope)target_ir).owner).baseType.ToType());
  3165.                     else if (source_ir == Typeob.String)
  3166.                         return true;
  3167.                     else if (source_ir == target_ir)
  3168.                         return true;
  3169.                     return false;
  3170.                 }
  3171.                 if (source_ir is ClassScope)
  3172.                     return (((ClassScope)source_ir).IsSameOrDerivedFrom((ClassScope)target_ir));
  3173.                 return false;
  3174.                 //The source is not in the same compilation unit. Thus it can only extend the target type if there is a circular dependency and separate compilation. Can't handle that.
  3175.             }
  3176.             else if (target_ir is Type) {
  3177.                 if (target_ir == Typeob.Object)
  3178.                     return !(source_ir is Type) || !((Type)source_ir).IsByRef;
  3179.                 target_type = (Type)target_ir;
  3180.             }
  3181.             else if (target_ir is ScriptFunction)
  3182.                 target_type = Typeob.ScriptFunction;
  3183.             else
  3184.                 //assert that target_ir is JSObject
  3185.                 target_type = Globals.TypeRefs.ToReferenceContext(target_ir.GetType());
  3186.             if (source_ir is ClassScope)
  3187.                 return ((ClassScope)source_ir).IsPromotableTo(target_type);
  3188.             else
  3189.                 return IsPromotableTo(source_ir is Type ? (Type)source_ir : Globals.TypeRefs.ToReferenceContext(source_ir.GetType()), target_type);
  3190.         }
  3191.        
  3192.         // IsPromotableToArray determines whether or not we _know_ at compile time
  3193.         // that a given source type may be _promoted_ safely to a given target type.
  3194.         // Here we are concerned about two things:
  3195.         // (1) Is the target a base class of the source?
  3196.         // (2) Is the target a wrapper class of the source?
  3197.         //
  3198.         // We wish to implement the following semantics:
  3199.         //
  3200.         // * No non-array is promotable to any array.
  3201.         // * An array is only promotable to another array or Object.
  3202.         // * Any array (regardless of element type or rank) is promotable to Object.
  3203.         // * JScript arrays are not promotable to anything except JS Array and Object.
  3204.         // * Every array (other than JScript array) is promotable to System.Array.
  3205.         // * System.Array is not promotable to anything -- we do not have enough information
  3206.         // to make a safe promotion. Note that System Arrays are _assignment compatible_ to
  3207.         // JScript arrays but not _promotable_ to JScript arrays. We wish to be conservative
  3208.         // here and we do not know if the System.Array is of rank one.
  3209.         // * Any rank-one array (regardless of element type) is promotable to a JScript array
  3210.         // via the wrapper class.
  3211.         // * A source array is promotable to a typed array only if the source and the target
  3212.         // are known to be both equal in rank and element-type compatible.
  3213.         // * By "element type compatible" we mean the following: Value types are only compatible
  3214.         // with equal value types. (Int16[] is not promotable to Int32[] even though Int16
  3215.         // is promotable to Int32.) Value types are never compatible with reference types.
  3216.         // (Int32[] is not promotable to Object[].) Reference types are only compatible if
  3217.         // they are promotable. (Derived[] is promotable to Base[] but Base[] is not
  3218.         // promotable to Derived[].)
  3219.        
  3220.         private static bool IsPromotableToArray(IReflect source_ir, IReflect target_ir)
  3221.         {
  3222.             Debug.PreCondition(IsArray(source_ir) || IsArray(target_ir));
  3223.             if (!IsArray(source_ir))
  3224.                 return false;
  3225.             else if (target_ir == Typeob.Object)
  3226.                 return true;
  3227.             else if (!IsArray(target_ir)) {
  3228.                 if (target_ir is Type) {
  3229.                     Type tt = (Type)target_ir;
  3230.                     if (tt.IsInterface && tt.IsAssignableFrom(Typeob.Array))
  3231.                         return source_ir is TypedArray || (source_ir is Type && ((Type)source_ir).IsArray);
  3232.                 }
  3233.                 return false;
  3234.             }
  3235.             else if (IsJScriptArray(source_ir) && !IsJScriptArray(target_ir))
  3236.                 return false;
  3237.             else if (target_ir == Typeob.Array)
  3238.                 return !IsJScriptArray(source_ir);
  3239.             else if (source_ir == Typeob.Array)
  3240.                 return false;
  3241.             else if (GetArrayRank(source_ir) == 1 && IsJScriptArray(target_ir))
  3242.                 return true;
  3243.             else if (GetArrayRank(source_ir) != GetArrayRank(target_ir))
  3244.                 return false;
  3245.            
  3246.             IReflect source_element_ir = GetArrayElementType(source_ir);
  3247.             IReflect target_element_ir = GetArrayElementType(target_ir);
  3248.            
  3249.             if (null == source_element_ir || null == target_element_ir)
  3250.                 return false;
  3251.            
  3252.             if ((source_element_ir is Type && ((Type)source_element_ir).IsValueType) || (target_element_ir is Type && ((Type)target_element_ir).IsValueType))
  3253.                 return source_element_ir == target_element_ir;
  3254.             else
  3255.                 return Convert.IsPromotableTo(source_element_ir, target_element_ir);
  3256.         }
  3257.        
  3258.         private static bool IsWhiteSpace(char c)
  3259.         {
  3260.             switch (c) {
  3261.                 case (char)9:
  3262.                 case (char)10:
  3263.                 case (char)11:
  3264.                 case (char)12:
  3265.                 case (char)13:
  3266.                 case (char)32:
  3267.                 case (char)160:
  3268.                     return true;
  3269.                 default:
  3270.                     if (c >= 128)
  3271.                         return Char.IsWhiteSpace(c);
  3272.                     else
  3273.                         return false;
  3274.                     break;
  3275.             }
  3276.         }
  3277.        
  3278.         private static bool IsWhiteSpaceTrailer(char[] s, int i, int max)
  3279.         {
  3280.             for (; i < max; i++)
  3281.                 if (!IsWhiteSpace(s[i]))
  3282.                     return false;
  3283.             return true;
  3284.         }
  3285.        
  3286.         static internal object LiteralToNumber(string str)
  3287.         {
  3288.             return Convert.LiteralToNumber(str, null);
  3289.         }
  3290.        
  3291.         static internal object LiteralToNumber(string str, Context context)
  3292.         {
  3293.             //Called from the parser for integer literals
  3294.             uint r = 10;
  3295.             if (str[0] == '0' && str.Length > 1)
  3296.                 if (str[1] == 'x' || str[1] == 'X')
  3297.                     r = 16;
  3298.                 else
  3299.                     r = 8;
  3300.             object result = Convert.parseRadix(str.ToCharArray(), r, r == 16 ? 2 : 0, 1, false);
  3301.             if (result != null) {
  3302.                
  3303.                 if (r == 8 && context != null && result is Int32 && ((int)result) > 7)
  3304.                     context.HandleError(JSError.OctalLiteralsAreDeprecated);
  3305.                 return result;
  3306.             }
  3307.             context.HandleError(JSError.BadOctalLiteral);
  3308.             return Convert.parseRadix(str.ToCharArray(), 10, 0, 1, false);
  3309.         }
  3310.        
  3311.         static internal bool NeedsWrapper(TypeCode code)
  3312.         {
  3313.             switch (code) {
  3314.                 case TypeCode.Boolean:
  3315.                 case TypeCode.Char:
  3316.                 case TypeCode.SByte:
  3317.                 case TypeCode.Byte:
  3318.                 case TypeCode.Int16:
  3319.                 case TypeCode.UInt16:
  3320.                 case TypeCode.Int32:
  3321.                 case TypeCode.UInt32:
  3322.                 case TypeCode.Int64:
  3323.                 case TypeCode.UInt64:
  3324.                 case TypeCode.Single:
  3325.                 case TypeCode.Double:
  3326.                 case TypeCode.Decimal:
  3327.                 case TypeCode.String:
  3328.                     return true;
  3329.             }
  3330.             return false;
  3331.         }
  3332.        
  3333.         private static double DoubleParse(string str)
  3334.         {
  3335.             try {
  3336.                 return Double.Parse(str, NumberStyles.Float, CultureInfo.InvariantCulture);
  3337.             }
  3338.             catch (OverflowException) {
  3339.                 int i = 0;
  3340.                 int n = str.Length;
  3341.                 while (i < n && IsWhiteSpace(str[i]))
  3342.                     i++;
  3343.                 if (i < n && str[i] == '-')
  3344.                     return Double.NegativeInfinity;
  3345.                 else
  3346.                     return Double.PositiveInfinity;
  3347.             }
  3348.         }
  3349.        
  3350.         private static object parseRadix(char[] s, uint rdx, int i, int sign, bool ignoreTrailers)
  3351.         {
  3352.             int max = s.Length;
  3353.             if (i >= max)
  3354.                 return null;
  3355.             ulong multmax = (ulong)(UInt64.MaxValue / rdx);
  3356.             int digit = RadixDigit(s[i], rdx);
  3357.             if (digit < 0)
  3358.                 return null;
  3359.             ulong result = (ulong)digit;
  3360.             int saved_i = i;
  3361.             for (;;) {
  3362.                 if (++i == max)
  3363.                     goto returnAsInteger;
  3364.                 digit = RadixDigit(s[i], rdx);
  3365.                 if (digit < 0)
  3366.                     if (ignoreTrailers || IsWhiteSpaceTrailer(s, i, max))
  3367.                         goto returnAsInteger;
  3368.                     else
  3369.                         return null;
  3370.                 if (result > multmax)
  3371.                     goto returnAsDouble;
  3372.                 unchecked {
  3373.                     ulong r1 = result * rdx;
  3374.                     ulong r2 = r1 + (ulong)digit;
  3375.                     if (r1 > r2)
  3376.                         goto returnAsDouble;
  3377.                     result = r2;
  3378.                 }
  3379.             }
  3380.             returnAsInteger:
  3381.            
  3382.             if (sign < 0) {
  3383.                 if (result <= 2147483648u)
  3384.                     return (int)(-(long)result);
  3385.                 if (result < 9223372036854775808ul)
  3386.                     return -(long)result;
  3387.                 if (result == 9223372036854775808ul)
  3388.                     return -9223372036854775808l;
  3389.                 return -(double)result;
  3390.             }
  3391.             if (result <= 2147483647)
  3392.                 return (int)result;
  3393.             if (result <= 9223372036854775807l)
  3394.                 return (long)result;
  3395.             return result;
  3396.             returnAsDouble:
  3397.            
  3398.             //too long for a ulong. Try double. Be consistent with Double.FromString.
  3399.             if (rdx == 10)
  3400.                 try {
  3401.                     double r = DoubleParse(new string(s, saved_i, max - saved_i));
  3402.                     if (r == r)
  3403.                         return sign * r;
  3404.                     if (!ignoreTrailers)
  3405.                         return null;
  3406.                 }
  3407.                 catch {
  3408.                 }
  3409.            
  3410.             //Get here for string with trailers, or for radix other than 10
  3411.             //continue accummulating, but with loss of precision. Not quite as good as Double.FromString, but simple.
  3412.             double double_result = ((double)result) * rdx + digit;
  3413.             for (;;) {
  3414.                 if (++i == max)
  3415.                     return sign * double_result;
  3416.                 digit = RadixDigit(s[i], rdx);
  3417.                 if (digit < 0)
  3418.                     if (ignoreTrailers || IsWhiteSpaceTrailer(s, i, max))
  3419.                         return sign * double_result;
  3420.                     else
  3421.                         return null;
  3422.                 double_result = double_result * rdx + digit;
  3423.             }
  3424.         }
  3425.        
  3426.         private static int RadixDigit(char c, uint r)
  3427.         {
  3428.             int d;
  3429.             if (c >= '0' && c <= '9')
  3430.                 d = ((int)c) - ((int)'0');
  3431.             else if (c >= 'A' && c <= 'Z')
  3432.                 d = 10 + ((int)c) - ((int)'A');
  3433.             else if (c >= 'a' && c <= 'z')
  3434.                 d = 10 + ((int)c) - ((int)'a');
  3435.             else
  3436.                 return -1;
  3437.             if (d >= r)
  3438.                 return -1;
  3439.             else
  3440.                 return d;
  3441.         }
  3442.        
  3443.         #if !DEBUG
  3444.         [DebuggerStepThroughAttribute()]
  3445.         [DebuggerHiddenAttribute()]
  3446.         #endif
  3447.         public static void ThrowTypeMismatch(object val)
  3448.         {
  3449.             throw new JScriptException(JSError.TypeMismatch, new Context(new DocumentContext("", null), val.ToString()));
  3450.         }
  3451.        
  3452.         public static bool ToBoolean(double d)
  3453.         {
  3454.             return d == d && d != 0;
  3455.         }
  3456.        
  3457.         #if !DEBUG
  3458.         [DebuggerStepThroughAttribute()]
  3459.         [DebuggerHiddenAttribute()]
  3460.         #endif
  3461.         public static bool ToBoolean(object value)
  3462.         {
  3463.             if (value is bool)
  3464.                 return (bool)value;
  3465.             return Convert.ToBoolean(value, Convert.GetIConvertible(value));
  3466.         }
  3467.        
  3468.         #if !DEBUG
  3469.         [DebuggerStepThroughAttribute()]
  3470.         [DebuggerHiddenAttribute()]
  3471.         #endif
  3472.         public static bool ToBoolean(object value, bool explicitConversion)
  3473.         {
  3474.             if (value is bool)
  3475.                 return (bool)value;
  3476.             if (!explicitConversion && value is BooleanObject)
  3477.                 return ((BooleanObject)value).value;
  3478.             return Convert.ToBoolean(value, Convert.GetIConvertible(value));
  3479.         }
  3480.        
  3481.         #if !DEBUG
  3482.         [DebuggerStepThroughAttribute()]
  3483.         [DebuggerHiddenAttribute()]
  3484.         #endif
  3485.         static internal bool ToBoolean(object value, IConvertible ic)
  3486.         {
  3487.             switch (Convert.GetTypeCode(value, ic)) {
  3488.                 case TypeCode.Empty:
  3489.                     return false;
  3490.                 case TypeCode.Object:
  3491.                     if (value is Missing || value is System.Reflection.Missing)
  3492.                         return false;
  3493.                     Type t = value.GetType();
  3494.                     MethodInfo meth = t.GetMethod("op_True", BindingFlags.ExactBinding | BindingFlags.Public | BindingFlags.Static, null, new Type[] {t}, null);
  3495.                     if (meth != null && (meth.Attributes & MethodAttributes.SpecialName) != 0 && meth.ReturnType == typeof(bool)) {
  3496.                         meth = new JSMethodInfo(meth);
  3497.                         return (bool)meth.Invoke(null, BindingFlags.SuppressChangeType, null, new object[] {value}, null);
  3498.                     }
  3499.                     return true;
  3500.                 case TypeCode.DBNull:
  3501.                     return false;
  3502.                 case TypeCode.Boolean:
  3503.                     return ic.ToBoolean(null);
  3504.                 case TypeCode.Char:
  3505.                     return ic.ToChar(null) != (char)0;
  3506.                 case TypeCode.SByte:
  3507.                 case TypeCode.Byte:
  3508.                 case TypeCode.Int16:
  3509.                 case TypeCode.UInt16:
  3510.                 case TypeCode.Int32:
  3511.                     return ic.ToInt32(null) != 0;
  3512.                 case TypeCode.UInt32:
  3513.                 case TypeCode.Int64:
  3514.                     return ic.ToInt64(null) != 0;
  3515.                 case TypeCode.UInt64:
  3516.                     return ic.ToUInt64(null) != 0;
  3517.                 case TypeCode.Single:
  3518.                 case TypeCode.Double:
  3519.                     double d = ic.ToDouble(null);
  3520.                     if (d != d)
  3521.                         return false;
  3522.                     else
  3523.                         return d != 0;
  3524.                     break;
  3525.                 case TypeCode.Decimal:
  3526.                     return ic.ToDecimal(null) != (decimal)0;
  3527.                 case TypeCode.DateTime:
  3528.                     return true;
  3529.                 case TypeCode.String:
  3530.                     return ic.ToString(null).Length != 0;
  3531.             }
  3532.             return false;
  3533.             //should never get here
  3534.         }
  3535.        
  3536.         static internal char ToChar(object value)
  3537.         {
  3538.             return (char)Convert.ToUint32(value);
  3539.         }
  3540.        
  3541.         private static char ToDigit(int digit)
  3542.         {
  3543.             return digit < 10 ? (char)('0' + digit) : (char)('a' + digit - 10);
  3544.         }
  3545.        
  3546.         public static object ToForInObject(object value, VsaEngine engine)
  3547.         {
  3548.             if (value is ScriptObject)
  3549.                 return value;
  3550.             IConvertible ic = Convert.GetIConvertible(value);
  3551.             switch (Convert.GetTypeCode(value, ic)) {
  3552.                 case TypeCode.Boolean:
  3553.                     return engine.Globals.globalObject.originalBoolean.ConstructImplicitWrapper(ic.ToBoolean(null));
  3554.                 case TypeCode.Char:
  3555.                 case TypeCode.SByte:
  3556.                 case TypeCode.Byte:
  3557.                 case TypeCode.Int16:
  3558.                 case TypeCode.UInt16:
  3559.                 case TypeCode.Int32:
  3560.                 case TypeCode.UInt32:
  3561.                 case TypeCode.Int64:
  3562.                 case TypeCode.UInt64:
  3563.                 case TypeCode.Single:
  3564.                 case TypeCode.Double:
  3565.                 case TypeCode.Decimal:
  3566.                     return engine.Globals.globalObject.originalNumber.ConstructImplicitWrapper(value);
  3567.                 case TypeCode.String:
  3568.                     return engine.Globals.globalObject.originalString.ConstructImplicitWrapper(ic.ToString(null));
  3569.                 case TypeCode.DateTime:
  3570.                     return value;
  3571.                 case TypeCode.Object:
  3572.                     return value;
  3573.             }
  3574.             return engine.Globals.globalObject.originalObject.ConstructObject();
  3575.         }
  3576.        
  3577.         static internal double ToInteger(double number)
  3578.         {
  3579.             if (number != number)
  3580.                 return 0;
  3581.             return Math.Sign(number) * Math.Floor(Math.Abs(number));
  3582.         }
  3583.        
  3584.         static internal double ToInteger(object value)
  3585.         {
  3586.             if (value is double)
  3587.                 return Convert.ToInteger((double)value);
  3588.             if (value is Int32)
  3589.                 return (double)(int)value;
  3590.             return Convert.ToInteger(value, Convert.GetIConvertible(value));
  3591.         }
  3592.        
  3593.         static internal double ToInteger(object value, IConvertible ic)
  3594.         {
  3595.             switch (Convert.GetTypeCode(value, ic)) {
  3596.                 case TypeCode.Empty:
  3597.                     return 0;
  3598.                 case TypeCode.DBNull:
  3599.                     return 0;
  3600.                 case TypeCode.Boolean:
  3601.                     return ic.ToBoolean(null) ? 1 : 0;
  3602.                 case TypeCode.Char:
  3603.                     return (double)ic.ToChar(null);
  3604.                 case TypeCode.SByte:
  3605.                 case TypeCode.Byte:
  3606.                 case TypeCode.Int16:
  3607.                 case TypeCode.UInt16:
  3608.                 case TypeCode.Int32:
  3609.                 case TypeCode.UInt32:
  3610.                 case TypeCode.Int64:
  3611.                 case TypeCode.UInt64:
  3612.                     return ic.ToDouble(null);
  3613.                 case TypeCode.Single:
  3614.                 case TypeCode.Double:
  3615.                 case TypeCode.Decimal:
  3616.                     return Convert.ToInteger(ic.ToDouble(null));
  3617.                 case TypeCode.Object:
  3618.                 case TypeCode.DateTime:
  3619.                     object pval = Convert.ToPrimitive(value, PreferredType.Number, ref ic);
  3620.                     if (pval != value)
  3621.                         return Convert.ToInteger(Convert.ToNumber(pval, ic));
  3622.                     else
  3623.                         return Double.NaN;
  3624.                     break;
  3625.                 case TypeCode.String:
  3626.                     return Convert.ToInteger(Convert.ToNumber(ic.ToString(null)));
  3627.             }
  3628.             return 0;
  3629.             //should never get here
  3630.         }
  3631.        
  3632.         public static int ToInt32(object value)
  3633.         {
  3634.             if (value is double)
  3635.                 return (int)Runtime.DoubleToInt64((double)value);
  3636.             if (value is Int32)
  3637.                 return (int)value;
  3638.             return Convert.ToInt32(value, Convert.GetIConvertible(value));
  3639.         }
  3640.        
  3641.         static internal int ToInt32(object value, IConvertible ic)
  3642.         {
  3643.             switch (Convert.GetTypeCode(value, ic)) {
  3644.                 case TypeCode.Empty:
  3645.                     return 0;
  3646.                 case TypeCode.DBNull:
  3647.                     return 0;
  3648.                 case TypeCode.Boolean:
  3649.                     return ic.ToBoolean(null) ? 1 : 0;
  3650.                 case TypeCode.Char:
  3651.                     return (int)ic.ToChar(null);
  3652.                 case TypeCode.SByte:
  3653.                 case TypeCode.Byte:
  3654.                 case TypeCode.Int16:
  3655.                 case TypeCode.UInt16:
  3656.                 case TypeCode.Int32:
  3657.                     return ic.ToInt32(null);
  3658.                 case TypeCode.UInt32:
  3659.                 case TypeCode.Int64:
  3660.                     return (int)ic.ToInt64(null);
  3661.                 case TypeCode.UInt64:
  3662.                     return (int)ic.ToUInt64(null);
  3663.                 case TypeCode.Single:
  3664.                 case TypeCode.Double:
  3665.                     return (int)Runtime.DoubleToInt64(ic.ToDouble(null));
  3666.                 case TypeCode.Decimal:
  3667.                     return (int)Runtime.UncheckedDecimalToInt64(ic.ToDecimal(null));
  3668.                 case TypeCode.Object:
  3669.                 case TypeCode.DateTime:
  3670.                     object pval = Convert.ToPrimitive(value, PreferredType.Number, ref ic);
  3671.                     if (pval != value)
  3672.                         return Convert.ToInt32(pval, ic);
  3673.                     else
  3674.                         return 0;
  3675.                     break;
  3676.                 case TypeCode.String:
  3677.                     return (int)Runtime.DoubleToInt64(Convert.ToNumber(ic.ToString(null)));
  3678.             }
  3679.             return 0;
  3680.             //should never get here.
  3681.         }
  3682.        
  3683.         static internal IReflect ToIReflect(Type t, VsaEngine engine)
  3684.         {
  3685.             GlobalObject glob = engine.Globals.globalObject;
  3686.             object result = t;
  3687.             if (t == Typeob.ArrayObject)
  3688.                 result = glob.originalArray.Construct();
  3689.             else if (t == Typeob.BooleanObject)
  3690.                 result = glob.originalBoolean.Construct();
  3691.             else if (t == Typeob.DateObject)
  3692.                 result = glob.originalDate.Construct(new object[0]);
  3693.             else if (t == Typeob.EnumeratorObject)
  3694.                 result = glob.originalEnumerator.Construct(new object[0]);
  3695.             else if (t == Typeob.ErrorObject)
  3696.                 result = glob.originalError.Construct(new object[0]);
  3697.             else if (t == Typeob.EvalErrorObject)
  3698.                 result = glob.originalEvalError.Construct(new object[0]);
  3699.             else if (t == Typeob.JSObject)
  3700.                 result = glob.originalObject.Construct(new object[0]);
  3701.             else if (t == Typeob.NumberObject)
  3702.                 result = glob.originalNumber.Construct();
  3703.             else if (t == Typeob.RangeErrorObject)
  3704.                 result = glob.originalRangeError.Construct(new object[0]);
  3705.             else if (t == Typeob.ReferenceErrorObject)
  3706.                 result = glob.originalReferenceError.Construct(new object[0]);
  3707.             else if (t == Typeob.RegExpObject)
  3708.                 result = glob.originalRegExp.Construct(new object[0]);
  3709.             else if (t == Typeob.ScriptFunction)
  3710.                 result = FunctionPrototype.ob;
  3711.             else if (t == Typeob.StringObject)
  3712.                 result = glob.originalString.Construct();
  3713.             else if (t == Typeob.SyntaxErrorObject)
  3714.                 result = glob.originalSyntaxError.Construct(new object[0]);
  3715.             else if (t == Typeob.TypeErrorObject)
  3716.                 result = glob.originalTypeError.Construct(new object[0]);
  3717.             else if (t == Typeob.URIErrorObject)
  3718.                 result = glob.originalURIError.Construct(new object[0]);
  3719.             else if (t == Typeob.VBArrayObject)
  3720.                 result = glob.originalVBArray.Construct();
  3721.             else if (t == Typeob.ArgumentsObject)
  3722.                 result = glob.originalObject.Construct(new object[0]);
  3723.             return (IReflect)result;
  3724.         }
  3725.        
  3726.         public static double ToNumber(object value)
  3727.         {
  3728.             if (value is Int32)
  3729.                 return (double)(int)value;
  3730.             if (value is double)
  3731.                 return (double)value;
  3732.             return Convert.ToNumber(value, Convert.GetIConvertible(value));
  3733.         }
  3734.        
  3735.         static internal double ToNumber(object value, IConvertible ic)
  3736.         {
  3737.             switch (Convert.GetTypeCode(value, ic)) {
  3738.                 case TypeCode.Empty:
  3739.                     return Double.NaN;
  3740.                 case TypeCode.DBNull:
  3741.                     return 0;
  3742.                 case TypeCode.Boolean:
  3743.                     return ic.ToBoolean(null) ? 1 : 0;
  3744.                 case TypeCode.Char:
  3745.                     return (double)ic.ToChar(null);
  3746.                 case TypeCode.SByte:
  3747.                 case TypeCode.Byte:
  3748.                 case TypeCode.Int16:
  3749.                 case TypeCode.UInt16:
  3750.                 case TypeCode.Int32:
  3751.                     return (double)ic.ToInt32(null);
  3752.                 case TypeCode.UInt32:
  3753.                 case TypeCode.Int64:
  3754.                     return (double)ic.ToInt64(null);
  3755.                 case TypeCode.UInt64:
  3756.                     return (double)ic.ToUInt64(null);
  3757.                 case TypeCode.Single:
  3758.                 case TypeCode.Double:
  3759.                 case TypeCode.Decimal:
  3760.                     return ic.ToDouble(null);
  3761.                 case TypeCode.Object:
  3762.                 case TypeCode.DateTime:
  3763.                     object pval = Convert.ToPrimitive(value, PreferredType.Number, ref ic);
  3764.                     if (pval != value)
  3765.                         return Convert.ToNumber(pval, ic);
  3766.                     else
  3767.                         return Double.NaN;
  3768.                     break;
  3769.                 case TypeCode.String:
  3770.                     return Convert.ToNumber(ic.ToString(null));
  3771.             }
  3772.             return 0;
  3773.             //should never get here
  3774.         }
  3775.        
  3776.         public static double ToNumber(string str)
  3777.         {
  3778.             return Convert.ToNumber(str, true, false, Missing.Value);
  3779.         }
  3780.        
  3781.         static internal double ToNumber(string str, bool hexOK, bool octalOK, object radix)
  3782.         {
  3783.             //Called from ToNumber, GlobalObject.parseFloat, GlobalObject.parseInt and from the parser for floating point literals
  3784.             //ToNumber, parseFloat and parseInt each have their own pecularities when it comes to leading whitespace, trailing characters, signs and hex/octal.
  3785.             //For ToNumber: hexOK = true, octalOK = false
  3786.             //For parseFloat: hexOK = false, octalOK = false
  3787.             //For parseInt: hexOK = true, octalOK = true and radix might be supplied,
  3788.             //For floating point literals: hexOK = false, octalOK = false
  3789.            
  3790.             if (!octalOK) {
  3791.                 //only parseInt will set octalOK. Integers can always be converted without COM+ help
  3792.                 try {
  3793.                     double d = DoubleParse(str);
  3794.                     //This should work (and be fastest) for the common case
  3795.                     if (d != 0)
  3796.                         return d;
  3797.                     int i = 0;
  3798.                     int n = str.Length;
  3799.                     while (i < n && IsWhiteSpace(str[i]))
  3800.                         i++;
  3801.                     if (i < n && str[i] == '-')
  3802.                         return (double)(-0.0);
  3803.                     else
  3804.                         return (double)0;
  3805.                 }
  3806.                 catch {
  3807.                     //We might get here if there are trailing characters in the string that should be ignored.
  3808.                     //parseFloat ignores leading whitespace and any trailing characters which do not form part of a StrDecimalLiteral
  3809.                     //ToNumber ignores leading and trailing whitespace, but not other trailing characters
  3810.                     //We should never get here if called from the parser for a floating point literal (COM+ should always work for those).
  3811.                     int n = str.Length;
  3812.                     int j = n - 1;
  3813.                     int i = 0;
  3814.                     //skip leading whitespace
  3815.                     while (i < n && IsWhiteSpace(str[i]))
  3816.                         i++;
  3817.                     if (hexOK) {
  3818.                         //The ToNumber case.
  3819.                         //Double.FromString might have failed because of trailing whitespace, or because this is a hexadecimal literal.
  3820.                         while (j >= i && IsWhiteSpace(str[j]))
  3821.                             j--;
  3822.                         //Strip any trailing whitespace
  3823.                         if (i > j)
  3824.                             //String empty or all whitespace
  3825.                             return (double)0;
  3826.                         if (j < n - 1)
  3827.                             //Had some trailing whitespace, try COM+ again
  3828.                             return Convert.ToNumber(str.Substring(i, j - i + 1), hexOK, octalOK, radix);
  3829.                         //otherwise drop through and try to parse the number as a hex literal
  3830.                     }
  3831.                     else {
  3832.                         //The parseFloat case: all trailers are ignored. Prefix starting at i must match StrDecimalLiteral
  3833.                         //Might be "Infinity"
  3834.                         if (n - i >= 8 && String.CompareOrdinal(str, i, "Infinity", 0, 8) == 0)
  3835.                             return Double.PositiveInfinity;
  3836.                         else if (n - i >= 9 && String.CompareOrdinal(str, i, "-Infinity", 0, 8) == 0)
  3837.                             return Double.NegativeInfinity;
  3838.                         else if (n - i >= 9 && String.CompareOrdinal(str, i, "+Infinity", 0, 8) == 0)
  3839.                             return Double.PositiveInfinity;
  3840.                         //Reduce string length until last character is a decimal digit or '.'
  3841.                         char ch;
  3842.                         //If the last character is a digit there could be noise further upstream. First skip over trailing digits
  3843.                         while (j >= i) {
  3844.                             ch = str[j];
  3845.                             if (!JSScanner.IsDigit(ch))
  3846.                                 break;
  3847.                             j--;
  3848.                         }
  3849.                         while (j >= i) {
  3850.                             ch = str[j];
  3851.                             if (JSScanner.IsDigit(ch))
  3852.                                 break;
  3853.                             j--;
  3854.                         }
  3855.                         if (j < n - 1)
  3856.                             //Had some trailing noise, try COM+ again
  3857.                             return Convert.ToNumber(str.Substring(i, j - i + 1), hexOK, octalOK, radix);
  3858.                         //Whatever is left in str does not parse to a double, give up and return NaN.
  3859.                         return Double.NaN;
  3860.                     }
  3861.                 }
  3862.             }
  3863.             //if we get here, we are dealing with an integer, or we might be dealing with (+|-)Infinity
  3864.             //Never get here for parseFloat or floating point literals from the parser.
  3865.             //For parseInt Only the prefix matters. Trailing characters (those that can not form part of an integer literal) are ignored.
  3866.             //For ToNumber, any trailing characters must be whitespace.
  3867.             {
  3868.                 int n = str.Length;
  3869.                 int i = 0;
  3870.                 //skip leading whitespace
  3871.                 while (i < n && IsWhiteSpace(str[i]))
  3872.                     i++;
  3873.                 if (i >= n)
  3874.                     if (hexOK && octalOK)
  3875.                         return double.NaN;
  3876.                     else
  3877.                     //parseInt case
  3878.                         return (double)0;
  3879.                 //ToNumber case
  3880.                 int sign = 1;
  3881.                 bool explicitSign = false;
  3882.                 if (str[i] == '-') {
  3883.                     sign = -1;
  3884.                     i++;
  3885.                     explicitSign = true;
  3886.                 }
  3887.                 else if (str[i] == '+') {
  3888.                     i++;
  3889.                     explicitSign = true;
  3890.                 }
  3891.                 while (i < n && IsWhiteSpace(str[i]))
  3892.                     i++;
  3893.                 bool radixMissing = radix == null || radix is Missing;
  3894.                 if (i + 8 <= n && radixMissing && !octalOK && str.Substring(i, 8).Equals("Infinity"))
  3895.                     return sign > 0 ? Double.PositiveInfinity : Double.NegativeInfinity;
  3896.                 int r = 10;
  3897.                 if (!radixMissing)
  3898.                     r = Convert.ToInt32(radix);
  3899.                 if (r == 0) {
  3900.                     radixMissing = true;
  3901.                     r = 10;
  3902.                 }
  3903.                 else if (r < 2 || r > 36)
  3904.                     return Double.NaN;
  3905.                 if (i < n - 2 && str[i] == '0')
  3906.                     if (str[i + 1] == 'x' || str[i + 1] == 'X') {
  3907.                         if (!hexOK)
  3908.                             return 0;
  3909.                         if (explicitSign && !octalOK)
  3910.                             //ToNumber case
  3911.                             return Double.NaN;
  3912.                         if (radixMissing) {
  3913.                             r = 16;
  3914.                             i += 2;
  3915.                         }
  3916.                         else if (r == 16)
  3917.                             i += 2;
  3918.                     }
  3919.                     else if (octalOK && radixMissing)
  3920.                         r = 8;
  3921.                 if (i < n)
  3922.                     return Convert.ToNumber(Convert.parseRadix(str.ToCharArray(), (uint)r, i, sign, hexOK && octalOK));
  3923.                 else
  3924.                     return Double.NaN;
  3925.             }
  3926.         }
  3927.        
  3928.         static internal string ToLocaleString(object value)
  3929.         {
  3930.             return Convert.ToString(value, PreferredType.LocaleString, true);
  3931.         }
  3932.        
  3933.         public static object ToNativeArray(object value, RuntimeTypeHandle handle)
  3934.         {
  3935.             if (value is ArrayObject) {
  3936.                 Type elementType = Type.GetTypeFromHandle(handle);
  3937.                 return ((ArrayObject)value).ToNativeArray(elementType);
  3938.             }
  3939.             return value;
  3940.         }
  3941.        
  3942.         public static object ToObject(object value, VsaEngine engine)
  3943.         {
  3944.             if (value is ScriptObject)
  3945.                 return value;
  3946.             string str = value as string;
  3947.             if (str != null)
  3948.                 return engine.Globals.globalObject.originalString.ConstructImplicitWrapper(str);
  3949.             IConvertible ic = Convert.GetIConvertible(value);
  3950.             switch (Convert.GetTypeCode(value, ic)) {
  3951.                 case TypeCode.Boolean:
  3952.                     return engine.Globals.globalObject.originalBoolean.ConstructImplicitWrapper(ic.ToBoolean(null));
  3953.                 case TypeCode.Char:
  3954.                 case TypeCode.SByte:
  3955.                 case TypeCode.Byte:
  3956.                 case TypeCode.Int16:
  3957.                 case TypeCode.UInt16:
  3958.                 case TypeCode.Int32:
  3959.                 case TypeCode.UInt32:
  3960.                 case TypeCode.Int64:
  3961.                 case TypeCode.UInt64:
  3962.                 case TypeCode.Single:
  3963.                 case TypeCode.Double:
  3964.                 case TypeCode.Decimal:
  3965.                     return engine.Globals.globalObject.originalNumber.ConstructImplicitWrapper(value);
  3966.                 case TypeCode.String:
  3967.                     return engine.Globals.globalObject.originalString.ConstructImplicitWrapper(ic.ToString(null));
  3968.                 case TypeCode.DateTime:
  3969.                     return ic.ToDateTime(null);
  3970.                 case TypeCode.Object:
  3971.                     if (value is Array)
  3972.                         return engine.Globals.globalObject.originalArray.ConstructImplicitWrapper((Array)value);
  3973.                     else
  3974.                         return value;
  3975.                     break;
  3976.             }
  3977.             throw new JScriptException(JSError.NeedObject);
  3978.         }
  3979.        
  3980.         public static object ToObject2(object value, VsaEngine engine)
  3981.         {
  3982.             if (value is ScriptObject)
  3983.                 return value;
  3984.             IConvertible ic = Convert.GetIConvertible(value);
  3985.             switch (Convert.GetTypeCode(value, ic)) {
  3986.                 case TypeCode.Boolean:
  3987.                     return engine.Globals.globalObject.originalBoolean.ConstructImplicitWrapper(ic.ToBoolean(null));
  3988.                 case TypeCode.Char:
  3989.                 case TypeCode.SByte:
  3990.                 case TypeCode.Byte:
  3991.                 case TypeCode.Int16:
  3992.                 case TypeCode.UInt16:
  3993.                 case TypeCode.Int32:
  3994.                 case TypeCode.UInt32:
  3995.                 case TypeCode.Int64:
  3996.                 case TypeCode.UInt64:
  3997.                 case TypeCode.Single:
  3998.                 case TypeCode.Double:
  3999.                 case TypeCode.Decimal:
  4000.                     return engine.Globals.globalObject.originalNumber.ConstructImplicitWrapper(value);
  4001.                 case TypeCode.String:
  4002.                     return engine.Globals.globalObject.originalString.ConstructImplicitWrapper(ic.ToString(null));
  4003.                 case TypeCode.DateTime:
  4004.                     return ic.ToDateTime(null);
  4005.                 case TypeCode.Object:
  4006.                     if (value is Array)
  4007.                         return engine.Globals.globalObject.originalArray.ConstructImplicitWrapper((Array)value);
  4008.                     else
  4009.                         return value;
  4010.                     break;
  4011.             }
  4012.             return null;
  4013.         }
  4014.        
  4015.         static internal object ToObject3(object value, VsaEngine engine)
  4016.         {
  4017.             if (value is ScriptObject)
  4018.                 return value;
  4019.             IConvertible ic = Convert.GetIConvertible(value);
  4020.             switch (Convert.GetTypeCode(value, ic)) {
  4021.                 case TypeCode.Boolean:
  4022.                     return engine.Globals.globalObject.originalBoolean.ConstructWrapper(ic.ToBoolean(null));
  4023.                 case TypeCode.Char:
  4024.                 case TypeCode.SByte:
  4025.                 case TypeCode.Byte:
  4026.                 case TypeCode.Int16:
  4027.                 case TypeCode.UInt16:
  4028.                 case TypeCode.Int32:
  4029.                 case TypeCode.UInt32:
  4030.                 case TypeCode.Int64:
  4031.                 case TypeCode.UInt64:
  4032.                 case TypeCode.Single:
  4033.                 case TypeCode.Double:
  4034.                 case TypeCode.Decimal:
  4035.                     return engine.Globals.globalObject.originalNumber.ConstructWrapper(value);
  4036.                 case TypeCode.String:
  4037.                     return engine.Globals.globalObject.originalString.ConstructWrapper(ic.ToString(null));
  4038.                 case TypeCode.DateTime:
  4039.                     return ic.ToDateTime(null);
  4040.                 case TypeCode.Object:
  4041.                     if (value is Array)
  4042.                         return engine.Globals.globalObject.originalArray.ConstructWrapper((Array)value);
  4043.                     else
  4044.                         return value;
  4045.                     break;
  4046.             }
  4047.             return null;
  4048.         }
  4049.        
  4050.         #if !DEBUG
  4051.         [DebuggerStepThroughAttribute()]
  4052.         [DebuggerHiddenAttribute()]
  4053.         #endif
  4054.         static internal object ToPrimitive(object value, PreferredType preferredType)
  4055.         {
  4056.             IConvertible ic = Convert.GetIConvertible(value);
  4057.             TypeCode tcode = Convert.GetTypeCode(value, ic);
  4058.             return Convert.ToPrimitive(value, preferredType, ic, tcode);
  4059.         }
  4060.        
  4061.         #if !DEBUG
  4062.         [DebuggerStepThroughAttribute()]
  4063.         [DebuggerHiddenAttribute()]
  4064.         #endif
  4065.         static internal object ToPrimitive(object value, PreferredType preferredType, ref IConvertible ic)
  4066.         {
  4067.             TypeCode tcode = Convert.GetTypeCode(value, ic);
  4068.             switch (tcode) {
  4069.                 case TypeCode.Object:
  4070.                 case TypeCode.DateTime:
  4071.                     object result = Convert.ToPrimitive(value, preferredType, ic, tcode);
  4072.                     if (result != value) {
  4073.                         value = result;
  4074.                         ic = Convert.GetIConvertible(value);
  4075.                     }
  4076.                     break;
  4077.             }
  4078.             return value;
  4079.         }
  4080.        
  4081.        
  4082.         #if !DEBUG
  4083.         [DebuggerStepThroughAttribute()]
  4084.         [DebuggerHiddenAttribute()]
  4085.         #endif
  4086.         private static object ToPrimitive(object value, PreferredType preferredType, IConvertible ic, TypeCode tcode)
  4087.         {
  4088.             switch (tcode) {
  4089.                 case TypeCode.Object:
  4090.                     System.Array arr = value as System.Array;
  4091.                     if (arr != null && arr.Rank == 1)
  4092.                         value = new ArrayWrapper(ArrayPrototype.ob, arr, true);
  4093.                     if (value is ScriptObject) {
  4094.                         object result = ((ScriptObject)value).GetDefaultValue(preferredType);
  4095.                         if (Convert.GetTypeCode(result) != TypeCode.Object)
  4096.                             return result;
  4097.                         else if (value == result && preferredType == PreferredType.String || preferredType == PreferredType.LocaleString) {
  4098.                             if (value is JSObject) {
  4099.                                 ScriptObject proto = ((JSObject)value).GetParent();
  4100.                                 if (proto is ClassScope)
  4101.                                     return ((ClassScope)proto).GetFullName();
  4102.                                 return "[object Object]";
  4103.                             }
  4104.                             return value.ToString();
  4105.                         }
  4106.                         else
  4107.                             throw new JScriptException(JSError.TypeMismatch);
  4108.                     }
  4109.                     else if (value is Missing || value is System.Reflection.Missing)
  4110.                         return null;
  4111.                     else {
  4112.                         IReflect ir;
  4113.                         if (value is IReflect && !(value is Type))
  4114.                             ir = (IReflect)value;
  4115.                         else
  4116.                             ir = value.GetType();
  4117.                        
  4118.                         //Look for an op_Explicit conversion to String or Double (this always fails for IDispatch/Ex objects
  4119.                         MethodInfo meth = null;
  4120.                         if (preferredType == PreferredType.String || preferredType == PreferredType.LocaleString)
  4121.                             meth = Convert.GetToXXXXMethod(ir, typeof(string), true);
  4122.                         else {
  4123.                             meth = Convert.GetToXXXXMethod(ir, typeof(double), true);
  4124.                             if (meth == null)
  4125.                                 meth = Convert.GetToXXXXMethod(ir, typeof(Int64), true);
  4126.                             if (meth == null)
  4127.                                 meth = Convert.GetToXXXXMethod(ir, typeof(UInt64), true);
  4128.                         }
  4129.                         if (meth != null) {
  4130.                             meth = new JSMethodInfo(meth);
  4131.                             return meth.Invoke(null, BindingFlags.SuppressChangeType, null, new object[] {value}, null);
  4132.                         }
  4133.                        
  4134.                         //Invoke the default method/property or get the value of the default field. If an exception is thrown
  4135.                         //because the target doesn't have a non-paramterized default member, mask it and execute the
  4136.                         //default handling.
  4137.                         try {
  4138.                             try {
  4139.                                 MemberInfo member = LateBinding.SelectMember(JSBinder.GetDefaultMembers(Runtime.TypeRefs, ir));
  4140.                                 if (member != null) {
  4141.                                     switch (member.MemberType) {
  4142.                                         case MemberTypes.Field:
  4143.                                             return ((FieldInfo)member).GetValue(value);
  4144.                                         case MemberTypes.Method:
  4145.                                             return ((MethodInfo)member).Invoke(value, new object[0]);
  4146.                                         case MemberTypes.Property:
  4147.                                             return JSProperty.GetValue((PropertyInfo)member, value, null);
  4148.                                         case MemberTypes.Event:
  4149.                                             return null;
  4150.                                         case MemberTypes.NestedType:
  4151.                                             return member;
  4152.                                     }
  4153.                                 }
  4154.                                
  4155.                                 return ir.InvokeMember(String.Empty, BindingFlags.ExactBinding | BindingFlags.SuppressChangeType | BindingFlags.InvokeMethod | BindingFlags.GetProperty | BindingFlags.GetField, null, value, new object[0], null, null, new string[0]);
  4156.                             }
  4157.                             catch (TargetInvocationException e) {
  4158.                                 throw e.InnerException;
  4159.                             }
  4160.                         }
  4161.                         catch (ArgumentException) {
  4162.                         }
  4163.                         catch (IndexOutOfRangeException) {
  4164.                         }
  4165.                         catch (MissingMemberException) {
  4166.                         }
  4167.                         catch (SecurityException) {
  4168.                         }
  4169.                         catch (TargetParameterCountException) {
  4170.                         }
  4171.                        
  4172.                         if (preferredType != PreferredType.Number)
  4173.                             if (value is char[])
  4174.                                 return new string((char[])value);
  4175.                             else
  4176.                                 return value.ToString();
  4177.                         return value;
  4178.                     }
  4179.                     break;
  4180.                 case TypeCode.DateTime:
  4181.                     return DateConstructor.ob.Construct(ic.ToDateTime(null)).GetDefaultValue(preferredType);
  4182.             }
  4183.             return value;
  4184.         }
  4185.        
  4186.         static internal string ToString(object value)
  4187.         {
  4188.             return Convert.ToString(value, PreferredType.String, true);
  4189.         }
  4190.        
  4191.         #if !DEBUG
  4192.         [DebuggerStepThroughAttribute()]
  4193.         [DebuggerHiddenAttribute()]
  4194.         #endif
  4195.         public static string ToString(object value, bool explicitOK)
  4196.         {
  4197.             return Convert.ToString(value, PreferredType.String, explicitOK);
  4198.         }
  4199.        
  4200.         #if !DEBUG
  4201.         [DebuggerStepThroughAttribute()]
  4202.         [DebuggerHiddenAttribute()]
  4203.         #endif
  4204.         static internal string ToString(object value, IConvertible ic)
  4205.         {
  4206.             return Convert.ToString(value, PreferredType.String, ic, true);
  4207.         }
  4208.        
  4209.         #if !DEBUG
  4210.         [DebuggerStepThroughAttribute()]
  4211.         [DebuggerHiddenAttribute()]
  4212.         #endif
  4213.         static internal string ToString(object value, PreferredType pref, bool explicitOK)
  4214.         {
  4215.             string str = value as string;
  4216.             if (str != null)
  4217.                 return str;
  4218.             StringObject strObj = value as StringObject;
  4219.             if (strObj != null && strObj.noExpando)
  4220.                 return strObj.value;
  4221.             return Convert.ToString(value, pref, Convert.GetIConvertible(value), explicitOK);
  4222.         }
  4223.        
  4224.         #if !DEBUG
  4225.         [DebuggerStepThroughAttribute()]
  4226.         [DebuggerHiddenAttribute()]
  4227.         #endif
  4228.         static internal string ToString(object value, PreferredType pref, IConvertible ic, bool explicitOK)
  4229.         {
  4230.             Enum e = value as Enum;
  4231.             if (e != null)
  4232.                 return e.ToString("G");
  4233.             EnumWrapper ew = value as EnumWrapper;
  4234.             if (ew != null)
  4235.                 return ew.ToString();
  4236.             TypeCode code = Convert.GetTypeCode(value, ic);
  4237.             if (pref == PreferredType.LocaleString) {
  4238.                 switch (code) {
  4239.                     case TypeCode.SByte:
  4240.                     case TypeCode.Byte:
  4241.                     case TypeCode.Int16:
  4242.                     case TypeCode.UInt16:
  4243.                     case TypeCode.Int32:
  4244.                     case TypeCode.UInt32:
  4245.                     case TypeCode.Single:
  4246.                     case TypeCode.Double:
  4247.                        
  4248.                         {
  4249.                             double d = ic.ToDouble(null);
  4250.                             return d.ToString(d <= -1E+15 || d >= 1E+15 ? "g" : "n", NumberFormatInfo.CurrentInfo);
  4251.                         }
  4252.                         break;
  4253.                     case TypeCode.Int64:
  4254.                         return ic.ToInt64(null).ToString("n", NumberFormatInfo.CurrentInfo);
  4255.                     case TypeCode.UInt64:
  4256.                         return ic.ToUInt64(null).ToString("n", NumberFormatInfo.CurrentInfo);
  4257.                     case TypeCode.Decimal:
  4258.                         return ic.ToDecimal(null).ToString("n", NumberFormatInfo.CurrentInfo);
  4259.                 }
  4260.             }
  4261.             switch (code) {
  4262.                 case TypeCode.Empty:
  4263.                     return explicitOK ? "undefined" : null;
  4264.                 case TypeCode.Object:
  4265.                     return Convert.ToString(Convert.ToPrimitive(value, pref, ref ic), ic);
  4266.                 case TypeCode.DBNull:
  4267.                     return explicitOK ? "null" : null;
  4268.                 case TypeCode.Boolean:
  4269.                     return ic.ToBoolean(null) ? "true" : "false";
  4270.                 case TypeCode.Char:
  4271.                 case TypeCode.SByte:
  4272.                 case TypeCode.Byte:
  4273.                 case TypeCode.Int16:
  4274.                 case TypeCode.UInt16:
  4275.                 case TypeCode.Int32:
  4276.                 case TypeCode.UInt32:
  4277.                 case TypeCode.Int64:
  4278.                 case TypeCode.UInt64:
  4279.                 case TypeCode.Decimal:
  4280.                 case TypeCode.String:
  4281.                     return ic.ToString(null);
  4282.                 case TypeCode.DateTime:
  4283.                     return Convert.ToString(DateConstructor.ob.Construct(ic.ToDateTime(null)));
  4284.                 case TypeCode.Single:
  4285.                 case TypeCode.Double:
  4286.                     return Convert.ToString(ic.ToDouble(null));
  4287.             }
  4288.             return null;
  4289.             //Should never get here
  4290.         }
  4291.        
  4292.         public static string ToString(bool b)
  4293.         {
  4294.             return b ? "true" : "false";
  4295.         }
  4296.        
  4297.         public static string ToString(double d)
  4298.         {
  4299.             long i = (long)d;
  4300.             if ((double)i == d) {
  4301.                 return i.ToString(CultureInfo.InvariantCulture);
  4302.             }
  4303.             else if (d != d)
  4304.                 return "NaN";
  4305.             else if (Double.IsPositiveInfinity(d))
  4306.                 return "Infinity";
  4307.             else if (Double.IsNegativeInfinity(d))
  4308.                 return "-Infinity";
  4309.             else {
  4310.                 double e = d < 0 ? -d : d;
  4311.                 int k = 15;
  4312.                 string result = e.ToString("e14", CultureInfo.InvariantCulture);
  4313.                 if (DoubleParse(result) != e) {
  4314.                     result = e.ToString("e15", CultureInfo.InvariantCulture);
  4315.                     k = 16;
  4316.                     if (DoubleParse(result) != e) {
  4317.                         result = e.ToString("e16", CultureInfo.InvariantCulture);
  4318.                         k = 17;
  4319.                         if (DoubleParse(result) != e) {
  4320.                             result = e.ToString("e17", CultureInfo.InvariantCulture);
  4321.                             k = 18;
  4322.                         }
  4323.                     }
  4324.                 }
  4325.                 int exp = Int32.Parse(result.Substring(k + 2, result.Length - (k + 2)), CultureInfo.InvariantCulture);
  4326.                 while (result[k] == '0')
  4327.                     k--;
  4328.                 //at the end of the loop, k == the number of significant digits
  4329.                 int n = exp + 1;
  4330.                 if (k <= n && n <= 21) {
  4331.                     StringBuilder r = new StringBuilder(n + 1);
  4332.                     if (d < 0)
  4333.                         r.Append('-');
  4334.                     r.Append(result[0]);
  4335.                     if (k > 1)
  4336.                         r.Append(result, 2, k - 1);
  4337.                     if (exp - k >= 0)
  4338.                         r.Append('0', n - k);
  4339.                     return r.ToString();
  4340.                 }
  4341.                 if (0 < n && n <= 21) {
  4342.                     StringBuilder r = new StringBuilder(k + 2);
  4343.                     if (d < 0)
  4344.                         r.Append('-');
  4345.                     r.Append(result[0]);
  4346.                     if (n > 1)
  4347.                         r.Append(result, 2, n - 1);
  4348.                     r.Append('.');
  4349.                     r.Append(result, n + 1, k - n);
  4350.                     return r.ToString();
  4351.                 }
  4352.                 if (-6 < n && n <= 0) {
  4353.                     StringBuilder r = new StringBuilder(2 - n);
  4354.                     if (d < 0)
  4355.                         r.Append("-0.");
  4356.                     else
  4357.                         r.Append("0.");
  4358.                     if (n < 0)
  4359.                         r.Append('0', -n);
  4360.                     r.Append(result[0]);
  4361.                     r.Append(result, 2, k - 1);
  4362.                     return r.ToString();
  4363.                 }
  4364.                 {
  4365.                     StringBuilder r = new StringBuilder(28);
  4366.                     if (d < 0)
  4367.                         r.Append('-');
  4368.                     r.Append(result.Substring(0, k == 1 ? 1 : k + 1));
  4369.                     r.Append('e');
  4370.                     if (exp >= 0)
  4371.                         r.Append('+');
  4372.                     r.Append(exp);
  4373.                     return r.ToString();
  4374.                 }
  4375.             }
  4376.         }
  4377.        
  4378.         private static int[] rgcchSig = new int[] {53, 34, 27, 24, 22, 20, 19, 18, 17, 17,
  4379.         16, 16, 15, 15, 14, 14, 14, 14, 14, 13,
  4380.         13, 13, 13, 13, 13, 12, 12, 12, 12, 12,
  4381.         12, 12, 12, 12, 12};
  4382.        
  4383.         static internal string ToString(object value, int radix)
  4384.         {
  4385.             if (radix == 10 || radix < 2 || radix > 36)
  4386.                 return Convert.ToString(value);
  4387.             double dbl = Convert.ToNumber(value);
  4388.             if (dbl == 0.0)
  4389.                 return "0";
  4390.             if (Double.IsNaN(dbl))
  4391.                 return "NaN";
  4392.             if (Double.IsPositiveInfinity(dbl))
  4393.                 return "Infinity";
  4394.             if (Double.IsNegativeInfinity(dbl))
  4395.                 return "-Infinity";
  4396.            
  4397.             StringBuilder sb = new StringBuilder();
  4398.             if (dbl < 0.0) {
  4399.                 sb.Append('-');
  4400.                 dbl = -dbl;
  4401.             }
  4402.             int cchMax = rgcchSig[radix - 2];
  4403.            
  4404.             if (dbl < 8.67361737988404E-19 || dbl >= 2.30584300921369E+18) {
  4405.                 // Exponential notation
  4406.                
  4407.                 int wExp = (int)Math.Log(dbl, radix) + 1;
  4408.                 double dblT = Math.Pow(radix, wExp);
  4409.                 if (Double.IsPositiveInfinity(dblT))
  4410.                     dblT = Math.Pow(radix, --wExp);
  4411.                 else if (dblT == 0.0)
  4412.                     dblT = Math.Pow(radix, ++wExp);
  4413.                 dbl /= dblT;
  4414.                 while (dbl < 1.0) {
  4415.                     dbl *= radix;
  4416.                     wExp--;
  4417.                 }
  4418.                
  4419.                 int wDig = (int)dbl;
  4420.                 sb.Append(Convert.ToDigit(wDig));
  4421.                 cchMax--;
  4422.                 dbl -= wDig;
  4423.                
  4424.                 if (dbl != 0.0) {
  4425.                     sb.Append('.');
  4426.                     while (dbl != 0.0 && cchMax-- > 0) {
  4427.                         dbl *= radix;
  4428.                         wDig = (int)dbl;
  4429.                         if (wDig >= radix)
  4430.                             wDig = radix - 1;
  4431.                         sb.Append(Convert.ToDigit(wDig));
  4432.                         dbl -= wDig;
  4433.                     }
  4434.                 }
  4435.                
  4436.                 sb.Append((wExp >= 0 ? "(e+" : "(e"));
  4437.                 sb.Append(wExp.ToString(CultureInfo.InvariantCulture));
  4438.                 sb.Append(')');
  4439.                
  4440.             }
  4441.             else {
  4442.                 // Regular notation
  4443.                
  4444.                 int wDig;
  4445.                 int cchSig;
  4446.                 if (dbl >= 1.0) {
  4447.                     // Integral portion
  4448.                    
  4449.                     double dblDen;
  4450.                     double dblT;
  4451.                     cchSig = 1;
  4452.                     for (dblDen = 1.0; (dblT = dblDen * radix) <= dbl; dblDen = dblT)
  4453.                         cchSig++;
  4454.                    
  4455.                     for (int cch = 0; cch < cchSig; cch++) {
  4456.                         wDig = (int)(dbl / dblDen);
  4457.                         if (wDig >= radix)
  4458.                             wDig = radix - 1;
  4459.                         sb.Append(Convert.ToDigit(wDig));
  4460.                         dbl -= wDig * dblDen;
  4461.                         dblDen /= radix;
  4462.                     }
  4463.                 }
  4464.                 else {
  4465.                     sb.Append('0');
  4466.                     cchSig = 0;
  4467.                 }
  4468.                
  4469.                 if (dbl != 0.0 && cchSig < cchMax) {
  4470.                     // Fractional portion
  4471.                    
  4472.                     sb.Append('.');
  4473.                     while (dbl != 0.0 && cchSig < cchMax) {
  4474.                         dbl *= radix;
  4475.                         wDig = (int)dbl;
  4476.                         if (wDig >= radix)
  4477.                             wDig = radix - 1;
  4478.                         sb.Append(Convert.ToDigit(wDig));
  4479.                         dbl -= wDig;
  4480.                         if (wDig != 0 || cchSig != 0)
  4481.                             cchSig++;
  4482.                     }
  4483.                 }
  4484.             }
  4485.            
  4486.             return sb.ToString();
  4487.         }
  4488.        
  4489.         static internal Type ToType(IReflect ir)
  4490.         {
  4491.             return Convert.ToType(Globals.TypeRefs, ir);
  4492.         }
  4493.        
  4494.         static internal Type ToType(TypeReferences typeRefs, IReflect ir)
  4495.         {
  4496.             if (ir is Type)
  4497.                 return (Type)ir;
  4498.             if (ir is ClassScope)
  4499.                 return ((ClassScope)ir).GetTypeBuilderOrEnumBuilder();
  4500.             if (ir is TypedArray) {
  4501.                 return typeRefs.ToReferenceContext(((TypedArray)ir).ToType());
  4502.             }
  4503.             if (ir is ScriptFunction)
  4504.                 return typeRefs.ScriptFunction;
  4505.             return typeRefs.ToReferenceContext(ir.GetType());
  4506.         }
  4507.        
  4508.         static internal Type ToType(string descriptor, Type elementType)
  4509.         {
  4510.             Module mod = elementType.Module;
  4511.             if (mod is ModuleBuilder)
  4512.                 return mod.GetType(elementType.FullName + descriptor);
  4513.             else
  4514.                 return mod.Assembly.GetType(elementType.FullName + descriptor);
  4515.         }
  4516.        
  4517.         static internal string ToTypeName(IReflect ir)
  4518.         {
  4519.             if (ir is ClassScope)
  4520.                 return ((ClassScope)ir).GetName();
  4521.             else if (ir is JSObject)
  4522.                 return ((JSObject)ir).GetClassName();
  4523.             else if (ir is GlobalScope)
  4524.                 return "Global Object";
  4525.             else {
  4526.                 Debug.Assert(ir is Type || ir is TypedArray);
  4527.                 return ir.ToString();
  4528.             }
  4529.         }
  4530.        
  4531.         static internal uint ToUint32(object value)
  4532.         {
  4533.             if (value is UInt32)
  4534.                 return (uint)value;
  4535.             return Convert.ToUint32(value, Convert.GetIConvertible(value));
  4536.         }
  4537.        
  4538.         static internal uint ToUint32(object value, IConvertible ic)
  4539.         {
  4540.             switch (Convert.GetTypeCode(value, ic)) {
  4541.                 case TypeCode.Empty:
  4542.                     return 0;
  4543.                 case TypeCode.DBNull:
  4544.                     return 0;
  4545.                 case TypeCode.Boolean:
  4546.                     return ic.ToBoolean(null) ? (uint)1 : (uint)0;
  4547.                 case TypeCode.Char:
  4548.                     return (uint)ic.ToChar(null);
  4549.                 case TypeCode.Byte:
  4550.                 case TypeCode.UInt16:
  4551.                 case TypeCode.UInt32:
  4552.                     return ic.ToUInt32(null);
  4553.                 case TypeCode.UInt64:
  4554.                     return (uint)ic.ToUInt64(null);
  4555.                 case TypeCode.SByte:
  4556.                 case TypeCode.Int16:
  4557.                 case TypeCode.Int32:
  4558.                 case TypeCode.Int64:
  4559.                     return (uint)ic.ToInt64(null);
  4560.                 case TypeCode.Single:
  4561.                 case TypeCode.Double:
  4562.                     return (uint)Runtime.DoubleToInt64(ic.ToDouble(null));
  4563.                 case TypeCode.Decimal:
  4564.                     return (uint)Runtime.UncheckedDecimalToInt64(ic.ToDecimal(null));
  4565.                 case TypeCode.Object:
  4566.                 case TypeCode.DateTime:
  4567.                     object pval = Convert.ToPrimitive(value, PreferredType.Number, ref ic);
  4568.                     if (pval != value)
  4569.                         return Convert.ToUint32(pval, ic);
  4570.                     else
  4571.                         return 0;
  4572.                     break;
  4573.                 case TypeCode.String:
  4574.                     return (uint)Runtime.DoubleToInt64(Convert.ToNumber(ic.ToString(null)));
  4575.             }
  4576.             return 0;
  4577.             //should never get here
  4578.         }
  4579.        
  4580.     }
  4581. }

Developer Fusion