Example #1
0
        /// <summary>
        /// Primary method for emitting integer switch jump table
        /// </summary>
        /// <param name="caseLabels">switch case labels</param>
        /// <param name="fallThroughLabel">fall through label for the jump table</param>
        /// <param name="keyArgumentIndex">Index of the parameter to switch on.
        /// This value has already been loaded onto the execution stack.
        /// </param>
        /// <param name="keyTypeCode">Primitive type code of switch key</param>
        internal void EmitIntegerSwitchJumpTable(
            KeyValuePair <ConstantValue, object>[] caseLabels,
            object fallThroughLabel,
            int keyArgumentIndex,
            Microsoft.Cci.PrimitiveTypeCode keyTypeCode)
        {
            Debug.Assert(caseLabels.Length > 0);
            Debug.Assert(keyTypeCode != Microsoft.Cci.PrimitiveTypeCode.String);

            // CONSIDER: SwitchIntegralJumpTableEmitter will modify the caseLabels array by sorting it.
            // CONSIDER: Currently, only purpose of creating this caseLabels array is for Emitting the jump table.
            // CONSIDER: If this requirement changes, we may want to pass in ArrayBuilder<KeyValuePair<ConstantValue, object>> instead.

            var emitter = new SwitchIntegralJumpTableEmitter(this, caseLabels, fallThroughLabel, keyTypeCode, null, keyArgumentIndex);

            emitter.EmitJumpTable();
        }
        internal SwitchIntegralJumpTableEmitter(
            ILBuilder builder,
            KeyValuePair <ConstantValue, object>[] caseLabels,
            object fallThroughLabel,
            Microsoft.Cci.PrimitiveTypeCode keyTypeCode,
            LocalDefinition keyLocal = null,
            int keyArgument          = -1)
        {
            Debug.Assert(keyArgument == -1 ^ keyLocal == null, "cannot have both valid key argument and valid key local");

            this.builder          = builder;
            this.keyLocal         = keyLocal;
            this.keyArgument      = keyArgument;
            this.keyTypeCode      = keyTypeCode;
            this.fallThroughLabel = fallThroughLabel;

            // Sort the switch case labels, see comments below for more details.
            Debug.Assert(caseLabels.Length > 0);
            Array.Sort(caseLabels, CompareIntegralSwitchLabels);
            sortedCaseLabels = ImmutableArray.Create <KeyValuePair <ConstantValue, object> >(caseLabels);
        }
Example #3
0
        public void PrimitiveType(PrimitiveTypeCode type)
        {
            switch (type)
            {
            case PrimitiveTypeCode.Boolean: Boolean(); return;

            case PrimitiveTypeCode.Char: Char(); return;

            case PrimitiveTypeCode.Int8: Int8(); return;

            case PrimitiveTypeCode.UInt8: UInt8(); return;

            case PrimitiveTypeCode.Int16: Int16(); return;

            case PrimitiveTypeCode.UInt16: UInt16(); return;

            case PrimitiveTypeCode.Int32: Int32(); return;

            case PrimitiveTypeCode.UInt32: UInt32(); return;

            case PrimitiveTypeCode.Int64: Int64(); return;

            case PrimitiveTypeCode.UInt64: UInt64(); return;

            case PrimitiveTypeCode.Float32: Float32(); return;

            case PrimitiveTypeCode.Float64: Float64(); return;

            case PrimitiveTypeCode.String: String(); return;

            case PrimitiveTypeCode.IntPtr: IntPtr(); return;

            case PrimitiveTypeCode.UIntPtr: UIntPtr(); return;

            default:
                throw new InvalidOperationException();
            }
        }
Example #4
0
        public T PrimitiveType(PrimitiveTypeCode type)
        {
            switch (type)
            {
            case PrimitiveTypeCode.Boolean: return(Boolean());

            case PrimitiveTypeCode.Char: return(Char());

            case PrimitiveTypeCode.Int8: return(Int8());

            case PrimitiveTypeCode.UInt8: return(UInt8());

            case PrimitiveTypeCode.Int16: return(Int16());

            case PrimitiveTypeCode.UInt16: return(UInt16());

            case PrimitiveTypeCode.Int32: return(Int32());

            case PrimitiveTypeCode.UInt32: return(UInt32());

            case PrimitiveTypeCode.Int64: return(Int64());

            case PrimitiveTypeCode.UInt64: return(UInt64());

            case PrimitiveTypeCode.Float32: return(Float32());

            case PrimitiveTypeCode.Float64: return(Float64());

            case PrimitiveTypeCode.String: return(String());

            case PrimitiveTypeCode.IntPtr: return(IntPtr());

            case PrimitiveTypeCode.UIntPtr: return(UIntPtr());

            default:
                throw new InvalidOperationException();
            }
        }
