コード例 #1
0
        internal static object?CheckArgument(object?srcObject, EETypePtr dstEEType, CheckArgumentSemantics semantics, BinderBundle?binderBundle)
        {
            // Methods with ByRefLike types in signatures should be filtered out earlier
            Debug.Assert(!dstEEType.IsByRefLike);

            if (srcObject == null)
            {
                // null -> default(T)
                if (dstEEType.IsPointer)
                {
                    return(default(IntPtr));
                }
                else if (dstEEType.IsValueType && !dstEEType.IsNullable)
                {
                    if (semantics == CheckArgumentSemantics.SetFieldDirect)
                    {
                        throw CreateChangeTypeException(typeof(object).TypeHandle.ToEETypePtr(), dstEEType, semantics);
                    }
                    return(Runtime.RuntimeImports.RhNewObject(dstEEType));
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                EETypePtr srcEEType = srcObject.GetEETypePtr();

                if (srcEEType.RawValue == dstEEType.RawValue ||
                    RuntimeImports.AreTypesAssignable(srcEEType, dstEEType) ||
                    (dstEEType.IsInterface && srcObject is Runtime.InteropServices.IDynamicInterfaceCastable castable &&
                     castable.IsInterfaceImplemented(new RuntimeTypeHandle(dstEEType), throwIfNotImplemented: false)))
                {
                    return(srcObject);
                }

                return(CheckArgumentConversions(srcObject, dstEEType, semantics, binderBundle));
            }
        }
コード例 #2
0
        internal static Object CheckArgument(Object srcObject, EETypePtr dstEEType, CheckArgumentSemantics semantics, BinderBundle binderBundle, Func <Type> getExactTypeForCustomBinder = null)
        {
            if (srcObject == null)
            {
                // null -> default(T)
                if (dstEEType.IsValueType && !dstEEType.IsNullable)
                {
                    if (semantics == CheckArgumentSemantics.SetFieldDirect)
                    {
                        throw CreateChangeTypeException(CommonRuntimeTypes.Object.TypeHandle.ToEETypePtr(), dstEEType, semantics);
                    }
                    return(Runtime.RuntimeImports.RhNewObject(dstEEType));
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                EETypePtr srcEEType = srcObject.EETypePtr;

                if (RuntimeImports.AreTypesAssignable(srcEEType, dstEEType))
                {
                    return(srcObject);
                }


                if (dstEEType.IsInterface)
                {
                    ICastable castable = srcObject as ICastable;
                    Exception castError;

                    if (castable != null && castable.IsInstanceOfInterface(new RuntimeTypeHandle(dstEEType), out castError))
                    {
                        return(srcObject);
                    }
                }

                object    dstObject;
                Exception exception = ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(srcObject, srcEEType, dstEEType, semantics, out dstObject);
                if (exception == null)
                {
                    return(dstObject);
                }

                if (binderBundle == null)
                {
                    throw exception;
                }

                // Our normal coercion rules could not convert the passed in argument but we were supplied a custom binder. See if it can do it.
                Type exactDstType;
                if (getExactTypeForCustomBinder == null)
                {
                    // We were called by someone other than DynamicInvokeParamHelperCore(). Those callers pass the correct dstEEType.
                    exactDstType = Type.GetTypeFromHandle(new RuntimeTypeHandle(dstEEType));
                }
                else
                {
                    // We were called by DynamicInvokeParamHelperCore(). He passes a dstEEType that enums folded to int and possibly other adjustments. A custom binder
                    // is app code however and needs the exact type.
                    exactDstType = getExactTypeForCustomBinder();
                }

                srcObject = binderBundle.ChangeType(srcObject, exactDstType);

                // For compat with desktop, the result of the binder call gets processed through the default rules again.
                dstObject = CheckArgument(srcObject, dstEEType, semantics, binderBundle: null, getExactTypeForCustomBinder: null);
                return(dstObject);
            }
        }
コード例 #3
0
        private static Exception CreateChangeTypeException(EETypePtr srcEEType, EETypePtr dstEEType, CheckArgumentSemantics semantics)
        {
            switch (semantics)
            {
            case CheckArgumentSemantics.DynamicInvoke:
            case CheckArgumentSemantics.SetFieldDirect:
                return(CreateChangeTypeArgumentException(srcEEType, dstEEType));

            case CheckArgumentSemantics.ArraySet:
                return(CreateChangeTypeInvalidCastException(srcEEType, dstEEType));

            default:
                Debug.Fail("Unexpected CheckArgumentSemantics value: " + semantics);
                throw new InvalidOperationException();
            }
        }
コード例 #4
0
        private static Exception ConvertPointerIfPossible(object srcObject, EETypePtr srcEEType, EETypePtr dstEEType, CheckArgumentSemantics semantics, out IntPtr dstIntPtr)
        {
            if (srcObject is IntPtr srcIntPtr)
            {
                dstIntPtr = srcIntPtr;
                return(null);
            }

            if (srcObject is Pointer srcPointer)
            {
                if (dstEEType == typeof(void *).TypeHandle.ToEETypePtr() || RuntimeImports.AreTypesAssignable(pSourceType: srcPointer.GetPointerType().TypeHandle.ToEETypePtr(), pTargetType: dstEEType))
                {
                    dstIntPtr = srcPointer.GetPointerValue();
                    return(null);
                }
            }

            dstIntPtr = IntPtr.Zero;
            return(CreateChangeTypeException(srcEEType, dstEEType, semantics));
        }
コード例 #5
0
        // Special coersion rules for primitives, enums and pointer.
        private static Exception ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(object srcObject, EETypePtr srcEEType, EETypePtr dstEEType, CheckArgumentSemantics semantics, out object dstObject)
        {
            if (semantics == CheckArgumentSemantics.SetFieldDirect && (srcEEType.IsEnum || dstEEType.IsEnum))
            {
                dstObject = null;
                return(CreateChangeTypeException(srcEEType, dstEEType, semantics));
            }

            if (dstEEType.IsPointer)
            {
                Exception exception = ConvertPointerIfPossible(srcObject, srcEEType, dstEEType, semantics, out IntPtr dstIntPtr);
                if (exception != null)
                {
                    dstObject = null;
                    return(exception);
                }
                dstObject = dstIntPtr;
                return(null);
            }

            if (!(srcEEType.IsPrimitive && dstEEType.IsPrimitive))
            {
                dstObject = null;
                return(CreateChangeTypeException(srcEEType, dstEEType, semantics));
            }

            RuntimeImports.RhCorElementType dstCorElementType = dstEEType.CorElementType;
            if (!srcEEType.CorElementTypeInfo.CanWidenTo(dstCorElementType))
            {
                dstObject = null;
                return(CreateChangeTypeArgumentException(srcEEType, dstEEType));
            }

            switch (dstCorElementType)
            {
            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_BOOLEAN:
                bool boolValue = Convert.ToBoolean(srcObject);
                dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, boolValue ? 1 : 0) : boolValue;
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_CHAR:
                char charValue = Convert.ToChar(srcObject);
                dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, charValue) : charValue;
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I1:
                sbyte sbyteValue = Convert.ToSByte(srcObject);
                dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, sbyteValue) : sbyteValue;
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I2:
                short shortValue = Convert.ToInt16(srcObject);
                dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, shortValue) : shortValue;
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I4:
                int intValue = Convert.ToInt32(srcObject);
                dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, intValue) : intValue;
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I8:
                long longValue = Convert.ToInt64(srcObject);
                dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, longValue) : longValue;
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U1:
                byte byteValue = Convert.ToByte(srcObject);
                dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, byteValue) : byteValue;
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U2:
                ushort ushortValue = Convert.ToUInt16(srcObject);
                dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, ushortValue) : ushortValue;
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U4:
                uint uintValue = Convert.ToUInt32(srcObject);
                dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, uintValue) : uintValue;
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U8:
                ulong ulongValue = Convert.ToUInt64(srcObject);
                dstObject = dstEEType.IsEnum ? Enum.ToObject(dstEEType, (long)ulongValue) : ulongValue;
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_R4:
                if (srcEEType.CorElementType == RuntimeImports.RhCorElementType.ELEMENT_TYPE_CHAR)
                {
                    dstObject = (float)(char)srcObject;
                }
                else
                {
                    dstObject = Convert.ToSingle(srcObject);
                }
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_R8:
                if (srcEEType.CorElementType == RuntimeImports.RhCorElementType.ELEMENT_TYPE_CHAR)
                {
                    dstObject = (double)(char)srcObject;
                }
                else
                {
                    dstObject = Convert.ToDouble(srcObject);
                }
                break;

            default:
                Debug.Fail("Unexpected CorElementType: " + dstCorElementType + ": Not a valid widening target.");
                dstObject = null;
                return(CreateChangeTypeException(srcEEType, dstEEType, semantics));
            }

            Debug.Assert(dstObject.EETypePtr == dstEEType);
            return(null);
        }
