Exemple #1
0
        private bool TryGetTypeFromSimpleTypeSignature(ref NativeParser parser, NativeFormatModuleInfo moduleHandle, out RuntimeTypeHandle typeHandle)
        {
            uint data;
            TypeSignatureKind kind = parser.GetTypeSignatureKind(out data);

            if (kind == TypeSignatureKind.Lookback)
            {
                var lookbackParser = parser.GetLookbackParser(data);
                return(TryGetTypeFromSimpleTypeSignature(ref lookbackParser, moduleHandle, out typeHandle));
            }
            else if (kind == TypeSignatureKind.External)
            {
                typeHandle = GetExternalTypeHandle(moduleHandle, data);
                return(true);
            }
            else if (kind == TypeSignatureKind.BuiltIn)
            {
                typeHandle = ((WellKnownType)data).GetRuntimeTypeHandle();
                return(true);
            }

            // Not a simple type signature... requires more work to skip
            typeHandle = default(RuntimeTypeHandle);
            return(false);
        }
        private bool TryGetTypeFromSimpleTypeSignature(ref NativeParser parser, out RuntimeTypeHandle typeHandle)
        {
            uint data;
            TypeSignatureKind kind = parser.GetTypeSignatureKind(out data);

            if (kind == TypeSignatureKind.Lookback)
            {
                var lookbackParser = parser.GetLookbackParser(data);
                return(TryGetTypeFromSimpleTypeSignature(ref lookbackParser, out typeHandle));
            }
            else if (kind == TypeSignatureKind.External)
            {
                typeHandle = GetExternalTypeHandle(ref parser, data);
                return(true);
            }

            // Not a simple type signature... requires more work to skip
            typeHandle = default(RuntimeTypeHandle);
            return(false);
        }
        private unsafe TypeDesc GetLookbackType(ref NativeParser parser, uint lookback)
        {
            var lookbackParser = parser.GetLookbackParser(lookback);

            return(GetType(ref lookbackParser));
        }
