public bool IsBlocked(MetadataType typeDef)
        {
            if (typeDef.Name == "ICastable")
                return true;

            return false;
        }
示例#2
0
        public void TestFunctionPointerSignatures()
        {
            var ilModule = _context.GetModuleForSimpleName("ILMetadataAssembly");

            Cts.MetadataType typeWithFunctionPointers = ilModule.GetType("SampleMetadata", "TypeWithFunctionPointers");

            var policy          = new SingleFileMetadataPolicy();
            var transformResult = MetadataTransform.Run(policy,
                                                        new[] { _systemModule, ilModule });

            var typeWithFunctionPointersType = transformResult.GetTransformedTypeDefinition(typeWithFunctionPointers);
            var objectType = transformResult.GetTransformedTypeDefinition((Cts.MetadataType)_context.GetWellKnownType(Cts.WellKnownType.Object));

            Assert.Equal(1, typeWithFunctionPointersType.Fields.Count);

            var theField = typeWithFunctionPointersType.Fields[0];

            Assert.IsType <TypeSpecification>(theField.Signature.Type);
            var theFieldSignature = (TypeSpecification)theField.Signature.Type;

            Assert.IsType <FunctionPointerSignature>(theFieldSignature.Signature);
            var theFieldPointerSignature = (FunctionPointerSignature)theFieldSignature.Signature;

            Assert.Equal(objectType, theFieldPointerSignature.Signature.ReturnType);
            Assert.Equal(1, theFieldPointerSignature.Signature.Parameters.Count);
            Assert.Equal(objectType, theFieldPointerSignature.Signature.Parameters[0]);
        }
示例#3
0
        public void TestExplicitScopeAttributesForWinRTSingleFilePolicy()
        {
            // Test that custom attributes referring to blocked types don't show up in metadata

            var sampleMetadataModule       = _context.GetModuleForSimpleName("SampleMetadataAssembly");
            var sampleWinRTMetadataModule  = _context.GetModuleForSimpleName("SampleWinRTMetadataAssembly");
            var windowsWinRTMetadataModule = _context.GetModuleForSimpleName("WindowsWinRTMetadataAssembly");

            Cts.MetadataType controlType        = windowsWinRTMetadataModule.GetType("Windows", "Control");
            Cts.MetadataType derivedFromControl = sampleWinRTMetadataModule.GetType("SampleMetadataWinRT", "DerivedFromControl");
            Cts.MetadataType derivedFromControlInCustomScope = sampleWinRTMetadataModule.GetType("SampleMetadataWinRT", "DerivedFromControlAndInCustomScope");

            var policy = new SingleFileMetadataPolicy();

            var transformResult = MetadataTransform.Run(policy,
                                                        new[] { _systemModule, sampleMetadataModule, sampleWinRTMetadataModule, windowsWinRTMetadataModule });

            var controlTypeMetadata        = transformResult.GetTransformedTypeDefinition(controlType);
            var derivedFromControlMetadata = transformResult.GetTransformedTypeDefinition(derivedFromControl);
            var derivedFromControlInCustomScopeMetadata = transformResult.GetTransformedTypeDefinition(derivedFromControlInCustomScope);

            CheckTypeDefinitionForProperWinRTHome(controlTypeMetadata, "Windows");
            ScopeDefinition scopeDefOfDerivedFromControlType = GetScopeDefinitionOfType(derivedFromControlMetadata);

            Assert.Equal("SampleWinRTMetadataAssembly", scopeDefOfDerivedFromControlType.Name.Value);
            CheckTypeDefinitionForProperWinRTHome(derivedFromControlInCustomScopeMetadata, "SampleMetadataWinRT");
        }
        public bool IsBlocked(MetadataType typeDef)
        {
            if (typeDef.Name == "ICastable")
                return true;

            if (typeDef.HasCustomAttribute("System.Runtime.CompilerServices", "__BlockReflectionAttribute"))
                return true;

            return false;
        }
        public Cts.ModuleDesc GetModuleOfType(Cts.MetadataType typeDef)
        {
            Cts.ModuleDesc overrideModule = OverrideModuleOfTypeViaExplicitScope(typeDef);
            if (overrideModule != null)
            {
                return(overrideModule);
            }

            return(typeDef.Module);
        }
示例#6
0
        public NonGCStaticsNode(MetadataType type)
        {
            _type = type;

            if (HasClassConstructorContext)
            {
                _classConstructorContext = new ObjectAndOffsetSymbolNode(this, 0,
                    "__CCtorContext_" + NodeFactory.NameMangler.GetMangledTypeName(_type));
            }
        }
        public VirtualMethodEnumerationAlgorithmTests()
        {
            _context = new TestTypeSystemContext(TargetArchitecture.Unknown);
            var systemModule = _context.CreateModuleForSimpleName("CoreTestAssembly");
            _context.SetSystemModule(systemModule);

            _testModule = systemModule;

            _testType = _testModule.GetType("VirtualFunctionOverride", "SimpleGeneric`1")
                .MakeInstantiatedType(_context.GetWellKnownType(WellKnownType.Object));
        }
        public VirtualFunctionOverrideTests()
        {
            _context = new TestTypeSystemContext(TargetArchitecture.X64);
            var systemModule = _context.CreateModuleForSimpleName("CoreTestAssembly");
            _context.SetSystemModule(systemModule);

            _testModule = systemModule;

            _stringType = _context.GetWellKnownType(WellKnownType.String);
            _voidType = _context.GetWellKnownType(WellKnownType.Void);
        }
示例#9
0
        public NonGCStaticsNode(MetadataType type, NodeFactory factory)
        {
            _type = type;

            if (factory.TypeInitializationManager.HasLazyStaticConstructor(type))
            {
                // Class constructor context is a small struct prepended to type's non-GC static data region
                // that keeps track of whether the .cctor executed and holds the pointer to the .cctor method.
                _classConstructorContext = new ObjectAndOffsetSymbolNode(this, 0,
                    "__CCtorContext_" + NodeFactory.NameMangler.GetMangledTypeName(_type));
            }
        }
示例#10
0
        public ModuleDesc GetModuleOfType(MetadataType typeDef)
        {
            if (_explicitScopePolicyMixin == null)
            {
                lock (s_lazyInitThreadSafetyLock)
                {
                    if (_explicitScopePolicyMixin == null)
                        _explicitScopePolicyMixin = new ExplicitScopeAssemblyPolicyMixin();
                }
            }

            return _explicitScopePolicyMixin.GetModuleOfType(typeDef);
        }
示例#11
0
        private void InitializeTypeRef(Cts.MetadataType entity, TypeReference record)
        {
            if (entity.ContainingType != null)
            {
                record.ParentNamespaceOrType = HandleType(entity.ContainingType);
            }
            else
            {
                record.ParentNamespaceOrType = HandleNamespaceDefinition(entity.Module, entity.Namespace);
            }

            record.TypeName = HandleString(entity.Name);
        }
        /// <summary>
        /// Attempts to retrieve a <see cref="TypeReference"/> record corresponding to the specified
        /// <paramref name="type"/>. Returns null if not found.
        /// </summary>
        public TypeReference GetTransformedTypeReference(Cts.MetadataType type)
        {
            Debug.Assert(type.IsTypeDefinition);

            MetadataRecord rec;

            if (!_transform._types.TryGet(type, out rec))
            {
                return(null);
            }

            return(rec as TypeReference);
        }
示例#13
0
        internal EcmaType(EcmaModule module, TypeDefinitionHandle handle)
        {
            _module = module;
            _handle = handle;

            _typeDefinition = module.MetadataReader.GetTypeDefinition(handle);

            _baseType = this; // Not yet initialized flag

#if DEBUG
            // Initialize name eagerly in debug builds for convenience
            this.ToString();
#endif
        }
示例#14
0
        public CanonicalizationTests()
        {
            _context = new TestTypeSystemContext(TargetArchitecture.Unknown);
            var systemModule = _context.CreateModuleForSimpleName("CoreTestAssembly");
            _context.SetSystemModule(systemModule);

            _testModule = systemModule;

            _referenceType = _testModule.GetType("Canonicalization", "ReferenceType");
            _otherReferenceType = _testModule.GetType("Canonicalization", "OtherReferenceType");
            _structType = _testModule.GetType("Canonicalization", "StructType");
            _otherStructType = _testModule.GetType("Canonicalization", "OtherStructType");
            _genericReferenceType = _testModule.GetType("Canonicalization", "GenericReferenceType`1");
            _genericStructType = _testModule.GetType("Canonicalization", "GenericStructType`1");
        }