Example #5
0
 /// <summary>
 /// Get symbol for predefined type from Cor Library used by this assembly.
 /// </summary>
 /// <param name="type"></param>
 /// <returns></returns>
 internal NamedTypeSymbol GetPrimitiveType(Microsoft.Cci.PrimitiveTypeCode type)
 {
     return(GetSpecialType(SpecialTypes.GetTypeFromMetadataName(type)));
 }
Example #6
0
        public void EmitNumericConversion(Microsoft.Cci.PrimitiveTypeCode fromPredefTypeKind, Microsoft.Cci.PrimitiveTypeCode toPredefTypeKind, bool @checked)
        {
            bool fromUnsigned = fromPredefTypeKind.IsUnsigned();

            switch (toPredefTypeKind)
            {
            case Microsoft.Cci.PrimitiveTypeCode.Int8:
                switch (fromPredefTypeKind)
                {
                case Microsoft.Cci.PrimitiveTypeCode.Int8:
                    break;         // NOP

                default:
                    if (@checked)
                    {
                        this.EmitOpCode(fromUnsigned ? ILOpCode.Conv_ovf_i1_un : ILOpCode.Conv_ovf_i1);
                    }
                    else
                    {
                        this.EmitOpCode(ILOpCode.Conv_i1);
                    }
                    break;
                }
                break;

            case Microsoft.Cci.PrimitiveTypeCode.UInt8:
                switch (fromPredefTypeKind)
                {
                case Microsoft.Cci.PrimitiveTypeCode.UInt8:
                    break;         // NOP

                default:
                    if (@checked)
                    {
                        this.EmitOpCode(fromUnsigned ? ILOpCode.Conv_ovf_u1_un : ILOpCode.Conv_ovf_u1);
                    }
                    else
                    {
                        this.EmitOpCode(ILOpCode.Conv_u1);
                    }
                    break;
                }
                break;

            case Microsoft.Cci.PrimitiveTypeCode.Int16:
                switch (fromPredefTypeKind)
                {
                case Microsoft.Cci.PrimitiveTypeCode.Int8:
                case Microsoft.Cci.PrimitiveTypeCode.UInt8:
                case Microsoft.Cci.PrimitiveTypeCode.Int16:
                    break;         // NOP

                default:
                    if (@checked)
                    {
                        this.EmitOpCode(fromUnsigned ? ILOpCode.Conv_ovf_i2_un : ILOpCode.Conv_ovf_i2);
                    }
                    else
                    {
                        this.EmitOpCode(ILOpCode.Conv_i2);
                    }
                    break;
                }
                break;

            case Microsoft.Cci.PrimitiveTypeCode.Char:
            case Microsoft.Cci.PrimitiveTypeCode.UInt16:
                switch (fromPredefTypeKind)
                {
                case Microsoft.Cci.PrimitiveTypeCode.UInt8:
                case Microsoft.Cci.PrimitiveTypeCode.UInt16:
                case Microsoft.Cci.PrimitiveTypeCode.Char:
                    break;         // NOP

                default:
                    if (@checked)
                    {
                        this.EmitOpCode(fromUnsigned ? ILOpCode.Conv_ovf_u2_un : ILOpCode.Conv_ovf_u2);
                    }
                    else
                    {
                        this.EmitOpCode(ILOpCode.Conv_u2);
                    }
                    break;
                }
                break;

            case Microsoft.Cci.PrimitiveTypeCode.Int32:
                switch (fromPredefTypeKind)
                {
                case Microsoft.Cci.PrimitiveTypeCode.Int8:
                case Microsoft.Cci.PrimitiveTypeCode.UInt8:
                case Microsoft.Cci.PrimitiveTypeCode.Int16:
                case Microsoft.Cci.PrimitiveTypeCode.UInt16:
                case Microsoft.Cci.PrimitiveTypeCode.Int32:
                case Microsoft.Cci.PrimitiveTypeCode.Char:
                    break;         // NOP

                case Microsoft.Cci.PrimitiveTypeCode.UInt32:
                    if (@checked)
                    {
                        this.EmitOpCode(ILOpCode.Conv_ovf_i4_un);
                    }
                    break;         // NOP in unchecked

                default:
                    if (@checked)
                    {
                        this.EmitOpCode(fromUnsigned ? ILOpCode.Conv_ovf_i4_un : ILOpCode.Conv_ovf_i4);
                    }
                    else
                    {
                        this.EmitOpCode(ILOpCode.Conv_i4);
                    }
                    break;
                }
                break;

            case Microsoft.Cci.PrimitiveTypeCode.UInt32:
                switch (fromPredefTypeKind)
                {
                case Microsoft.Cci.PrimitiveTypeCode.UInt8:
                case Microsoft.Cci.PrimitiveTypeCode.UInt16:
                case Microsoft.Cci.PrimitiveTypeCode.UInt32:
                case Microsoft.Cci.PrimitiveTypeCode.Char:
                    break;         // NOP

                case Microsoft.Cci.PrimitiveTypeCode.Int8:
                case Microsoft.Cci.PrimitiveTypeCode.Int16:
                case Microsoft.Cci.PrimitiveTypeCode.Int32:
                    if (@checked)
                    {
                        this.EmitOpCode(ILOpCode.Conv_ovf_u4);
                    }
                    break;         // NOP in unchecked

                default:
                    if (@checked)
                    {
                        this.EmitOpCode(fromUnsigned ? ILOpCode.Conv_ovf_u4_un : ILOpCode.Conv_ovf_u4);
                    }
                    else
                    {
                        this.EmitOpCode(ILOpCode.Conv_u4);
                    }
                    break;
                }
                break;

            case Microsoft.Cci.PrimitiveTypeCode.IntPtr:
                switch (fromPredefTypeKind)
                {
                case Microsoft.Cci.PrimitiveTypeCode.IntPtr:
                    break;         // NOP

                case Microsoft.Cci.PrimitiveTypeCode.Int8:
                case Microsoft.Cci.PrimitiveTypeCode.Int16:
                case Microsoft.Cci.PrimitiveTypeCode.Int32:
                    this.EmitOpCode(ILOpCode.Conv_i);         // potentially widening, so not NOP
                    break;

                case Microsoft.Cci.PrimitiveTypeCode.UInt8:
                case Microsoft.Cci.PrimitiveTypeCode.UInt16:
                case Microsoft.Cci.PrimitiveTypeCode.Char:
                    // Doesn't actually matter whether we sign extend, because
                    // bit 32 can't be set in any of these types.
                    this.EmitOpCode(ILOpCode.Conv_u);         // potentially widening, so not NOP
                    break;

                case Microsoft.Cci.PrimitiveTypeCode.UInt32:
                    if (@checked)
                    {
                        this.EmitOpCode(ILOpCode.Conv_ovf_i_un);
                    }
                    else
                    {
                        // Don't want to sign extend if this is a widening conversion.
                        this.EmitOpCode(ILOpCode.Conv_u);         // potentially widening, so not NOP
                    }
                    break;

                default:
                    if (@checked)
                    {
                        this.EmitOpCode(fromUnsigned ? ILOpCode.Conv_ovf_i_un : ILOpCode.Conv_ovf_i);
                    }
                    else
                    {
                        this.EmitOpCode(ILOpCode.Conv_i);
                    }
                    break;
                }
                break;

            case Microsoft.Cci.PrimitiveTypeCode.UIntPtr:
                switch (fromPredefTypeKind)
                {
                case Microsoft.Cci.PrimitiveTypeCode.UIntPtr:
                    break;         // NOP

                case Microsoft.Cci.PrimitiveTypeCode.UInt8:
                case Microsoft.Cci.PrimitiveTypeCode.UInt16:
                case Microsoft.Cci.PrimitiveTypeCode.UInt32:
                case Microsoft.Cci.PrimitiveTypeCode.Char:
                    this.EmitOpCode(ILOpCode.Conv_u);         // potentially widening, so not NOP
                    break;

                case Microsoft.Cci.PrimitiveTypeCode.Int8:
                case Microsoft.Cci.PrimitiveTypeCode.Int16:
                case Microsoft.Cci.PrimitiveTypeCode.Int32:
                    if (@checked)
                    {
                        this.EmitOpCode(ILOpCode.Conv_ovf_u);
                    }
                    else
                    {
                        this.EmitOpCode(ILOpCode.Conv_i);         // potentially widening, so not NOP
                    }
                    break;

                default:
                    if (@checked)
                    {
                        this.EmitOpCode(fromUnsigned ? ILOpCode.Conv_ovf_u_un : ILOpCode.Conv_ovf_u);
                    }
                    else
                    {
                        this.EmitOpCode(ILOpCode.Conv_u);
                    }
                    break;
                }
                break;

            case Microsoft.Cci.PrimitiveTypeCode.Int64:
                switch (fromPredefTypeKind)
                {
                case Microsoft.Cci.PrimitiveTypeCode.Int64:
                    break;         //NOP

                case Microsoft.Cci.PrimitiveTypeCode.Int8:
                case Microsoft.Cci.PrimitiveTypeCode.Int16:
                case Microsoft.Cci.PrimitiveTypeCode.Int32:
                case Microsoft.Cci.PrimitiveTypeCode.IntPtr:
                    this.EmitOpCode(ILOpCode.Conv_i8);         // sign extend
                    break;

                case Microsoft.Cci.PrimitiveTypeCode.UInt8:
                case Microsoft.Cci.PrimitiveTypeCode.UInt16:
                case Microsoft.Cci.PrimitiveTypeCode.UInt32:
                case Microsoft.Cci.PrimitiveTypeCode.Char:
                    this.EmitOpCode(ILOpCode.Conv_u8);         // 0 extend
                    break;

                case Microsoft.Cci.PrimitiveTypeCode.Pointer:
                case Microsoft.Cci.PrimitiveTypeCode.UIntPtr:
                    if (@checked)
                    {
                        this.EmitOpCode(ILOpCode.Conv_ovf_i8_un);
                    }
                    else
                    {
                        this.EmitOpCode(ILOpCode.Conv_u8);         // 0 extend if unchecked
                    }
                    break;

                case Microsoft.Cci.PrimitiveTypeCode.UInt64:
                    if (@checked)
                    {
                        this.EmitOpCode(ILOpCode.Conv_ovf_i8_un);
                    }
                    break;         // NOP in unchecked

                default:
                    Debug.Assert(fromPredefTypeKind.IsFloatingPoint());
                    if (@checked)
                    {
                        this.EmitOpCode(ILOpCode.Conv_ovf_i8);
                    }
                    else
                    {
                        this.EmitOpCode(ILOpCode.Conv_i8);
                    }
                    break;
                }
                break;

            case Microsoft.Cci.PrimitiveTypeCode.UInt64:
                switch (fromPredefTypeKind)
                {
                case Microsoft.Cci.PrimitiveTypeCode.UInt64:
                    break;         //NOP

                case Microsoft.Cci.PrimitiveTypeCode.UInt8:
                case Microsoft.Cci.PrimitiveTypeCode.UInt16:
                case Microsoft.Cci.PrimitiveTypeCode.UInt32:
                case Microsoft.Cci.PrimitiveTypeCode.Pointer:
                case Microsoft.Cci.PrimitiveTypeCode.UIntPtr:
                case Microsoft.Cci.PrimitiveTypeCode.Char:
                    this.EmitOpCode(ILOpCode.Conv_u8);         // 0 extend
                    break;

                case Microsoft.Cci.PrimitiveTypeCode.Int8:
                case Microsoft.Cci.PrimitiveTypeCode.Int16:
                case Microsoft.Cci.PrimitiveTypeCode.Int32:
                case Microsoft.Cci.PrimitiveTypeCode.IntPtr:
                    if (@checked)
                    {
                        this.EmitOpCode(ILOpCode.Conv_ovf_u8);
                    }
                    else
                    {
                        this.EmitOpCode(ILOpCode.Conv_i8);         // sign extend if unchecked
                    }
                    break;

                case Microsoft.Cci.PrimitiveTypeCode.Int64:
                    if (@checked)
                    {
                        this.EmitOpCode(ILOpCode.Conv_ovf_u8);
                    }
                    break;         // NOP in unchecked

                default:
                    Debug.Assert(fromPredefTypeKind.IsFloatingPoint());
                    if (@checked)
                    {
                        this.EmitOpCode(ILOpCode.Conv_ovf_u8);
                    }
                    else
                    {
                        this.EmitOpCode(ILOpCode.Conv_u8);
                    }
                    break;
                }
                break;

            case Microsoft.Cci.PrimitiveTypeCode.Float32:
                switch (fromPredefTypeKind)
                {
                case Microsoft.Cci.PrimitiveTypeCode.UInt32:
                case Microsoft.Cci.PrimitiveTypeCode.UInt64:
                    this.EmitOpCode(ILOpCode.Conv_r_un);
                    break;
                }
                this.EmitOpCode(ILOpCode.Conv_r4);
                break;

            case Microsoft.Cci.PrimitiveTypeCode.Float64:
                switch (fromPredefTypeKind)
                {
                case Microsoft.Cci.PrimitiveTypeCode.UInt32:
                case Microsoft.Cci.PrimitiveTypeCode.UInt64:
                    this.EmitOpCode(ILOpCode.Conv_r_un);
                    break;
                }
                this.EmitOpCode(ILOpCode.Conv_r8);
                break;

            case Microsoft.Cci.PrimitiveTypeCode.Pointer:
                if (@checked)
                {
                    switch (fromPredefTypeKind)
                    {
                    case Microsoft.Cci.PrimitiveTypeCode.UInt8:
                    case Microsoft.Cci.PrimitiveTypeCode.UInt16:
                    case Microsoft.Cci.PrimitiveTypeCode.UInt32:
                        this.EmitOpCode(ILOpCode.Conv_u);
                        break;

                    case Microsoft.Cci.PrimitiveTypeCode.UInt64:
                        this.EmitOpCode(ILOpCode.Conv_ovf_u_un);
                        break;

                    case Microsoft.Cci.PrimitiveTypeCode.Int8:
                    case Microsoft.Cci.PrimitiveTypeCode.Int16:
                    case Microsoft.Cci.PrimitiveTypeCode.Int32:
                    case Microsoft.Cci.PrimitiveTypeCode.Int64:
                        this.EmitOpCode(ILOpCode.Conv_ovf_u);
                        break;

                    default:
                        throw ExceptionUtilities.UnexpectedValue(fromPredefTypeKind);
                    }
                }
                else
                {
                    switch (fromPredefTypeKind)
                    {
                    case Microsoft.Cci.PrimitiveTypeCode.UInt8:
                    case Microsoft.Cci.PrimitiveTypeCode.UInt16:
                    case Microsoft.Cci.PrimitiveTypeCode.UInt32:
                    case Microsoft.Cci.PrimitiveTypeCode.UInt64:
                    case Microsoft.Cci.PrimitiveTypeCode.Int64:
                        this.EmitOpCode(ILOpCode.Conv_u);
                        break;

                    case Microsoft.Cci.PrimitiveTypeCode.Int8:
                    case Microsoft.Cci.PrimitiveTypeCode.Int16:
                    case Microsoft.Cci.PrimitiveTypeCode.Int32:
                        // This matches dev10.  Presumably, we're using conv_i,
                        // rather than conv_u, to sign-extend the value.
                        this.EmitOpCode(ILOpCode.Conv_i);
                        break;

                    default:
                        throw ExceptionUtilities.UnexpectedValue(fromPredefTypeKind);
                    }
                }
                break;

            default:
                throw ExceptionUtilities.UnexpectedValue(toPredefTypeKind);
            }
        }
