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