EmitILToLoadEngine() private method

private EmitILToLoadEngine ( ILGenerator il ) : void
il ILGenerator
return void
Example #1
0
      internal static void Emit(AST ast, ILGenerator il, Type source_type, Type target_type, bool truncationPermitted){
        if (source_type == target_type) return;
        if (target_type == Typeob.Void){
          il.Emit(OpCodes.Pop);
          return;
        }
        if (target_type.IsEnum){
          if (source_type == Typeob.String || source_type == Typeob.Object){
            il.Emit(OpCodes.Ldtoken, target_type);
            il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod);
            ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
            il.Emit(OpCodes.Call, CompilerGlobals.coerceTMethod);
            Convert.EmitUnbox(il, target_type, Type.GetTypeCode(Convert.GetUnderlyingType(target_type)));
          }else
            Convert.Emit(ast, il, source_type, Convert.GetUnderlyingType(target_type));
          return;
        }
        if (source_type.IsEnum){
          if (target_type.IsPrimitive){
            Convert.Emit(ast, il, Convert.GetUnderlyingType(source_type), target_type);
            return;
          }
          if (target_type == Typeob.Object || target_type == typeof(Enum)){
            il.Emit(OpCodes.Box, source_type);
            return;
          }
          if (target_type == Typeob.String){
            il.Emit(OpCodes.Box, source_type);
            ConstantWrapper.TranslateToILInt(il, 0);
            il.Emit(OpCodes.Call, CompilerGlobals.toStringMethod);
            return;
          }
        }

        while (source_type is TypeBuilder){
          source_type = source_type.BaseType;
          if (source_type == null) source_type = Typeob.Object; //It is an interface
          if (source_type == target_type) return;
        }

        if (source_type.IsArray && target_type.IsArray)
          //This should only be called if the two types are known to be compatible, so:
          return;

        TypeCode source = Type.GetTypeCode(source_type);
        TypeCode target = target_type is TypeBuilder ? TypeCode.Object : Type.GetTypeCode(target_type);
        switch (source){
          case TypeCode.Empty: //can never occur
            return;

          case TypeCode.Object:
            if (source_type == Typeob.Void){
              il.Emit(OpCodes.Ldnull);
              source_type = Typeob.Object;
            }
            switch (target){
              case TypeCode.Object:
                //The conversion from function object to delegate never happens here. ConstantWrapper takes care of it.
                //First check for array target type or TypeBuilder target type. These do not support IsAssignableFrom.
                if (target_type.IsArray || target_type == Typeob.Array){
                  if (source_type == Typeob.ArrayObject || source_type == Typeob.Object){
                    if (target_type.IsArray)
                      il.Emit(OpCodes.Ldtoken, target_type.GetElementType());
                    else
                      il.Emit(OpCodes.Ldtoken, Typeob.Object);
                    il.Emit(OpCodes.Call, CompilerGlobals.toNativeArrayMethod);
                  }
                  il.Emit(OpCodes.Castclass, target_type);
                  return;
                }else if (target_type is TypeBuilder){
                  il.Emit(OpCodes.Castclass, target_type);
                  return;
                }else if (target_type == typeof(Enum) && source_type.BaseType == typeof(Enum)){
                  il.Emit(OpCodes.Box, source_type);
                  return;
                }else if (target_type == Typeob.Object || target_type.IsAssignableFrom(source_type)){
                  if (source_type.IsValueType)
                    il.Emit(OpCodes.Box, source_type);
                  return;
                }

                if (Typeob.JSObject.IsAssignableFrom(target_type)){
                  if (source_type.IsValueType)
                    il.Emit(OpCodes.Box, source_type);
                  ast.EmitILToLoadEngine(il);
                  il.Emit(OpCodes.Call, CompilerGlobals.toObject2Method); //Do this here so that we need not pass engine to Coerce
                  il.Emit(OpCodes.Castclass, target_type);
                  return;
                }

                if (Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
                  return;

                //Either no conversion is possible, or not enough information is available at compile time.
                //PartialEvaluator is supposed to give errors when conversions are known to be impossible.
                //Defer to run-time type checking
                if (target_type.IsValueType || target_type.IsArray){
                  il.Emit(OpCodes.Ldtoken, target_type);
                  il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod);
                  ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
                  il.Emit(OpCodes.Call, CompilerGlobals.coerceTMethod);
                }
                if (target_type.IsValueType)
                  Convert.EmitUnbox(il, target_type, target);
                else
                  il.Emit(OpCodes.Castclass, target_type);
                return;

              case TypeCode.Boolean:
                if (source_type.IsValueType)
                  il.Emit(OpCodes.Box, source_type);
                ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
                il.Emit(OpCodes.Call, CompilerGlobals.toBooleanMethod);
                return;

              case TypeCode.Single:
                if (source_type.IsValueType)
                  il.Emit(OpCodes.Box, source_type);
                il.Emit(OpCodes.Call, CompilerGlobals.toNumberMethod);
                il.Emit(OpCodes.Conv_R4);
                return;

              case TypeCode.Double:
                if (source_type.IsValueType)
                  il.Emit(OpCodes.Box, source_type);
                il.Emit(OpCodes.Call, CompilerGlobals.toNumberMethod);
                return;

              case TypeCode.Char:
              case TypeCode.SByte:
              case TypeCode.Byte:
              case TypeCode.Int16:
              case TypeCode.UInt16:
              case TypeCode.Int32:
              case TypeCode.UInt32:
              case TypeCode.Int64:
              case TypeCode.UInt64:
              case TypeCode.Decimal:
              case TypeCode.DateTime:
                if (source_type.IsValueType)
                  il.Emit(OpCodes.Box, source_type);
                if (truncationPermitted && target == TypeCode.Int32){
                  il.Emit(OpCodes.Call, CompilerGlobals.toInt32Method);
                  return;
                }else{
                  ConstantWrapper.TranslateToILInt(il, (int)target);
                  ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
                  il.Emit(OpCodes.Call, CompilerGlobals.coerce2Method);
                }
                if (target_type.IsValueType)
                  Convert.EmitUnbox(il, target_type, target);
                return;

              case TypeCode.String:
                if (source_type.IsValueType)
                  il.Emit(OpCodes.Box, source_type);
                if (truncationPermitted) //explict cast to type string
                  il.Emit(OpCodes.Castclass, Typeob.String);
                else{
                  ConstantWrapper.TranslateToILInt(il, 1);
                  il.Emit(OpCodes.Call, CompilerGlobals.toStringMethod);
                }
                return;
            }
            return;

          case TypeCode.DBNull:
            if (source_type.IsValueType) //Not likely, but a hacker might cause this to be true.
              il.Emit(OpCodes.Box, source_type);
            if (target == TypeCode.Object || (target == TypeCode.String && !truncationPermitted)){
              if (target_type == Typeob.Object)
                return;
              if (!target_type.IsValueType){
                il.Emit(OpCodes.Pop);
                il.Emit(OpCodes.Ldnull);
                return;
              }
            }
            if (target_type.IsValueType){
              il.Emit(OpCodes.Ldtoken, target_type);
              il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod);
              ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
              il.Emit(OpCodes.Call, CompilerGlobals.coerceTMethod);
              Convert.EmitUnbox(il, target_type, target);
            }else{
              ConstantWrapper.TranslateToILInt(il, (int)target);
              ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
              il.Emit(OpCodes.Call, CompilerGlobals.coerce2Method); //constructs and boxes whatever value is needed
            }
            return;

          case TypeCode.Boolean:
            switch (target){
              case TypeCode.Object:
                if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
                  return;
                il.Emit(OpCodes.Box, source_type);
                Convert.Emit(ast, il, Typeob.Object, target_type);
                return;
              case TypeCode.Boolean:
              case TypeCode.Char:
              case TypeCode.SByte:
              case TypeCode.Int16:
              case TypeCode.Int32:
              case TypeCode.Byte:
              case TypeCode.UInt16:
              case TypeCode.UInt32:
                 return;
              case TypeCode.Int64:
              case TypeCode.UInt64:
                il.Emit(OpCodes.Conv_U8);
                return;
              case TypeCode.Single:
                il.Emit(OpCodes.Conv_R4);
                return;
              case TypeCode.Double:
                il.Emit(OpCodes.Conv_R8);
                return;
              case TypeCode.Decimal:
                il.Emit(OpCodes.Call, CompilerGlobals.int32ToDecimalMethod);
                return;
              case TypeCode.DateTime:
                il.Emit(OpCodes.Conv_I8);
                il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                return;
              case TypeCode.String:
                Label false_label = il.DefineLabel();
                Label end_label = il.DefineLabel();
                il.Emit(OpCodes.Brfalse, false_label);
                il.Emit(OpCodes.Ldstr, "true");
                il.Emit(OpCodes.Br, end_label);
                il.MarkLabel(false_label);
                il.Emit(OpCodes.Ldstr, "false");
                il.MarkLabel(end_label);
                return;
            }
            break;

          case TypeCode.SByte:
            switch (target){
              case TypeCode.Object:
                if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
                  return;
                il.Emit(OpCodes.Box, source_type);
                Convert.Emit(ast, il, Typeob.Object, target_type);
                return;
              case TypeCode.SByte:
              case TypeCode.Int16:
              case TypeCode.Int32:
                return;
              case TypeCode.Byte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U1);
                else
                  il.Emit(OpCodes.Conv_Ovf_U1);
                return;
              case TypeCode.Char:
              case TypeCode.UInt16:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U2);
                else
                  il.Emit(OpCodes.Conv_Ovf_U2);
                return;
              case TypeCode.UInt32:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U4);
                else
                  il.Emit(OpCodes.Conv_Ovf_U4);
                return;
              case TypeCode.Int64:
                il.Emit(OpCodes.Conv_I8);
                return;
              case TypeCode.UInt64:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I8);
                else
                  il.Emit(OpCodes.Conv_Ovf_U8);
                return;
              case TypeCode.Single:
              case TypeCode.Double:
                il.Emit(OpCodes.Conv_R8);
                return;
              case TypeCode.Boolean:
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                return;
              case TypeCode.Decimal:
                il.Emit(OpCodes.Call, CompilerGlobals.int32ToDecimalMethod);
                return;
              case TypeCode.DateTime:
                il.Emit(OpCodes.Conv_I8);
                il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                return;
              case TypeCode.String:
                Convert.EmitLdloca(il, Typeob.Int32);
                il.Emit(OpCodes.Call, CompilerGlobals.int32ToStringMethod);
                return;
            }
            break;

          case TypeCode.Byte:
            switch (target){
              case TypeCode.Object:
                if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
                  return;
                il.Emit(OpCodes.Box, source_type);
                Convert.Emit(ast, il, Typeob.Object, target_type);
                return;
              case TypeCode.SByte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I1);
                else
                  il.Emit(OpCodes.Conv_Ovf_I1_Un);
                return;
              case TypeCode.Byte:
              case TypeCode.Int16:
              case TypeCode.Char:
              case TypeCode.UInt16:
              case TypeCode.Int32:
              case TypeCode.UInt32:
                return;
              case TypeCode.Int64:
              case TypeCode.UInt64:
                il.Emit(OpCodes.Conv_U8);
                return;
              case TypeCode.Single:
              case TypeCode.Double:
                il.Emit(OpCodes.Conv_R_Un);
                return;
              case TypeCode.Boolean:
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                return;
              case TypeCode.Decimal:
                il.Emit(OpCodes.Call, CompilerGlobals.uint32ToDecimalMethod);
                return;
              case TypeCode.DateTime:
                il.Emit(OpCodes.Conv_I8);
                il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                return;
              case TypeCode.String:
                Convert.EmitLdloca(il, Typeob.UInt32);
                il.Emit(OpCodes.Call, CompilerGlobals.uint32ToStringMethod);
                return;
            }
            break;

          case TypeCode.Int16:
            switch (target){
              case TypeCode.Object:
                if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
                  return;
                il.Emit(OpCodes.Box, source_type);
                Convert.Emit(ast, il, Typeob.Object, target_type);
                return;
              case TypeCode.SByte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I1);
                else
                  il.Emit(OpCodes.Conv_Ovf_I1);
                return;
              case TypeCode.Int16:
              case TypeCode.Int32:
                return;
              case TypeCode.Byte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U1);
                else
                  il.Emit(OpCodes.Conv_Ovf_U1);
                return;
              case TypeCode.Char:
              case TypeCode.UInt16:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U2);
                else
                  il.Emit(OpCodes.Conv_Ovf_U2);
                return;
              case TypeCode.UInt32:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U4);
                else
                  il.Emit(OpCodes.Conv_Ovf_U4);
                return;
              case TypeCode.Int64:
                il.Emit(OpCodes.Conv_I8);
                return;
              case TypeCode.UInt64:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I8);
                else
                  il.Emit(OpCodes.Conv_Ovf_U8);
                return;
              case TypeCode.Single:
              case TypeCode.Double:
                il.Emit(OpCodes.Conv_R8);
                return;
              case TypeCode.Boolean:
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                return;
              case TypeCode.Decimal:
                il.Emit(OpCodes.Call, CompilerGlobals.int32ToDecimalMethod);
                return;
              case TypeCode.DateTime:
                il.Emit(OpCodes.Conv_I8);
                il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                return;
              case TypeCode.String:
                Convert.EmitLdloca(il, Typeob.Int32);
                il.Emit(OpCodes.Call, CompilerGlobals.int32ToStringMethod);
                return;
            }
            break;

          case TypeCode.Char:
          case TypeCode.UInt16:
            switch (target){
              case TypeCode.Object:
                if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
                  return;
                il.Emit(OpCodes.Box, source_type);
                Convert.Emit(ast, il, Typeob.Object, target_type);
                return;
              case TypeCode.SByte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I1);
                else
                  il.Emit(OpCodes.Conv_Ovf_I1);
                return;
              case TypeCode.Byte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U1);
                else
                  il.Emit(OpCodes.Conv_Ovf_U1);
                return;
              case TypeCode.Int16:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I2);
                else
                  il.Emit(OpCodes.Conv_Ovf_I2);
                return;
              case TypeCode.Char:
              case TypeCode.UInt16:
              case TypeCode.Int32:
              case TypeCode.UInt32:
                return;
              case TypeCode.Int64:
                il.Emit(OpCodes.Conv_I8);
                return;
              case TypeCode.UInt64:
                il.Emit(OpCodes.Conv_U8);
                return;
              case TypeCode.Single:
              case TypeCode.Double:
                il.Emit(OpCodes.Conv_R_Un);
                return;
              case TypeCode.Boolean:
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                return;
              case TypeCode.Decimal:
                il.Emit(OpCodes.Call, CompilerGlobals.uint32ToDecimalMethod);
                return;
              case TypeCode.DateTime:
                il.Emit(OpCodes.Conv_I8);
                il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                return;
              case TypeCode.String:
                if (source == TypeCode.Char)
                  il.Emit(OpCodes.Call, CompilerGlobals.convertCharToStringMethod);
                else{
                  Convert.EmitLdloca(il, Typeob.UInt32);
                  il.Emit(OpCodes.Call, CompilerGlobals.uint32ToStringMethod);
                }
                return;
            }
            break;

          case TypeCode.Int32:
            switch (target){
              case TypeCode.Object:
                if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
                  return;
                il.Emit(OpCodes.Box, source_type);
                Convert.Emit(ast, il, Typeob.Object, target_type);
                return;
              case TypeCode.SByte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I1);
                else
                  il.Emit(OpCodes.Conv_Ovf_I1);
                return;
              case TypeCode.Int16:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I2);
                else
                  il.Emit(OpCodes.Conv_Ovf_I2);
                return;
              case TypeCode.Int32:
                return;
              case TypeCode.Byte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U1);
                else
                  il.Emit(OpCodes.Conv_Ovf_U1);
                return;
              case TypeCode.Char:
              case TypeCode.UInt16:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U2);
                else
                  il.Emit(OpCodes.Conv_Ovf_U2);
                return;
              case TypeCode.UInt32:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U4);
                else
                  il.Emit(OpCodes.Conv_Ovf_U4);
                return;
              case TypeCode.Int64:
                il.Emit(OpCodes.Conv_I8);
                return;
              case TypeCode.UInt64:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U8);
                else
                  il.Emit(OpCodes.Conv_Ovf_U8);
                return;
              case TypeCode.Single:
              case TypeCode.Double:
                il.Emit(OpCodes.Conv_R8);
                return;
              case TypeCode.Boolean:
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                return;
              case TypeCode.Decimal:
                il.Emit(OpCodes.Call, CompilerGlobals.int32ToDecimalMethod);
                return;
              case TypeCode.DateTime:
                il.Emit(OpCodes.Conv_I8);
                il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                return;
              case TypeCode.String:
                Convert.EmitLdloca(il, Typeob.Int32);
                il.Emit(OpCodes.Call, CompilerGlobals.int32ToStringMethod);
                return;
            }
            break;

          case TypeCode.UInt32:
            switch (target){
              case TypeCode.Object:
                if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
                  return;
                il.Emit(OpCodes.Box, source_type);
                Convert.Emit(ast, il, Typeob.Object, target_type);
                return;
              case TypeCode.SByte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I1);
                else
                  il.Emit(OpCodes.Conv_Ovf_I1);
                return;
              case TypeCode.Byte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U1);
                else
                  il.Emit(OpCodes.Conv_Ovf_U1);
                return;
              case TypeCode.Int16:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I2);
                else
                  il.Emit(OpCodes.Conv_Ovf_I2);
                return;
              case TypeCode.Char:
              case TypeCode.UInt16:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U2);
                else
                  il.Emit(OpCodes.Conv_Ovf_U2);
                return;
              case TypeCode.Int32:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I4);
                else
                  il.Emit(OpCodes.Conv_Ovf_I4_Un);
                return;
              case TypeCode.UInt32:
                return;
              case TypeCode.Int64:
                il.Emit(OpCodes.Conv_I8);
                return;
              case TypeCode.UInt64:
                il.Emit(OpCodes.Conv_U8);
                return;
              case TypeCode.Single:
              case TypeCode.Double:
                il.Emit(OpCodes.Conv_R_Un);
                return;
              case TypeCode.Boolean:
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                return;
              case TypeCode.Decimal:
                il.Emit(OpCodes.Call, CompilerGlobals.uint32ToDecimalMethod);
                return;
              case TypeCode.DateTime:
                il.Emit(OpCodes.Conv_I8);
                il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                return;
              case TypeCode.String:
                Convert.EmitLdloca(il, Typeob.UInt32);
                il.Emit(OpCodes.Call, CompilerGlobals.uint32ToStringMethod);
                return;
            }
            break;

          case TypeCode.Int64:
            switch (target){
              case TypeCode.Object:
                if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
                  return;
                il.Emit(OpCodes.Box, source_type);
                Convert.Emit(ast, il, Typeob.Object, target_type);
                return;
              case TypeCode.SByte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I1);
                else
                  il.Emit(OpCodes.Conv_Ovf_I1);
                return;
              case TypeCode.Int16:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I2);
                else
                  il.Emit(OpCodes.Conv_Ovf_I2);
                return;
              case TypeCode.Int32:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I4);
                else
                  il.Emit(OpCodes.Conv_Ovf_I4);
                return;
              case TypeCode.Byte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U1);
                else
                  il.Emit(OpCodes.Conv_Ovf_U1);
                return;
              case TypeCode.Char:
              case TypeCode.UInt16:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U2);
                else
                  il.Emit(OpCodes.Conv_Ovf_U2);
                return;
              case TypeCode.UInt32:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U4);
                else
                  il.Emit(OpCodes.Conv_Ovf_U4);
                return;
              case TypeCode.Int64:
                return;
              case TypeCode.UInt64:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U8);
                else
                  il.Emit(OpCodes.Conv_Ovf_U8);
                return;
              case TypeCode.Single:
              case TypeCode.Double:
                il.Emit(OpCodes.Conv_R8);
                return;
              case TypeCode.Boolean:
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Conv_I8);
                il.Emit(OpCodes.Ceq);
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                return;
              case TypeCode.Decimal:
                il.Emit(OpCodes.Call, CompilerGlobals.int64ToDecimalMethod);
                return;
              case TypeCode.DateTime:
                il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                return;
              case TypeCode.String:
                Convert.EmitLdloca(il, Typeob.Int64);
                il.Emit(OpCodes.Call, CompilerGlobals.int64ToStringMethod);
                return;
            }
            break;

          case TypeCode.UInt64:
            switch (target){
              case TypeCode.Object:
                if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
                  return;
                il.Emit(OpCodes.Box, source_type);
                Convert.Emit(ast, il, Typeob.Object, target_type);
                return;
              case TypeCode.SByte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I1);
                else
                  il.Emit(OpCodes.Conv_Ovf_I1);
                return;
              case TypeCode.Byte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U1);
                else
                  il.Emit(OpCodes.Conv_Ovf_U1);
                return;
              case TypeCode.Int16:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I2);
                else
                  il.Emit(OpCodes.Conv_Ovf_I2);
                return;
              case TypeCode.Char:
              case TypeCode.UInt16:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U2);
                else
                  il.Emit(OpCodes.Conv_Ovf_U2);
                return;
              case TypeCode.Int32:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I4);
                else
                  il.Emit(OpCodes.Conv_Ovf_I4);
                return;
              case TypeCode.UInt32:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U4);
                else
                  il.Emit(OpCodes.Conv_Ovf_U4);
                return;
              case TypeCode.Int64:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I8);
                else
                  il.Emit(OpCodes.Conv_Ovf_I8_Un);
                return;
              case TypeCode.UInt64:
                return;
              case TypeCode.Single:
              case TypeCode.Double:
                il.Emit(OpCodes.Conv_R_Un);
                return;
              case TypeCode.Boolean:
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Conv_I8);
                il.Emit(OpCodes.Ceq);
                il.Emit(OpCodes.Ldc_I4_0);
                il.Emit(OpCodes.Ceq);
                return;
              case TypeCode.Decimal:
                il.Emit(OpCodes.Call, CompilerGlobals.uint64ToDecimalMethod);
                return;
              case TypeCode.DateTime:
                il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                return;
              case TypeCode.String:
                Convert.EmitLdloca(il, Typeob.UInt64);
                il.Emit(OpCodes.Call, CompilerGlobals.uint64ToStringMethod);
                return;
            }
            break;

          case TypeCode.Single:
            switch (target){
              case TypeCode.Object:
                if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
                  return;
                il.Emit(OpCodes.Box, source_type);
                Convert.Emit(ast, il, Typeob.Object, target_type);
                return;
              case TypeCode.SByte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I1);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_Ovf_I1);
                }
                return;
              case TypeCode.Int16:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I2);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_Ovf_I2);
                }
                return;
              case TypeCode.Int32:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I4);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_I4);
                }
                return;
              case TypeCode.Byte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U1);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_Ovf_U1);
                }
                return;
              case TypeCode.Char:
              case TypeCode.UInt16:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U2);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_Ovf_U2);
                }
                return;
              case TypeCode.UInt32:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_Ovf_U4);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_Ovf_U4);
                }
                return;
              case TypeCode.Int64:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I8);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_I8);
                }
                return;
              case TypeCode.UInt64:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U8);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_Ovf_U8);
                }
                return;
              case TypeCode.Single:
              case TypeCode.Double:
                return;
              case TypeCode.DateTime:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I8);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_Ovf_I8);
                }
                il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                return;
              case TypeCode.Boolean:
              case TypeCode.Decimal:
              case TypeCode.String:
                il.Emit(OpCodes.Conv_R8);
                Convert.Emit(ast, il, Typeob.Double, target_type);
                return;
            }
            break;

          case TypeCode.Double:
            switch (target){
              case TypeCode.Object:
                if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
                  return;
                il.Emit(OpCodes.Box, source_type);
                Convert.Emit(ast, il, Typeob.Object, target_type);
                return;
              case TypeCode.SByte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I1);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_Ovf_I1);
                }
                return;
              case TypeCode.Int16:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I2);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_Ovf_I2);
                }
                return;
              case TypeCode.Int32:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I4);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_Ovf_I4);
                }
                return;
              case TypeCode.Byte:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U1);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_Ovf_U1);
                }
                return;
              case TypeCode.Char:
              case TypeCode.UInt16:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U2);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_Ovf_U2);
                }
                return;
              case TypeCode.UInt32:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U4);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_Ovf_U4);
                }
                return;
              case TypeCode.Int64:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I8);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_I8);
                }
                return;
              case TypeCode.UInt64:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_U8);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_Ovf_U8);
                }
                return;
              case TypeCode.Single:
              case TypeCode.Double:
                return;
              case TypeCode.Boolean:
                il.Emit(OpCodes.Call, CompilerGlobals.doubleToBooleanMethod);
                return;
              case TypeCode.Decimal:
                il.Emit(OpCodes.Call, CompilerGlobals.doubleToDecimalMethod);
                return;
              case TypeCode.DateTime:
                if (truncationPermitted)
                  il.Emit(OpCodes.Conv_I8);
                else{
                  il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                  il.Emit(OpCodes.Conv_Ovf_I8);
                }
                il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                return;
              case TypeCode.String:
                il.Emit(OpCodes.Call, CompilerGlobals.doubleToStringMethod);
                return;
            }
            break;

          case TypeCode.Decimal:
            switch (target){
              case TypeCode.Object:
                if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
                  return;
                il.Emit(OpCodes.Box, source_type);
                Convert.Emit(ast, il, Typeob.Object, target_type);
                return;
              case TypeCode.Char:
              case TypeCode.SByte:
              case TypeCode.Byte:
              case TypeCode.Int16:
              case TypeCode.UInt16:
              case TypeCode.Int32:
                if (truncationPermitted){
                  il.Emit(OpCodes.Call, CompilerGlobals.decimalToDoubleMethod);
                  il.Emit(OpCodes.Conv_I4);
                }else
                  il.Emit(OpCodes.Call, CompilerGlobals.decimalToInt32Method);
                Convert.Emit(ast, il, Typeob.Int32, target_type, truncationPermitted);
                return;
              case TypeCode.UInt32:
                if (truncationPermitted){
                  il.Emit(OpCodes.Call, CompilerGlobals.decimalToDoubleMethod);
                  il.Emit(OpCodes.Conv_U4);
                }else
                  il.Emit(OpCodes.Call, CompilerGlobals.decimalToUInt32Method);
                return;
              case TypeCode.Boolean:
              case TypeCode.Single:
              case TypeCode.Double:
                il.Emit(OpCodes.Call, CompilerGlobals.decimalToDoubleMethod);
                Convert.Emit(ast, il, Typeob.Double, target_type, truncationPermitted);
                return;
              case TypeCode.Int64:
                if (truncationPermitted){
                  il.Emit(OpCodes.Call, CompilerGlobals.decimalToDoubleMethod);
                  il.Emit(OpCodes.Conv_I8);
                }else
                  il.Emit(OpCodes.Call, CompilerGlobals.decimalToInt64Method);
                return;
              case TypeCode.UInt64:
                if (truncationPermitted){
                  il.Emit(OpCodes.Call, CompilerGlobals.decimalToDoubleMethod);
                  il.Emit(OpCodes.Conv_U8);
                }else
                  il.Emit(OpCodes.Call, CompilerGlobals.decimalToUInt64Method);
                return;
              case TypeCode.Decimal:
                return;
              case TypeCode.DateTime:
                if (truncationPermitted){
                  il.Emit(OpCodes.Call, CompilerGlobals.decimalToDoubleMethod);
                  il.Emit(OpCodes.Conv_I8);
                }else
                  il.Emit(OpCodes.Call, CompilerGlobals.decimalToInt64Method);
                Convert.Emit(ast, il, Typeob.Int64, target_type);
                return;
              case TypeCode.String:
                Convert.EmitLdloca(il, source_type);
                il.Emit(OpCodes.Call, CompilerGlobals.decimalToStringMethod);
                return;
            }
            break;

          case TypeCode.DateTime:
            switch (target){
              case TypeCode.Object:
                if (target_type != Typeob.Object && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
                  return;
                il.Emit(OpCodes.Box, source_type);
                Convert.Emit(ast, il, Typeob.Object, target_type);
                return;
              case TypeCode.Boolean:
              case TypeCode.Char:
              case TypeCode.SByte:
              case TypeCode.Byte:
              case TypeCode.Int16:
              case TypeCode.UInt16:
              case TypeCode.Int32:
              case TypeCode.UInt32:
              case TypeCode.Int64:
              case TypeCode.UInt64:
              case TypeCode.Single:
              case TypeCode.Double:
              case TypeCode.Decimal:
                Convert.EmitLdloca(il, source_type);
                il.Emit(OpCodes.Call, CompilerGlobals.dateTimeToInt64Method);
                Convert.Emit(ast, il, Typeob.Int64, target_type, truncationPermitted);
                return;
              case TypeCode.DateTime:
                return;
              case TypeCode.String:
                Convert.EmitLdloca(il, source_type);
                il.Emit(OpCodes.Call, CompilerGlobals.dateTimeToStringMethod);
                return;
            }
            break;

          case TypeCode.String:
            switch (target){
              case TypeCode.Object:
                if (target_type != Typeob.Object && !(target_type is TypeBuilder) && Convert.EmittedCallToConversionMethod(ast, il, source_type, target_type))
                  return;
                Convert.Emit(ast, il, Typeob.Object, target_type);
                return;
              case TypeCode.Boolean:
              case TypeCode.Char:
              case TypeCode.SByte:
              case TypeCode.Byte:
              case TypeCode.Int16:
              case TypeCode.UInt16:
              case TypeCode.Int32:
              case TypeCode.UInt32:
              case TypeCode.Int64:
              case TypeCode.UInt64:
              case TypeCode.Single:
              case TypeCode.Double:
              case TypeCode.Decimal:
              case TypeCode.DateTime:
                //Resort to calling the Coerce routine. The extra call and the extra box/unbox adds neglible cost to such an expensive conversion.
                if (truncationPermitted && target == TypeCode.Int32){
                  il.Emit(OpCodes.Call, CompilerGlobals.toInt32Method);
                  return;
                }else{
                  ConstantWrapper.TranslateToILInt(il, (int)target);
                  ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
                  il.Emit(OpCodes.Call, CompilerGlobals.coerce2Method);
                }
                if (target_type.IsValueType) //Should always be true, but may as well check
                  Convert.EmitUnbox(il, target_type, target);
                return;
              case TypeCode.String:
                return;
            }
            break;
        }
        Convert.Emit(ast, il, source_type, Typeob.Object); //The thing on the stack cannot be converted to target_type. Arrange for an error message.
        il.Emit(OpCodes.Call, CompilerGlobals.throwTypeMismatch);
        LocalBuilder tok = il.DeclareLocal(target_type); //Add dummy code to reassure the verifier.
        il.Emit(OpCodes.Ldloc, tok);
      }
        internal static void Emit(AST ast, ILGenerator il, Type source_type, Type target_type, bool truncationPermitted)
        {
            if (source_type != target_type)
            {
                if (target_type == Typeob.Void)
                {
                    il.Emit(OpCodes.Pop);
                    return;
                }
                if (target_type.IsEnum)
                {
                    if ((source_type == Typeob.String) || (source_type == Typeob.Object))
                    {
                        il.Emit(OpCodes.Ldtoken, target_type);
                        il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod);
                        ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
                        il.Emit(OpCodes.Call, CompilerGlobals.coerceTMethod);
                        EmitUnbox(il, target_type, Type.GetTypeCode(GetUnderlyingType(target_type)));
                        return;
                    }
                    Emit(ast, il, source_type, GetUnderlyingType(target_type));
                    return;
                }
                if (!source_type.IsEnum)
                {
                    goto Label_013D;
                }
                if (target_type.IsPrimitive)
                {
                    Emit(ast, il, GetUnderlyingType(source_type), target_type);
                    return;
                }
                if ((target_type == Typeob.Object) || (target_type == Typeob.Enum))
                {
                    il.Emit(OpCodes.Box, source_type);
                    return;
                }
                if (!(target_type == Typeob.String))
                {
                    goto Label_013D;
                }
                il.Emit(OpCodes.Box, source_type);
                ConstantWrapper.TranslateToILInt(il, 0);
                il.Emit(OpCodes.Call, CompilerGlobals.toStringMethod);
            }
            return;
        Label_013D:
            while (source_type is TypeBuilder)
            {
                source_type = source_type.BaseType;
                if (source_type == null)
                {
                    source_type = Typeob.Object;
                }
                if (source_type == target_type)
                {
                    return;
                }
            }
            if (source_type.IsArray && target_type.IsArray)
            {
                return;
            }
            TypeCode typeCode = Type.GetTypeCode(source_type);
            TypeCode target = (target_type is TypeBuilder) ? TypeCode.Object : Type.GetTypeCode(target_type);
            switch (typeCode)
            {
                case TypeCode.Empty:
                    return;

                case TypeCode.Object:
                    if (source_type == Typeob.Void)
                    {
                        il.Emit(OpCodes.Ldnull);
                        source_type = Typeob.Object;
                    }
                    switch (target)
                    {
                        case TypeCode.Object:
                            if (!target_type.IsArray && !(target_type == Typeob.Array))
                            {
                                if (target_type is TypeBuilder)
                                {
                                    il.Emit(OpCodes.Castclass, target_type);
                                    return;
                                }
                                if ((target_type == Typeob.Enum) && (source_type.BaseType == Typeob.Enum))
                                {
                                    il.Emit(OpCodes.Box, source_type);
                                    return;
                                }
                                if ((target_type == Typeob.Object) || target_type.IsAssignableFrom(source_type))
                                {
                                    if (source_type.IsValueType)
                                    {
                                        il.Emit(OpCodes.Box, source_type);
                                    }
                                    return;
                                }
                                if (Typeob.JSObject.IsAssignableFrom(target_type))
                                {
                                    if (source_type.IsValueType)
                                    {
                                        il.Emit(OpCodes.Box, source_type);
                                    }
                                    ast.EmitILToLoadEngine(il);
                                    il.Emit(OpCodes.Call, CompilerGlobals.toObject2Method);
                                    il.Emit(OpCodes.Castclass, target_type);
                                    return;
                                }
                                if (!EmittedCallToConversionMethod(ast, il, source_type, target_type))
                                {
                                    if (target_type.IsValueType || target_type.IsArray)
                                    {
                                        il.Emit(OpCodes.Ldtoken, target_type);
                                        il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod);
                                        ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
                                        il.Emit(OpCodes.Call, CompilerGlobals.coerceTMethod);
                                    }
                                    if (target_type.IsValueType)
                                    {
                                        EmitUnbox(il, target_type, target);
                                        return;
                                    }
                                    il.Emit(OpCodes.Castclass, target_type);
                                }
                                return;
                            }
                            if (!(source_type == Typeob.ArrayObject) && !(source_type == Typeob.Object))
                            {
                                goto Label_02A9;
                            }
                            if (!target_type.IsArray)
                            {
                                il.Emit(OpCodes.Ldtoken, Typeob.Object);
                            }
                            else
                            {
                                il.Emit(OpCodes.Ldtoken, target_type.GetElementType());
                            }
                            goto Label_0299;

                        case TypeCode.DBNull:
                        case (TypeCode.DateTime | TypeCode.Object):
                            return;

                        case TypeCode.Boolean:
                            if (source_type.IsValueType)
                            {
                                il.Emit(OpCodes.Box, source_type);
                            }
                            ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
                            il.Emit(OpCodes.Call, CompilerGlobals.toBooleanMethod);
                            return;

                        case TypeCode.Char:
                        case TypeCode.SByte:
                        case TypeCode.Byte:
                        case TypeCode.Int16:
                        case TypeCode.UInt16:
                        case TypeCode.Int32:
                        case TypeCode.UInt32:
                        case TypeCode.Int64:
                        case TypeCode.UInt64:
                        case TypeCode.Decimal:
                        case TypeCode.DateTime:
                            if (source_type.IsValueType)
                            {
                                il.Emit(OpCodes.Box, source_type);
                            }
                            if (truncationPermitted && (target == TypeCode.Int32))
                            {
                                il.Emit(OpCodes.Call, CompilerGlobals.toInt32Method);
                                return;
                            }
                            ConstantWrapper.TranslateToILInt(il, (int) target);
                            ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
                            il.Emit(OpCodes.Call, CompilerGlobals.coerce2Method);
                            if (target_type.IsValueType)
                            {
                                EmitUnbox(il, target_type, target);
                            }
                            return;

                        case TypeCode.Single:
                            if (source_type.IsValueType)
                            {
                                il.Emit(OpCodes.Box, source_type);
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.toNumberMethod);
                            il.Emit(OpCodes.Conv_R4);
                            return;

                        case TypeCode.Double:
                            if (source_type.IsValueType)
                            {
                                il.Emit(OpCodes.Box, source_type);
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.toNumberMethod);
                            return;

                        case TypeCode.String:
                            if (source_type.IsValueType)
                            {
                                il.Emit(OpCodes.Box, source_type);
                            }
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Castclass, Typeob.String);
                                return;
                            }
                            ConstantWrapper.TranslateToILInt(il, 1);
                            il.Emit(OpCodes.Call, CompilerGlobals.toStringMethod);
                            return;
                    }
                    return;

                case TypeCode.DBNull:
                    if (source_type.IsValueType)
                    {
                        il.Emit(OpCodes.Box, source_type);
                    }
                    if ((target == TypeCode.Object) || ((target == TypeCode.String) && !truncationPermitted))
                    {
                        if (target_type == Typeob.Object)
                        {
                            return;
                        }
                        if (!target_type.IsValueType)
                        {
                            il.Emit(OpCodes.Pop);
                            il.Emit(OpCodes.Ldnull);
                            return;
                        }
                    }
                    if (target_type.IsValueType)
                    {
                        il.Emit(OpCodes.Ldtoken, target_type);
                        il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod);
                        ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
                        il.Emit(OpCodes.Call, CompilerGlobals.coerceTMethod);
                        EmitUnbox(il, target_type, target);
                        return;
                    }
                    ConstantWrapper.TranslateToILInt(il, (int) target);
                    ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
                    il.Emit(OpCodes.Call, CompilerGlobals.coerce2Method);
                    return;

                case TypeCode.Boolean:
                    switch (target)
                    {
                        case TypeCode.Object:
                            if ((target_type == Typeob.Object) || !EmittedCallToConversionMethod(ast, il, source_type, target_type))
                            {
                                il.Emit(OpCodes.Box, source_type);
                                Emit(ast, il, Typeob.Object, target_type);
                            }
                            return;

                        case TypeCode.Boolean:
                        case TypeCode.Char:
                        case TypeCode.SByte:
                        case TypeCode.Byte:
                        case TypeCode.Int16:
                        case TypeCode.UInt16:
                        case TypeCode.Int32:
                        case TypeCode.UInt32:
                            return;

                        case TypeCode.Int64:
                        case TypeCode.UInt64:
                            il.Emit(OpCodes.Conv_U8);
                            return;

                        case TypeCode.Single:
                            il.Emit(OpCodes.Conv_R4);
                            return;

                        case TypeCode.Double:
                            il.Emit(OpCodes.Conv_R8);
                            return;

                        case TypeCode.Decimal:
                            il.Emit(OpCodes.Call, CompilerGlobals.int32ToDecimalMethod);
                            return;

                        case TypeCode.DateTime:
                            il.Emit(OpCodes.Conv_I8);
                            il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                            return;

                        case TypeCode.String:
                        {
                            Label label = il.DefineLabel();
                            Label label2 = il.DefineLabel();
                            il.Emit(OpCodes.Brfalse, label);
                            il.Emit(OpCodes.Ldstr, "true");
                            il.Emit(OpCodes.Br, label2);
                            il.MarkLabel(label);
                            il.Emit(OpCodes.Ldstr, "false");
                            il.MarkLabel(label2);
                            return;
                        }
                    }
                    goto Label_1C18;

                case TypeCode.Char:
                case TypeCode.UInt16:
                    switch (target)
                    {
                        case TypeCode.Object:
                            if ((target_type == Typeob.Object) || !EmittedCallToConversionMethod(ast, il, source_type, target_type))
                            {
                                il.Emit(OpCodes.Box, source_type);
                                Emit(ast, il, Typeob.Object, target_type);
                            }
                            return;

                        case TypeCode.Boolean:
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Ceq);
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Ceq);
                            return;

                        case TypeCode.Char:
                        case TypeCode.UInt16:
                        case TypeCode.Int32:
                        case TypeCode.UInt32:
                            return;

                        case TypeCode.SByte:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I1);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_I1);
                            return;

                        case TypeCode.Byte:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U1);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U1);
                            return;

                        case TypeCode.Int16:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I2);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_I2);
                            return;

                        case TypeCode.Int64:
                            il.Emit(OpCodes.Conv_I8);
                            return;

                        case TypeCode.UInt64:
                            il.Emit(OpCodes.Conv_U8);
                            return;

                        case TypeCode.Single:
                        case TypeCode.Double:
                            il.Emit(OpCodes.Conv_R_Un);
                            return;

                        case TypeCode.Decimal:
                            il.Emit(OpCodes.Call, CompilerGlobals.uint32ToDecimalMethod);
                            return;

                        case TypeCode.DateTime:
                            il.Emit(OpCodes.Conv_I8);
                            il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                            return;

                        case TypeCode.String:
                            if (typeCode == TypeCode.Char)
                            {
                                il.Emit(OpCodes.Call, CompilerGlobals.convertCharToStringMethod);
                                return;
                            }
                            EmitLdloca(il, Typeob.UInt32);
                            il.Emit(OpCodes.Call, CompilerGlobals.uint32ToStringMethod);
                            return;
                    }
                    goto Label_1C18;

                case TypeCode.SByte:
                    switch (target)
                    {
                        case TypeCode.Object:
                            if ((target_type == Typeob.Object) || !EmittedCallToConversionMethod(ast, il, source_type, target_type))
                            {
                                il.Emit(OpCodes.Box, source_type);
                                Emit(ast, il, Typeob.Object, target_type);
                            }
                            return;

                        case TypeCode.Boolean:
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Ceq);
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Ceq);
                            return;

                        case TypeCode.Char:
                        case TypeCode.UInt16:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U2);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U2);
                            return;

                        case TypeCode.SByte:
                        case TypeCode.Int16:
                        case TypeCode.Int32:
                            return;

                        case TypeCode.Byte:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U1);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U1);
                            return;

                        case TypeCode.UInt32:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U4);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U4);
                            return;

                        case TypeCode.Int64:
                            il.Emit(OpCodes.Conv_I8);
                            return;

                        case TypeCode.UInt64:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I8);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U8);
                            return;

                        case TypeCode.Single:
                        case TypeCode.Double:
                            il.Emit(OpCodes.Conv_R8);
                            return;

                        case TypeCode.Decimal:
                            il.Emit(OpCodes.Call, CompilerGlobals.int32ToDecimalMethod);
                            return;

                        case TypeCode.DateTime:
                            il.Emit(OpCodes.Conv_I8);
                            il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                            return;

                        case TypeCode.String:
                            EmitLdloca(il, Typeob.Int32);
                            il.Emit(OpCodes.Call, CompilerGlobals.int32ToStringMethod);
                            return;
                    }
                    goto Label_1C18;

                case TypeCode.Byte:
                    switch (target)
                    {
                        case TypeCode.Object:
                            if ((target_type == Typeob.Object) || !EmittedCallToConversionMethod(ast, il, source_type, target_type))
                            {
                                il.Emit(OpCodes.Box, source_type);
                                Emit(ast, il, Typeob.Object, target_type);
                            }
                            return;

                        case TypeCode.Boolean:
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Ceq);
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Ceq);
                            return;

                        case TypeCode.Char:
                        case TypeCode.Byte:
                        case TypeCode.Int16:
                        case TypeCode.UInt16:
                        case TypeCode.Int32:
                        case TypeCode.UInt32:
                            return;

                        case TypeCode.SByte:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I1);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_I1_Un);
                            return;

                        case TypeCode.Int64:
                        case TypeCode.UInt64:
                            il.Emit(OpCodes.Conv_U8);
                            return;

                        case TypeCode.Single:
                        case TypeCode.Double:
                            il.Emit(OpCodes.Conv_R_Un);
                            return;

                        case TypeCode.Decimal:
                            il.Emit(OpCodes.Call, CompilerGlobals.uint32ToDecimalMethod);
                            return;

                        case TypeCode.DateTime:
                            il.Emit(OpCodes.Conv_I8);
                            il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                            return;

                        case TypeCode.String:
                            EmitLdloca(il, Typeob.UInt32);
                            il.Emit(OpCodes.Call, CompilerGlobals.uint32ToStringMethod);
                            return;
                    }
                    goto Label_1C18;

                case TypeCode.Int16:
                    switch (target)
                    {
                        case TypeCode.Object:
                            if ((target_type == Typeob.Object) || !EmittedCallToConversionMethod(ast, il, source_type, target_type))
                            {
                                il.Emit(OpCodes.Box, source_type);
                                Emit(ast, il, Typeob.Object, target_type);
                            }
                            return;

                        case TypeCode.Boolean:
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Ceq);
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Ceq);
                            return;

                        case TypeCode.Char:
                        case TypeCode.UInt16:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U2);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U2);
                            return;

                        case TypeCode.SByte:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I1);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_I1);
                            return;

                        case TypeCode.Byte:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U1);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U1);
                            return;

                        case TypeCode.Int16:
                        case TypeCode.Int32:
                            return;

                        case TypeCode.UInt32:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U4);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U4);
                            return;

                        case TypeCode.Int64:
                            il.Emit(OpCodes.Conv_I8);
                            return;

                        case TypeCode.UInt64:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I8);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U8);
                            return;

                        case TypeCode.Single:
                        case TypeCode.Double:
                            il.Emit(OpCodes.Conv_R8);
                            return;

                        case TypeCode.Decimal:
                            il.Emit(OpCodes.Call, CompilerGlobals.int32ToDecimalMethod);
                            return;

                        case TypeCode.DateTime:
                            il.Emit(OpCodes.Conv_I8);
                            il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                            return;

                        case TypeCode.String:
                            EmitLdloca(il, Typeob.Int32);
                            il.Emit(OpCodes.Call, CompilerGlobals.int32ToStringMethod);
                            return;
                    }
                    goto Label_1C18;

                case TypeCode.Int32:
                    switch (target)
                    {
                        case TypeCode.Object:
                            if ((target_type == Typeob.Object) || !EmittedCallToConversionMethod(ast, il, source_type, target_type))
                            {
                                il.Emit(OpCodes.Box, source_type);
                                Emit(ast, il, Typeob.Object, target_type);
                            }
                            return;

                        case TypeCode.Boolean:
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Ceq);
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Ceq);
                            return;

                        case TypeCode.Char:
                        case TypeCode.UInt16:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U2);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U2);
                            return;

                        case TypeCode.SByte:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I1);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_I1);
                            return;

                        case TypeCode.Byte:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U1);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U1);
                            return;

                        case TypeCode.Int16:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I2);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_I2);
                            return;

                        case TypeCode.Int32:
                            return;

                        case TypeCode.UInt32:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U4);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U4);
                            return;

                        case TypeCode.Int64:
                            il.Emit(OpCodes.Conv_I8);
                            return;

                        case TypeCode.UInt64:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U8);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U8);
                            return;

                        case TypeCode.Single:
                        case TypeCode.Double:
                            il.Emit(OpCodes.Conv_R8);
                            return;

                        case TypeCode.Decimal:
                            il.Emit(OpCodes.Call, CompilerGlobals.int32ToDecimalMethod);
                            return;

                        case TypeCode.DateTime:
                            il.Emit(OpCodes.Conv_I8);
                            il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                            return;

                        case TypeCode.String:
                            EmitLdloca(il, Typeob.Int32);
                            il.Emit(OpCodes.Call, CompilerGlobals.int32ToStringMethod);
                            return;
                    }
                    goto Label_1C18;

                case TypeCode.UInt32:
                    switch (target)
                    {
                        case TypeCode.Object:
                            if ((target_type == Typeob.Object) || !EmittedCallToConversionMethod(ast, il, source_type, target_type))
                            {
                                il.Emit(OpCodes.Box, source_type);
                                Emit(ast, il, Typeob.Object, target_type);
                            }
                            return;

                        case TypeCode.Boolean:
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Ceq);
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Ceq);
                            return;

                        case TypeCode.Char:
                        case TypeCode.UInt16:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U2);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U2);
                            return;

                        case TypeCode.SByte:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I1);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_I1);
                            return;

                        case TypeCode.Byte:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U1);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U1);
                            return;

                        case TypeCode.Int16:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I2);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_I2);
                            return;

                        case TypeCode.Int32:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I4);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_I4_Un);
                            return;

                        case TypeCode.UInt32:
                            return;

                        case TypeCode.Int64:
                            il.Emit(OpCodes.Conv_I8);
                            return;

                        case TypeCode.UInt64:
                            il.Emit(OpCodes.Conv_U8);
                            return;

                        case TypeCode.Single:
                        case TypeCode.Double:
                            il.Emit(OpCodes.Conv_R_Un);
                            return;

                        case TypeCode.Decimal:
                            il.Emit(OpCodes.Call, CompilerGlobals.uint32ToDecimalMethod);
                            return;

                        case TypeCode.DateTime:
                            il.Emit(OpCodes.Conv_I8);
                            il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                            return;

                        case TypeCode.String:
                            EmitLdloca(il, Typeob.UInt32);
                            il.Emit(OpCodes.Call, CompilerGlobals.uint32ToStringMethod);
                            return;
                    }
                    goto Label_1C18;

                case TypeCode.Int64:
                    switch (target)
                    {
                        case TypeCode.Object:
                            if ((target_type == Typeob.Object) || !EmittedCallToConversionMethod(ast, il, source_type, target_type))
                            {
                                il.Emit(OpCodes.Box, source_type);
                                Emit(ast, il, Typeob.Object, target_type);
                            }
                            return;

                        case TypeCode.Boolean:
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Conv_I8);
                            il.Emit(OpCodes.Ceq);
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Ceq);
                            return;

                        case TypeCode.Char:
                        case TypeCode.UInt16:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U2);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U2);
                            return;

                        case TypeCode.SByte:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I1);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_I1);
                            return;

                        case TypeCode.Byte:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U1);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U1);
                            return;

                        case TypeCode.Int16:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I2);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_I2);
                            return;

                        case TypeCode.Int32:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I4);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_I4);
                            return;

                        case TypeCode.UInt32:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U4);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U4);
                            return;

                        case TypeCode.Int64:
                            return;

                        case TypeCode.UInt64:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U8);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U8);
                            return;

                        case TypeCode.Single:
                        case TypeCode.Double:
                            il.Emit(OpCodes.Conv_R8);
                            return;

                        case TypeCode.Decimal:
                            il.Emit(OpCodes.Call, CompilerGlobals.int64ToDecimalMethod);
                            return;

                        case TypeCode.DateTime:
                            il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                            return;

                        case TypeCode.String:
                            EmitLdloca(il, Typeob.Int64);
                            il.Emit(OpCodes.Call, CompilerGlobals.int64ToStringMethod);
                            return;
                    }
                    goto Label_1C18;

                case TypeCode.UInt64:
                    switch (target)
                    {
                        case TypeCode.Object:
                            if ((target_type == Typeob.Object) || !EmittedCallToConversionMethod(ast, il, source_type, target_type))
                            {
                                il.Emit(OpCodes.Box, source_type);
                                Emit(ast, il, Typeob.Object, target_type);
                            }
                            return;

                        case TypeCode.Boolean:
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Conv_I8);
                            il.Emit(OpCodes.Ceq);
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Ceq);
                            return;

                        case TypeCode.Char:
                        case TypeCode.UInt16:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U2);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U2);
                            return;

                        case TypeCode.SByte:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I1);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_I1);
                            return;

                        case TypeCode.Byte:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U1);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U1);
                            return;

                        case TypeCode.Int16:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I2);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_I2);
                            return;

                        case TypeCode.Int32:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I4);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_I4);
                            return;

                        case TypeCode.UInt32:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_U4);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_U4);
                            return;

                        case TypeCode.Int64:
                            if (truncationPermitted)
                            {
                                il.Emit(OpCodes.Conv_I8);
                                return;
                            }
                            il.Emit(OpCodes.Conv_Ovf_I8_Un);
                            return;

                        case TypeCode.UInt64:
                            return;

                        case TypeCode.Single:
                        case TypeCode.Double:
                            il.Emit(OpCodes.Conv_R_Un);
                            return;

                        case TypeCode.Decimal:
                            il.Emit(OpCodes.Call, CompilerGlobals.uint64ToDecimalMethod);
                            return;

                        case TypeCode.DateTime:
                            il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                            return;

                        case TypeCode.String:
                            EmitLdloca(il, Typeob.UInt64);
                            il.Emit(OpCodes.Call, CompilerGlobals.uint64ToStringMethod);
                            return;
                    }
                    goto Label_1C18;

                case TypeCode.Single:
                    switch (target)
                    {
                        case TypeCode.Object:
                            if ((target_type == Typeob.Object) || !EmittedCallToConversionMethod(ast, il, source_type, target_type))
                            {
                                il.Emit(OpCodes.Box, source_type);
                                Emit(ast, il, Typeob.Object, target_type);
                            }
                            return;

                        case TypeCode.Boolean:
                        case TypeCode.Decimal:
                        case TypeCode.String:
                            il.Emit(OpCodes.Conv_R8);
                            Emit(ast, il, Typeob.Double, target_type);
                            return;

                        case TypeCode.Char:
                        case TypeCode.UInt16:
                            if (truncationPermitted)
                            {
                                EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_U2);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                            il.Emit(OpCodes.Conv_Ovf_U2);
                            return;

                        case TypeCode.SByte:
                            if (truncationPermitted)
                            {
                                EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_I1);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                            il.Emit(OpCodes.Conv_Ovf_I1);
                            return;

                        case TypeCode.Byte:
                            if (truncationPermitted)
                            {
                                EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_U1);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                            il.Emit(OpCodes.Conv_Ovf_U1);
                            return;

                        case TypeCode.Int16:
                            if (truncationPermitted)
                            {
                                EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_I2);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                            il.Emit(OpCodes.Conv_Ovf_I2);
                            return;

                        case TypeCode.Int32:
                            if (truncationPermitted)
                            {
                                EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_I4);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                            il.Emit(OpCodes.Conv_I4);
                            return;

                        case TypeCode.UInt32:
                            if (truncationPermitted)
                            {
                                EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_Ovf_U4);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                            il.Emit(OpCodes.Conv_Ovf_U4);
                            return;

                        case TypeCode.Int64:
                            if (truncationPermitted)
                            {
                                EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_I8);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                            il.Emit(OpCodes.Conv_I8);
                            return;

                        case TypeCode.UInt64:
                            if (truncationPermitted)
                            {
                                EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_U8);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                            il.Emit(OpCodes.Conv_Ovf_U8);
                            return;

                        case TypeCode.Single:
                        case TypeCode.Double:
                            return;

                        case TypeCode.DateTime:
                            if (truncationPermitted)
                            {
                                EmitSingleToIntegerTruncatedConversion(il, OpCodes.Conv_I8);
                            }
                            else
                            {
                                il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                                il.Emit(OpCodes.Conv_Ovf_I8);
                            }
                            il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                            return;
                    }
                    goto Label_1C18;

                case TypeCode.Double:
                    switch (target)
                    {
                        case TypeCode.Object:
                            if ((target_type == Typeob.Object) || !EmittedCallToConversionMethod(ast, il, source_type, target_type))
                            {
                                il.Emit(OpCodes.Box, source_type);
                                Emit(ast, il, Typeob.Object, target_type);
                            }
                            return;

                        case TypeCode.Boolean:
                            il.Emit(OpCodes.Call, CompilerGlobals.doubleToBooleanMethod);
                            return;

                        case TypeCode.Char:
                        case TypeCode.UInt16:
                            if (truncationPermitted)
                            {
                                EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_U2);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
                            il.Emit(OpCodes.Conv_Ovf_U2);
                            return;

                        case TypeCode.SByte:
                            if (truncationPermitted)
                            {
                                EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_I1);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
                            il.Emit(OpCodes.Conv_Ovf_I1);
                            return;

                        case TypeCode.Byte:
                            if (truncationPermitted)
                            {
                                EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_U1);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
                            il.Emit(OpCodes.Conv_Ovf_U1);
                            return;

                        case TypeCode.Int16:
                            if (truncationPermitted)
                            {
                                EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_I2);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
                            il.Emit(OpCodes.Conv_Ovf_I2);
                            return;

                        case TypeCode.Int32:
                            if (truncationPermitted)
                            {
                                EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_I4);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
                            il.Emit(OpCodes.Conv_Ovf_I4);
                            return;

                        case TypeCode.UInt32:
                            if (truncationPermitted)
                            {
                                EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_U4);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
                            il.Emit(OpCodes.Conv_Ovf_U4);
                            return;

                        case TypeCode.Int64:
                            if (truncationPermitted)
                            {
                                EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_I8);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
                            il.Emit(OpCodes.Conv_I8);
                            return;

                        case TypeCode.UInt64:
                            if (truncationPermitted)
                            {
                                EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_U8);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.checkIfDoubleIsIntegerMethod);
                            il.Emit(OpCodes.Conv_Ovf_U8);
                            return;

                        case TypeCode.Single:
                        case TypeCode.Double:
                            return;

                        case TypeCode.Decimal:
                            il.Emit(OpCodes.Call, CompilerGlobals.doubleToDecimalMethod);
                            return;

                        case TypeCode.DateTime:
                            if (truncationPermitted)
                            {
                                EmitDoubleToIntegerTruncatedConversion(il, OpCodes.Conv_I8);
                            }
                            else
                            {
                                il.Emit(OpCodes.Call, CompilerGlobals.checkIfSingleIsIntegerMethod);
                                il.Emit(OpCodes.Conv_Ovf_I8);
                            }
                            il.Emit(OpCodes.Newobj, CompilerGlobals.dateTimeConstructor);
                            return;

                        case TypeCode.String:
                            il.Emit(OpCodes.Call, CompilerGlobals.doubleToStringMethod);
                            return;
                    }
                    goto Label_1C18;

                case TypeCode.Decimal:
                    switch (target)
                    {
                        case TypeCode.Object:
                            if ((target_type == Typeob.Object) || !EmittedCallToConversionMethod(ast, il, source_type, target_type))
                            {
                                il.Emit(OpCodes.Box, source_type);
                                Emit(ast, il, Typeob.Object, target_type);
                            }
                            return;

                        case TypeCode.Boolean:
                            il.Emit(OpCodes.Ldsfld, CompilerGlobals.decimalZeroField);
                            il.Emit(OpCodes.Call, CompilerGlobals.decimalCompare);
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Ceq);
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Ceq);
                            return;

                        case TypeCode.Char:
                        case TypeCode.SByte:
                        case TypeCode.Byte:
                        case TypeCode.Int16:
                        case TypeCode.UInt16:
                        case TypeCode.Int32:
                            if (truncationPermitted)
                            {
                                EmitDecimalToIntegerTruncatedConversion(il, OpCodes.Conv_I4);
                            }
                            else
                            {
                                il.Emit(OpCodes.Call, CompilerGlobals.decimalToInt32Method);
                            }
                            Emit(ast, il, Typeob.Int32, target_type, truncationPermitted);
                            return;

                        case TypeCode.UInt32:
                            if (truncationPermitted)
                            {
                                EmitDecimalToIntegerTruncatedConversion(il, OpCodes.Conv_U4);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.decimalToUInt32Method);
                            return;

                        case TypeCode.Int64:
                            if (truncationPermitted)
                            {
                                EmitDecimalToIntegerTruncatedConversion(il, OpCodes.Conv_I8);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.decimalToInt64Method);
                            return;

                        case TypeCode.UInt64:
                            if (truncationPermitted)
                            {
                                EmitDecimalToIntegerTruncatedConversion(il, OpCodes.Conv_U8);
                                return;
                            }
                            il.Emit(OpCodes.Call, CompilerGlobals.decimalToUInt64Method);
                            return;

                        case TypeCode.Single:
                        case TypeCode.Double:
                            il.Emit(OpCodes.Call, CompilerGlobals.decimalToDoubleMethod);
                            Emit(ast, il, Typeob.Double, target_type, truncationPermitted);
                            return;

                        case TypeCode.Decimal:
                            return;

                        case TypeCode.DateTime:
                            if (truncationPermitted)
                            {
                                EmitDecimalToIntegerTruncatedConversion(il, OpCodes.Conv_I8);
                            }
                            else
                            {
                                il.Emit(OpCodes.Call, CompilerGlobals.decimalToInt64Method);
                            }
                            Emit(ast, il, Typeob.Int64, target_type);
                            return;

                        case TypeCode.String:
                            EmitLdloca(il, source_type);
                            il.Emit(OpCodes.Call, CompilerGlobals.decimalToStringMethod);
                            return;
                    }
                    goto Label_1C18;

                case TypeCode.DateTime:
                    switch (target)
                    {
                        case TypeCode.Object:
                            if ((target_type == Typeob.Object) || !EmittedCallToConversionMethod(ast, il, source_type, target_type))
                            {
                                il.Emit(OpCodes.Box, source_type);
                                Emit(ast, il, Typeob.Object, target_type);
                            }
                            return;

                        case TypeCode.Boolean:
                        case TypeCode.Char:
                        case TypeCode.SByte:
                        case TypeCode.Byte:
                        case TypeCode.Int16:
                        case TypeCode.UInt16:
                        case TypeCode.Int32:
                        case TypeCode.UInt32:
                        case TypeCode.Int64:
                        case TypeCode.UInt64:
                        case TypeCode.Single:
                        case TypeCode.Double:
                        case TypeCode.Decimal:
                            EmitLdloca(il, source_type);
                            il.Emit(OpCodes.Call, CompilerGlobals.dateTimeToInt64Method);
                            Emit(ast, il, Typeob.Int64, target_type, truncationPermitted);
                            return;

                        case TypeCode.DateTime:
                            return;

                        case TypeCode.String:
                            EmitLdloca(il, source_type);
                            il.Emit(OpCodes.Call, CompilerGlobals.dateTimeToStringMethod);
                            return;
                    }
                    goto Label_1C18;

                case TypeCode.String:
                    switch (target)
                    {
                        case TypeCode.Object:
                            if (((target_type == Typeob.Object) || (target_type is TypeBuilder)) || !EmittedCallToConversionMethod(ast, il, source_type, target_type))
                            {
                                Emit(ast, il, Typeob.Object, target_type);
                            }
                            return;

                        case TypeCode.Boolean:
                        case TypeCode.Char:
                        case TypeCode.SByte:
                        case TypeCode.Byte:
                        case TypeCode.Int16:
                        case TypeCode.UInt16:
                        case TypeCode.Int32:
                        case TypeCode.UInt32:
                        case TypeCode.Int64:
                        case TypeCode.UInt64:
                        case TypeCode.Single:
                        case TypeCode.Double:
                        case TypeCode.Decimal:
                        case TypeCode.DateTime:
                            if (truncationPermitted && (target == TypeCode.Int32))
                            {
                                il.Emit(OpCodes.Call, CompilerGlobals.toInt32Method);
                                return;
                            }
                            ConstantWrapper.TranslateToILInt(il, (int) target);
                            ConstantWrapper.TranslateToILInt(il, truncationPermitted ? 1 : 0);
                            il.Emit(OpCodes.Call, CompilerGlobals.coerce2Method);
                            if (target_type.IsValueType)
                            {
                                EmitUnbox(il, target_type, target);
                            }
                            return;

                        case TypeCode.String:
                            return;
                    }
                    goto Label_1C18;

                default:
                    goto Label_1C18;
            }
        Label_0299:
            il.Emit(OpCodes.Call, CompilerGlobals.toNativeArrayMethod);
        Label_02A9:
            il.Emit(OpCodes.Castclass, target_type);
            return;
        Label_1C18:
            Emit(ast, il, source_type, Typeob.Object);
            il.Emit(OpCodes.Call, CompilerGlobals.throwTypeMismatch);
            LocalBuilder local = il.DeclareLocal(target_type);
            il.Emit(OpCodes.Ldloc, local);
        }