Example #7
0
 public static SpecialType GetTypeFromMetadataName(Microsoft.Cci.PrimitiveTypeCode typeCode)
 {
     return(s_typeCodeToTypeIdMap[(int)typeCode]);
 }
Example #8
0
 public void PrimitiveType(PrimitiveTypeCode type)
 {
     switch (type)
     {
         case PrimitiveTypeCode.Boolean: Boolean(); return;
         case PrimitiveTypeCode.Char: Char(); return;
         case PrimitiveTypeCode.Int8: Int8(); return;
         case PrimitiveTypeCode.UInt8: UInt8(); return;
         case PrimitiveTypeCode.Int16: Int16(); return;
         case PrimitiveTypeCode.UInt16: UInt16(); return;
         case PrimitiveTypeCode.Int32: Int32(); return;
         case PrimitiveTypeCode.UInt32: UInt32(); return;
         case PrimitiveTypeCode.Int64: Int64(); return;
         case PrimitiveTypeCode.UInt64: UInt64(); return;
         case PrimitiveTypeCode.Float32: Float32(); return;
         case PrimitiveTypeCode.Float64: Float64(); return;
         case PrimitiveTypeCode.String: String(); return;
         case PrimitiveTypeCode.IntPtr: IntPtr(); return;
         case PrimitiveTypeCode.UIntPtr: UIntPtr(); return;
         default:
             throw new InvalidOperationException();
     }
 }