示例#15
0
        internal NativeFormatType(NativeFormatMetadataUnit metadataUnit, TypeDefinitionHandle handle)
        {
            _handle = handle;
            _metadataUnit = metadataUnit;

            _typeDefinition = metadataUnit.MetadataReader.GetTypeDefinition(handle);
            _module = metadataUnit.GetModuleFromNamespaceDefinition(_typeDefinition.NamespaceDefinition);

            _baseType = this; // Not yet initialized flag

#if DEBUG
            // Initialize name eagerly in debug builds for convenience
            this.ToString();
#endif
        }
示例#16
0
        private void InitializeTypeRef(Cts.MetadataType entity, TypeReference record)
        {
            Debug.Assert(entity.IsTypeDefinition);

            if (entity.ContainingType != null)
            {
                record.ParentNamespaceOrType = GetNestedReferenceParent(entity);
            }
            else
            {
                record.ParentNamespaceOrType = HandleNamespaceReference(entity.Module, entity.Namespace);
            }

            record.TypeName = HandleString(entity.Name);
        }
示例#17
0
        public void TestMethodImplMetadata()
        {
            // Test that custom attributes referring to blocked types don't show up in metadata

            var sampleMetadataModule = _context.GetModuleForSimpleName("SampleMetadataAssembly");

            Cts.MetadataType iCloneable                      = sampleMetadataModule.GetType("SampleMetadataMethodImpl", "ICloneable");
            Cts.MetadataType implementsICloneable            = sampleMetadataModule.GetType("SampleMetadataMethodImpl", "ImplementsICloneable");
            Cts.MethodDesc   iCloneableDotClone              = iCloneable.GetMethod("Clone", null);
            Cts.MethodDesc   iCloneableImplementation        = implementsICloneable.GetMethod("SampleMetadataMethodImpl.ICloneable.Clone", null);
            Cts.MethodDesc   iCloneableDotGenericClone       = iCloneable.GetMethod("GenericClone", null);
            Cts.MethodDesc   iCloneableGenericImplementation = implementsICloneable.GetMethod("SampleMetadataMethodImpl.ICloneable.GenericClone", null);

            var policy          = new SingleFileMetadataPolicy();
            var transformResult = MetadataTransform.Run(policy,
                                                        new[] { _systemModule, sampleMetadataModule });

            var iCloneableType           = transformResult.GetTransformedTypeDefinition(iCloneable);
            var implementsICloneableType = transformResult.GetTransformedTypeDefinition(implementsICloneable);

            Assert.Equal(2, implementsICloneableType.MethodImpls.Count);

            // non-generic MethodImpl
            Method          iCloneableDotCloneMethod       = transformResult.GetTransformedMethodDefinition(iCloneableDotClone);
            Method          iCloneableImplementationMethod = transformResult.GetTransformedMethodDefinition(iCloneableImplementation);
            QualifiedMethod methodImplMethodDecl           = (QualifiedMethod)implementsICloneableType.MethodImpls[0].MethodDeclaration;
            QualifiedMethod methodImplMethodBody           = (QualifiedMethod)implementsICloneableType.MethodImpls[0].MethodBody;

            Assert.Equal(iCloneableDotCloneMethod, methodImplMethodDecl.Method);
            Assert.Equal(iCloneableType, methodImplMethodDecl.EnclosingType);

            Assert.Equal(iCloneableImplementationMethod, methodImplMethodBody.Method);
            Assert.Equal(implementsICloneableType, methodImplMethodBody.EnclosingType);

            // generic MethodImpl
            Method          iCloneableDotGenericCloneMethod       = transformResult.GetTransformedMethodDefinition(iCloneableDotGenericClone);
            Method          iCloneableGenericImplementationMethod = transformResult.GetTransformedMethodDefinition(iCloneableGenericImplementation);
            QualifiedMethod methodImplGenericMethodDecl           = (QualifiedMethod)implementsICloneableType.MethodImpls[1].MethodDeclaration;
            QualifiedMethod methodImplGenericMethodBody           = (QualifiedMethod)implementsICloneableType.MethodImpls[1].MethodBody;

            Assert.Equal(iCloneableDotGenericCloneMethod, methodImplGenericMethodDecl.Method);
            Assert.Equal(iCloneableType, methodImplGenericMethodDecl.EnclosingType);

            Assert.Equal(iCloneableGenericImplementationMethod, methodImplGenericMethodBody.Method);
            Assert.Equal(implementsICloneableType, methodImplGenericMethodBody.EnclosingType);
        }
        private Cts.ModuleDesc OverrideModuleOfTypeViaExplicitScope(Cts.MetadataType typeDef)
        {
            if (typeDef.HasCustomAttribute("Internal.Reflection", "ExplicitScopeAttribute"))
            {
                // There is no current cross type system way to represent custom attributes
                Cts.Ecma.EcmaType ecmaType = (Cts.Ecma.EcmaType)typeDef;

                var customAttributeValue = Internal.TypeSystem.Ecma.MetadataExtensions.GetDecodedCustomAttribute(
                    ecmaType, "Internal.Reflection", "ExplicitScopeAttribute");

                if (!customAttributeValue.HasValue)
                {
                    return(null);
                }

                if (customAttributeValue.Value.FixedArguments.Length != 1)
                {
                    return(null);
                }

                if (customAttributeValue.Value.FixedArguments[0].Type != typeDef.Context.GetWellKnownType(Cts.WellKnownType.String))
                {
                    return(null);
                }

                string       assemblyNameString = (string)customAttributeValue.Value.FixedArguments[0].Value;
                AssemblyName assemblyName       = new AssemblyName(assemblyNameString);
                Debug.Assert(typeDef.Context.ResolveAssembly(assemblyName, false) == null, "ExplicitScopeAttribute must not refer to an assembly which is actually present in the type system.");
                lock (_dynamicallyGeneratedExplicitScopes)
                {
                    ExplicitScopeAssembly explicitScopeAssembly;

                    if (_dynamicallyGeneratedExplicitScopes.TryGetValue(assemblyName, out explicitScopeAssembly))
                    {
                        return(explicitScopeAssembly);
                    }
                    explicitScopeAssembly = new ExplicitScopeAssembly(typeDef.Context, assemblyName);
                    _dynamicallyGeneratedExplicitScopes.Add(assemblyName, explicitScopeAssembly);
                    return(explicitScopeAssembly);
                }
            }

            return(null);
        }
        /// <summary>
        /// Metadata based computation of interfaces.
        /// </summary>
        private DefType[] ComputeRuntimeInterfacesForNonInstantiatedMetadataType(MetadataType type)
        {
            DefType[] explicitInterfaces = type.ExplicitlyImplementedInterfaces;
            DefType[] baseTypeInterfaces = (type.BaseType != null) ? (type.BaseType.RuntimeInterfaces) : Array.Empty<DefType>();

            // Optimized case for no interfaces newly defined.
            if (explicitInterfaces.Length == 0)
                return baseTypeInterfaces;

            ArrayBuilder<DefType> interfacesArray = new ArrayBuilder<DefType>();
            interfacesArray.Append(baseTypeInterfaces);

            foreach (DefType iface in explicitInterfaces)
            {
                BuildPostOrderInterfaceList(iface, ref interfacesArray);
            }

            return interfacesArray.ToArray();
        }
示例#20
0
        private TypeAttributes GetTypeAttributes(Cts.MetadataType type)
        {
            TypeAttributes result;

            var ecmaType = type as Cts.Ecma.EcmaType;

            if (ecmaType != null)
            {
                Ecma.TypeDefinition ecmaRecord = ecmaType.MetadataReader.GetTypeDefinition(ecmaType.Handle);
                result = ecmaRecord.Attributes;
            }
            else
            {
                result = 0;

                if (type.IsExplicitLayout)
                {
                    result |= TypeAttributes.ExplicitLayout;
                }
                if (type.IsSequentialLayout)
                {
                    result |= TypeAttributes.SequentialLayout;
                }
                if (type.IsInterface)
                {
                    result |= TypeAttributes.Interface;
                }
                if (type.IsSealed)
                {
                    result |= TypeAttributes.Sealed;
                }
                if (type.IsBeforeFieldInit)
                {
                    result |= TypeAttributes.BeforeFieldInit;
                }

                // Not set: Abstract, Ansi/Unicode/Auto, HasSecurity, Import, visibility, Serializable,
                //          WindowsRuntime, HasSecurity, SpecialName, RTSpecialName
            }

            return(result);
        }
