public void TestGenericMethodInterfaceMethodImplOverride()
        {
            //
            // Ensure MethodImpl based overriding works for MethodSpecs
            //

            MetadataType interfaceType   = _testModule.GetType("VirtualFunctionOverride", "IIFaceWithGenericMethod");
            MethodDesc   interfaceMethod = null;

            foreach (MethodDesc m in interfaceType.GetMethods())
            {
                if (m.Name == "GenMethod")
                {
                    interfaceMethod = m;
                    break;
                }
            }
            Assert.NotNull(interfaceMethod);

            MetadataType objectType            = _testModule.GetType("VirtualFunctionOverride", "HasMethodInterfaceOverrideOfGenericMethod");
            MethodDesc   expectedVirtualMethod = null;

            foreach (MethodDesc m in objectType.GetMethods())
            {
                if (m.Name.Contains("GenMethod"))
                {
                    expectedVirtualMethod = m;
                    break;
                }
            }
            Assert.NotNull(expectedVirtualMethod);

            Assert.Equal(expectedVirtualMethod, VirtualFunctionResolution.ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethod, objectType));
        }
        public sealed override bool TryGetModuleTokenForExternalType(TypeDesc type, out ModuleToken token)
        {
            Debug.Assert(!VersionsWithType(type));

            if (_typeRefsInCompilationModuleSet == null)
            {
                _typeRefsInCompilationModuleSet = new Dictionary <TypeDesc, ModuleToken>();

                foreach (var module in _compilationModuleSet)
                {
                    EcmaModule ecmaModule = (EcmaModule)module;
                    foreach (var typeRefHandle in ecmaModule.MetadataReader.TypeReferences)
                    {
                        try
                        {
                            TypeDesc typeFromTypeRef = ecmaModule.GetType(typeRefHandle);
                            if (!_typeRefsInCompilationModuleSet.ContainsKey(typeFromTypeRef))
                            {
                                _typeRefsInCompilationModuleSet.Add(typeFromTypeRef, new ModuleToken(ecmaModule, typeRefHandle));
                            }
                        }
                        catch (TypeSystemException) { }
                    }
                }
            }

            return(_typeRefsInCompilationModuleSet.TryGetValue(type, out token));
        }
예제 #3
0
        private uint LookupIbcTypeToken(EcmaModule externalModule, uint ibcToken, Dictionary <IBCBlobKey, BlobEntry> blobs)
        {
            var    typeEntry     = (BlobEntry.ExternalTypeEntry)blobs[new IBCBlobKey(ibcToken, BlobType.ExternalTypeDef)];
            string typeNamespace = null;
            string typeName      = Encoding.UTF8.GetString(typeEntry.Name);
            TypeDefinitionHandle enclosingType = default;

            if (!Cor.Macros.IsNilToken(typeEntry.NamespaceToken))
            {
                if (!Cor.Macros.IsNilToken(typeEntry.NestedClassToken))
                {
                    // Do not support typedef with namespace that is nested
                    throw new Exception($"Ibc TypeToken {ibcToken:x} has both Namespace and NestedClass tokens");
                }

                uint nameSpaceToken = typeEntry.NamespaceToken;
                if (Cor.Macros.TypeFromToken(nameSpaceToken) != CorTokenType.ibcExternalNamespace)
                {
                    throw new Exception($"Ibc TypeToken {ibcToken:x} has Namespace tokens that is not a ibcExternalNamespace");
                }

                var namespaceEntry = (BlobEntry.ExternalNamespaceEntry)blobs[new IBCBlobKey(nameSpaceToken, BlobType.ExternalNamespaceDef)];
                typeNamespace = Encoding.UTF8.GetString(namespaceEntry.Name);
            }
            else if (!Cor.Macros.IsNilToken(typeEntry.NestedClassToken))
            {
                uint enclosingTypeTokenValue = LookupIbcTypeToken(externalModule, typeEntry.NestedClassToken, blobs);
                if (Cor.Macros.TypeFromToken(enclosingTypeTokenValue) != CorTokenType.mdtTypeDef)
                {
                    throw new Exception($"Ibc TypeToken {ibcToken:x} has NestedClass token which does not resolve to a type definition");
                }

                enclosingType = MetadataTokens.TypeDefinitionHandle((int)Cor.Macros.RidFromToken(enclosingTypeTokenValue));
                if (enclosingType.IsNil)
                {
                    throw new Exception($"Ibc TypeToken {ibcToken:x} has NestedClass token which resolves to a nil token");
                }
            }

            if (enclosingType.IsNil)
            {
                return((uint)externalModule.MetadataReader.GetToken(((EcmaType)externalModule.GetType(typeNamespace, typeName)).Handle));
            }
            else
            {
                TypeDefinition         nestedClassDefinition = externalModule.MetadataReader.GetTypeDefinition(enclosingType);
                MetadataStringComparer stringComparer        = externalModule.MetadataReader.StringComparer;
                foreach (TypeDefinitionHandle tdNested in nestedClassDefinition.GetNestedTypes())
                {
                    TypeDefinition candidateClassDefinition = externalModule.MetadataReader.GetTypeDefinition(tdNested);
                    if (stringComparer.Equals(candidateClassDefinition.Name, typeName))
                    {
                        return((uint)externalModule.MetadataReader.GetToken(tdNested));
                    }
                }

                throw new Exception($"Ibc TypeToken {ibcToken:x} unable to find nested type '{typeName}' on type '{externalModule.MetadataReader.GetToken(enclosingType):x}'");
            }
        }
