Exemplo n.º 1
0
 private static void EmitNullableToReferenceConversion(ILGenerator il, Type typeFrom)
 {
     Debug.Assert(TypeUtil.IsNullableType(typeFrom));
     // We've got a conversion from nullable to Object, ValueType, Enum, etc.  Just box it so that
     // we get the nullable semantics.
     il.Emit(OpCodes.Box, typeFrom);
 }
Exemplo n.º 2
0
 private static void EmitNullableToNonNullableConversion(ILGenerator il, Type typeFrom, Type typeTo, bool isChecked)
 {
     Debug.Assert(TypeUtil.IsNullableType(typeFrom));
     Debug.Assert(!TypeUtil.IsNullableType(typeTo));
     if (typeTo.IsValueType)
     {
         EmitNullableToNonNullableStructConversion(il, typeFrom, typeTo, isChecked);
     }
     else
     {
         EmitNullableToReferenceConversion(il, typeFrom);
     }
 }
Exemplo n.º 3
0
        private static void EmitNullableToNonNullableStructConversion(ILGenerator il, Type typeFrom, Type typeTo, bool isChecked)
        {
            Debug.Assert(TypeUtil.IsNullableType(typeFrom));
            Debug.Assert(!TypeUtil.IsNullableType(typeTo));
            Debug.Assert(typeTo.IsValueType);
            LocalBuilder locFrom = il.DeclareLocal(typeFrom);

            il.Emit(OpCodes.Stloc, locFrom);
            il.Emit(OpCodes.Ldloca, locFrom);
            EmitGetValue(il, typeFrom);
            Type nnTypeFrom = TypeUtil.GetNonNullableType(typeFrom);

            EmitConvertToType(il, nnTypeFrom, typeTo, isChecked);
        }
Exemplo n.º 4
0
        private static void EmitNonNullableToNullableConversion(ILGenerator il, Type typeFrom, Type typeTo, bool isChecked)
        {
            Debug.Assert(!TypeUtil.IsNullableType(typeFrom));
            Debug.Assert(TypeUtil.IsNullableType(typeTo));
            LocalBuilder locTo    = il.DeclareLocal(typeTo);
            Type         nnTypeTo = TypeUtil.GetNonNullableType(typeTo);

            EmitConvertToType(il, typeFrom, nnTypeTo, isChecked);
            ConstructorInfo ci = typeTo.GetConstructor(new[] { nnTypeTo });

            il.Emit(OpCodes.Newobj, ci);
            il.Emit(OpCodes.Stloc, locTo);
            il.Emit(OpCodes.Ldloc, locTo);
        }
Exemplo n.º 5
0
        public static void EmitConvertToType(ILGenerator il, Type typeFrom, Type typeTo, bool isChecked)
        {
            if (TypeUtil.AreEquivalent(typeFrom, typeTo))
            {
                return;
            }

            if (typeFrom == typeof(void) || typeTo == typeof(void))
            {
                throw new InvalidOperationException();
            }

            bool isTypeFromNullable = TypeUtil.IsNullableType(typeFrom);
            bool isTypeToNullable   = TypeUtil.IsNullableType(typeTo);

            Type nnExprType = TypeUtil.GetNonNullableType(typeFrom);
            Type nnType     = TypeUtil.GetNonNullableType(typeTo);

            if (typeFrom.IsInterface ||       // interface cast
                typeTo.IsInterface ||
                typeFrom == typeof(object) || // boxing cast
                typeTo == typeof(object) ||
                typeFrom == typeof(System.Enum) ||
                typeFrom == typeof(System.ValueType) ||
                TypeUtil.IsLegalExplicitVariantDelegateConversion(typeFrom, typeTo))
            {
                EmitCastToType(il, typeFrom, typeTo);
            }
            else if (isTypeFromNullable || isTypeToNullable)
            {
                EmitNullableConversion(il, typeFrom, typeTo, isChecked);
            }
            else if (!(TypeUtil.IsConvertible(typeFrom) && TypeUtil.IsConvertible(typeTo)) // primitive runtime conversion
                     &&
                     (nnExprType.IsAssignableFrom(nnType) ||                               // down cast
                      nnType.IsAssignableFrom(nnExprType)))                                // up cast
            {
                EmitCastToType(il, typeFrom, typeTo);
            }
            else if (typeFrom.IsArray && typeTo.IsArray)
            {
                // See DevDiv Bugs #94657.
                EmitCastToType(il, typeFrom, typeTo);
            }
            else
            {
                EmitNumericConversion(il, typeFrom, typeTo, isChecked);
            }
        }
Exemplo n.º 6
0
        private static void EmitNullableConversion(ILGenerator il, Type typeFrom, Type typeTo, bool isChecked)
        {
            bool isTypeFromNullable = TypeUtil.IsNullableType(typeFrom);
            bool isTypeToNullable   = TypeUtil.IsNullableType(typeTo);

            Debug.Assert(isTypeFromNullable || isTypeToNullable);
            if (isTypeFromNullable && isTypeToNullable)
            {
                EmitNullableToNullableConversion(il, typeFrom, typeTo, isChecked);
            }
            else if (isTypeFromNullable)
            {
                EmitNullableToNonNullableConversion(il, typeFrom, typeTo, isChecked);
            }
            else
            {
                EmitNonNullableToNullableConversion(il, typeFrom, typeTo, isChecked);
            }
        }
Exemplo n.º 7
0
        private static void EmitNullableToNullableConversion(ILGenerator il, Type typeFrom, Type typeTo, bool isChecked)
        {
            Debug.Assert(TypeUtil.IsNullableType(typeFrom));
            Debug.Assert(TypeUtil.IsNullableType(typeTo));
            LocalBuilder locFrom = il.DeclareLocal(typeFrom);

            il.Emit(OpCodes.Stloc, locFrom);
            LocalBuilder locTo = il.DeclareLocal(typeTo);

            // test for null
            il.Emit(OpCodes.Ldloca, locFrom);
            EmitHasValue(il, typeFrom);
            Label labIfNull = il.DefineLabel();

            il.Emit(OpCodes.Brfalse_S, labIfNull);
            il.Emit(OpCodes.Ldloca, locFrom);
            EmitGetValueOrDefault(il, typeFrom);
            Type nnTypeFrom = TypeUtil.GetNonNullableType(typeFrom);
            Type nnTypeTo   = TypeUtil.GetNonNullableType(typeTo);

            EmitConvertToType(il, nnTypeFrom, nnTypeTo, isChecked);
            // construct result type
            ConstructorInfo ci = typeTo.GetConstructor(new[] { nnTypeTo });

            il.Emit(OpCodes.Newobj, ci);
            il.Emit(OpCodes.Stloc, locTo);
            Label labEnd = il.DefineLabel();

            il.Emit(OpCodes.Br_S, labEnd);
            // if null then create a default one
            il.MarkLabel(labIfNull);
            il.Emit(OpCodes.Ldloca, locTo);
            il.Emit(OpCodes.Initobj, typeTo);
            il.MarkLabel(labEnd);
            il.Emit(OpCodes.Ldloc, locTo);
        }