示例#21
0
        public void TestBlockedInterface()
        {
            // BlockedObject implements IBlockedInterface, which is a metadata blocked type and should not show
            // up in the BlockedObject interface list.

            var policy          = new SingleFileMetadataPolicy();
            var transformResult = MetadataTransform.Run(policy, new[] { _systemModule });

            Cts.MetadataType iblockedinterface = _systemModule.GetType("System.Private.CompilerServices", "IBlockedInterface");
            Cts.MetadataType comObject         = _systemModule.GetType("System", "BlockedObject");
            Assert.Equal(1, comObject.ExplicitlyImplementedInterfaces.Length);
            Assert.Equal(iblockedinterface, comObject.ExplicitlyImplementedInterfaces[0]);

            Assert.Null(transformResult.GetTransformedTypeDefinition(iblockedinterface));
            Assert.Null(transformResult.GetTransformedTypeReference(iblockedinterface));

            TypeDefinition comObjectRecord = transformResult.GetTransformedTypeDefinition(comObject);

            Assert.NotNull(comObjectRecord);
            Assert.Equal(comObject.Name, comObjectRecord.Name.Value);
            Assert.Equal(0, comObjectRecord.Interfaces.Count);
        }
示例#22
0
        private TypeReference GetNestedReferenceParent(Cts.MetadataType entity)
        {
            // This special code deals with the metadata format requirement saying that
            // nested type *references* need to have a type *reference* as their containing type.
            // This is potentially in conflict with our other rule that says to always resolve
            // references to their definition records (we are avoiding emitting references
            // to things that have a definition within the same blob to save space).

            Cts.MetadataType containingType        = (Cts.MetadataType)entity.ContainingType;
            MetadataRecord   parentRecord          = HandleType(containingType);
            TypeReference    parentReferenceRecord = parentRecord as TypeReference;

            if (parentReferenceRecord != null)
            {
                // Easy case - parent type doesn't have a definition record.
                return(parentReferenceRecord);
            }

            // Parent has a type definition record. We need to make a new record that's a reference.
            // We don't bother with interning these because this will be rare and metadata writer
            // will do the interning anyway.
            Debug.Assert(parentRecord is TypeDefinition);

            parentReferenceRecord = new TypeReference
            {
                TypeName = HandleString(containingType.Name),
            };

            if (containingType.ContainingType != null)
            {
                parentReferenceRecord.ParentNamespaceOrType = GetNestedReferenceParent(containingType);
            }
            else
            {
                parentReferenceRecord.ParentNamespaceOrType = HandleNamespaceReference(containingType.Module, containingType.Namespace);
            }

            return(parentReferenceRecord);
        }
示例#23
0
        public TypeNameParsingTests()
        {
            _context = new TestTypeSystemContext(TargetArchitecture.X64);

            // TODO-NICE: split test types into a separate, non-core, module
            _testModule = _context.CreateModuleForSimpleName("CoreTestAssembly");
            _context.SetSystemModule(_testModule);

            _simpleType = _testModule.GetType("TypeNameParsing", "Simple");
            _nestedType = _simpleType.GetNestedType("Nested");
            _nestedTwiceType = _nestedType.GetNestedType("NestedTwice");

            _genericType = _testModule.GetType("TypeNameParsing", "Generic`1");
            _nestedGenericType = _genericType.GetNestedType("NestedGeneric`1");
            _nestedNongenericType = _genericType.GetNestedType("NestedNongeneric");

            _veryGenericType = _testModule.GetType("TypeNameParsing", "VeryGeneric`3");

            _structType = _testModule.GetType("TypeNameParsing", "Struct");

            _coreAssemblyQualifier = ((IAssemblyDesc)_testModule).GetName().FullName;
        }
示例#24
0
        public void TestNestedTypeReference()
        {
            // A type reference nested under a type that has a definition record. The transform is required
            // to create a type reference for the containing type because a type *definition* can't be a parent
            // to a type *reference*.

            var sampleMetadataModule = _context.GetModuleForSimpleName("SampleMetadataAssembly");

            Cts.MetadataType genericOutside = sampleMetadataModule.GetType("SampleMetadata", "GenericOutside`1");
            Cts.MetadataType inside         = genericOutside.GetNestedType("Inside");

            {
                MockPolicy policy = new MockPolicy(
                    type =>
                {
                    return(type == genericOutside);
                });

                var result = MetadataTransform.Run(policy, new[] { sampleMetadataModule });

                Assert.Equal(1, result.Scopes.Count);
                Assert.Equal(1, result.Scopes.Single().GetAllTypes().Count());

                var genericOutsideDefRecord = result.GetTransformedTypeDefinition(genericOutside);
                Assert.NotNull(genericOutsideDefRecord);

                Assert.Null(result.GetTransformedTypeReference(inside));

                var insideRecord = result.Transform.HandleType(inside);
                Assert.IsType <TypeReference>(insideRecord);

                var genericOutsideRefRecord = ((TypeReference)insideRecord).ParentNamespaceOrType as TypeReference;
                Assert.NotNull(genericOutsideRefRecord);
                Assert.Equal(genericOutside.Name, genericOutsideRefRecord.TypeName.Value);

                Assert.Same(genericOutsideDefRecord, result.GetTransformedTypeDefinition(genericOutside));
            }
        }
示例#25
0
        public void TestBlockedAttributes()
        {
            // Test that custom attributes referring to blocked types don't show up in metadata

            var sampleMetadataModule = _context.GetModuleForSimpleName("SampleMetadataAssembly");

            Cts.MetadataType attributeHolder = sampleMetadataModule.GetType("BlockedMetadata", "AttributeHolder");

            var policy          = new SingleFileMetadataPolicy();
            var transformResult = MetadataTransform.Run(policy,
                                                        new[] { _systemModule, sampleMetadataModule });

            int blockedCount = 0;
            int allowedCount = 0;

            foreach (var field in attributeHolder.GetFields())
            {
                var transformedRecord = transformResult.GetTransformedFieldDefinition(field);
                Assert.NotNull(transformedRecord);

                if (field.Name.StartsWith("Blocked"))
                {
                    blockedCount++;
                    Assert.Equal(0, transformedRecord.CustomAttributes.Count);
                }
                else
                {
                    allowedCount++;
                    Assert.StartsWith("Allowed", field.Name);
                    Assert.Equal(1, transformedRecord.CustomAttributes.Count);
                }
            }

            Assert.Equal(5, allowedCount);
            Assert.Equal(8, blockedCount);
        }
示例#26
0
 public ThreadStaticsNode(MetadataType type, NodeFactory factory)
 {
     _type = type;
 }
示例#27
0
 public override RuntimeInterfacesAlgorithm GetRuntimeInterfacesAlgorithmForMetadataType(MetadataType type)
 {
     throw new NotImplementedException();
 }
示例#28
0
 public override RuntimeInterfacesAlgorithm GetRuntimeInterfacesAlgorithmForMetadataType(MetadataType type)
 {
     return _metadataRuntimeInterfacesAlgorithm;
 }
示例#29
0
 public ModuleDesc GetModuleOfType(MetadataType typeDef)
 {
     return _explicitScopePolicyMixin.GetModuleOfType(typeDef);
 }