예제 #4
0
        public void TestNoPointers()
        {
            MetadataType t = _testModule.GetType("StaticFieldLayout", "NoPointers");

            foreach (var field in t.GetFields())
            {
                if (!field.IsStatic)
                {
                    continue;
                }

                switch (field.Name)
                {
                case "int1":
                    Assert.Equal(0, field.Offset);
                    break;

                case "byte1":
                    Assert.Equal(4, field.Offset);
                    break;

                case "char1":
                    Assert.Equal(6, field.Offset);
                    break;

                default:
                    throw new Exception(field.Name);
                }
            }
        }
예제 #5
0
        public void TestInstanceLayoutDoubleBool()
        {
            MetadataType tX64 = _testModuleX64.GetType("Sequential", "ClassDoubleBool");
            MetadataType tX86 = _testModuleX86.GetType("Sequential", "ClassDoubleBool");
            MetadataType tARM = _testModuleARM.GetType("Sequential", "ClassDoubleBool");

            Assert.Equal(0x8, tX64.InstanceByteAlignment);
            Assert.Equal(0x8, tARM.InstanceByteAlignment);
            Assert.Equal(0x4, tX86.InstanceByteAlignment);

            Assert.Equal(0x11, tX64.InstanceByteCountUnaligned);
            Assert.Equal(0x11, tARM.InstanceByteCountUnaligned);
            Assert.Equal(0x11, tX86.InstanceByteCountUnaligned);

            Assert.Equal(0x18, tX64.InstanceByteCount);
            Assert.Equal(0x18, tARM.InstanceByteCount);
            Assert.Equal(0x14, tX86.InstanceByteCount);
        }
예제 #6
0
        private static IEnumerable <VerificationResult> Verify(TestCase testCase)
        {
            EcmaModule module     = TestDataLoader.GetModuleForTestAssembly(testCase.ModuleName);
            var        typeHandle = (TypeDefinitionHandle)MetadataTokens.EntityHandle(testCase.MetadataToken);
            var        type       = (EcmaType)module.GetType(typeHandle);
            var        verifier   = new Verifier((ILVerifyTypeSystemContext)type.Context);

            return(verifier.Verify(module.PEReader, typeHandle));
        }
        public void SetSystemModule(EcmaModule systemModule)
        {
            _systemModule = systemModule;

            // Sanity check the name table
            Debug.Assert(s_wellKnownTypeNames[(int)WellKnownType.MulticastDelegate - 1] == "MulticastDelegate");

            // Initialize all well known types - it will save us from checking the name for each loaded type
            for (int typeIndex = 0; typeIndex < _wellKnownTypes.Length; typeIndex++)
            {
                MetadataType type = _systemModule.GetType("System", s_wellKnownTypeNames[typeIndex]);
                type.SetWellKnownType((WellKnownType)(typeIndex + 1));
                _wellKnownTypes[typeIndex] = type;
            }
        }
