Пример #1
0
        private static bool CanCastGenericParameterTo(this GenericParameterDesc thisType, TypeDesc otherType, StackOverflowProtect protect)
        {
            // A boxed variable type can be cast to any of its constraints, or object, if none are specified
            if (otherType.IsObject)
            {
                return(true);
            }

            if (thisType.HasNotNullableValueTypeConstraint &&
                otherType.IsWellKnownType(WellKnownType.ValueType))
            {
                return(true);
            }

            foreach (var typeConstraint in thisType.TypeConstraints)
            {
                if (typeConstraint.CanCastToInternal(otherType, protect))
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #2
0
        private static bool CanCastGenericParameterTo(this GenericParameterDesc thisType, TypeDesc otherType, StackOverflowProtect protect)
        {
            // A boxed variable type can be cast to any of its constraints, or object, if none are specified
            if (otherType.IsObject)
            {
                return true;
            }

            if (thisType.HasNotNullableValueTypeConstraint &&
                otherType.IsWellKnownType(WellKnownType.ValueType))
            {
                return true;
            }

            foreach (var typeConstraint in thisType.TypeConstraints)
            {
                if (typeConstraint.CanCastToInternal(otherType, protect))
                {
                    return true;
                }
            }

            return false;
        }
Пример #3
0
        public static UInt16 ComputeFlags(TypeDesc type)
        {
            UInt16 flags = (UInt16)EETypeKind.CanonicalEEType;

            if (type.IsInterface)
            {
                flags |= (UInt16)EETypeFlags.IsInterfaceFlag;
            }

            if (type.IsValueType)
            {
                flags |= (UInt16)EETypeFlags.ValueTypeFlag;
            }

            if (type.IsGenericDefinition)
            {
                flags |= (UInt16)EETypeKind.GenericTypeDefEEType;

                // Generic type definition EETypes don't set the other flags.
                return flags;
            }

            if (type.IsArray || type.IsPointer)
            {
                flags = (UInt16)EETypeKind.ParameterizedEEType;
            }

            if (type.HasFinalizer)
            {
                flags |= (UInt16)EETypeFlags.HasFinalizerFlag;
            }

            if (type.IsDefType && ((DefType)type).ContainsGCPointers)
            {
                flags |= (UInt16)EETypeFlags.HasPointersFlag;
            }
            else if (type.IsArray)
            {
                var elementType = ((ArrayType)type).ElementType;
                if ((elementType.IsValueType && ((DefType)elementType).ContainsGCPointers) || elementType.IsGCPointer)
                {
                    flags |= (UInt16)EETypeFlags.HasPointersFlag;
                }
            }

            if (type.HasInstantiation)
            {
                flags |= (UInt16)EETypeFlags.IsGenericFlag;

                if (type.HasVariance)
                {
                    flags |= (UInt16)EETypeFlags.GenericVarianceFlag;
                }
            }

            CorElementType corElementType = CorElementType.ELEMENT_TYPE_END;

            // The top 5 bits of flags are used to convey enum underlying type, primitive type, or mark the type as being System.Array
            if (type.IsEnum)
            {
                TypeDesc underlyingType = type.UnderlyingType;
                Debug.Assert(TypeFlags.SByte <= underlyingType.Category && underlyingType.Category <= TypeFlags.UInt64);
                corElementType = ComputeRhCorElementType(underlyingType);
            }
            else if (type.IsPrimitive)
            {
                corElementType = ComputeRhCorElementType(type);
            }
            else if (type.IsWellKnownType(WellKnownType.Array))
            {
                // Mark System.Array with CorElementType so casting code can distinguish it
                corElementType = CorElementType.ELEMENT_TYPE_ARRAY;
            }

            if (corElementType != CorElementType.ELEMENT_TYPE_END)
            {
                flags |= (UInt16)((UInt16)corElementType << (UInt16)EETypeFlags.CorElementTypeShift);
            }

            return flags;
        }
        private void EncodeType(BlobBuilder blobBuilder, TypeDesc type, EmbeddedSignatureDataEmitter signatureDataEmitter)
        {
            signatureDataEmitter.Push();
            signatureDataEmitter.Push();
            signatureDataEmitter.EmitAtCurrentIndexStack(blobBuilder);
            signatureDataEmitter.Pop();

            signatureDataEmitter.Push();
            if (type.IsPrimitive)
            {
                SignatureTypeCode primitiveCode;
                switch (type.Category)
                {
                case TypeFlags.Void:
                    primitiveCode = SignatureTypeCode.Void;
                    break;

                case TypeFlags.Boolean:
                    primitiveCode = SignatureTypeCode.Boolean;
                    break;

                case TypeFlags.Char:
                    primitiveCode = SignatureTypeCode.Char;
                    break;

                case TypeFlags.SByte:
                    primitiveCode = SignatureTypeCode.SByte;
                    break;

                case TypeFlags.Byte:
                    primitiveCode = SignatureTypeCode.Byte;
                    break;

                case TypeFlags.Int16:
                    primitiveCode = SignatureTypeCode.Int16;
                    break;

                case TypeFlags.UInt16:
                    primitiveCode = SignatureTypeCode.UInt16;
                    break;

                case TypeFlags.Int32:
                    primitiveCode = SignatureTypeCode.Int32;
                    break;

                case TypeFlags.UInt32:
                    primitiveCode = SignatureTypeCode.UInt32;
                    break;

                case TypeFlags.Int64:
                    primitiveCode = SignatureTypeCode.Int64;
                    break;

                case TypeFlags.UInt64:
                    primitiveCode = SignatureTypeCode.UInt64;
                    break;

                case TypeFlags.IntPtr:
                    primitiveCode = SignatureTypeCode.IntPtr;
                    break;

                case TypeFlags.UIntPtr:
                    primitiveCode = SignatureTypeCode.UIntPtr;
                    break;

                case TypeFlags.Single:
                    primitiveCode = SignatureTypeCode.Single;
                    break;

                case TypeFlags.Double:
                    primitiveCode = SignatureTypeCode.Double;
                    break;

                default:
                    throw new Exception("Unknown primitive type");
                }

                blobBuilder.WriteByte((byte)primitiveCode);
            }
            else if (type.IsSzArray)
            {
                blobBuilder.WriteByte((byte)SignatureTypeCode.SZArray);
                EncodeType(blobBuilder, type.GetParameterType(), signatureDataEmitter);
            }
            else if (type.IsArray)
            {
                var arrayType = (ArrayType)type;
                blobBuilder.WriteByte((byte)SignatureTypeCode.Array);
                EncodeType(blobBuilder, type.GetParameterType(), signatureDataEmitter);

                signatureDataEmitter.EmitArrayShapeAtCurrentIndexStack(blobBuilder, arrayType.Rank);
            }
            else if (type.IsPointer)
            {
                blobBuilder.WriteByte((byte)SignatureTypeCode.Pointer);
                EncodeType(blobBuilder, type.GetParameterType(), signatureDataEmitter);
            }
            else if (type.IsFunctionPointer)
            {
                FunctionPointerType fnptrType = (FunctionPointerType)type;
                blobBuilder.WriteByte((byte)SignatureTypeCode.FunctionPointer);
                EncodeMethodSignature(blobBuilder, fnptrType.Signature, signatureDataEmitter);
            }
            else if (type.IsByRef)
            {
                blobBuilder.WriteByte((byte)SignatureTypeCode.ByReference);
                EncodeType(blobBuilder, type.GetParameterType(), signatureDataEmitter);
            }
            else if (type.IsObject)
            {
                blobBuilder.WriteByte((byte)SignatureTypeCode.Object);
            }
            else if (type.IsString)
            {
                blobBuilder.WriteByte((byte)SignatureTypeCode.String);
            }
            else if (type.IsWellKnownType(WellKnownType.TypedReference))
            {
                blobBuilder.WriteByte((byte)SignatureTypeCode.TypedReference);
            }
            else if (type.IsWellKnownType(WellKnownType.Void))
            {
                blobBuilder.WriteByte((byte)SignatureTypeCode.Void);
            }
            else if (type is SignatureVariable)
            {
                SignatureVariable sigVar = (SignatureVariable)type;
                SignatureTypeCode code   = sigVar.IsMethodSignatureVariable ? SignatureTypeCode.GenericMethodParameter : SignatureTypeCode.GenericTypeParameter;
                blobBuilder.WriteByte((byte)code);
                blobBuilder.WriteCompressedInteger(sigVar.Index);
            }
            else if (type is InstantiatedType)
            {
                blobBuilder.WriteByte((byte)SignatureTypeCode.GenericTypeInstance);
                EncodeType(blobBuilder, type.GetTypeDefinition(), signatureDataEmitter);
                blobBuilder.WriteCompressedInteger(type.Instantiation.Length);
                foreach (var instantiationArg in type.Instantiation)
                {
                    EncodeType(blobBuilder, instantiationArg, signatureDataEmitter);
                }
            }
            else if (type is MetadataType)
            {
                var metadataType = (MetadataType)type;
                // Must be class or valuetype
                blobBuilder.WriteByte(type.IsValueType ? (byte)SignatureTypeKind.ValueType : (byte)SignatureTypeKind.Class);
                int codedIndex = CodedIndex.TypeDefOrRef(GetTypeRef(metadataType));
                blobBuilder.WriteCompressedInteger(codedIndex);
            }
            else
            {
                throw new Exception("Unexpected type");
            }
            signatureDataEmitter.Pop();
            signatureDataEmitter.Pop();
        }