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."); } }
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(); } } }
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"); } } }
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; }
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 })); }
/// <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); }
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"); } } }
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)); }
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); } }