예제 #8
0
        private MetadataType LoadTypeFromIBCZapSig(IBCModule ibcModule, EcmaModule ecmaModule, CorElementType typ, ref BlobReader sig)
        {
            switch (typ)
            {
            case CorElementType.ELEMENT_TYPE_CLASS:
            case CorElementType.ELEMENT_TYPE_VALUETYPE:
                uint token = (uint)ibcModule.EcmaModule.MetadataReader.GetToken(sig.ReadTypeHandle());
                if (ecmaModule != ibcModule.EcmaModule)
                {
                    // ibcExternalType tokens are actually encoded as mdtTypeDef tokens in the signature
                    uint rid      = Cor.Macros.RidFromToken(token);
                    uint ibcToken = Cor.Macros.TokenFromRid(rid, CorTokenType.ibcExternalType);
                    token = LookupIbcTypeToken(ref ecmaModule, ibcToken, ibcModule.Blobs);
                }
                switch (Cor.Macros.TypeFromToken(token))
                {
                case CorTokenType.mdtTypeDef:
                case CorTokenType.mdtTypeRef:
                    // success
                    break;

                default:
                    throw new Exception("Invalid token found while parsing IBC ZapSig generic instantiation");
                }
                if (Cor.Macros.IsNilToken(token))
                {
                    return(null);
                }

                var result = (MetadataType)ecmaModule.GetType(MetadataTokens.EntityHandle((int)token));
                if ((typ == CorElementType.ELEMENT_TYPE_VALUETYPE) != result.IsValueType)
                {
                    if (_logger.IsVerbose)
                    {
                        _logger.Writer.WriteLine("Mismatch between valuetype and reference type in while parsing generic instantiation");
                    }
                    return(null);
                }
                return(result);

            default:
                if (_logger.IsVerbose)
                {
                    _logger.Writer.WriteLine("Unexpected token type parsing ELEMENT_TYPE_GENERICINST");
                }
                return(null);
            }
        }
예제 #9
0
        public override bool TryGetModuleTokenForExternalType(TypeDesc type, out ModuleToken token)
        {
            Debug.Assert(!VersionsWithType(type));

            if (_typeRefsInCompilationModuleSet == null)
            {
                _typeRefsInCompilationModuleSet = new Dictionary <TypeDesc, ModuleToken>();

                EcmaModule ecmaModule = ((EcmaMethod)_method.GetTypicalMethodDefinition()).Module;
                foreach (var typeRefHandle in ecmaModule.MetadataReader.TypeReferences)
                {
                    try
                    {
                        TypeDesc typeFromTypeRef = ecmaModule.GetType(typeRefHandle);
                        _typeRefsInCompilationModuleSet[typeFromTypeRef] = new ModuleToken(ecmaModule, typeRefHandle);
                    }
                    catch (TypeSystemException) { }
                }
            }

            return(_typeRefsInCompilationModuleSet.TryGetValue(type, out token));
        }
