Beispiel #1
0
        private void ProcessMethodDirective(IRootingServiceProvider rootProvider, ModuleDesc containingModule, TypeDesc containingType, XElement methodElement)
        {
            var methodNameAttribute = methodElement.Attribute("Name");

            if (methodNameAttribute == null)
            {
                throw new Exception("The \"Name\" attribute is required on the \"Method\" Runtime Directive.");
            }

            var parameter = new List <TypeDesc>();
            var instArgs  = new List <TypeDesc>();

            foreach (var element in methodElement.Elements())
            {
                switch (element.Name.LocalName)
                {
                case "Parameter":
                    string paramName = element.Attribute("Name").Value;
                    parameter.Add(containingModule.GetTypeByCustomAttributeTypeName(paramName));
                    break;

                case "GenericArgument":
                    string instArgName = element.Attribute("Name").Value;
                    instArgs.Add(containingModule.GetTypeByCustomAttributeTypeName(instArgName));
                    break;

                default:
                    throw new NotSupportedException($"\"{element.Name.LocalName}\" is not a supported Runtime Directive.");
                }
            }
Beispiel #2
0
        private void ProcessTypeDirective(IRootingServiceProvider rootProvider, ModuleDesc containingModule, XElement typeElement)
        {
            var typeNameAttribute = typeElement.Attribute("Name");
            if (typeNameAttribute == null)
                throw new Exception();
            string typeName = typeNameAttribute.Value;
            TypeDesc type = containingModule.GetTypeByCustomAttributeTypeName(typeName);

            var dynamicDegreeAttribute = typeElement.Attribute("Dynamic");
            if (dynamicDegreeAttribute != null)
            {
                if (dynamicDegreeAttribute.Value != "Required All")
                    throw new NotSupportedException();

                RootingHelpers.RootType(rootProvider, type, "RD.XML root");
            }

            foreach (var element in typeElement.Elements())
            {
                switch (element.Name.LocalName)
                {
                    case "Method":
                        ProcessMethodDirective(rootProvider, containingModule, type, element);
                        break;
                    default:
                        throw new NotSupportedException();
                }
            }
        }
Beispiel #3
0
        private void ProcessMethodDirective(IRootingServiceProvider rootProvider, ModuleDesc containingModule, TypeDesc containingType, XElement methodElement)
        {
            var methodNameAttribute = methodElement.Attribute("Name");
            if (methodNameAttribute == null)
                throw new Exception();
            string methodName = methodNameAttribute.Value;
            MethodDesc method = containingType.GetMethod(methodName, null);

            var instArgs = new List<TypeDesc>();
            foreach (var element in methodElement.Elements())
            {
                switch (element.Name.LocalName)
                {
                    case "GenericArgument":
                        string instArgName = element.Attribute("Name").Value;
                        instArgs.Add(containingModule.GetTypeByCustomAttributeTypeName(instArgName));
                        break;
                    default:
                        throw new NotSupportedException();
                }
            }

            if (instArgs.Count != method.Instantiation.Length)
                throw new Exception();

            if (instArgs.Count > 0)
            {
                var methodInst = new Instantiation(instArgs.ToArray());
                method = method.MakeInstantiatedMethod(methodInst);
            }

            RootingHelpers.TryRootMethod(rootProvider, method, "RD.XML root");
        }
        private void ProcessTypeDirective(IRootingServiceProvider rootProvider, ModuleDesc containingModule, XElement typeElement)
        {
            var typeNameAttribute = typeElement.Attribute("Name");

            if (typeNameAttribute == null)
            {
                throw new Exception();
            }

            var dynamicDegreeAttribute = typeElement.Attribute("Dynamic");

            if (dynamicDegreeAttribute != null)
            {
                if (dynamicDegreeAttribute.Value != "Required All")
                {
                    throw new NotSupportedException();
                }
            }

            string typeName = typeNameAttribute.Value;

            TypeDesc type = containingModule.GetTypeByCustomAttributeTypeName(typeName);

            rootProvider.AddCompilationRoot(type, "RD.XML root");

            if (type.IsDefType)
            {
                foreach (var method in type.GetMethods())
                {
                    // We don't know what to instantiate generic methods over
                    if (method.HasInstantiation)
                    {
                        continue;
                    }

                    // Virtual methods should be rooted as if they were called virtually
                    if (method.IsVirtual)
                    {
                        MethodDesc slotMethod = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(method);
                        rootProvider.RootVirtualMethodUse(slotMethod, "RD.XML root");
                    }

                    // Abstract methods have no entrypoints
                    if (method.IsAbstract)
                    {
                        continue;
                    }

                    rootProvider.AddCompilationRoot(method, "RD.XML root");
                }
            }
        }
Beispiel #5
0
        private TypeDesc FindType(CompilerTypeSystemContext context, string typeName)
        {
            ModuleDesc systemModule = context.SystemModule;

            TypeDesc foundType = systemModule.GetTypeByCustomAttributeTypeName(typeName, false, (typeDefName, module, throwIfNotFound) =>
            {
                return (MetadataType)context.GetCanonType(typeDefName)
                    ?? CustomAttributeTypeNameParser.ResolveCustomAttributeTypeDefinitionName(typeDefName, module, throwIfNotFound);
            });
            if (foundType == null)
                throw new CommandLineException($"Type '{typeName}' not found");

            return foundType;
        }
Beispiel #6
0
        private TypeDesc FindType(CompilerTypeSystemContext context, string typeName)
        {
            ModuleDesc systemModule = context.SystemModule;

            TypeDesc foundType = systemModule.GetTypeByCustomAttributeTypeName(typeName);

            if (foundType == null)
            {
                throw new CommandLineException($"Type '{typeName}' not found");
            }

            TypeDesc classLibCanon    = systemModule.GetType("System", "__Canon", false);
            TypeDesc classLibUniCanon = systemModule.GetType("System", "__UniversalCanon", false);

            return(foundType.ReplaceTypesInConstructionOfType(
                       new TypeDesc[] { classLibCanon, classLibUniCanon },
                       new TypeDesc[] { context.CanonType, context.UniversalCanonType }));
        }
Beispiel #7
0
        /// <summary>
        /// Given a parsed out module, namespace + type, and method name, try to find a matching MethodDesc
        /// TODO: We have no signature information for the method - what policy should we apply where multiple methods exist with the same name
        /// but different signatures? For now we'll take the first matching and ignore others. Ideally we'll improve the profile data to include this.
        /// </summary>
        /// <returns>MethodDesc if found, null otherwise</returns>
        private MethodDesc ResolveMethodName(CompilerTypeSystemContext context, ModuleDesc module, string namespaceAndTypeName, string methodName)
        {
            TypeDesc resolvedType = module.GetTypeByCustomAttributeTypeName(namespaceAndTypeName, false, (typeDefName, module, throwIfNotFound) =>
            {
                return((MetadataType)context.GetCanonType(typeDefName)
                       ?? CustomAttributeTypeNameParser.ResolveCustomAttributeTypeDefinitionName(typeDefName, module, throwIfNotFound));
            });

            if (resolvedType != null)
            {
                var resolvedMethod = resolvedType.GetMethod(methodName, null);
                if (resolvedMethod != null)
                {
                    return(resolvedMethod);
                }
            }

            return(null);
        }
Beispiel #8
0
        private void ProcessTypeDirective(IRootingServiceProvider rootProvider, ModuleDesc containingModule, XElement typeElement)
        {
            var typeNameAttribute = typeElement.Attribute("Name");

            if (typeNameAttribute == null)
            {
                throw new Exception();
            }

            var dynamicDegreeAttribute = typeElement.Attribute("Dynamic");

            if (dynamicDegreeAttribute != null)
            {
                if (dynamicDegreeAttribute.Value != "Required All")
                {
                    throw new NotSupportedException();
                }
            }

            string typeName = typeNameAttribute.Value;

            TypeDesc type = containingModule.GetTypeByCustomAttributeTypeName(typeName);

            rootProvider.AddCompilationRoot(type, "RD.XML root");

            if (type.IsDefType)
            {
                foreach (var method in type.GetMethods())
                {
                    if (method.IsAbstract || method.HasInstantiation)
                    {
                        continue;
                    }

                    rootProvider.AddCompilationRoot(method, "RD.XML root");
                }
            }
        }
Beispiel #9
0
        private void ProcessTypeDirective(IRootingServiceProvider rootProvider, ModuleDesc containingModule, XElement typeElement)
        {
            var typeNameAttribute = typeElement.Attribute("Name");

            if (typeNameAttribute == null)
            {
                throw new Exception();
            }

            var dynamicDegreeAttribute = typeElement.Attribute("Dynamic");

            if (dynamicDegreeAttribute != null)
            {
                if (dynamicDegreeAttribute.Value != "Required All")
                {
                    throw new NotSupportedException();
                }
            }

            string typeName = typeNameAttribute.Value;

            RootType(rootProvider, containingModule.GetTypeByCustomAttributeTypeName(typeName));
        }
Beispiel #10
0
        private void ProcessTypeDirective(IRootingServiceProvider rootProvider, ModuleDesc containingModule, XElement typeElement)
        {
            var typeNameAttribute = typeElement.Attribute("Name");

            if (typeNameAttribute == null)
            {
                throw new Exception("The \"Name\" attribute is required on the \"Type\" Runtime Directive.");
            }

            string   typeName = typeNameAttribute.Value;
            TypeDesc type     = containingModule.GetTypeByCustomAttributeTypeName(typeName);

            var dynamicDegreeAttribute = typeElement.Attribute("Dynamic");

            if (dynamicDegreeAttribute != null)
            {
                if (dynamicDegreeAttribute.Value != "Required All")
                {
                    throw new NotSupportedException($"\"{dynamicDegreeAttribute.Value}\" is not a supported value for the \"Dynamic\" attribute of the \"Type\" Runtime Directive. Supported values are \"Required All\".");
                }

                RootingHelpers.RootType(rootProvider, type, "RD.XML root");
            }

            foreach (var element in typeElement.Elements())
            {
                switch (element.Name.LocalName)
                {
                case "Method":
                    ProcessMethodDirective(rootProvider, containingModule, type, element);
                    break;

                default:
                    throw new NotSupportedException($"\"{element.Name.LocalName}\" is not a supported Runtime Directive.");
                }
            }
        }
        private MetadataLoadedInfo LoadMetadata()
        {
            HashSet <ModuleDesc> metadataModules          = new HashSet <ModuleDesc>();
            MetadataType         typeWithMetadataMappings = (MetadataType)_metadataDescribingModule.GetTypeByCustomAttributeTypeName(MetadataMappingTypeName);

            MethodDesc fullMetadataMethod = typeWithMetadataMappings.GetMethod("Metadata", null);
            MethodDesc weakMetadataMethod = typeWithMetadataMappings.GetMethod("WeakMetadata", null);

            ILProvider ilProvider = new ILProvider(null);

            MetadataLoadedInfo result = new MetadataLoadedInfo();

            if (fullMetadataMethod != null)
            {
                MethodIL fullMethodIL = ilProvider.GetMethodIL(fullMetadataMethod);
                ReadMetadataMethod(fullMethodIL, ref result.AllTypeMappings, ref result.MethodMappings, ref result.FieldMappings, ref metadataModules);
                foreach (var mapping in result.AllTypeMappings)
                {
                    result.TypesWithStrongMetadataMappings.Add(mapping.Key);
                }
            }

            if (weakMetadataMethod != null)
            {
                MethodIL weakMethodIL = ilProvider.GetMethodIL(weakMetadataMethod);
                Dictionary <MethodDesc, int> weakMethodMappings = new Dictionary <MethodDesc, int>();
                Dictionary <FieldDesc, int>  weakFieldMappings  = new Dictionary <FieldDesc, int>();
                ReadMetadataMethod(weakMethodIL, ref result.AllTypeMappings, ref weakMethodMappings, ref weakFieldMappings, ref metadataModules);
                if ((weakMethodMappings.Count > 0) || (weakFieldMappings.Count > 0))
                {
                    // the format does not permit weak field/method mappings
                    throw new BadImageFormatException();
                }
            }

            result.MetadataModules = ImmutableArray.CreateRange(metadataModules);

            ImmutableArray <ModuleDesc> .Builder externalMetadataModulesBuilder = ImmutableArray.CreateBuilder <ModuleDesc>();
            ImmutableArray <ModuleDesc> .Builder localMetadataModulesBuilder    = ImmutableArray.CreateBuilder <ModuleDesc>();
            foreach (ModuleDesc module in result.MetadataModules)
            {
                if (!_compilationModules.Contains(module))
                {
                    externalMetadataModulesBuilder.Add(module);
                }
                else
                {
                    localMetadataModulesBuilder.Add(module);
                }
            }
            result.ExternalMetadataModules = externalMetadataModulesBuilder.ToImmutable();
            result.LocalMetadataModules    = localMetadataModulesBuilder.ToImmutable();

            // TODO! Replace with something more complete that capture the generic instantiations that the pre-analysis
            // indicates should have been present
            foreach (var pair in result.MethodMappings)
            {
                MethodDesc reflectableMethod = pair.Key;

                if (reflectableMethod.HasInstantiation)
                {
                    continue;
                }

                if (reflectableMethod.OwningType.HasInstantiation)
                {
                    continue;
                }

                MethodDesc typicalDynamicInvokeStub;
                if (!_dynamicInvokeStubs.Value.TryGetValue(reflectableMethod, out typicalDynamicInvokeStub))
                {
                    continue;
                }

                MethodDesc instantiatiatedDynamicInvokeStub = InstantiateDynamicInvokeMethodForMethod(typicalDynamicInvokeStub, reflectableMethod);
                result.DynamicInvokeCompiledMethods.Add(instantiatiatedDynamicInvokeStub.GetCanonMethodTarget(CanonicalFormKind.Specific));
            }

            return(result);
        }
 public static bool ModuleHasMetadataMappings(ModuleDesc metadataDescribingModule)
 {
     return(metadataDescribingModule.GetTypeByCustomAttributeTypeName(MetadataMappingTypeName, throwIfNotFound: false) != null);
 }
        private MetadataLoadedInfo LoadMetadata()
        {
            HashSet <ModuleDesc> metadataModules          = new HashSet <ModuleDesc>();
            MetadataType         typeWithMetadataMappings = (MetadataType)_metadataDescribingModule.GetTypeByCustomAttributeTypeName(MetadataMappingTypeName);

            MethodDesc fullMetadataMethod = typeWithMetadataMappings.GetMethod("Metadata", null);
            MethodDesc weakMetadataMethod = typeWithMetadataMappings.GetMethod("WeakMetadata", null);

            ILProvider ilProvider = new ILProvider(null);

            MetadataLoadedInfo result = new MetadataLoadedInfo();

            if (fullMetadataMethod != null)
            {
                MethodIL fullMethodIL = ilProvider.GetMethodIL(fullMetadataMethod);
                ReadMetadataMethod(fullMethodIL, out result.StrongTypeMappings, out result.MethodMappings, out result.FieldMappings, ref metadataModules);
            }

            if (weakMetadataMethod != null)
            {
                MethodIL weakMethodIL = ilProvider.GetMethodIL(weakMetadataMethod);
                List <MetadataMapping <MethodDesc> > weakMethodMappings = new List <MetadataMapping <MethodDesc> >();
                List <MetadataMapping <FieldDesc> >  weakFieldMappings  = new List <MetadataMapping <FieldDesc> >();
                ReadMetadataMethod(weakMethodIL, out result.AllTypeMappings, out weakMethodMappings, out weakFieldMappings, ref metadataModules);
                if ((weakMethodMappings.Count > 0) || (weakFieldMappings.Count > 0))
                {
                    // the format does not permit weak field/method mappings
                    throw new BadImageFormatException();
                }
            }

#if DEBUG
            // No duplicates are permitted in metadata mappings
            HashSet <TypeSystemEntity> mappingsDuplicateChecker = new HashSet <TypeSystemEntity>();
            foreach (MetadataMapping <MetadataType> mapping in result.AllTypeMappings)
            {
                if (!mappingsDuplicateChecker.Add(mapping.Entity))
                {
                    throw new BadImageFormatException();
                }
            }

            foreach (MetadataMapping <MetadataType> mapping in result.StrongTypeMappings)
            {
                if (!mappingsDuplicateChecker.Add(mapping.Entity))
                {
                    throw new BadImageFormatException();
                }
            }

            foreach (MetadataMapping <FieldDesc> mapping in result.FieldMappings)
            {
                if (!mappingsDuplicateChecker.Add(mapping.Entity))
                {
                    throw new BadImageFormatException();
                }
            }

            foreach (MetadataMapping <MethodDesc> mapping in result.MethodMappings)
            {
                if (!mappingsDuplicateChecker.Add(mapping.Entity))
                {
                    throw new BadImageFormatException();
                }
            }
#endif

            // All type mappings is the combination of strong and weak type mappings.
            result.AllTypeMappings.AddRange(result.StrongTypeMappings);

            result.MetadataModules = ImmutableArray.CreateRange(metadataModules);

            ImmutableArray <ModuleDesc> .Builder externalMetadataModulesBuilder = ImmutableArray.CreateBuilder <ModuleDesc>();
            ImmutableArray <ModuleDesc> .Builder localMetadataModulesBuilder    = ImmutableArray.CreateBuilder <ModuleDesc>();
            foreach (ModuleDesc module in result.MetadataModules)
            {
                if (!_compilationModules.Contains(module))
                {
                    externalMetadataModulesBuilder.Add(module);
                }
                else
                {
                    localMetadataModulesBuilder.Add(module);
                }
            }
            result.ExternalMetadataModules = externalMetadataModulesBuilder.ToImmutable();
            result.LocalMetadataModules    = localMetadataModulesBuilder.ToImmutable();

            return(result);
        }
        public void TestSimpleNames()
        {
            {
                TypeDesc result = _testModule.GetTypeByCustomAttributeTypeName("TypeNameParsing.Simple");
                Assert.Equal(_simpleType, result);
            }

            {
                TypeDesc result = _testModule.GetTypeByCustomAttributeTypeName("TypeNameParsing.Simple+Nested");
                Assert.Equal(_nestedType, result);
            }

            {
                TypeDesc result = _testModule.GetTypeByCustomAttributeTypeName("TypeNameParsing.Simple+Nested+NestedTwice");
                Assert.Equal(_nestedTwiceType, result);
            }

            {
                TypeDesc result = _testModule.GetTypeByCustomAttributeTypeName("System.Int32, " + _coreAssemblyQualifier);
                Assert.Equal(_context.GetWellKnownType(WellKnownType.Int32), result);
            }

            {
                TypeDesc result = _testModule.GetTypeByCustomAttributeTypeName("TypeNameParsing.VeryGeneric`3");
                Assert.Equal(_veryGenericType, result);
            }
        }