private EmitILToLoadEngine ( ILGenerator il ) : void | ||
il | ILGenerator | |
return | void |
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); }