private static void EmitConvertValue(GroboIL il, GroBufTypeCode typeCode, GroBufTypeCode expectedTypeCode) { if (expectedTypeCode == typeCode) { return; } switch (expectedTypeCode) { case GroBufTypeCode.Int8: il.Conv <sbyte>(); break; case GroBufTypeCode.UInt8: case GroBufTypeCode.Boolean: il.Conv <byte>(); break; case GroBufTypeCode.Int16: il.Conv <short>(); break; case GroBufTypeCode.UInt16: il.Conv <ushort>(); break; case GroBufTypeCode.Int32: if (typeCode == GroBufTypeCode.Int64 || typeCode == GroBufTypeCode.UInt64 || typeCode == GroBufTypeCode.Double || typeCode == GroBufTypeCode.Single || typeCode == GroBufTypeCode.DateTimeNew) { il.Conv <int>(); } break; case GroBufTypeCode.UInt32: if (typeCode == GroBufTypeCode.Int64 || typeCode == GroBufTypeCode.UInt64 || typeCode == GroBufTypeCode.Double || typeCode == GroBufTypeCode.Single || typeCode == GroBufTypeCode.DateTimeNew) { il.Conv <uint>(); } break; case GroBufTypeCode.Int64: if (typeCode != GroBufTypeCode.UInt64) { if (typeCode == GroBufTypeCode.UInt8 || typeCode == GroBufTypeCode.UInt16 || typeCode == GroBufTypeCode.UInt32) { il.Conv <ulong>(); } else { il.Conv <long>(); } } break; case GroBufTypeCode.UInt64: if (typeCode != GroBufTypeCode.Int64 && typeCode != GroBufTypeCode.DateTimeNew) { if (typeCode == GroBufTypeCode.Int8 || typeCode == GroBufTypeCode.Int16 || typeCode == GroBufTypeCode.Int32) { il.Conv <long>(); } else { il.Conv <ulong>(); } } break; case GroBufTypeCode.Single: if (typeCode == GroBufTypeCode.UInt64 || typeCode == GroBufTypeCode.UInt32) { il.Conv_R_Un(); } il.Conv <float>(); break; case GroBufTypeCode.Double: if (typeCode == GroBufTypeCode.UInt64 || typeCode == GroBufTypeCode.UInt32) { il.Conv_R_Un(); } il.Conv <double>(); break; case GroBufTypeCode.Decimal: switch (typeCode) { case GroBufTypeCode.Boolean: case GroBufTypeCode.Int8: case GroBufTypeCode.Int16: case GroBufTypeCode.Int32: case GroBufTypeCode.UInt8: case GroBufTypeCode.UInt16: il.Newobj(decimalByIntConstructor); break; case GroBufTypeCode.UInt32: il.Newobj(decimalByUIntConstructor); break; case GroBufTypeCode.Int64: case GroBufTypeCode.DateTimeNew: il.Newobj(decimalByLongConstructor); break; case GroBufTypeCode.UInt64: il.Newobj(decimalByULongConstructor); break; case GroBufTypeCode.Single: il.Call(decimalByFloatMethod); break; case GroBufTypeCode.Double: il.Call(decimalByDoubleMethod); break; default: throw new NotSupportedException("Type with type code '" + typeCode + "' is not supported"); } break; default: throw new NotSupportedException("Type with type code '" + expectedTypeCode + "' is not supported"); } }
private static void EmitConvertValueChecked(GroboIL il, Type from, Type to) { var fromTypeCode = Type.GetTypeCode(from); var toTypeCode = Type.GetTypeCode(to); switch (fromTypeCode) { case TypeCode.DBNull: case TypeCode.DateTime: case TypeCode.Decimal: case TypeCode.Empty: case TypeCode.Object: case TypeCode.String: throw new NotSupportedException("Cast from type '" + from + "' to type '" + to + "' is not supported"); } if (toTypeCode == fromTypeCode) { return; } switch (toTypeCode) { case TypeCode.SByte: il.Conv_Ovf <sbyte>(from.Unsigned()); break; case TypeCode.Byte: case TypeCode.Boolean: il.Conv_Ovf <byte>(from.Unsigned()); break; case TypeCode.Int16: il.Conv_Ovf <short>(from.Unsigned()); break; case TypeCode.UInt16: il.Conv_Ovf <ushort>(from.Unsigned()); break; case TypeCode.Int32: if (fromTypeCode == TypeCode.UInt32 || fromTypeCode == TypeCode.Int64 || fromTypeCode == TypeCode.UInt64 || fromTypeCode == TypeCode.Double || fromTypeCode == TypeCode.Single /* || fromTypeCode == TypeCode.DateTime*/) { il.Conv_Ovf <int>(from.Unsigned()); } break; case TypeCode.UInt32: if (fromTypeCode == TypeCode.SByte || fromTypeCode == TypeCode.Int16 || fromTypeCode == TypeCode.Int32 || fromTypeCode == TypeCode.Int64 || fromTypeCode == TypeCode.UInt64 || fromTypeCode == TypeCode.Double || fromTypeCode == TypeCode.Single /* || fromTypeCode == TypeCode.DateTime*/) { il.Conv_Ovf <uint>(from.Unsigned()); } break; case TypeCode.Int64: switch (fromTypeCode) { case TypeCode.Double: case TypeCode.Single: case TypeCode.UInt64: il.Conv_Ovf <long>(from.Unsigned()); break; case TypeCode.UInt32: case TypeCode.Char: case TypeCode.UInt16: case TypeCode.Byte: il.Conv <ulong>(); break; default: il.Conv <long>(); break; } break; case TypeCode.UInt64: switch (fromTypeCode) { case TypeCode.Double: case TypeCode.Single: case TypeCode.Int64: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: il.Conv_Ovf <ulong>(from.Unsigned()); break; case TypeCode.UInt32: case TypeCode.Char: case TypeCode.UInt16: case TypeCode.Byte: il.Conv <ulong>(); break; } break; case TypeCode.Single: if (fromTypeCode == TypeCode.UInt64 || fromTypeCode == TypeCode.UInt32) { il.Conv_R_Un(); } il.Conv <float>(); break; case TypeCode.Double: if (fromTypeCode == TypeCode.UInt64 || fromTypeCode == TypeCode.UInt32) { il.Conv_R_Un(); } il.Conv <double>(); break; default: throw new NotSupportedException("Type with type code '" + toTypeCode + "' is not supported"); } }