Exemplo n.º 1
0
            private void BinaryShiftExpression(BinaryExpression binaryExpression)
            {
                binaryExpression.Left.Accept(this);

                binaryExpression.Right.Accept(this);

                int bits = Marshal.SizeOf(binaryExpression.Left.Type) * 8;

                ILUtil.EmitConstant(_il, bits - 1);
                _il.Emit(OpCodes.And);

                switch (binaryExpression.ExpressionType)
                {
                case ExpressionType.ShiftLeft:
                    _il.Emit(OpCodes.Shl);
                    break;

                case ExpressionType.ShiftRight:
                    if (TypeUtil.IsUnsigned(binaryExpression.Left.Type))
                    {
                        _il.Emit(OpCodes.Shr_Un);
                    }
                    else
                    {
                        _il.Emit(OpCodes.Shr);
                    }
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }
Exemplo n.º 2
0
        private static void EmitNumericConversion(ILGenerator il, Type typeFrom, Type typeTo, bool isChecked)
        {
            if (
                !(typeFrom.IsEnum || TypeUtil.IsNumeric(typeFrom)) ||
                !(typeTo.IsEnum || TypeUtil.IsNumeric(typeTo))
                )
            {
                throw new InvalidOperationException("Unhandled convert");
            }

            bool isFromUnsigned      = TypeUtil.IsUnsigned(typeFrom);
            bool isFromFloatingPoint = TypeUtil.IsFloatingPoint(typeFrom);

            if (typeTo == typeof(Single))
            {
                if (isFromUnsigned)
                {
                    il.Emit(OpCodes.Conv_R_Un);
                }
                il.Emit(OpCodes.Conv_R4);
            }
            else if (typeTo == typeof(Double))
            {
                if (isFromUnsigned)
                {
                    il.Emit(OpCodes.Conv_R_Un);
                }
                il.Emit(OpCodes.Conv_R8);
            }
            else
            {
                TypeCode tc = Type.GetTypeCode(typeTo);
                if (isChecked)
                {
                    // Overflow checking needs to know if the source value on the IL stack is unsigned or not.
                    if (isFromUnsigned)
                    {
                        switch (tc)
                        {
                        case TypeCode.SByte:
                            il.Emit(OpCodes.Conv_Ovf_I1_Un);
                            break;

                        case TypeCode.Int16:
                            il.Emit(OpCodes.Conv_Ovf_I2_Un);
                            break;

                        case TypeCode.Int32:
                            il.Emit(OpCodes.Conv_Ovf_I4_Un);
                            break;

                        case TypeCode.Int64:
                            il.Emit(OpCodes.Conv_Ovf_I8_Un);
                            break;

                        case TypeCode.Byte:
                            il.Emit(OpCodes.Conv_Ovf_U1_Un);
                            break;

                        case TypeCode.UInt16:
                        case TypeCode.Char:
                            il.Emit(OpCodes.Conv_Ovf_U2_Un);
                            break;

                        case TypeCode.UInt32:
                            il.Emit(OpCodes.Conv_Ovf_U4_Un);
                            break;

                        case TypeCode.UInt64:
                            il.Emit(OpCodes.Conv_Ovf_U8_Un);
                            break;

                        default:
                            throw new InvalidOperationException("Unhandled convert");
                        }
                    }
                    else
                    {
                        switch (tc)
                        {
                        case TypeCode.SByte:
                            il.Emit(OpCodes.Conv_Ovf_I1);
                            break;

                        case TypeCode.Int16:
                            il.Emit(OpCodes.Conv_Ovf_I2);
                            break;

                        case TypeCode.Int32:
                            il.Emit(OpCodes.Conv_Ovf_I4);
                            break;

                        case TypeCode.Int64:
                            il.Emit(OpCodes.Conv_Ovf_I8);
                            break;

                        case TypeCode.Byte:
                            il.Emit(OpCodes.Conv_Ovf_U1);
                            break;

                        case TypeCode.UInt16:
                        case TypeCode.Char:
                            il.Emit(OpCodes.Conv_Ovf_U2);
                            break;

                        case TypeCode.UInt32:
                            il.Emit(OpCodes.Conv_Ovf_U4);
                            break;

                        case TypeCode.UInt64:
                            il.Emit(OpCodes.Conv_Ovf_U8);
                            break;

                        default:
                            throw new InvalidOperationException("Unhandled convert");
                        }
                    }
                }
                else
                {
                    switch (tc)
                    {
                    case TypeCode.SByte:
                        il.Emit(OpCodes.Conv_I1);
                        break;

                    case TypeCode.Byte:
                        il.Emit(OpCodes.Conv_U1);
                        break;

                    case TypeCode.Int16:
                        il.Emit(OpCodes.Conv_I2);
                        break;

                    case TypeCode.UInt16:
                    case TypeCode.Char:
                        il.Emit(OpCodes.Conv_U2);
                        break;

                    case TypeCode.Int32:
                        il.Emit(OpCodes.Conv_I4);
                        break;

                    case TypeCode.UInt32:
                        il.Emit(OpCodes.Conv_U4);
                        break;

                    case TypeCode.Int64:
                        if (isFromUnsigned)
                        {
                            il.Emit(OpCodes.Conv_U8);
                        }
                        else
                        {
                            il.Emit(OpCodes.Conv_I8);
                        }
                        break;

                    case TypeCode.UInt64:
                        if (isFromUnsigned || isFromFloatingPoint)
                        {
                            il.Emit(OpCodes.Conv_U8);
                        }
                        else
                        {
                            il.Emit(OpCodes.Conv_I8);
                        }
                        break;

                    default:
                        throw new InvalidOperationException("Unhandled convert");
                    }
                }
            }
        }
Exemplo n.º 3
0
            private void BinaryArithicExpression(BinaryExpression binaryExpression)
            {
                // Reference compares.

                if (
                    !binaryExpression.Left.Type.IsValueType &&
                    !binaryExpression.Right.Type.IsValueType && (
                        binaryExpression.ExpressionType == ExpressionType.Equals ||
                        binaryExpression.ExpressionType == ExpressionType.NotEquals
                        )
                    )
                {
                    binaryExpression.Left.Accept(this);
                    binaryExpression.Right.Accept(this);

                    _il.Emit(OpCodes.Ceq);

                    if (binaryExpression.ExpressionType == ExpressionType.NotEquals)
                    {
                        _il.Emit(OpCodes.Ldc_I4_0);
                        _il.Emit(OpCodes.Ceq);
                    }

                    return;
                }

                Emit(binaryExpression.Left, binaryExpression.CommonType);
                Emit(binaryExpression.Right, binaryExpression.CommonType);

                switch (binaryExpression.ExpressionType)
                {
                case ExpressionType.Equals:
                case ExpressionType.NotEquals:
                    _il.Emit(OpCodes.Ceq);

                    if (binaryExpression.ExpressionType == ExpressionType.NotEquals)
                    {
                        _il.Emit(OpCodes.Ldc_I4_0);
                        _il.Emit(OpCodes.Ceq);
                    }
                    break;

                case ExpressionType.Greater:
                case ExpressionType.LessOrEquals:
                    if (TypeUtil.IsUnsigned(binaryExpression.CommonType))
                    {
                        _il.Emit(OpCodes.Cgt_Un);
                    }
                    else
                    {
                        _il.Emit(OpCodes.Cgt);
                    }

                    if (binaryExpression.ExpressionType == ExpressionType.LessOrEquals)
                    {
                        _il.Emit(OpCodes.Ldc_I4_0);
                        _il.Emit(OpCodes.Ceq);
                    }
                    break;

                case ExpressionType.Less:
                case ExpressionType.GreaterOrEquals:
                    if (TypeUtil.IsUnsigned(binaryExpression.CommonType))
                    {
                        _il.Emit(OpCodes.Clt_Un);
                    }
                    else
                    {
                        _il.Emit(OpCodes.Clt);
                    }

                    if (binaryExpression.ExpressionType == ExpressionType.GreaterOrEquals)
                    {
                        _il.Emit(OpCodes.Ldc_I4_0);
                        _il.Emit(OpCodes.Ceq);
                    }
                    break;

                case ExpressionType.Add:
                    if (_compiler._resolver.Options.Checked && TypeUtil.IsInteger(binaryExpression.CommonType))
                    {
                        if (TypeUtil.IsUnsigned(binaryExpression.CommonType))
                        {
                            _il.Emit(OpCodes.Add_Ovf_Un);
                        }
                        else
                        {
                            _il.Emit(OpCodes.Add_Ovf);
                        }
                    }
                    else
                    {
                        _il.Emit(OpCodes.Add);
                    }
                    break;

                case ExpressionType.Divide:
                    if (TypeUtil.IsUnsigned(binaryExpression.CommonType))
                    {
                        _il.Emit(OpCodes.Div_Un);
                    }
                    else
                    {
                        _il.Emit(OpCodes.Div);
                    }
                    break;

                case ExpressionType.Multiply:
                    if (_compiler._resolver.Options.Checked && TypeUtil.IsInteger(binaryExpression.CommonType))
                    {
                        if (TypeUtil.IsUnsigned(binaryExpression.CommonType))
                        {
                            _il.Emit(OpCodes.Mul_Ovf_Un);
                        }
                        else
                        {
                            _il.Emit(OpCodes.Mul_Ovf);
                        }
                    }
                    else
                    {
                        _il.Emit(OpCodes.Mul);
                    }
                    break;

                case ExpressionType.Subtract:
                    if (_compiler._resolver.Options.Checked && TypeUtil.IsInteger(binaryExpression.CommonType))
                    {
                        if (TypeUtil.IsUnsigned(binaryExpression.CommonType))
                        {
                            _il.Emit(OpCodes.Sub_Ovf_Un);
                        }
                        else
                        {
                            _il.Emit(OpCodes.Sub_Ovf);
                        }
                    }
                    else
                    {
                        _il.Emit(OpCodes.Sub);
                    }
                    break;


                case ExpressionType.Modulo:
                    if (TypeUtil.IsUnsigned(binaryExpression.CommonType))
                    {
                        _il.Emit(OpCodes.Rem_Un);
                    }
                    else
                    {
                        _il.Emit(OpCodes.Rem);
                    }
                    break;

                default:
                    throw new InvalidOperationException();
                }
            }