Exemple #4
0
        private bool CompareTypeSigs(ref NativeParser parser1, NativeFormatModuleInfo moduleHandle1, ref NativeParser parser2, NativeFormatModuleInfo moduleHandle2)
        {
            // startOffset lets us backtrack to the TypeSignatureKind for external types since the TypeLoader
            // expects to read it in.
            uint data1;
            uint startOffset1       = parser1.Offset;
            var  typeSignatureKind1 = parser1.GetTypeSignatureKind(out data1);

            // If the parser is at a lookback type, get a new parser for it and recurse.
            // Since we haven't read the element type of parser2 yet, we just pass it in unchanged
            if (typeSignatureKind1 == TypeSignatureKind.Lookback)
            {
                NativeParser lookbackParser1 = parser1.GetLookbackParser(data1);
                return(CompareTypeSigs(ref lookbackParser1, moduleHandle1, ref parser2, moduleHandle2));
            }

            uint data2;
            uint startOffset2       = parser2.Offset;
            var  typeSignatureKind2 = parser2.GetTypeSignatureKind(out data2);

            // If parser2 is a lookback type, we need to rewind parser1 to its startOffset1
            // before recursing.
            if (typeSignatureKind2 == TypeSignatureKind.Lookback)
            {
                NativeParser lookbackParser2 = parser2.GetLookbackParser(data2);
                parser1 = new NativeParser(parser1.Reader, startOffset1);
                return(CompareTypeSigs(ref parser1, moduleHandle1, ref lookbackParser2, moduleHandle2));
            }

            if (typeSignatureKind1 != typeSignatureKind2)
            {
                return(false);
            }

            switch (typeSignatureKind1)
            {
            case TypeSignatureKind.Lookback:
            {
                //  Recursion above better have removed all lookbacks
                Debug.Assert(false, "Unexpected lookback type");
                return(false);
            }

            case TypeSignatureKind.Modifier:
            {
                // Ensure the modifier kind (vector, pointer, byref) is the same
                if (data1 != data2)
                {
                    return(false);
                }
                return(CompareTypeSigs(ref parser1, moduleHandle1, ref parser2, moduleHandle2));
            }

            case TypeSignatureKind.Variable:
            {
                // variable index is in data
                if (data1 != data2)
                {
                    return(false);
                }
                break;
            }

            case TypeSignatureKind.MultiDimArray:
            {
                // rank is in data
                if (data1 != data2)
                {
                    return(false);
                }

                if (!CompareTypeSigs(ref parser1, moduleHandle1, ref parser2, moduleHandle2))
                {
                    return(false);
                }

                uint boundCount1 = parser1.GetUnsigned();
                uint boundCount2 = parser2.GetUnsigned();
                if (boundCount1 != boundCount2)
                {
                    return(false);
                }

                for (uint i = 0; i < boundCount1; i++)
                {
                    if (parser1.GetUnsigned() != parser2.GetUnsigned())
                    {
                        return(false);
                    }
                }

                uint lowerBoundCount1 = parser1.GetUnsigned();
                uint lowerBoundCount2 = parser2.GetUnsigned();
                if (lowerBoundCount1 != lowerBoundCount2)
                {
                    return(false);
                }

                for (uint i = 0; i < lowerBoundCount1; i++)
                {
                    if (parser1.GetUnsigned() != parser2.GetUnsigned())
                    {
                        return(false);
                    }
                }
                break;
            }

            case TypeSignatureKind.FunctionPointer:
            {
                // callingConvention is in data
                if (data1 != data2)
                {
                    return(false);
                }
                uint argCount1 = parser1.GetUnsigned();
                uint argCount2 = parser2.GetUnsigned();
                if (argCount1 != argCount2)
                {
                    return(false);
                }
                for (uint i = 0; i < argCount1; i++)
                {
                    if (!CompareTypeSigs(ref parser1, moduleHandle1, ref parser2, moduleHandle2))
                    {
                        return(false);
                    }
                }
                break;
            }

            case TypeSignatureKind.Instantiation:
            {
                // Type parameter count is in data
                if (data1 != data2)
                {
                    return(false);
                }

                if (!CompareTypeSigs(ref parser1, moduleHandle1, ref parser2, moduleHandle2))
                {
                    return(false);
                }

                for (uint i = 0; i < data1; i++)
                {
                    if (!CompareTypeSigs(ref parser1, moduleHandle1, ref parser2, moduleHandle2))
                    {
                        return(false);
                    }
                }
                break;
            }

            case TypeSignatureKind.BuiltIn:
                RuntimeTypeHandle typeHandle3 = ((WellKnownType)data1).GetRuntimeTypeHandle();
                RuntimeTypeHandle typeHandle4 = ((WellKnownType)data2).GetRuntimeTypeHandle();
                if (!typeHandle3.Equals(typeHandle4))
                {
                    return(false);
                }

                break;

            case TypeSignatureKind.External:
            {
                RuntimeTypeHandle typeHandle1 = GetExternalTypeHandle(moduleHandle1, data1);
                RuntimeTypeHandle typeHandle2 = GetExternalTypeHandle(moduleHandle2, data2);
                if (!typeHandle1.Equals(typeHandle2))
                {
                    return(false);
                }

                break;
            }

            default:
                return(false);
            }
            return(true);
        }