示例#30
0
        private void InitializeTypeDef(Cts.MetadataType entity, TypeDefinition record)
        {
            Debug.Assert(entity.IsTypeDefinition);

            Cts.MetadataType containingType = (Cts.MetadataType)entity.ContainingType;
            if (containingType != null)
            {
                var enclosingType = (TypeDefinition)HandleType(containingType);
                record.EnclosingType = enclosingType;
                enclosingType.NestedTypes.Add(record);

                var namespaceDefinition =
                    HandleNamespaceDefinition(containingType.Module, entity.ContainingType.Namespace);
                record.NamespaceDefinition = namespaceDefinition;
            }
            else
            {
                var namespaceDefinition = HandleNamespaceDefinition(entity.Module, entity.Namespace);
                record.NamespaceDefinition = namespaceDefinition;

                if (entity.IsModuleType)
                {
                    // These don't get added to the global namespace.
                    // Instead, they have a dedicated field on the scope record.
                }
                else
                {
                    namespaceDefinition.TypeDefinitions.Add(record);
                }
            }

            record.Name = HandleString(entity.Name);

            Cts.ClassLayoutMetadata layoutMetadata = entity.GetClassLayout();
            record.Size        = checked ((uint)layoutMetadata.Size);
            record.PackingSize = checked ((ushort)layoutMetadata.PackingSize);
            record.Flags       = GetTypeAttributes(entity);

            try
            {
                if (entity.HasBaseType)
                {
                    record.BaseType = HandleType(entity.BaseType);
                }
            }
            catch (Cts.TypeSystemException) when(HasNestedTypes(entity))
            {
                // We might have been forced to generate metadata for a type
                // that wasn't looked at during code generation because it's an owning
                // type of a type we did look at. Allow those to generate incomplete
                // metadata. The ultimate fix is to rewrite metadata generation to be
                // System.Reflection.Metadata-based as opposed to type system based.
                // If there's no nested types, this is a bug and should tear down
                // the compiler at this point.
            }

            try
            {
                record.Interfaces.Capacity = entity.ExplicitlyImplementedInterfaces.Length;
                foreach (var interfaceType in entity.ExplicitlyImplementedInterfaces)
                {
                    if (IsBlocked(interfaceType))
                    {
                        continue;
                    }
                    record.Interfaces.Add(HandleType(interfaceType));
                }
            }
            catch (Cts.TypeSystemException) when(HasNestedTypes(entity))
            {
                // We might have been forced to generate metadata for a type
                // that wasn't looked at during code generation because it's an owning
                // type of a type we did look at. Allow those to generate incomplete
                // metadata. The ultimate fix is to rewrite metadata generation to be
                // System.Reflection.Metadata-based as opposed to type system based.
                // If there's no nested types, this is a bug and should tear down
                // the compiler at this point.
            }

            if (entity.HasInstantiation)
            {
                record.GenericParameters.Capacity = entity.Instantiation.Length;
                foreach (var p in entity.Instantiation)
                {
                    record.GenericParameters.Add(HandleGenericParameter((Cts.GenericParameterDesc)p));
                }
            }

            foreach (var field in entity.GetFields())
            {
                if (_policy.GeneratesMetadata(field))
                {
                    record.Fields.Add(HandleFieldDefinition(field));
                }
            }

            foreach (var method in entity.GetMethods())
            {
                if (_policy.GeneratesMetadata(method))
                {
                    record.Methods.Add(HandleMethodDefinition(method));
                }
            }

            var ecmaEntity = entity as Cts.Ecma.EcmaType;

            if (ecmaEntity != null)
            {
                Ecma.TypeDefinition ecmaRecord = ecmaEntity.MetadataReader.GetTypeDefinition(ecmaEntity.Handle);

                foreach (var e in ecmaRecord.GetEvents())
                {
                    Event evt = HandleEvent(ecmaEntity.EcmaModule, e);
                    if (evt != null)
                    {
                        record.Events.Add(evt);
                    }
                }

                foreach (var property in ecmaRecord.GetProperties())
                {
                    Property prop = HandleProperty(ecmaEntity.EcmaModule, property);
                    if (prop != null)
                    {
                        record.Properties.Add(prop);
                    }
                }

                Ecma.CustomAttributeHandleCollection customAttributes = ecmaRecord.GetCustomAttributes();
                if (customAttributes.Count > 0)
                {
                    record.CustomAttributes = HandleCustomAttributes(ecmaEntity.EcmaModule, customAttributes);
                }

                /* COMPLETENESS
                 * foreach (var miHandle in ecmaRecord.GetMethodImplementations())
                 * {
                 *  Ecma.MetadataReader reader = ecmaEntity.EcmaModule.MetadataReader;
                 *
                 *  Ecma.MethodImplementation miDef = reader.GetMethodImplementation(miHandle);
                 *
                 *  Cts.MethodDesc methodBody = (Cts.MethodDesc)ecmaEntity.EcmaModule.GetObject(miDef.MethodBody);
                 *  if (_policy.IsBlocked(methodBody))
                 *      continue;
                 *
                 *  Cts.MethodDesc methodDecl = (Cts.MethodDesc)ecmaEntity.EcmaModule.GetObject(miDef.MethodDeclaration);
                 *  if (_policy.IsBlocked(methodDecl.GetTypicalMethodDefinition()))
                 *      continue;
                 *
                 *  MethodImpl methodImplRecord = new MethodImpl
                 *  {
                 *      MethodBody = HandleQualifiedMethod(methodBody),
                 *      MethodDeclaration = HandleQualifiedMethod(methodDecl)
                 *  };
                 *
                 *  record.MethodImpls.Add(methodImplRecord);
                 * }*/
            }
示例#31
0
        private MetadataType InitializeBaseType()
        {
            var baseTypeHandle = _typeDefinition.BaseType;
            if (baseTypeHandle.IsNil)
            {
                _baseType = null;
                return null;
            }

            var type = _module.GetType(baseTypeHandle) as MetadataType;
            if (type == null)
            {
                throw new BadImageFormatException();
            }
            _baseType = type;
            return type;
        }
示例#32
0
        public static MethodDesc ResolveVariantInterfaceMethodToVirtualMethodOnType(MethodDesc interfaceMethod, MetadataType currentType)
        {
            MetadataType interfaceType  = (MetadataType)interfaceMethod.OwningType;
            bool         foundInterface = IsInterfaceImplementedOnType(currentType, interfaceType);
            MethodDesc   implMethod;

            if (foundInterface)
            {
                implMethod = ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethod, currentType);
                if (implMethod != null)
                {
                    return(implMethod);
                }
            }

            foreach (TypeDesc iface in currentType.RuntimeInterfaces)
            {
                if (iface.HasSameTypeDefinition(interfaceType) && iface.CanCastTo(interfaceType))
                {
                    implMethod = iface.FindMethodOnTypeWithMatchingTypicalMethod(interfaceMethod);
                    Debug.Assert(implMethod != null);
                    implMethod = ResolveInterfaceMethodToVirtualMethodOnType(implMethod, currentType);
                    if (implMethod != null)
                    {
                        return(implMethod);
                    }
                }
            }

            return(null);
        }
示例#33
0
 static public InstantiatedType MakeInstantiatedType(this MetadataType typeDef, params TypeDesc[] genericParameters)
 {
     return(typeDef.Context.GetInstantiatedType(typeDef, new Instantiation(genericParameters)));
 }
示例#34
0
        // Perform a name/sig match for a virtual method across the specified types and all of the types parents.
        private static MethodDesc FindNameSigOverrideForInterfaceMethodRecursive(MethodDesc interfaceMethod, MetadataType currentType)
        {
            while (true)
            {
                if (currentType == null)
                {
                    return(null);
                }

                MethodDesc nameSigOverride = FindMatchingVirtualMethodOnTypeByNameAndSig(interfaceMethod, currentType,
                                                                                         reverseMethodSearch: true, /* When searching for a name sig match for an interface on parent types search in reverse order of declaration */
                                                                                         nameSigMatchMethodIsValidCandidate: null);

                if (nameSigOverride != null)
                {
                    return(FindSlotDefiningMethodForVirtualMethod(nameSigOverride));
                }

                currentType = currentType.MetadataBaseType;
            }
        }
示例#35
0
        // Helper routine used during implicit interface implementation discovery
        private static MethodDesc ResolveInterfaceMethodToVirtualMethodOnTypeRecursive(MethodDesc interfaceMethod, MetadataType currentType)
        {
            while (true)
            {
                if (currentType == null)
                {
                    return(null);
                }

                MetadataType interfaceType = (MetadataType)interfaceMethod.OwningType;

                if (!IsInterfaceImplementedOnType(currentType, interfaceType))
                {
                    // If the interface isn't implemented on this type at all, don't go searching
                    return(null);
                }

                MethodDesc currentTypeInterfaceResolution = ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethod, currentType);
                if (currentTypeInterfaceResolution != null)
                {
                    return(currentTypeInterfaceResolution);
                }

                currentType = currentType.MetadataBaseType;
            }
        }
 public CompilerGeneratedAssembly(TypeSystemContext context)
     : base(context, null)
 {
     _globalModuleType = new CompilerGeneratedType(this, "<Module>");
 }
