예제 #1
0
        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");
            }
        }