Exemple #5
0
        /// <summary>
        /// IF THESE SEMANTICS EVER CHANGE UPDATE THE LOGIC WHICH DEFINES THIS BEHAVIOR IN
        /// THE DYNAMIC TYPE LOADER AS WELL AS THE COMPILER.
        /// (There is a version of this in UniversalGenericParameterLayout.cs that must be kept in sync with this.)
        ///
        /// Parameter's are considered to have type layout dependent on their generic instantiation
        /// if the type of the parameter in its signature is a type variable, or if the type is a generic
        /// structure which meets 2 characteristics:
        /// 1. Structure size/layout is affected by the size/layout of one or more of its generic parameters
        /// 2. One or more of the generic parameters is a type variable, or a generic structure which also recursively
        ///    would satisfy constraint 2. (Note, that in the recursion case, whether or not the structure is affected
        ///    by the size/layout of its generic parameters is not investigated.)
        ///
        /// Examples parameter types, and behavior.
        ///
        /// T = true
        /// List[T] = false
        /// StructNotDependentOnArgsForSize[T] = false
        /// GenStructDependencyOnArgsForSize[T] = true
        /// StructNotDependentOnArgsForSize[GenStructDependencyOnArgsForSize[T]] = true
        /// StructNotDependentOnArgsForSize[GenStructDependencyOnArgsForSize[List[T]]]] = false
        ///
        /// Example non-parameter type behavior
        /// T = true
        /// List[T] = false
        /// StructNotDependentOnArgsForSize[T] = *true*
        /// GenStructDependencyOnArgsForSize[T] = true
        /// StructNotDependentOnArgsForSize[GenStructDependencyOnArgsForSize[T]] = true
        /// StructNotDependentOnArgsForSize[GenStructDependencyOnArgsForSize[List[T]]]] = false
        /// </summary>
        private bool TypeSignatureHasVarsNeedingCallingConventionConverter(ref NativeParser parser, NativeFormatModuleInfo moduleHandle, TypeSystemContext context, HasVarsInvestigationLevel investigationLevel)
        {
            uint data;
            var  kind = parser.GetTypeSignatureKind(out data);

            switch (kind)
            {
            case TypeSignatureKind.External: return(false);

            case TypeSignatureKind.Variable: return(true);

            case TypeSignatureKind.BuiltIn: return(false);

            case TypeSignatureKind.Lookback:
            {
                var lookbackParser = parser.GetLookbackParser(data);
                return(TypeSignatureHasVarsNeedingCallingConventionConverter(ref lookbackParser, moduleHandle, context, investigationLevel));
            }

            case TypeSignatureKind.Instantiation:
            {
                RuntimeTypeHandle genericTypeDef;
                if (!TryGetTypeFromSimpleTypeSignature(ref parser, moduleHandle, out genericTypeDef))
                {
                    Debug.Assert(false);
                    return(true);           // Returning true will prevent further reading from the native parser
                }

                if (!RuntimeAugments.IsValueType(genericTypeDef))
                {
                    // Reference types are treated like pointers. No calling convention conversion needed. Just consume the rest of the signature.
                    for (uint i = 0; i < data; i++)
                    {
                        TypeSignatureHasVarsNeedingCallingConventionConverter(ref parser, moduleHandle, context, HasVarsInvestigationLevel.Ignore);
                    }
                    return(false);
                }
                else
                {
                    bool result = false;
                    for (uint i = 0; i < data; i++)
                    {
                        result = TypeSignatureHasVarsNeedingCallingConventionConverter(ref parser, moduleHandle, context, HasVarsInvestigationLevel.NotParameter) || result;
                    }

                    if ((result == true) && (investigationLevel == HasVarsInvestigationLevel.Parameter))
                    {
                        if (!TryComputeHasInstantiationDeterminedSize(genericTypeDef, context, out result))
                        {
                            Environment.FailFast("Unable to setup calling convention converter correctly");
                        }

                        return(result);
                    }

                    return(result);
                }
            }

            case TypeSignatureKind.Modifier:
            {
                // Arrays, pointers and byref types signatures are treated as pointers, not requiring calling convention conversion.
                // Just consume the parameter type from the stream and return false;
                TypeSignatureHasVarsNeedingCallingConventionConverter(ref parser, moduleHandle, context, HasVarsInvestigationLevel.Ignore);
                return(false);
            }

            case TypeSignatureKind.MultiDimArray:
            {
                // No need for a calling convention converter for this case. Just consume the signature from the stream.

                TypeSignatureHasVarsNeedingCallingConventionConverter(ref parser, moduleHandle, context, HasVarsInvestigationLevel.Ignore);

                uint boundCount = parser.GetUnsigned();
                for (uint i = 0; i < boundCount; i++)
                {
                    parser.GetUnsigned();
                }

                uint lowerBoundCount = parser.GetUnsigned();
                for (uint i = 0; i < lowerBoundCount; i++)
                {
                    parser.GetUnsigned();
                }
            }
                return(false);

            case TypeSignatureKind.FunctionPointer:
            {
                // No need for a calling convention converter for this case. Just consume the signature from the stream.

                uint argCount = parser.GetUnsigned();
                for (uint i = 0; i < argCount; i++)
                {
                    TypeSignatureHasVarsNeedingCallingConventionConverter(ref parser, moduleHandle, context, HasVarsInvestigationLevel.Ignore);
                }
            }
                return(false);

            default:
                parser.ThrowBadImageFormatException();
                return(true);
            }
        }