示例#37
0
        private static DefaultInterfaceMethodResolution ResolveInterfaceMethodToDefaultImplementationOnType(MethodDesc interfaceMethod, MetadataType currentType, out MethodDesc impl)
        {
            TypeDesc     interfaceMethodOwningType = interfaceMethod.OwningType;
            MetadataType mostSpecificInterface     = null;
            bool         diamondCase = false;

            impl = null;

            DefType[] consideredInterfaces;
            if (!currentType.IsInterface)
            {
                // If this is not an interface, only things on the interface list could provide
                // default implementations.
                consideredInterfaces = currentType.RuntimeInterfaces;
            }
            else
            {
                // If we're asking about an interface, include the interface in the list.
                consideredInterfaces = new DefType[currentType.RuntimeInterfaces.Length + 1];
                Array.Copy(currentType.RuntimeInterfaces, consideredInterfaces, currentType.RuntimeInterfaces.Length);
                consideredInterfaces[consideredInterfaces.Length - 1] = (DefType)currentType.InstantiateAsOpen();
            }

            foreach (MetadataType runtimeInterface in consideredInterfaces)
            {
                if (runtimeInterface == interfaceMethodOwningType)
                {
                    // Also consider the default interface method implementation on the interface itself
                    // if we don't have anything else yet
                    if (mostSpecificInterface == null && !interfaceMethod.IsAbstract)
                    {
                        mostSpecificInterface = runtimeInterface;
                        impl = interfaceMethod;
                    }
                }
                else if (Array.IndexOf(runtimeInterface.RuntimeInterfaces, interfaceMethodOwningType) != -1)
                {
                    // This interface might provide a default implementation
                    MethodImplRecord[] possibleImpls = runtimeInterface.FindMethodsImplWithMatchingDeclName(interfaceMethod.Name);
                    if (possibleImpls != null)
                    {
                        foreach (MethodImplRecord implRecord in possibleImpls)
                        {
                            if (implRecord.Decl == interfaceMethod)
                            {
                                // This interface provides a default implementation.
                                // Is it also most specific?
                                if (mostSpecificInterface == null || Array.IndexOf(runtimeInterface.RuntimeInterfaces, mostSpecificInterface) != -1)
                                {
                                    mostSpecificInterface = runtimeInterface;
                                    impl        = implRecord.Body;
                                    diamondCase = false;
                                }
                                else if (Array.IndexOf(mostSpecificInterface.RuntimeInterfaces, runtimeInterface) == -1)
                                {
                                    diamondCase = true;
                                }

                                break;
                            }
                        }
                    }
                }
            }

            if (diamondCase)
            {
                impl = null;
                return(DefaultInterfaceMethodResolution.Diamond);
            }
            else if (impl == null)
            {
                return(DefaultInterfaceMethodResolution.None);
            }
            else if (impl.IsAbstract)
            {
                return(DefaultInterfaceMethodResolution.Reabstraction);
            }

            return(DefaultInterfaceMethodResolution.DefaultImplementation);
        }
示例#38
0
 public static bool HasLayout(this MetadataType mdType)
 {
     return(mdType.IsSequentialLayout || mdType.IsExplicitLayout);
 }
示例#39
0
        //////////////////////// INTERFACE RESOLUTION
        //Interface function resolution
        //    Interface function resolution follows the following rules
        //    1.    Apply any method impl that may exist, if once of these exists, resolve to target immediately.
        //    2.    If an interface is explicitly defined on a type, then attempt to perform a namesig match on the
        //          current type to resolve.If the interface isn't resolved, if it isn't implemented on a base type,
        //          scan all base types for name / sig matches.
        //    3.    If implicitly defined, attempt to perform a namesig match if the interface method implementation
        //          has not been found on some base type.
        //    The above will resolve an interface to a virtual method slot. From there perform virtual resolution
        //    to find out the actual target.Note, to preserve correct behavior in the presence of variance, this
        //    function returns null if the interface method implementation is not defined by the current type in
        //    the hierarchy.For variance to work correctly, this requires that interfaces be queried in correct order.
        //    See current interface call resolution for details on how that happens.
        private static MethodDesc ResolveInterfaceMethodToVirtualMethodOnType(MethodDesc interfaceMethod, MetadataType currentType)
        {
            if (currentType.IsInterface)
            {
                return(null);
            }

            MethodDesc methodImpl = FindImplFromDeclFromMethodImpls(currentType, interfaceMethod);

            if (methodImpl != null)
            {
                return(methodImpl);
            }

            MetadataType interfaceType = (MetadataType)interfaceMethod.OwningType;

            // If interface is explicitly defined on a type, search for a name/sig match.
            bool         foundExplicitInterface = IsInterfaceExplicitlyImplementedOnType(currentType, interfaceType);
            MetadataType baseType = currentType.MetadataBaseType;

            if (foundExplicitInterface)
            {
                MethodDesc foundOnCurrentType = FindMatchingVirtualMethodOnTypeByNameAndSig(interfaceMethod, currentType,
                                                                                            reverseMethodSearch: false, /* When searching for name/sig overrides on a type that explicitly defines an interface, search through the type in the forward direction*/
                                                                                            nameSigMatchMethodIsValidCandidate: null);
                foundOnCurrentType = FindSlotDefiningMethodForVirtualMethod(foundOnCurrentType);

                if (baseType == null)
                {
                    return(foundOnCurrentType);
                }

                if (foundOnCurrentType == null && (ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethod, baseType) == null))
                {
                    // TODO! Does this handle the case where the base type explicitly implements the interface, but is abstract
                    // and doesn't actually have an implementation?
                    if (!IsInterfaceImplementedOnType(baseType, interfaceType))
                    {
                        return(FindNameSigOverrideForInterfaceMethodRecursive(interfaceMethod, baseType));
                    }
                }
                return(foundOnCurrentType);
            }
            else
            {
                // Implicit interface case
                if (!IsInterfaceImplementedOnType(currentType, interfaceType))
                {
                    // If the interface isn't implemented on this type at all, don't go searching
                    return(null);
                }

                // This is an implicitly implemented interface method. Only return a vlaue if this is the first type in the class
                // hierarchy that implements the interface. NOTE: If we pay attention to whether or not the parent type is
                // abstract or not, we may be able to be more efficient here, but let's skip that for now
                MethodDesc baseClassImplementationOfInterfaceMethod = ResolveInterfaceMethodToVirtualMethodOnTypeRecursive(interfaceMethod, baseType);
                if (baseClassImplementationOfInterfaceMethod != null)
                {
                    return(null);
                }
                else
                {
                    MethodDesc foundOnCurrentType = FindMatchingVirtualMethodOnTypeByNameAndSig(interfaceMethod, currentType,
                                                                                                reverseMethodSearch: false, /* When searching for name/sig overrides on a type that is the first type in the hierarchy to require the interface, search through the type in the forward direction*/
                                                                                                nameSigMatchMethodIsValidCandidate: null);

                    foundOnCurrentType = FindSlotDefiningMethodForVirtualMethod(foundOnCurrentType);

                    if (foundOnCurrentType != null)
                    {
                        return(foundOnCurrentType);
                    }

                    return(FindNameSigOverrideForInterfaceMethodRecursive(interfaceMethod, baseType));
                }
            }
        }
示例#40
0
 static public InstantiatedType MakeInstantiatedType(this MetadataType typeDef, Instantiation instantiation)
 {
     return(typeDef.Context.GetInstantiatedType(typeDef, instantiation));
 }
示例#41
0
 public GCStaticsNode(MetadataType type)
 {
     Debug.Assert(!type.IsCanonicalSubtype(CanonicalFormKind.Specific));
     _type = type;
 }
示例#42
0
 private static bool IsInterfaceExplicitlyImplementedOnType(MetadataType type, MetadataType interfaceType)
 {
     foreach (TypeDesc iface in type.ExplicitlyImplementedInterfaces)
     {
         if (iface == interfaceType)
         {
             return(true);
         }
     }
     return(false);
 }