예제 #10
0
        // LookupIbcTypeToken and (possibly) find the module associated with it.
        // externalModule may be null if the exact assembly isn't known
        private uint LookupIbcTypeToken(ref EcmaModule externalModule, uint ibcToken, Dictionary <IBCBlobKey, BlobEntry> blobs)
        {
            if (!blobs.TryGetValue(new IBCBlobKey(ibcToken, BlobType.ExternalTypeDef), out BlobEntry externalTypeDefBlob))
            {
                if (_logger.IsVerbose)
                {
                    _logger.Writer.WriteLine($"Ibc TypeToken {ibcToken:x} unable to find external typedef");
                }
                return(Cor.Macros.RidToToken(0, CorTokenType.mdtTypeDef)); // Nil TypeDef token
            }

            var typeEntry = (BlobEntry.ExternalTypeEntry)externalTypeDefBlob;

            string typeNamespace = "";
            string typeName      = Encoding.UTF8.GetString(typeEntry.Name, 0, typeEntry.Name.Length - 1 /* these strings are null terminated */);
            TypeDefinitionHandle enclosingType = default;

            if (!Cor.Macros.IsNilToken(typeEntry.NamespaceToken))
            {
                if (!Cor.Macros.IsNilToken(typeEntry.NestedClassToken))
                {
                    // Do not support typedef with namespace that is nested
                    throw new Exception($"Ibc TypeToken {ibcToken:x} has both Namespace and NestedClass tokens");
                }

                uint nameSpaceToken = typeEntry.NamespaceToken;
                if (Cor.Macros.TypeFromToken(nameSpaceToken) != CorTokenType.ibcExternalNamespace)
                {
                    throw new Exception($"Ibc TypeToken {ibcToken:x} has Namespace tokens that is not a ibcExternalNamespace");
                }


                if (!blobs.TryGetValue(new IBCBlobKey(nameSpaceToken, BlobType.ExternalNamespaceDef), out BlobEntry namespaceEntryBlob))
                {
                    if (_logger.IsVerbose)
                    {
                        _logger.Writer.WriteLine($"Ibc TypeToken {ibcToken:x} unable to find external namespace blob '{nameSpaceToken:x}");
                    }
                    return(Cor.Macros.RidToToken(0, CorTokenType.mdtTypeDef)); // Nil TypeDef token
                }

                var namespaceEntry = (BlobEntry.ExternalNamespaceEntry)namespaceEntryBlob;
                typeNamespace = Encoding.UTF8.GetString(namespaceEntry.Name, 0, namespaceEntry.Name.Length - 1 /* these strings are null terminated */);
            }
            else if (!Cor.Macros.IsNilToken(typeEntry.NestedClassToken))
            {
                uint enclosingTypeTokenValue = LookupIbcTypeToken(ref externalModule, typeEntry.NestedClassToken, blobs);
                if (Cor.Macros.TypeFromToken(enclosingTypeTokenValue) != CorTokenType.mdtTypeDef)
                {
                    throw new Exception($"Ibc TypeToken {ibcToken:x} has NestedClass token which does not resolve to a type definition");
                }

                enclosingType = MetadataTokens.TypeDefinitionHandle((int)Cor.Macros.RidFromToken(enclosingTypeTokenValue));
                if (enclosingType.IsNil && _logger.IsVerbose)
                {
                    _logger.Writer.WriteLine($"Ibc TypeToken {ibcToken:x} has NestedClass token which resolves to a nil token");
                }
            }

            if (enclosingType.IsNil)
            {
                EcmaType foundType = null;
                if (externalModule == null)
                {
                    // Lookup actual module scenario.
                    foreach (ModuleDesc m in _possibleReferenceModules)
                    {
                        if (!(m is EcmaModule))
                        {
                            continue;
                        }

                        foundType = (EcmaType)m.GetType(typeNamespace, typeName, throwIfNotFound: false);
                        if (foundType != null)
                        {
                            externalModule = foundType.EcmaModule;
                            break;
                        }
                    }
                }
                else
                {
                    foundType = (EcmaType)externalModule.GetType(typeNamespace, typeName, throwIfNotFound: false);
                }

                if (foundType == null)
                {
                    if (_logger.IsVerbose)
                    {
                        _logger.Writer.WriteLine($"Ibc TypeToken {ibcToken:x} has type token which resolves to a nil token");
                    }
                    return(Cor.Macros.RidToToken(0, CorTokenType.mdtTypeDef)); // Nil TypeDef token
                }

                return((uint)externalModule.MetadataReader.GetToken(foundType.Handle));
            }
            else
            {
                TypeDefinition         nestedClassDefinition = externalModule.MetadataReader.GetTypeDefinition(enclosingType);
                MetadataStringComparer stringComparer        = externalModule.MetadataReader.StringComparer;
                foreach (TypeDefinitionHandle tdNested in nestedClassDefinition.GetNestedTypes())
                {
                    TypeDefinition candidateClassDefinition = externalModule.MetadataReader.GetTypeDefinition(tdNested);
                    if (stringComparer.Equals(candidateClassDefinition.Name, typeName))
                    {
                        return((uint)externalModule.MetadataReader.GetToken(tdNested));
                    }
                }

                if (_logger.IsVerbose)
                {
                    _logger.Writer.WriteLine($"Ibc TypeToken {ibcToken:x} unable to find nested type '{typeName}' on type '{externalModule.MetadataReader.GetToken(enclosingType):x}'");
                }
                return(Cor.Macros.RidToToken(0, CorTokenType.mdtTypeDef)); // Nil TypeDef token
            }
        }