Exemple #6
0
        private static bool CompareTypeSigWithType(ref NativeParser parser, Type type)
        {
            // startOffset lets us backtrack to the TypeSignatureKind for external types since the TypeLoader
            // expects to read it in.
            uint startOffset = parser.Offset;

            uint data;
            var typeSignatureKind = parser.GetTypeSignatureKind(out data);

            switch (typeSignatureKind)
            {
                case TypeSignatureKind.Lookback:
                    {
                        NativeParser lookbackParser = parser.GetLookbackParser(data);
                        return CompareTypeSigWithType(ref lookbackParser, type);
                    }

                case TypeSignatureKind.Modifier:
                    {
                        // Ensure the modifier kind (vector, pointer, byref) is the same
                        TypeModifierKind modifierKind = (TypeModifierKind)data;
                        switch (modifierKind)
                        {
                            case TypeModifierKind.Array:
                                if (!type.IsArray)
                                    return false;
                                break;
                            case TypeModifierKind.ByRef:
                                if (!type.IsByRef)
                                    return false;
                                break;
                            case TypeModifierKind.Pointer:
                                if (!type.IsPointer)
                                    return false;
                                break;
                        }
                        return CompareTypeSigWithType(ref parser, type.GetElementType());
                    }

                case TypeSignatureKind.Variable:
                    {
                        if (!type.IsGenericParameter)
                            return false;

                        bool isMethodVar = (data & 0x1) == 1;
                        uint index = data >> 1;

                        if (index != type.GenericParameterPosition)
                            return false;

                        // MVARs are represented as having a non-null DeclaringMethod in the reflection object model
                        if (isMethodVar ^ (type.GetTypeInfo().DeclaringMethod != null))
                            return false;

                        break;
                    }

                case TypeSignatureKind.MultiDimArray:
                    {
                        if (!type.IsArray)
                            return false;

                        if (data != type.GetArrayRank())
                            return false;

                        if (!CompareTypeSigWithType(ref parser, type.GetElementType()))
                            return false;

                        uint boundCount1 = parser.GetUnsigned();
                        for (uint i = 0; i < boundCount1; i++)
                        {
                            parser.GetUnsigned();
                        }

                        uint lowerBoundCount1 = parser.GetUnsigned();

                        for (uint i = 0; i < lowerBoundCount1; i++)
                        {
                            parser.GetUnsigned();
                        }
                        break;
                    }

                case TypeSignatureKind.FunctionPointer:
                    {
                        // callingConvention is in data
                        uint argCount1 = parser.GetUnsigned();

                        for (uint i = 0; i < argCount1; i++)
                        {
                            if (!CompareTypeSigWithType(ref parser, type))
                                return false;
                        }
                        return false;
                    }

                case TypeSignatureKind.Instantiation:
                    {
                        // Type Def                    
                        if (!type.GetTypeInfo().IsGenericType)
                            return false;

                        if (!CompareTypeSigWithType(ref parser, type.GetGenericTypeDefinition()))
                            return false;

                        for (uint i = 0; i < data; i++)
                        {
                            if (!CompareTypeSigWithType(ref parser, type.GenericTypeArguments[i]))
                                return false;
                        }
                        break;
                    }

                case TypeSignatureKind.External:
                    {
                        RuntimeTypeHandle type1 = SigParsing.GetTypeFromNativeLayoutSignature(ref parser, startOffset);

                        if (!CanGetTypeHandle(type))
                            return false;

                        RuntimeTypeHandle type2 = type.TypeHandle;
                        if (!type1.Equals(type2))
                            return false;
                        break;
                    }

                default:
                    return false;
            }
            return true;
        }
        private bool CompareTypeSigWithType(ref NativeParser parser, Handle typeHandle)
        {
            while (typeHandle.HandleType == HandleType.TypeSpecification)
            {
                typeHandle = typeHandle
                             .ToTypeSpecificationHandle(_metadataReader)
                             .GetTypeSpecification(_metadataReader)
                             .Signature;
            }

            // startOffset lets us backtrack to the TypeSignatureKind for external types since the TypeLoader
            // expects to read it in.
            uint startOffset = parser.Offset;

            uint data;
            var  typeSignatureKind = parser.GetTypeSignatureKind(out data);

            switch (typeSignatureKind)
            {
            case TypeSignatureKind.Lookback:
            {
                NativeParser lookbackParser = parser.GetLookbackParser(data);
                return(CompareTypeSigWithType(ref lookbackParser, typeHandle));
            }

            case TypeSignatureKind.Modifier:
            {
                // Ensure the modifier kind (vector, pointer, byref) is the same
                TypeModifierKind modifierKind = (TypeModifierKind)data;
                switch (modifierKind)
                {
                case TypeModifierKind.Array:
                    if (typeHandle.HandleType == HandleType.SZArraySignature)
                    {
                        return(CompareTypeSigWithType(ref parser, typeHandle
                                                      .ToSZArraySignatureHandle(_metadataReader)
                                                      .GetSZArraySignature(_metadataReader)
                                                      .ElementType));
                    }
                    return(false);

                case TypeModifierKind.ByRef:
                    if (typeHandle.HandleType == HandleType.ByReferenceSignature)
                    {
                        return(CompareTypeSigWithType(ref parser, typeHandle
                                                      .ToByReferenceSignatureHandle(_metadataReader)
                                                      .GetByReferenceSignature(_metadataReader)
                                                      .Type));
                    }
                    return(false);

                case TypeModifierKind.Pointer:
                    if (typeHandle.HandleType == HandleType.PointerSignature)
                    {
                        return(CompareTypeSigWithType(ref parser, typeHandle
                                                      .ToPointerSignatureHandle(_metadataReader)
                                                      .GetPointerSignature(_metadataReader)
                                                      .Type));
                    }
                    return(false);

                default:
                    Debug.Assert(null == "invalid type modifier kind");
                    return(false);
                }
            }

            case TypeSignatureKind.Variable:
            {
                bool isMethodVar = (data & 0x1) == 1;
                uint index       = data >> 1;

                if (isMethodVar)
                {
                    if (typeHandle.HandleType == HandleType.MethodTypeVariableSignature)
                    {
                        return(index == typeHandle
                               .ToMethodTypeVariableSignatureHandle(_metadataReader)
                               .GetMethodTypeVariableSignature(_metadataReader)
                               .Number);
                    }
                }
                else
                {
                    if (typeHandle.HandleType == HandleType.TypeVariableSignature)
                    {
                        return(index == typeHandle
                               .ToTypeVariableSignatureHandle(_metadataReader)
                               .GetTypeVariableSignature(_metadataReader)
                               .Number);
                    }
                }

                return(false);
            }

            case TypeSignatureKind.MultiDimArray:
            {
                if (typeHandle.HandleType != HandleType.ArraySignature)
                {
                    return(false);
                }

                ArraySignature sig = typeHandle
                                     .ToArraySignatureHandle(_metadataReader)
                                     .GetArraySignature(_metadataReader);

                if (data != sig.Rank)
                {
                    return(false);
                }

                if (!CompareTypeSigWithType(ref parser, sig.ElementType))
                {
                    return(false);
                }

                uint boundCount1 = parser.GetUnsigned();
                for (uint i = 0; i < boundCount1; i++)
                {
                    parser.GetUnsigned();
                }

                uint lowerBoundCount1 = parser.GetUnsigned();

                for (uint i = 0; i < lowerBoundCount1; i++)
                {
                    parser.GetUnsigned();
                }
                break;
            }

            case TypeSignatureKind.FunctionPointer:
            {
                // callingConvention is in data
                uint argCount1 = parser.GetUnsigned();

                for (uint i = 0; i < argCount1; i++)
                {
                    if (!CompareTypeSigWithType(ref parser, typeHandle))
                    {
                        return(false);
                    }
                }
                return(false);
            }

            case TypeSignatureKind.Instantiation:
            {
                if (typeHandle.HandleType != HandleType.TypeInstantiationSignature)
                {
                    return(false);
                }

                TypeInstantiationSignature sig = typeHandle
                                                 .ToTypeInstantiationSignatureHandle(_metadataReader)
                                                 .GetTypeInstantiationSignature(_metadataReader);

                if (!CompareTypeSigWithType(ref parser, sig.GenericType))
                {
                    return(false);
                }

                uint genericArgIndex = 0;
                foreach (Handle genericArgumentTypeHandle in sig.GenericTypeArguments)
                {
                    if (genericArgIndex >= data)
                    {
                        // The metadata generic has more parameters than the native layour
                        return(false);
                    }
                    if (!CompareTypeSigWithType(ref parser, genericArgumentTypeHandle))
                    {
                        return(false);
                    }
                    genericArgIndex++;
                }
                // Make sure all generic parameters have been matched
                return(genericArgIndex == data);
            }

            case TypeSignatureKind.External:
            {
                RuntimeTypeHandle type2;
                switch (typeHandle.HandleType)
                {
                case HandleType.TypeDefinition:
                    if (!TypeLoaderEnvironment.Instance.TryGetOrCreateNamedTypeForMetadata(
                            _metadataReader, typeHandle.ToTypeDefinitionHandle(_metadataReader), out type2))
                    {
                        return(false);
                    }
                    break;

                case HandleType.TypeReference:
                    if (!TypeLoaderEnvironment.TryGetNamedTypeForTypeReference(
                            _metadataReader, typeHandle.ToTypeReferenceHandle(_metadataReader), out type2))
                    {
                        return(false);
                    }
                    break;

                default:
                    return(false);
                }

                RuntimeTypeHandle type1 = SigParsing.GetTypeFromNativeLayoutSignature(ref parser, startOffset);
                return(type1.Equals(type2));
            }

            default:
                return(false);
            }
            return(true);
        }
        private bool CompareTypeSigWithType(ref NativeParser parser, Handle typeHandle)
        {
            while (typeHandle.HandleType == HandleType.TypeSpecification)
            {
                typeHandle = typeHandle
                    .ToTypeSpecificationHandle(_metadataReader)
                    .GetTypeSpecification(_metadataReader)
                    .Signature;
            }

            // startOffset lets us backtrack to the TypeSignatureKind for external types since the TypeLoader
            // expects to read it in.
            uint startOffset = parser.Offset;

            uint data;
            var typeSignatureKind = parser.GetTypeSignatureKind(out data);

            switch (typeSignatureKind)
            {
                case TypeSignatureKind.Lookback:
                    {
                        NativeParser lookbackParser = parser.GetLookbackParser(data);
                        return CompareTypeSigWithType(ref lookbackParser, typeHandle);
                    }

                case TypeSignatureKind.Modifier:
                    {
                        // Ensure the modifier kind (vector, pointer, byref) is the same
                        TypeModifierKind modifierKind = (TypeModifierKind)data;
                        switch (modifierKind)
                        {
                            case TypeModifierKind.Array:
                                if (typeHandle.HandleType == HandleType.SZArraySignature)
                                {
                                    return CompareTypeSigWithType(ref parser, typeHandle
                                        .ToSZArraySignatureHandle(_metadataReader)
                                        .GetSZArraySignature(_metadataReader)
                                        .ElementType);
                                }
                                return false;

                            case TypeModifierKind.ByRef:
                                if (typeHandle.HandleType == HandleType.ByReferenceSignature)
                                {
                                    return CompareTypeSigWithType(ref parser, typeHandle
                                        .ToByReferenceSignatureHandle(_metadataReader)
                                        .GetByReferenceSignature(_metadataReader)
                                        .Type);
                                }
                                return false;

                            case TypeModifierKind.Pointer:
                                if (typeHandle.HandleType == HandleType.PointerSignature)
                                {
                                    return CompareTypeSigWithType(ref parser, typeHandle
                                        .ToPointerSignatureHandle(_metadataReader)
                                        .GetPointerSignature(_metadataReader)
                                        .Type);
                                }
                                return false;

                            default:
                                Debug.Assert(null == "invalid type modifier kind");
                                return false;
                        }
                    }

                case TypeSignatureKind.Variable:
                    {
                        bool isMethodVar = (data & 0x1) == 1;
                        uint index = data >> 1;

                        if (isMethodVar)
                        {
                            if (typeHandle.HandleType == HandleType.MethodTypeVariableSignature)
                            {
                                return index == typeHandle
                                    .ToMethodTypeVariableSignatureHandle(_metadataReader)
                                    .GetMethodTypeVariableSignature(_metadataReader)
                                    .Number;
                            }
                        }
                        else
                        {
                            if (typeHandle.HandleType == HandleType.TypeVariableSignature)
                            {
                                return index == typeHandle
                                    .ToTypeVariableSignatureHandle(_metadataReader)
                                    .GetTypeVariableSignature(_metadataReader)
                                    .Number;
                            }
                        }

                        return false;
                    }

                case TypeSignatureKind.MultiDimArray:
                    {
                        if (typeHandle.HandleType != HandleType.ArraySignature)
                        {
                            return false;
                        }

                        ArraySignature sig = typeHandle
                            .ToArraySignatureHandle(_metadataReader)
                            .GetArraySignature(_metadataReader);

                        if (data != sig.Rank)
                            return false;

                        if (!CompareTypeSigWithType(ref parser, sig.ElementType))
                            return false;

                        uint boundCount1 = parser.GetUnsigned();
                        for (uint i = 0; i < boundCount1; i++)
                        {
                            parser.GetUnsigned();
                        }

                        uint lowerBoundCount1 = parser.GetUnsigned();

                        for (uint i = 0; i < lowerBoundCount1; i++)
                        {
                            parser.GetUnsigned();
                        }
                        break;
                    }

                case TypeSignatureKind.FunctionPointer:
                    {
                        // callingConvention is in data
                        uint argCount1 = parser.GetUnsigned();

                        for (uint i = 0; i < argCount1; i++)
                        {
                            if (!CompareTypeSigWithType(ref parser, typeHandle))
                                return false;
                        }
                        return false;
                    }

                case TypeSignatureKind.Instantiation:
                    {
                        if (typeHandle.HandleType != HandleType.TypeInstantiationSignature)
                        {
                            return false;
                        }

                        TypeInstantiationSignature sig = typeHandle
                            .ToTypeInstantiationSignatureHandle(_metadataReader)
                            .GetTypeInstantiationSignature(_metadataReader);

                        if (!CompareTypeSigWithType(ref parser, sig.GenericType))
                        {
                            return false;
                        }

                        uint genericArgIndex = 0;
                        foreach (Handle genericArgumentTypeHandle in sig.GenericTypeArguments)
                        {
                            if (genericArgIndex >= data)
                            {
                                // The metadata generic has more parameters than the native layour
                                return false;
                            }
                            if (!CompareTypeSigWithType(ref parser, genericArgumentTypeHandle))
                            {
                                return false;
                            }
                            genericArgIndex++;
                        }
                        // Make sure all generic parameters have been matched
                        return genericArgIndex == data;
                    }

                case TypeSignatureKind.External:
                    {
                        RuntimeTypeHandle type2;
                        switch (typeHandle.HandleType)
                        {
                            case HandleType.TypeDefinition:
                                if (!TypeLoaderEnvironment.Instance.TryGetOrCreateNamedTypeForMetadata(
                                    _metadataReader, typeHandle.ToTypeDefinitionHandle(_metadataReader), out type2))
                                {
                                    return false;
                                }
                                break;

                            case HandleType.TypeReference:
                                if (!TypeLoaderEnvironment.TryGetNamedTypeForTypeReference(
                                    _metadataReader, typeHandle.ToTypeReferenceHandle(_metadataReader), out type2))
                                {
                                    return false;
                                }
                                break;

                            default:
                                return false;
                        }

                        RuntimeTypeHandle type1 = SigParsing.GetTypeFromNativeLayoutSignature(ref parser, startOffset);
                        return type1.Equals(type2);
                    }

                default:
                    return false;
            }
            return true;
        }