示例#43
0
        private static void FindBaseUnificationGroup(MetadataType currentType, UnificationGroup unificationGroup)
        {
            MethodDesc originalDefiningMethod = unificationGroup.DefiningMethod;

            MethodDesc methodImpl = FindImplFromDeclFromMethodImpls(currentType, unificationGroup.DefiningMethod);

            if (methodImpl != null)
            {
                if (methodImpl.RequiresSlotUnification())
                {
                    unificationGroup.AddMethodRequiringSlotUnification(unificationGroup.DefiningMethod);
                    unificationGroup.AddMethodRequiringSlotUnification(methodImpl);
                }
                unificationGroup.SetDefiningMethod(methodImpl);
            }

            MethodDesc   nameSigMatchMethod = FindMatchingVirtualMethodOnTypeByNameAndSigWithSlotCheck(unificationGroup.DefiningMethod, currentType, reverseMethodSearch: true);
            MetadataType baseType           = currentType.MetadataBaseType;

            // Unless the current type has a name/sig match for the group, look to the base type to define the unification group further
            if ((nameSigMatchMethod == null) && (baseType != null))
            {
                FindBaseUnificationGroup(baseType, unificationGroup);
            }

            Debug.Assert(unificationGroup.IsInGroupOrIsDefiningSlot(originalDefiningMethod));

            // Now, we have the unification group from the type, or have discovered its defined on the current type.
            // Adjust the group to contain all of the elements that are added to it on this type, remove the components that
            // have seperated themselves from the group

            // Start with removing methods that seperated themselves from the group via name/sig matches
            MethodDescHashtable separatedMethods = null;

            foreach (MethodDesc memberMethod in unificationGroup.Members)
            {
                // If a method is both overriden via MethodImpl and name/sig, we don't remove it from the unification list
                // as the local MethodImpl takes priority over the name/sig match, and prevents the slot disunificaiton
                if (FindSlotDefiningMethodForVirtualMethod(memberMethod) == FindSlotDefiningMethodForVirtualMethod(originalDefiningMethod))
                {
                    continue;
                }

                MethodDesc nameSigMatchMemberMethod = FindMatchingVirtualMethodOnTypeByNameAndSigWithSlotCheck(memberMethod, currentType, reverseMethodSearch: true);
                if (nameSigMatchMemberMethod != null && nameSigMatchMemberMethod != memberMethod)
                {
                    if (separatedMethods == null)
                    {
                        separatedMethods = new MethodDescHashtable();
                    }
                    separatedMethods.AddOrGetExisting(memberMethod);
                }
            }

            if (separatedMethods != null)
            {
                foreach (MethodDesc seperatedMethod in MethodDescHashtable.Enumerator.Get(separatedMethods))
                {
                    unificationGroup.RemoveFromGroup(seperatedMethod);
                }
            }

            // Next find members which have seperated or added themselves to the group via MethodImpls
            foreach (MethodImplRecord methodImplRecord in currentType.VirtualMethodImplsForType)
            {
                MethodDesc declSlot = FindSlotDefiningMethodForVirtualMethod(methodImplRecord.Decl);
                MethodDesc implSlot = FindSlotDefiningMethodForVirtualMethod(methodImplRecord.Body);

                if (unificationGroup.IsInGroup(declSlot) && !unificationGroup.IsInGroupOrIsDefiningSlot(implSlot))
                {
                    unificationGroup.RemoveFromGroup(declSlot);

                    if (separatedMethods == null)
                    {
                        separatedMethods = new MethodDescHashtable();
                    }
                    separatedMethods.AddOrGetExisting(declSlot);

                    if (unificationGroup.RequiresSlotUnification(declSlot) || implSlot.RequiresSlotUnification())
                    {
                        if (implSlot.Signature.EqualsWithCovariantReturnType(unificationGroup.DefiningMethod.Signature))
                        {
                            unificationGroup.AddMethodRequiringSlotUnification(declSlot);
                            unificationGroup.AddMethodRequiringSlotUnification(implSlot);
                            unificationGroup.SetDefiningMethod(implSlot);
                        }
                    }

                    continue;
                }
                if (!unificationGroup.IsInGroupOrIsDefiningSlot(declSlot))
                {
                    if (unificationGroup.IsInGroupOrIsDefiningSlot(implSlot))
                    {
                        // Add decl to group.

                        // To do so, we need to have the Unification Group of the decl slot, as it may have multiple members itself
                        UnificationGroup addDeclGroup = new UnificationGroup(declSlot);
                        FindBaseUnificationGroup(baseType, addDeclGroup);
                        Debug.Assert(
                            addDeclGroup.IsInGroupOrIsDefiningSlot(declSlot) ||
                            (addDeclGroup.RequiresSlotUnification(declSlot) && addDeclGroup.DefiningMethod.Signature.EqualsWithCovariantReturnType(declSlot.Signature)));

                        foreach (MethodDesc methodImplRequiredToRemainInEffect in addDeclGroup.MethodsRequiringSlotUnification)
                        {
                            unificationGroup.AddMethodRequiringSlotUnification(methodImplRequiredToRemainInEffect);
                        }

                        // Add all members from the decl's unification group except for ones that have been seperated by name/sig matches
                        // or previously processed methodimpls. NOTE: This implies that method impls are order dependent.
                        if (separatedMethods == null || !separatedMethods.Contains(addDeclGroup.DefiningMethod))
                        {
                            unificationGroup.AddToGroup(addDeclGroup.DefiningMethod);
                        }

                        foreach (MethodDesc addDeclGroupMemberMethod in addDeclGroup.Members)
                        {
                            if (separatedMethods == null || !separatedMethods.Contains(addDeclGroupMemberMethod))
                            {
                                unificationGroup.AddToGroup(addDeclGroupMemberMethod);
                            }
                        }

                        if (unificationGroup.RequiresSlotUnification(declSlot))
                        {
                            unificationGroup.AddMethodRequiringSlotUnification(implSlot);
                        }
                        else if (implSlot == unificationGroup.DefiningMethod && implSlot.RequiresSlotUnification())
                        {
                            unificationGroup.AddMethodRequiringSlotUnification(declSlot);
                            unificationGroup.AddMethodRequiringSlotUnification(implSlot);
                        }
                    }
                    else if (unificationGroup.RequiresSlotUnification(declSlot))
                    {
                        if (implSlot.Signature.EqualsWithCovariantReturnType(unificationGroup.DefiningMethod.Signature))
                        {
                            unificationGroup.AddMethodRequiringSlotUnification(implSlot);
                            unificationGroup.SetDefiningMethod(implSlot);
                        }
                    }
                }
            }
        }
示例#44
0
 public TypeGCStaticBaseGenericLookupResult(TypeDesc type)
 {
     Debug.Assert(type.IsRuntimeDeterminedSubtype, "Concrete static base in a generic dictionary?");
     Debug.Assert(type is MetadataType);
     _type = (MetadataType)type;
 }
示例#45
0
 static bool HasNestedTypes(Cts.MetadataType entity)
 => entity.GetNestedTypes().GetEnumerator().MoveNext();
        private static ComputedInstanceFieldLayout ComputeSequentialFieldLayout(MetadataType type, int numInstanceFields)
        {
            var offsets = new FieldAndOffset[numInstanceFields];

            // For types inheriting from another type, field offsets continue on from where they left off
            int cumulativeInstanceFieldPos = ComputeBytesUsedInParentType(type);

            int largestAlignmentRequirement = 1;
            int fieldOrdinal = 0;
            int packingSize = ComputePackingSize(type);

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

                var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(field.FieldType, packingSize);

                if (fieldSizeAndAlignment.Alignment > largestAlignmentRequirement)
                    largestAlignmentRequirement = fieldSizeAndAlignment.Alignment;

                cumulativeInstanceFieldPos = AlignmentHelper.AlignUp(cumulativeInstanceFieldPos, fieldSizeAndAlignment.Alignment);
                offsets[fieldOrdinal] = new FieldAndOffset(field, cumulativeInstanceFieldPos);
                cumulativeInstanceFieldPos = checked(cumulativeInstanceFieldPos + fieldSizeAndAlignment.Size);

                fieldOrdinal++;
            }

            if (type.IsValueType)
            {
                var layoutMetadata = type.GetClassLayout();
                cumulativeInstanceFieldPos = Math.Max(cumulativeInstanceFieldPos, layoutMetadata.Size);
            }

            SizeAndAlignment instanceByteSizeAndAlignment;
            var instanceSizeAndAlignment = ComputeInstanceSize(type, cumulativeInstanceFieldPos, largestAlignmentRequirement, out instanceByteSizeAndAlignment);

            ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout();
            computedLayout.FieldAlignment = instanceSizeAndAlignment.Alignment;
            computedLayout.FieldSize = instanceSizeAndAlignment.Size;
            computedLayout.ByteCountUnaligned = instanceByteSizeAndAlignment.Size;
            computedLayout.ByteCountAlignment = instanceByteSizeAndAlignment.Alignment;
            computedLayout.Offsets = offsets;

            return computedLayout;
        }