예제 #11
0
        public TypeDesc ResolveTypeHandle(long handle, bool throwIfNotFound = true)
        {
            lock(_lock)
            {
                TypeHandleInfo tinfo;
                if (_types.TryGetValue(handle, out tinfo))
                {
                    if (tinfo.Type != null)
                        return tinfo.Type;

                    if ((tinfo.TypeValue.Flags & Microsoft.Diagnostics.Tracing.Parsers.Clr.TypeFlags.Array) != 0)
                    {
                        if (tinfo.TypeValue.TypeParameters.Length != 1)
                        {
                            throw new Exception("Bad format for BulkType");
                        }

                        TypeDesc elementType = ResolveTypeHandle((long)tinfo.TypeValue.TypeParameters[0], throwIfNotFound);
                        if (elementType == null)
                            return null;

                        if (tinfo.TypeValue.CorElementType == (byte)SignatureTypeCode.SZArray)
                        {
                            tinfo.Type = elementType.MakeArrayType();
                        }
                        else
                        {
                            int rank = tinfo.TypeValue.Flags.GetArrayRank();
                            tinfo.Type = elementType.MakeArrayType(rank);
                        }
                    }
                    else if (tinfo.TypeValue.CorElementType == (byte)SignatureTypeCode.ByReference)
                    {
                        if (tinfo.TypeValue.TypeParameters.Length != 1)
                        {
                            throw new Exception("Bad format for BulkType");
                        }

                        TypeDesc elementType = ResolveTypeHandle((long)tinfo.TypeValue.TypeParameters[0], throwIfNotFound);
                        if (elementType == null)
                            return null;

                        tinfo.Type = elementType.MakeByRefType();
                    }
                    else if (tinfo.TypeValue.CorElementType == (byte)SignatureTypeCode.Pointer)
                    {
                        if (tinfo.TypeValue.TypeParameters.Length != 1)
                        {
                            throw new Exception("Bad format for BulkType");
                        }

                        TypeDesc elementType = ResolveTypeHandle((long)tinfo.TypeValue.TypeParameters[0], throwIfNotFound);
                        if (elementType == null)
                            return null;

                        tinfo.Type = elementType.MakePointerType();
                    }
                    else if (tinfo.TypeValue.CorElementType == (byte)SignatureTypeCode.FunctionPointer)
                    {
                        tinfo.Type = null;
                    }
                    else
                    {
                        // Must be class type or instantiated type.
                        ModuleDesc module = ResolveModuleID((long)tinfo.TypeValue.ModuleID, throwIfNotFound);
                        if (module == null)
                            return null;

                        EcmaModule ecmaModule = module as EcmaModule;
                        if (ecmaModule == null)
                        {
                            if (throwIfNotFound)
                                throw new Exception($"Unable to resolve module for {handle:8x}");
                            return null;
                        }

                        if ((tinfo.TypeValue.TypeNameID & 0xFF000000) != 0x02000000)
                        {
                            throw new Exception($"Invalid typedef {tinfo.TypeValue.TypeNameID:4x}");
                        }

                        TypeDefinitionHandle typedef = MetadataTokens.TypeDefinitionHandle(tinfo.TypeValue.TypeNameID & 0xFFFFFF);
                        MetadataType uninstantiatedType = (MetadataType)ecmaModule.GetType(typedef);
                        // Instantiate the type if requested
                        if ((tinfo.TypeValue.TypeParameters.Length != 0) && uninstantiatedType != null)
                        {
                            if (uninstantiatedType.Instantiation.Length != tinfo.TypeValue.TypeParameters.Length)
                            {
                                throw new Exception($"Invalid TypeParameterCount {tinfo.TypeValue.TypeParameters.Length} expected {uninstantiatedType.Instantiation.Length} as needed by '{uninstantiatedType}'");
                            }

                            TypeDesc[] instantiation = new TypeDesc[tinfo.TypeValue.TypeParameters.Length];
                            for (int i = 0; i < instantiation.Length; i++)
                            {
                                instantiation[i] = ResolveTypeHandle((long)tinfo.TypeValue.TypeParameters[i], throwIfNotFound);
                                if (instantiation[i] == null)
                                    return null;
                            }
                            tinfo.Type = uninstantiatedType.Context.GetInstantiatedType(uninstantiatedType, new Instantiation(instantiation));
                        }
                        else
                        {
                            if ((uninstantiatedType.Name == "__Canon") && uninstantiatedType.Namespace == "System" && (uninstantiatedType.Module == uninstantiatedType.Context.SystemModule))
                            {
                                tinfo.Type = uninstantiatedType.Context.CanonType;
                            }
                            else
                            {
                                tinfo.Type = uninstantiatedType;
                            }
                        }
                    }
                    if (tinfo.Type == null)
                    {
                        if (throwIfNotFound)
                            throw new Exception("Unknown typeHandle value");
                        return null;
                    }
                    return tinfo.Type;
                }
                else
                {
                    if (throwIfNotFound)
                        throw new Exception("Unknown typeHandle value");
                    return null;
                }
            }
        }