Exemple #9
0
        private static bool CompareTypeSigWithType(ref NativeParser parser, Type type)
        {
            // startOffset lets us backtrack to the TypeSignatureKind for external types since the TypeLoader
            // expects to read it in.
            uint startOffset = parser.Offset;

            uint data;
            var  typeSignatureKind = parser.GetTypeSignatureKind(out data);

            switch (typeSignatureKind)
            {
            case TypeSignatureKind.Lookback:
            {
                NativeParser lookbackParser = parser.GetLookbackParser(data);
                return(CompareTypeSigWithType(ref lookbackParser, type));
            }

            case TypeSignatureKind.Modifier:
            {
                // Ensure the modifier kind (vector, pointer, byref) is the same
                TypeModifierKind modifierKind = (TypeModifierKind)data;
                switch (modifierKind)
                {
                case TypeModifierKind.Array:
                    if (!type.IsArray)
                    {
                        return(false);
                    }
                    break;

                case TypeModifierKind.ByRef:
                    if (!type.IsByRef)
                    {
                        return(false);
                    }
                    break;

                case TypeModifierKind.Pointer:
                    if (!type.IsPointer)
                    {
                        return(false);
                    }
                    break;
                }
                return(CompareTypeSigWithType(ref parser, type.GetElementType()));
            }

            case TypeSignatureKind.Variable:
            {
                if (!type.IsGenericParameter)
                {
                    return(false);
                }

                bool isMethodVar = (data & 0x1) == 1;
                uint index       = data >> 1;

                if (index != type.GenericParameterPosition)
                {
                    return(false);
                }

                // MVARs are represented as having a non-null DeclaringMethod in the reflection object model
                if (isMethodVar ^ (type.GetTypeInfo().DeclaringMethod != null))
                {
                    return(false);
                }

                break;
            }

            case TypeSignatureKind.MultiDimArray:
            {
                if (!type.IsArray)
                {
                    return(false);
                }

                if (data != type.GetArrayRank())
                {
                    return(false);
                }

                if (!CompareTypeSigWithType(ref parser, type.GetElementType()))
                {
                    return(false);
                }

                uint boundCount1 = parser.GetUnsigned();
                for (uint i = 0; i < boundCount1; i++)
                {
                    parser.GetUnsigned();
                }

                uint lowerBoundCount1 = parser.GetUnsigned();

                for (uint i = 0; i < lowerBoundCount1; i++)
                {
                    parser.GetUnsigned();
                }
                break;
            }

            case TypeSignatureKind.FunctionPointer:
            {
                // callingConvention is in data
                uint argCount1 = parser.GetUnsigned();

                for (uint i = 0; i < argCount1; i++)
                {
                    if (!CompareTypeSigWithType(ref parser, type))
                    {
                        return(false);
                    }
                }
                return(false);
            }

            case TypeSignatureKind.Instantiation:
            {
                // Type Def
                if (!type.GetTypeInfo().IsGenericType)
                {
                    return(false);
                }

                if (!CompareTypeSigWithType(ref parser, type.GetGenericTypeDefinition()))
                {
                    return(false);
                }

                for (uint i = 0; i < data; i++)
                {
                    if (!CompareTypeSigWithType(ref parser, type.GenericTypeArguments[i]))
                    {
                        return(false);
                    }
                }
                break;
            }

            case TypeSignatureKind.External:
            {
                RuntimeTypeHandle type1 = SigParsing.GetTypeFromNativeLayoutSignature(ref parser, startOffset);

                if (!CanGetTypeHandle(type))
                {
                    return(false);
                }

                RuntimeTypeHandle type2 = type.TypeHandle;
                if (!type1.Equals(type2))
                {
                    return(false);
                }
                break;
            }

            default:
                return(false);
            }
            return(true);
        }