示例#47
0
        // This function is used to find the name/sig based override for a given method. This method ignores all
        // method impl's as it assumes they have been resolved. The algorithm is simple. Walk to the base type looking
        // for overrides by name and signature. If one is found, return it as long as the newslot defining method
        // for the found method matches that of the target method.
        private static MethodDesc FindNameSigOverrideForVirtualMethod(MethodDesc targetMethod, MetadataType currentType)
        {
            while (currentType != null)
            {
                MethodDesc nameSigOverride = FindMatchingVirtualMethodOnTypeByNameAndSigWithSlotCheck(targetMethod, currentType, reverseMethodSearch: true);

                if (nameSigOverride != null)
                {
                    return(nameSigOverride);
                }

                currentType = currentType.MetadataBaseType;
            }

            return(null);
        }
        private static SizeAndAlignment ComputeInstanceSize(MetadataType type, int count, int alignment, out SizeAndAlignment byteCount)
        {
            SizeAndAlignment result;

            int targetPointerSize = type.Context.Target.PointerSize;

            // Pad the length of structs to be 1 if they are empty so we have no zero-length structures
            if (type.IsValueType && count == 0)
            {
                count = 1;
            }

            if (type.IsValueType)
            {
                count = AlignmentHelper.AlignUp(count, alignment);
                result.Size = count;
                result.Alignment = alignment;
            }
            else
            {
                result.Size = targetPointerSize;
                result.Alignment = targetPointerSize;
                if (type.HasBaseType)
                    alignment = Math.Max(alignment, type.BaseType.InstanceByteAlignment);
            }

            // Determine the alignment needed by the type when allocated
            // This is target specific, and not just pointer sized due to 
            // 8 byte alignment requirements on ARM for longs and doubles
            alignment = type.Context.Target.GetObjectAlignment(alignment);

            byteCount.Size = count;
            byteCount.Alignment = alignment;

            return result;
        }
示例#49
0
 public bool GeneratesMetadata(MetadataType typeDef)
 {
     return _typeGeneratesMetadata(typeDef);
 }
示例#50
0
 public bool GeneratesMetadata(MetadataType typeDef)
 {
     return _modules.Contains(typeDef.Module);
 }
示例#51
0
        private void InitializeTypeDef(Cts.MetadataType entity, TypeDefinition record)
        {
            if (entity.ContainingType != null)
            {
                var enclosingType = (TypeDefinition)HandleType(entity.ContainingType);
                record.EnclosingType = enclosingType;
                enclosingType.NestedTypes.Add(record);

                var namespaceDefinition =
                    HandleNamespaceDefinition(entity.ContainingType.Module, entity.ContainingType.Namespace);
                record.NamespaceDefinition = namespaceDefinition;
            }
            else
            {
                var namespaceDefinition = HandleNamespaceDefinition(entity.Module, entity.Namespace);
                record.NamespaceDefinition = namespaceDefinition;
                namespaceDefinition.TypeDefinitions.Add(record);
            }

            record.Name = HandleString(entity.Name);

            Cts.ClassLayoutMetadata layoutMetadata = entity.GetClassLayout();
            record.Size        = checked ((uint)layoutMetadata.Size);
            record.PackingSize = checked ((uint)layoutMetadata.PackingSize);
            record.Flags       = GetTypeAttributes(entity);

            if (entity.HasBaseType)
            {
                record.BaseType = HandleType(entity.BaseType);
            }

            if (entity.ExplicitlyImplementedInterfaces.Length > 0)
            {
                record.Interfaces = entity.ExplicitlyImplementedInterfaces
                                    .Where(i => !IsBlocked(i))
                                    .Select(i => HandleType(i)).ToList();
            }

            if (entity.HasInstantiation)
            {
                var genericParams = new List <GenericParameter>(entity.Instantiation.Length);
                foreach (var p in entity.Instantiation)
                {
                    genericParams.Add(HandleGenericParameter((Cts.GenericParameterDesc)p));
                }
                record.GenericParameters = genericParams;
            }

            var fields = new List <Field>();

            foreach (var field in entity.GetFields())
            {
                if (_policy.GeneratesMetadata(field))
                {
                    fields.Add(HandleFieldDefinition(field));
                }
            }
            record.Fields = fields;

            var methods = new List <Method>();

            foreach (var method in entity.GetMethods())
            {
                if (_policy.GeneratesMetadata(method))
                {
                    methods.Add(HandleMethodDefinition(method));
                }
            }
            record.Methods = methods;

            var ecmaEntity = entity as Cts.Ecma.EcmaType;

            if (ecmaEntity != null)
            {
                Ecma.TypeDefinition ecmaRecord = ecmaEntity.MetadataReader.GetTypeDefinition(ecmaEntity.Handle);
                foreach (var property in ecmaRecord.GetProperties())
                {
                    Property prop = HandleProperty(ecmaEntity.EcmaModule, property);
                    if (prop != null)
                    {
                        record.Properties.Add(prop);
                    }
                }

                // TODO: Events

                // TODO: CustomAttributes
            }
        }
示例#52
0
 public bool IsBlocked(MetadataType typeDef)
 {
     if (_isBlockedType != null)
         return _isBlockedType(typeDef);
     return false;
 }
        private static ComputedInstanceFieldLayout ComputeExplicitFieldLayout(MetadataType type, int numInstanceFields)
        {
            // Instance slice size is the total size of instance not including the base type.
            // It is calculated as the field whose offset and size add to the greatest value.
            int cumulativeInstanceFieldPos =
                type.HasBaseType && !type.IsValueType ? type.BaseType.InstanceByteCount : 0;
            int instanceSize = cumulativeInstanceFieldPos;

            var layoutMetadata = type.GetClassLayout();

            int packingSize = ComputePackingSize(type);
            int largestAlignmentRequired = 1;

            var offsets = new FieldAndOffset[numInstanceFields];
            int fieldOrdinal = 0;

            foreach (var fieldAndOffset in layoutMetadata.Offsets)
            {
                var fieldSizeAndAlignment = ComputeFieldSizeAndAlignment(fieldAndOffset.Field.FieldType, packingSize);

                if (fieldSizeAndAlignment.Alignment > largestAlignmentRequired)
                    largestAlignmentRequired = fieldSizeAndAlignment.Alignment;

                if (fieldAndOffset.Offset == FieldAndOffset.InvalidOffset)
                    throw new TypeLoadException();

                int computedOffset = checked(fieldAndOffset.Offset + cumulativeInstanceFieldPos);

                switch (fieldAndOffset.Field.FieldType.Category)
                {
                    case TypeFlags.Array:
                    case TypeFlags.Class:
                        {
                            int offsetModulo = computedOffset % type.Context.Target.PointerSize;
                            if (offsetModulo != 0)
                            {
                                // GC pointers MUST be aligned.
                                if (offsetModulo == 4)
                                {
                                    // We must be attempting to compile a 32bit app targeting a 64 bit platform.
                                    throw new TypeLoadException();
                                }
                                else
                                {
                                    // Its just wrong
                                    throw new TypeLoadException();
                                }
                            }
                            break;
                        }
                }

                offsets[fieldOrdinal] = new FieldAndOffset(fieldAndOffset.Field, computedOffset);

                int fieldExtent = checked(computedOffset + fieldSizeAndAlignment.Size);
                if (fieldExtent > instanceSize)
                {
                    instanceSize = fieldExtent;
                }

                fieldOrdinal++;
            }

            if (type.IsValueType && layoutMetadata.Size > instanceSize)
            {
                instanceSize = layoutMetadata.Size;
            }

            SizeAndAlignment instanceByteSizeAndAlignment;
            var instanceSizeAndAlignment = ComputeInstanceSize(type, instanceSize, largestAlignmentRequired, out instanceByteSizeAndAlignment);

            ComputedInstanceFieldLayout computedLayout = new ComputedInstanceFieldLayout();
            computedLayout.FieldAlignment = instanceSizeAndAlignment.Alignment;
            computedLayout.FieldSize = instanceSizeAndAlignment.Size;
            computedLayout.ByteCountUnaligned = instanceByteSizeAndAlignment.Size;
            computedLayout.ByteCountAlignment = instanceByteSizeAndAlignment.Alignment;
            computedLayout.Offsets = offsets;

            return computedLayout;
        }