예제 #12
0
 public override RuntimeInterfacesAlgorithm GetRuntimeInterfacesAlgorithmForNonPointerArrayType(ArrayType type)
 {
     if (_arrayOfTRuntimeInterfacesAlgorithm == null)
     {
         _arrayOfTRuntimeInterfacesAlgorithm = new ArrayOfTRuntimeInterfacesAlgorithm(_systemModule.GetType("System", "Array`1"));
     }
     return(_arrayOfTRuntimeInterfacesAlgorithm);
 }
예제 #13
0
        public void TestExplicitLayout()
        {
            MetadataType t = _testModule.GetType("Explicit", "Class1");

            // With 64bit, there should be 8 bytes for the System.Object EE data pointer +
            // 10 bytes up until the offset of the char field + the char size of 2 + we
            // round up the whole instance size to the next pointer size (+4) = 24
            Assert.Equal(24, t.InstanceByteCount);

            foreach (var field in t.GetFields())
            {
                if (field.IsStatic)
                {
                    continue;
                }

                if (field.Name == "Bar")
                {
                    // Bar has explicit offset 4 and is in a class (with S.O size overhead of <pointer size>)
                    // Therefore it should have offset 4 + 8 = 12
                    Assert.Equal(12, field.Offset);
                }
                else if (field.Name == "Baz")
                {
                    // Baz has explicit offset 10. 10 + 8 = 18
                    Assert.Equal(18, field.Offset);
                }
                else
                {
                    Assert.True(false);
                }
            }
        }
예제 #14
0
        public void TestSingleDimensionalArrays()
        {
            MetadataType systemArrayType    = _context.GetWellKnownType(WellKnownType.Array);
            MetadataType systemIListOfTType = _testModule.GetType("System.Collections.Generic", "IList`1");

            TypeDesc objectType = _context.GetWellKnownType(WellKnownType.Object);

            ArrayType objectArray = (ArrayType)_context.GetArrayType(objectType);

            // The set of interfaces on an array shall start with the same set that exists on System.Array
            for (int i = 0; i < systemArrayType.RuntimeInterfaces.Length; i++)
            {
                Assert.Equal(systemArrayType.RuntimeInterfaces[i], objectArray.RuntimeInterfaces[i]);
            }

            // The set of interfaces on an array of type T shall include IList<T>
            TypeDesc ilistOfObject = _context.GetInstantiatedType(systemIListOfTType, new Instantiation(new TypeDesc[] { objectType }));

            Assert.Contains(ilistOfObject, objectArray.RuntimeInterfaces);
        }