private TypeDesc GetModifierType(ref NativeParser parser, TypeModifierKind modifier)
        {
            TypeDesc typeParameter = GetType(ref parser);

            switch (modifier)
            {
            case TypeModifierKind.Array:
                return(_typeSystemContext.GetArrayType(typeParameter));

            case TypeModifierKind.ByRef:
                return(_typeSystemContext.GetByRefType(typeParameter));

            case TypeModifierKind.Pointer:
                return(_typeSystemContext.GetPointerType(typeParameter));

            default:
                parser.ThrowBadImageFormatException();
                return(null);
            }
        }
        private TypeDesc GetModifierType(ref NativeParser parser, TypeModifierKind modifier)
        {
            TypeDesc typeParameter = GetType(ref parser);

            switch (modifier)
            {
                case TypeModifierKind.Array:
                    return _typeSystemContext.GetArrayType(typeParameter);

                case TypeModifierKind.ByRef:
                    return _typeSystemContext.GetByRefType(typeParameter);

                case TypeModifierKind.Pointer:
                    return _typeSystemContext.GetPointerType(typeParameter);

                default:
                    parser.ThrowBadImageFormatException();
                    return null;
            }
        }
        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);
        }
Пример #4
0
        public Vertex GetModifierTypeSignature(TypeModifierKind modifier, Vertex param)
        {
            ModifierTypeSignature sig = new ModifierTypeSignature(modifier, param);

            return(Unify(sig));
        }
Пример #5
0
 public ModifierTypeSignature(TypeModifierKind modifier, Vertex param)
 {
     _modifier = modifier;
     _param    = param;
 }
Пример #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);
        }