示例#54
0
 public ModuleDesc GetModuleOfType(MetadataType typeDef)
 {
     if (_moduleOfType != null)
         return _moduleOfType(typeDef);
     return typeDef.Module;
 }
        private static int ComputePackingSize(MetadataType type)
        {
            var layoutMetadata = type.GetClassLayout();

            // If a type contains pointers then the metadata specified packing size is ignored (On desktop this is disqualification from ManagedSequential)
            if (layoutMetadata.PackingSize == 0 || type.ContainsPointers)
                return type.Context.Target.DefaultPackingSize;
            else
                return layoutMetadata.PackingSize;
        }
示例#56
0
 public GCStaticsNode(MetadataType type)
 {
     _type = type;
 }
示例#57
0
        private void InitializeScopeDefinition(Cts.ModuleDesc module, ScopeDefinition scopeDefinition)
        {
            var assemblyDesc = module as Cts.IAssemblyDesc;

            if (assemblyDesc != null)
            {
                var assemblyName = assemblyDesc.GetName();

                scopeDefinition.Name = HandleString(assemblyName.Name);
#if NETFX_45
                // With NET 4.5 contract System.Reflection 4.0.0.0 EcmaModule has no way
                // to set Culture in its AssemblyName.
                scopeDefinition.Culture = HandleString(assemblyName.CultureName ?? "");
#else
                scopeDefinition.Culture = HandleString(assemblyName.CultureName);
#endif
                scopeDefinition.MajorVersion   = checked ((ushort)assemblyName.Version.Major);
                scopeDefinition.MinorVersion   = checked ((ushort)assemblyName.Version.Minor);
                scopeDefinition.BuildNumber    = checked ((ushort)assemblyName.Version.Build);
                scopeDefinition.RevisionNumber = checked ((ushort)assemblyName.Version.Revision);

                Debug.Assert((int)AssemblyFlags.PublicKey == (int)AssemblyNameFlags.PublicKey);
                Debug.Assert((int)AssemblyFlags.Retargetable == (int)AssemblyNameFlags.Retargetable);
                scopeDefinition.Flags = (AssemblyFlags)assemblyName.Flags;

                if (assemblyName.ContentType == AssemblyContentType.WindowsRuntime)
                {
                    scopeDefinition.Flags |= (AssemblyFlags)((int)AssemblyContentType.WindowsRuntime << 9);
                }

                if ((scopeDefinition.Flags & AssemblyFlags.PublicKey) != 0)
                {
                    scopeDefinition.PublicKey = assemblyName.GetPublicKey();
                }
                else
                {
                    scopeDefinition.PublicKey = assemblyName.GetPublicKeyToken();
                }

                Cts.MetadataType moduleType = module.GetGlobalModuleType();
                if (moduleType != null && _policy.GeneratesMetadata(moduleType))
                {
                    scopeDefinition.GlobalModuleType = (TypeDefinition)HandleType(moduleType);
                }

                Cts.Ecma.EcmaAssembly ecmaAssembly = module as Cts.Ecma.EcmaAssembly;
                if (ecmaAssembly != null)
                {
                    Ecma.CustomAttributeHandleCollection customAttributes = ecmaAssembly.AssemblyDefinition.GetCustomAttributes();
                    if (customAttributes.Count > 0)
                    {
                        scopeDefinition.CustomAttributes = HandleCustomAttributes(ecmaAssembly, customAttributes);
                    }

                    Cts.MethodDesc entryPoint = ecmaAssembly.EntryPoint;
                    if (entryPoint != null && _policy.GeneratesMetadata(entryPoint))
                    {
                        scopeDefinition.EntryPoint = (QualifiedMethod)HandleQualifiedMethod(entryPoint);
                    }
                }
            }
            else
            {
                throw new NotSupportedException("Multi-module assemblies");
            }
        }
示例#58
0
        private void InitializeTypeDef(Cts.MetadataType entity, TypeDefinition record)
        {
            Debug.Assert(entity.IsTypeDefinition);

            Cts.MetadataType containingType = (Cts.MetadataType)entity.ContainingType;
            if (containingType != null)
            {
                var enclosingType = (TypeDefinition)HandleType(containingType);
                record.EnclosingType = enclosingType;
                enclosingType.NestedTypes.Add(record);

                var namespaceDefinition =
                    HandleNamespaceDefinition(containingType.Module, entity.ContainingType.Namespace);
                record.NamespaceDefinition = namespaceDefinition;
            }
            else
            {
                var namespaceDefinition = HandleNamespaceDefinition(entity.Module, entity.Namespace);
                record.NamespaceDefinition = namespaceDefinition;
                namespaceDefinition.TypeDefinitions.Add(record);
            }

            record.Name = HandleString(entity.Name);

            Cts.ClassLayoutMetadata layoutMetadata = entity.GetClassLayout();
            record.Size        = checked ((uint)layoutMetadata.Size);
            record.PackingSize = checked ((ushort)layoutMetadata.PackingSize);
            record.Flags       = GetTypeAttributes(entity);

            if (entity.HasBaseType)
            {
                record.BaseType = HandleType(entity.BaseType);
            }

            record.Interfaces.Capacity = entity.ExplicitlyImplementedInterfaces.Length;
            foreach (var interfaceType in entity.ExplicitlyImplementedInterfaces)
            {
                if (IsBlocked(interfaceType))
                {
                    continue;
                }
                record.Interfaces.Add(HandleType(interfaceType));
            }

            if (entity.HasInstantiation)
            {
                record.GenericParameters.Capacity = entity.Instantiation.Length;
                foreach (var p in entity.Instantiation)
                {
                    record.GenericParameters.Add(HandleGenericParameter((Cts.GenericParameterDesc)p));
                }
            }

            foreach (var field in entity.GetFields())
            {
                if (_policy.GeneratesMetadata(field))
                {
                    record.Fields.Add(HandleFieldDefinition(field));
                }
            }

            foreach (var method in entity.GetMethods())
            {
                if (_policy.GeneratesMetadata(method))
                {
                    record.Methods.Add(HandleMethodDefinition(method));
                }
            }

            var ecmaEntity = entity as Cts.Ecma.EcmaType;

            if (ecmaEntity != null)
            {
                Ecma.TypeDefinition ecmaRecord = ecmaEntity.MetadataReader.GetTypeDefinition(ecmaEntity.Handle);

                foreach (var e in ecmaRecord.GetEvents())
                {
                    Event evt = HandleEvent(ecmaEntity.EcmaModule, e);
                    if (evt != null)
                    {
                        record.Events.Add(evt);
                    }
                }

                foreach (var property in ecmaRecord.GetProperties())
                {
                    Property prop = HandleProperty(ecmaEntity.EcmaModule, property);
                    if (prop != null)
                    {
                        record.Properties.Add(prop);
                    }
                }

                Ecma.CustomAttributeHandleCollection customAttributes = ecmaRecord.GetCustomAttributes();
                if (customAttributes.Count > 0)
                {
                    record.CustomAttributes = HandleCustomAttributes(ecmaEntity.EcmaModule, customAttributes);
                }

                foreach (var miHandle in ecmaRecord.GetMethodImplementations())
                {
                    Ecma.MetadataReader reader = ecmaEntity.EcmaModule.MetadataReader;

                    Ecma.MethodImplementation miDef = reader.GetMethodImplementation(miHandle);

                    Cts.MethodDesc methodBody = (Cts.MethodDesc)ecmaEntity.EcmaModule.GetObject(miDef.MethodBody);
                    if (_policy.IsBlocked(methodBody))
                    {
                        continue;
                    }

                    Cts.MethodDesc methodDecl = (Cts.MethodDesc)ecmaEntity.EcmaModule.GetObject(miDef.MethodDeclaration);
                    if (_policy.IsBlocked(methodDecl.GetTypicalMethodDefinition()))
                    {
                        continue;
                    }

                    MethodImpl methodImplRecord = new MethodImpl
                    {
                        MethodBody        = HandleQualifiedMethod(methodBody),
                        MethodDeclaration = HandleQualifiedMethod(methodDecl)
                    };

                    record.MethodImpls.Add(methodImplRecord);
                }
            }
        }
示例#59
0
 public bool GeneratesMetadata(MetadataType typeDef)
 {
     return true;
 }
 /// <summary>
 /// RuntimeInterfaces algorithm for for array types which are similar to a generic type
 /// </summary>
 /// <param name="arrayOfTType">Open type to instantiate to get the interfaces associated with an array.</param>
 public ArrayOfTRuntimeInterfacesAlgorithm(MetadataType arrayOfTType)
 {
     _arrayOfTType = arrayOfTType;
     Debug.Assert(!(arrayOfTType is InstantiatedType));
 }