コード例 #6
0
ファイル: InvokeUtils.cs プロジェクト: jteer/runtime
        internal static object?CheckArgument(object?srcObject, EETypePtr dstEEType, CheckArgumentSemantics semantics, BinderBundle?binderBundle, ref ArgSetupState argSetupState)
        {
            // Methods with ByRefLike types in signatures should be filtered out by the compiler
            Debug.Assert(!dstEEType.IsByRefLike);

            if (srcObject == null)
            {
                // null -> default(T)
                if (dstEEType.IsPointer)
                {
                    return(default(IntPtr));
                }
                else if (dstEEType.IsValueType && !dstEEType.IsNullable)
                {
                    if (semantics == CheckArgumentSemantics.SetFieldDirect)
                    {
                        throw CreateChangeTypeException(typeof(object).TypeHandle.ToEETypePtr(), dstEEType, semantics);
                    }
                    return(Runtime.RuntimeImports.RhNewObject(dstEEType));
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                EETypePtr srcEEType = srcObject.EETypePtr;

                if (RuntimeImports.AreTypesAssignable(srcEEType, dstEEType))
                {
                    return(srcObject);
                }

                if (dstEEType.IsInterface)
                {
                    if (srcObject is Runtime.InteropServices.IDynamicInterfaceCastable castable &&
                        castable.IsInterfaceImplemented(new RuntimeTypeHandle(dstEEType), throwIfNotImplemented: false))
                    {
                        return(srcObject);
                    }
                }

                object    dstObject;
                Exception exception = ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(srcObject, srcEEType, dstEEType, semantics, out dstObject);
                if (exception == null)
                {
                    return(dstObject);
                }

                if (binderBundle == null)
                {
                    throw exception;
                }

                // Our normal coercion rules could not convert the passed in argument but we were supplied a custom binder. See if it can do it.
                Type exactDstType;
                if (Unsafe.IsNullRef(ref argSetupState))
                {
                    // We were called by someone other than DynamicInvokeParamHelperCore(). Those callers pass the correct dstEEType.
                    exactDstType = Type.GetTypeFromHandle(new RuntimeTypeHandle(dstEEType)) !;
                }
                else
                {
                    // We were called by DynamicInvokeParamHelperCore(). He passes a dstEEType that enums folded to int and possibly other adjustments. A custom binder
                    // is app code however and needs the exact type.
                    exactDstType = GetExactTypeForCustomBinder(argSetupState);
                }

                srcObject = binderBundle.ChangeType(srcObject, exactDstType);

                // For compat with desktop, the result of the binder call gets processed through the default rules again.
                dstObject = CheckArgument(srcObject, dstEEType, semantics, binderBundle: null, ref Unsafe.NullRef <ArgSetupState>());
                return(dstObject);
            }
        }
コード例 #7
0
ファイル: InvokeUtils.cs プロジェクト: jteer/runtime
 internal static object?CheckArgument(object?srcObject, EETypePtr dstEEType, CheckArgumentSemantics semantics, BinderBundle?binderBundle)
 {
     return(CheckArgument(srcObject, dstEEType, semantics, binderBundle, ref Unsafe.NullRef <ArgSetupState>()));
 }
コード例 #8
0
        // Special coersion rules for primitives, enums and pointer.
        private static Exception ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(object srcObject, EETypePtr srcEEType, EETypePtr dstEEType, CheckArgumentSemantics semantics, out object dstObject)
        {
            if (semantics == CheckArgumentSemantics.SetFieldDirect && (srcEEType.IsEnum || dstEEType.IsEnum))
            {
                dstObject = null;
                return(CreateChangeTypeException(srcEEType, dstEEType, semantics));
            }

            if (dstEEType.IsPointer)
            {
                Exception exception = ConvertPointerIfPossible(srcObject, srcEEType, dstEEType, semantics, out IntPtr dstIntPtr);
                if (exception != null)
                {
                    dstObject = null;
                    return(exception);
                }
                dstObject = dstIntPtr;
                return(null);
            }

            if (!(srcEEType.IsPrimitive && dstEEType.IsPrimitive))
            {
                dstObject = null;
                return(CreateChangeTypeException(srcEEType, dstEEType, semantics));
            }

            RuntimeImports.RhCorElementType dstCorElementType = dstEEType.CorElementType;
            if (!srcEEType.CorElementTypeInfo.CanWidenTo(dstCorElementType))
            {
                dstObject = null;
                return(CreateChangeTypeArgumentException(srcEEType, dstEEType));
            }

            switch (dstCorElementType)
            {
            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_BOOLEAN:
                dstObject = Convert.ToBoolean(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_CHAR:
                dstObject = Convert.ToChar(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I1:
                dstObject = Convert.ToSByte(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I2:
                dstObject = Convert.ToInt16(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I4:
                dstObject = Convert.ToInt32(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I8:
                dstObject = Convert.ToInt64(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U1:
                dstObject = Convert.ToByte(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U2:
                dstObject = Convert.ToUInt16(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U4:
                dstObject = Convert.ToUInt32(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U8:
                dstObject = Convert.ToUInt64(srcObject);
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_R4:
                if (srcEEType.CorElementType == RuntimeImports.RhCorElementType.ELEMENT_TYPE_CHAR)
                {
                    dstObject = (float)(char)srcObject;
                }
                else
                {
                    dstObject = Convert.ToSingle(srcObject);
                }
                break;

            case RuntimeImports.RhCorElementType.ELEMENT_TYPE_R8:
                if (srcEEType.CorElementType == RuntimeImports.RhCorElementType.ELEMENT_TYPE_CHAR)
                {
                    dstObject = (double)(char)srcObject;
                }
                else
                {
                    dstObject = Convert.ToDouble(srcObject);
                }
                break;

            default:
                Debug.Assert(false, "Unexpected CorElementType: " + dstCorElementType + ": Not a valid widening target.");
                dstObject = null;
                return(CreateChangeTypeException(srcEEType, dstEEType, semantics));
            }

            if (dstEEType.IsEnum)
            {
                Type dstType = ReflectionCoreNonPortable.GetRuntimeTypeForEEType(dstEEType);
                dstObject = Enum.ToObject(dstType, dstObject);
            }

            Debug.Assert(dstObject.EETypePtr == dstEEType);
            return(null);
        }
コード例 #9
0
ファイル: InvokeUtils.cs プロジェクト: noahfalk/corert
        internal static Object CheckArgument(Object srcObject, EETypePtr dstEEType, CheckArgumentSemantics semantics)
        {
            if (srcObject == null)
            {
                // null -> default(T) 
                if (dstEEType.IsValueType && !RuntimeImports.RhIsNullable(dstEEType))
                    return Runtime.RuntimeImports.RhNewObject(dstEEType);
                else
                    return null;
            }
            else
            {
                EETypePtr srcEEType = srcObject.EETypePtr;

                if (RuntimeImports.AreTypesAssignable(srcEEType, dstEEType))
                    return srcObject;


                if (RuntimeImports.RhIsInterface(dstEEType))
                {
                    ICastable castable = srcObject as ICastable;
                    Exception castError;

                    if (castable != null && castable.IsInstanceOfInterface(new RuntimeTypeHandle(dstEEType), out castError))
                        return srcObject;
                }

                if (!((srcEEType.IsEnum || srcEEType.IsPrimitive) && (dstEEType.IsEnum || dstEEType.IsPrimitive)))
                    throw CreateChangeTypeException(srcEEType, dstEEType, semantics);

                RuntimeImports.RhCorElementType dstCorElementType = dstEEType.CorElementType;
                if (!srcEEType.CorElementTypeInfo.CanWidenTo(dstCorElementType))
                    throw CreateChangeTypeArgumentException(srcEEType, dstEEType);

                Object dstObject;
                switch (dstCorElementType)
                {
                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_BOOLEAN:
                        dstObject = Convert.ToBoolean(srcObject);
                        break;

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_CHAR:
                        dstObject = Convert.ToChar(srcObject);
                        break;

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I1:
                        dstObject = Convert.ToSByte(srcObject);
                        break;

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I2:
                        dstObject = Convert.ToInt16(srcObject);
                        break;

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I4:
                        dstObject = Convert.ToInt32(srcObject);
                        break;

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I8:
                        dstObject = Convert.ToInt64(srcObject);
                        break;

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U1:
                        dstObject = Convert.ToByte(srcObject);
                        break;

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U2:
                        dstObject = Convert.ToUInt16(srcObject);
                        break;

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U4:
                        dstObject = Convert.ToUInt32(srcObject);
                        break;

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U8:
                        dstObject = Convert.ToUInt64(srcObject);
                        break;

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_R4:
                        if (srcEEType.CorElementType == RuntimeImports.RhCorElementType.ELEMENT_TYPE_CHAR)
                        {
                            dstObject = (float)(char)srcObject;
                        }
                        else
                        {
                            dstObject = Convert.ToSingle(srcObject);
                        }
                        break;

                    case RuntimeImports.RhCorElementType.ELEMENT_TYPE_R8:
                        if (srcEEType.CorElementType == RuntimeImports.RhCorElementType.ELEMENT_TYPE_CHAR)
                        {
                            dstObject = (double)(char)srcObject;
                        }
                        else
                        {
                            dstObject = Convert.ToDouble(srcObject);
                        }
                        break;

                    default:
                        Debug.Assert(false, "Unexpected CorElementType: " + dstCorElementType + ": Not a valid widening target.");
                        throw CreateChangeTypeException(srcEEType, dstEEType, semantics);
                }

                if (dstEEType.IsEnum)
                {
                    Type dstType = ReflectionCoreNonPortable.GetRuntimeTypeForEEType(dstEEType);
                    dstObject = Enum.ToObject(dstType, dstObject);
                }

                Debug.Assert(dstObject.EETypePtr == dstEEType);
                return dstObject;
            }
        }
コード例 #10
0
ファイル: InvokeUtils.cs プロジェクト: noahfalk/corert
 private static Exception CreateChangeTypeException(EETypePtr srcEEType, EETypePtr dstEEType, CheckArgumentSemantics semantics)
 {
     switch (semantics)
     {
         case CheckArgumentSemantics.DynamicInvoke:
             return CreateChangeTypeArgumentException(srcEEType, dstEEType);
         case CheckArgumentSemantics.ArraySet:
             return CreateChangeTypeInvalidCastException(srcEEType, dstEEType);
         default:
             Debug.Assert(false, "Unexpected CheckArgumentSemantics value: " + semantics);
             throw new InvalidOperationException();
     }
 }
コード例 #11
0
        internal static Object CheckArgument(Object srcObject, EETypePtr dstEEType, CheckArgumentSemantics semantics)
        {
            if (srcObject == null)
            {
                // null -> default(T)
                if (dstEEType.IsValueType && !dstEEType.IsNullable)
                {
                    return(Runtime.RuntimeImports.RhNewObject(dstEEType));
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                EETypePtr srcEEType = srcObject.EETypePtr;

                if (RuntimeImports.AreTypesAssignable(srcEEType, dstEEType))
                {
                    return(srcObject);
                }


                if (dstEEType.IsInterface)
                {
                    ICastable castable = srcObject as ICastable;
                    Exception castError;

                    if (castable != null && castable.IsInstanceOfInterface(new RuntimeTypeHandle(dstEEType), out castError))
                    {
                        return(srcObject);
                    }
                }

                if (!((srcEEType.IsEnum || srcEEType.IsPrimitive) && (dstEEType.IsEnum || dstEEType.IsPrimitive)))
                {
                    throw CreateChangeTypeException(srcEEType, dstEEType, semantics);
                }

                RuntimeImports.RhCorElementType dstCorElementType = dstEEType.CorElementType;
                if (!srcEEType.CorElementTypeInfo.CanWidenTo(dstCorElementType))
                {
                    throw CreateChangeTypeArgumentException(srcEEType, dstEEType);
                }

                Object dstObject;
                switch (dstCorElementType)
                {
                case RuntimeImports.RhCorElementType.ELEMENT_TYPE_BOOLEAN:
                    dstObject = Convert.ToBoolean(srcObject);
                    break;

                case RuntimeImports.RhCorElementType.ELEMENT_TYPE_CHAR:
                    dstObject = Convert.ToChar(srcObject);
                    break;

                case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I1:
                    dstObject = Convert.ToSByte(srcObject);
                    break;

                case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I2:
                    dstObject = Convert.ToInt16(srcObject);
                    break;

                case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I4:
                    dstObject = Convert.ToInt32(srcObject);
                    break;

                case RuntimeImports.RhCorElementType.ELEMENT_TYPE_I8:
                    dstObject = Convert.ToInt64(srcObject);
                    break;

                case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U1:
                    dstObject = Convert.ToByte(srcObject);
                    break;

                case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U2:
                    dstObject = Convert.ToUInt16(srcObject);
                    break;

                case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U4:
                    dstObject = Convert.ToUInt32(srcObject);
                    break;

                case RuntimeImports.RhCorElementType.ELEMENT_TYPE_U8:
                    dstObject = Convert.ToUInt64(srcObject);
                    break;

                case RuntimeImports.RhCorElementType.ELEMENT_TYPE_R4:
                    if (srcEEType.CorElementType == RuntimeImports.RhCorElementType.ELEMENT_TYPE_CHAR)
                    {
                        dstObject = (float)(char)srcObject;
                    }
                    else
                    {
                        dstObject = Convert.ToSingle(srcObject);
                    }
                    break;

                case RuntimeImports.RhCorElementType.ELEMENT_TYPE_R8:
                    if (srcEEType.CorElementType == RuntimeImports.RhCorElementType.ELEMENT_TYPE_CHAR)
                    {
                        dstObject = (double)(char)srcObject;
                    }
                    else
                    {
                        dstObject = Convert.ToDouble(srcObject);
                    }
                    break;

                default:
                    Debug.Assert(false, "Unexpected CorElementType: " + dstCorElementType + ": Not a valid widening target.");
                    throw CreateChangeTypeException(srcEEType, dstEEType, semantics);
                }

                if (dstEEType.IsEnum)
                {
                    Type dstType = ReflectionCoreNonPortable.GetRuntimeTypeForEEType(dstEEType);
                    dstObject = Enum.ToObject(dstType, dstObject);
                }

                Debug.Assert(dstObject.EETypePtr == dstEEType);
                return(dstObject);
            }
        }
コード例 #12
0
        internal static object?CheckArgumentConversions(object srcObject, EETypePtr dstEEType, CheckArgumentSemantics semantics, BinderBundle?binderBundle)
        {
            object?   dstObject;
            Exception exception = ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(srcObject, dstEEType, semantics, out dstObject);

            if (exception == null)
            {
                return(dstObject);
            }

            if (binderBundle == null)
            {
                throw exception;
            }

            // Our normal coercion rules could not convert the passed in argument but we were supplied a custom binder. See if it can do it.
            Type exactDstType = Type.GetTypeFromHandle(new RuntimeTypeHandle(dstEEType)) !;

            srcObject = binderBundle.ChangeType(srcObject, exactDstType);

            // For compat with desktop, the result of the binder call gets processed through the default rules again.
            return(CheckArgument(srcObject, dstEEType, semantics, binderBundle: null));
        }