diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutFieldDesc.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutFieldDesc.cs index 056cb26016ef4..b658f1dc49c3a 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutFieldDesc.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutFieldDesc.cs @@ -39,6 +39,8 @@ public override TypeDesc FieldType } } + public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; + public override bool HasRva { get diff --git a/src/coreclr/tools/Common/TypeSystem/Common/FieldDesc.cs b/src/coreclr/tools/Common/TypeSystem/Common/FieldDesc.cs index ad44d48574795..23bd5ba923a54 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/FieldDesc.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/FieldDesc.cs @@ -45,6 +45,9 @@ public abstract TypeDesc FieldType get; } + // Get the embedded signature data used to hold custom modifiers and such within a field signature + public abstract EmbeddedSignatureData[] GetEmbeddedSignatureData(); + public abstract bool IsStatic { get; diff --git a/src/coreclr/tools/Common/TypeSystem/Common/FieldForInstantiatedType.cs b/src/coreclr/tools/Common/TypeSystem/Common/FieldForInstantiatedType.cs index b51d55660a686..fbc456a830639 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/FieldForInstantiatedType.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/FieldForInstantiatedType.cs @@ -51,6 +51,11 @@ public override TypeDesc FieldType } } + public override EmbeddedSignatureData[] GetEmbeddedSignatureData() + { + return _fieldDef.GetEmbeddedSignatureData(); + } + public override bool IsStatic { get diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs index b6d5e4fd41f8b..6ba7907106dd6 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs @@ -113,6 +113,19 @@ public override TypeDesc FieldType } } + // This is extremely rarely needed. Don't cache it at all. + public override EmbeddedSignatureData[] GetEmbeddedSignatureData() + { + var metadataReader = MetadataReader; + BlobReader signatureReader = metadataReader.GetBlobReader(metadataReader.GetFieldDefinition(_handle).Signature); + + EcmaSignatureParser parser = new EcmaSignatureParser(Module, signatureReader, NotFoundBehavior.Throw); + var fieldType = parser.ParseFieldSignature(out var embeddedSig); + Debug.Assert(fieldType == FieldType); + return embeddedSig; + } + + [MethodImpl(MethodImplOptions.NoInlining)] private int InitializeFieldFlags(int mask) { diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs index 2247f551fc29d..f2530ec8b19d7 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs @@ -471,6 +471,25 @@ public TypeDesc ParseFieldSignature() return ParseType(); } + public TypeDesc ParseFieldSignature(out EmbeddedSignatureData[] embeddedSigData) + { + try + { + _indexStack = new Stack(); + _indexStack.Push(1); + _indexStack.Push(0); + _embeddedSignatureDataList = new List(); + TypeDesc parsedType = ParseFieldSignature(); + embeddedSigData = _embeddedSignatureDataList.Count == 0 ? null : _embeddedSignatureDataList.ToArray(); + return parsedType; + } + finally + { + _indexStack = null; + _embeddedSignatureDataList = null; + } + } + public LocalVariableDefinition[] ParseLocalsSignature() { if (_reader.ReadSignatureHeader().Kind != SignatureKind.LocalVariables) diff --git a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs index c2a44b01653a5..5b49bfdb50faa 100644 --- a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs +++ b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs @@ -56,6 +56,8 @@ public override TypeDesc FieldType } } + public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; + public override bool HasRva { get diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/InlineArrayType.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/InlineArrayType.cs index 4cf06e8b6bfb4..51ac01f9a2fb6 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/InlineArrayType.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/InlineArrayType.cs @@ -441,6 +441,7 @@ public override TypeDesc FieldType return _owningType.ElementType; } } + public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; public override bool HasRva { diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/NativeStructType.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/NativeStructType.cs index bf5e0c6ef3d7b..149987476b3a3 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/NativeStructType.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/NativeStructType.cs @@ -348,6 +348,8 @@ public override TypeDesc FieldType } } + public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; + public override bool HasRva { get diff --git a/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs b/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs index 5a47094605c9e..46110f26bb2a8 100644 --- a/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs +++ b/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs @@ -18,14 +18,18 @@ class TypeSystemMetadataEmitter MetadataBuilder _metadataBuilder; BlobBuilder _ilBuilder; MethodBodyStreamEncoder _methodBodyStream; + Dictionary _assemblyRefNameHandles = new Dictionary(); Dictionary _assemblyRefs = new Dictionary(); Dictionary _typeRefs = new Dictionary(); Dictionary _methodRefs = new Dictionary(); + Dictionary _fieldRefs = new Dictionary(); Blob _mvidFixup; BlobHandle _noArgsVoidReturnStaticMethodSigHandle; + protected TypeSystemContext _typeSystemContext; - public TypeSystemMetadataEmitter(AssemblyName assemblyName, TypeSystemContext context, AssemblyFlags flags = default(AssemblyFlags)) + public TypeSystemMetadataEmitter(AssemblyName assemblyName, TypeSystemContext context, AssemblyFlags flags = default(AssemblyFlags), byte[] publicKeyArray = null, AssemblyHashAlgorithm hashAlgorithm = AssemblyHashAlgorithm.None) { + _typeSystemContext = context; _metadataBuilder = new MetadataBuilder(); _ilBuilder = new BlobBuilder(); _methodBodyStream = new MethodBodyStreamEncoder(_ilBuilder); @@ -33,21 +37,11 @@ class TypeSystemMetadataEmitter if (assemblyName.CultureName != null) throw new ArgumentException("assemblyName"); - if (assemblyName.GetPublicKeyToken() != null) - throw new ArgumentException("assemblyName"); - var mvid = _metadataBuilder.ReserveGuid(); _mvidFixup = mvid.Content; _metadataBuilder.AddModule(0, assemblyNameHandle, mvid.Handle, default(GuidHandle), default(GuidHandle)); - _metadataBuilder.AddAssembly(assemblyNameHandle, assemblyName.Version ?? new Version(0,0,0,0), default(StringHandle), default(BlobHandle), flags, AssemblyHashAlgorithm.None); - - var canonAssemblyNameHandle = _metadataBuilder.GetOrAddString("System.Private.Canon"); - var canonAssemblyRef = _metadataBuilder.AddAssemblyReference(canonAssemblyNameHandle, new Version(0, 0, 0, 0), default(StringHandle), default(BlobHandle), (AssemblyFlags)0, default(BlobHandle)); - var systemStringHandle = _metadataBuilder.GetOrAddString("System"); - var canonStringHandle = _metadataBuilder.GetOrAddString("__Canon"); - var canonTypeRef = _metadataBuilder.AddTypeReference(canonAssemblyRef, systemStringHandle, canonStringHandle); - _typeRefs.Add(context.CanonType, canonTypeRef); + _metadataBuilder.AddAssembly(assemblyNameHandle, assemblyName.Version ?? new Version(0,0,0,0), default(StringHandle), publicKey: publicKeyArray != null ? _metadataBuilder.GetOrAddBlob(publicKeyArray) : default(BlobHandle), flags, AssemblyHashAlgorithm.None); _metadataBuilder.AddTypeDefinition( default(TypeAttributes), @@ -56,7 +50,20 @@ class TypeSystemMetadataEmitter baseType: default(EntityHandle), fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: MetadataTokens.MethodDefinitionHandle(1)); + } + public void InjectSystemPrivateCanon() + { + var canonAssemblyNameHandle = _metadataBuilder.GetOrAddString("System.Private.Canon"); + var canonAssemblyRef = _metadataBuilder.AddAssemblyReference(canonAssemblyNameHandle, new Version(0, 0, 0, 0), default(StringHandle), default(BlobHandle), (AssemblyFlags)0, default(BlobHandle)); + var systemStringHandle = _metadataBuilder.GetOrAddString("System"); + var canonStringHandle = _metadataBuilder.GetOrAddString("__Canon"); + var canonTypeRef = _metadataBuilder.AddTypeReference(canonAssemblyRef, systemStringHandle, canonStringHandle); + _typeRefs.Add(_typeSystemContext.CanonType, canonTypeRef); + } + + public void AllowUseOfAddGlobalMethod() + { BlobBuilder noArgsNoReturnStaticMethodSig = new BlobBuilder(); BlobEncoder signatureEncoder = new BlobEncoder(noArgsNoReturnStaticMethodSig); @@ -79,6 +86,8 @@ public MethodDefinitionHandle AddGlobalMethod(string name, InstructionEncoder il private static readonly Guid s_guid = new Guid("97F4DBD4-F6D1-4FAD-91B3-1001F92068E5"); private static readonly BlobContentId s_contentId = new BlobContentId(s_guid, 0x04030201); + public MetadataBuilder Builder => _metadataBuilder; + public void SerializeToStream(Stream peStream) { var peHeaderBuilder = new PEHeaderBuilder(); @@ -91,6 +100,47 @@ public void SerializeToStream(Stream peStream) peBlob.WriteContentTo(peStream); } + // Generate only the metadata blob as a byte[] + public byte[] EmitToMetadataBlob() + { + MetadataRootBuilder metadataRootBuilder = new MetadataRootBuilder(_metadataBuilder); + BlobBuilder metadataBlobBuilder = new BlobBuilder(); + metadataRootBuilder.Serialize(metadataBlobBuilder, methodBodyStreamRva: 0, mappedFieldDataStreamRva: 0); + + // Clear some variables to catch any caller trying to emit data after writing the output file + _metadataBuilder = null; + + return metadataBlobBuilder.ToArray(); + } + + public AssemblyReferenceHandle GetAssemblyRef(AssemblyName name) + { + if (!_assemblyRefNameHandles.TryGetValue(name.FullName, out var handle)) + { + StringHandle assemblyName = _metadataBuilder.GetOrAddString(name.Name); + StringHandle cultureName = (name.CultureName != null) ? _metadataBuilder.GetOrAddString(name.CultureName) : default(StringHandle); + BlobHandle publicTokenBlob = name.GetPublicKeyToken() != null ? _metadataBuilder.GetOrAddBlob(name.GetPublicKeyToken()) : default(BlobHandle); + AssemblyFlags flags = default(AssemblyFlags); + if (name.Flags.HasFlag(AssemblyNameFlags.Retargetable)) + { + flags |= AssemblyFlags.Retargetable; + } + if (name.ContentType == AssemblyContentType.WindowsRuntime) + { + flags |= AssemblyFlags.WindowsRuntime; + } + + Version version = name.Version; + if (version == null) + version = new Version(0, 0); + + handle = _metadataBuilder.AddAssemblyReference(assemblyName, version, cultureName, publicTokenBlob, flags, default(BlobHandle)); + + _assemblyRefNameHandles[name.FullName] = handle; + } + return handle; + } + public AssemblyReferenceHandle GetAssemblyRef(IAssemblyDesc assemblyDesc) { if (_assemblyRefs.TryGetValue(assemblyDesc, out var handle)) @@ -98,26 +148,50 @@ public AssemblyReferenceHandle GetAssemblyRef(IAssemblyDesc assemblyDesc) return handle; } AssemblyName name = assemblyDesc.GetName(); - StringHandle assemblyName = _metadataBuilder.GetOrAddString(name.Name); - StringHandle cultureName = (name.CultureName != null) ? _metadataBuilder.GetOrAddString(name.CultureName) : default(StringHandle); - BlobHandle publicTokenBlob = name.GetPublicKeyToken() != null ? _metadataBuilder.GetOrAddBlob(name.GetPublicKeyToken()) : default(BlobHandle); - AssemblyFlags flags = default(AssemblyFlags); - if (name.Flags.HasFlag(AssemblyNameFlags.Retargetable)) + var referenceHandle = GetAssemblyRef(name); + _assemblyRefs.Add(assemblyDesc, referenceHandle); + return referenceHandle; + } + + public EntityHandle EmitMetadataHandleForTypeSystemEntity(TypeSystemEntity entity) + { + switch (entity) { - flags |= AssemblyFlags.Retargetable; + case FieldDesc field: return GetFieldRef(field); + case MethodDesc method: return GetMethodRef(method); + case TypeDesc type: return GetTypeRef(type); + case ModuleDesc assembly: return GetAssemblyRef(assembly.Assembly); + case MethodSignature methodSignature: return GetStandaloneSig(methodSignature); + + default: + throw new NotSupportedException(); } - if (name.ContentType == AssemblyContentType.WindowsRuntime) + } + + public IEnumerable> TypeSystemEntitiesKnown + { + get { - flags |= AssemblyFlags.WindowsRuntime; - } + foreach (var item in _typeRefs) + { + yield return new KeyValuePair(item.Key, item.Value); + } - Version version = name.Version; - if (version == null) - version = new Version(0, 0); + foreach (var item in _methodRefs) + { + yield return new KeyValuePair(item.Key, item.Value); + } - var referenceHandle = _metadataBuilder.AddAssemblyReference(assemblyName, version, cultureName, publicTokenBlob, flags, default(BlobHandle)); - _assemblyRefs.Add(assemblyDesc, referenceHandle); - return referenceHandle; + foreach (var item in _fieldRefs) + { + yield return new KeyValuePair(item.Key, item.Value); + } + } + } + + protected virtual EntityHandle GetNonNestedResolutionScope(MetadataType metadataType) + { + return GetAssemblyRef(metadataType.Module.Assembly); } public EntityHandle GetTypeRef(TypeDesc type) @@ -144,7 +218,7 @@ public EntityHandle GetTypeRef(TypeDesc type) if (metadataType.ContainingType == null) { // non-nested type - resolutionScope = GetAssemblyRef(metadataType.Module.Assembly); + resolutionScope = GetNonNestedResolutionScope(metadataType); } else { @@ -166,6 +240,58 @@ public EntityHandle GetTypeRef(TypeDesc type) return typeHandle; } + private BlobHandle GetMethodSignatureBlobHandle(MethodSignature sig) + { + EmbeddedSignatureDataEmitter signatureDataEmitter; + if (sig.HasEmbeddedSignatureData) + { + signatureDataEmitter = new EmbeddedSignatureDataEmitter(sig.GetEmbeddedSignatureData(), this); + } + else + { + signatureDataEmitter = EmbeddedSignatureDataEmitter.EmptySingleton; + } + + BlobBuilder memberRefSig = new BlobBuilder(); + EncodeMethodSignature(memberRefSig, sig, signatureDataEmitter); + + if (!signatureDataEmitter.Complete) + throw new ArgumentException(); + + var sigBlob = _metadataBuilder.GetOrAddBlob(memberRefSig); + return sigBlob; + } + + private BlobHandle GetFieldSignatureBlobHandle(FieldDesc field) + { + var fieldDef = field.GetTypicalFieldDefinition(); + var embeddedSigData = field.GetEmbeddedSignatureData(); + EmbeddedSignatureDataEmitter signatureDataEmitter; + if (embeddedSigData != null && embeddedSigData.Length != 0) + { + signatureDataEmitter = new EmbeddedSignatureDataEmitter(embeddedSigData, this); + } + else + { + signatureDataEmitter = EmbeddedSignatureDataEmitter.EmptySingleton; + } + + BlobBuilder memberRefSig = new BlobBuilder(); + EncodeFieldSignature(memberRefSig, field.FieldType, signatureDataEmitter); + + if (!signatureDataEmitter.Complete) + throw new ArgumentException(); + + var sigBlob = _metadataBuilder.GetOrAddBlob(memberRefSig); + return sigBlob; + } + + public EntityHandle GetStandaloneSig(MethodSignature sig) + { + var sigBlob = GetMethodSignatureBlobHandle(sig); + return _metadataBuilder.AddStandaloneSignature(sigBlob); + } + public EntityHandle GetMethodRef(MethodDesc method) { if (_methodRefs.TryGetValue(method, out var handle)) @@ -192,24 +318,8 @@ public EntityHandle GetMethodRef(MethodDesc method) EntityHandle typeHandle = GetTypeRef((MetadataType)method.OwningType); StringHandle methodName = _metadataBuilder.GetOrAddString(method.Name); var sig = method.GetTypicalMethodDefinition().Signature; + var sigBlob = GetMethodSignatureBlobHandle(sig); - EmbeddedSignatureDataEmitter signatureDataEmitter; - if (sig.HasEmbeddedSignatureData) - { - signatureDataEmitter = new EmbeddedSignatureDataEmitter(sig.GetEmbeddedSignatureData(), this); - } - else - { - signatureDataEmitter = EmbeddedSignatureDataEmitter.EmptySingleton; - } - - BlobBuilder memberRefSig = new BlobBuilder(); - EncodeMethodSignature(memberRefSig, sig, signatureDataEmitter); - - if (!signatureDataEmitter.Complete) - throw new ArgumentException(); - - var sigBlob = _metadataBuilder.GetOrAddBlob(memberRefSig); methodHandle = _metadataBuilder.AddMemberReference(typeHandle, methodName, sigBlob); } @@ -217,6 +327,25 @@ public EntityHandle GetMethodRef(MethodDesc method) return methodHandle; } + public EntityHandle GetFieldRef(FieldDesc field) + { + if (_fieldRefs.TryGetValue(field, out var handle)) + { + return handle; + } + + EntityHandle fieldHandle; + + EntityHandle typeHandle = GetTypeRef((MetadataType)field.OwningType); + StringHandle fieldName = _metadataBuilder.GetOrAddString(field.Name); + + var sigBlob = GetFieldSignatureBlobHandle(field.GetTypicalFieldDefinition()); + fieldHandle = _metadataBuilder.AddMemberReference(typeHandle, fieldName, sigBlob); + + _fieldRefs.Add(field, fieldHandle); + return fieldHandle; + } + private void EncodeType(BlobBuilder blobBuilder, TypeDesc type, EmbeddedSignatureDataEmitter signatureDataEmitter) { signatureDataEmitter.Push(); @@ -543,6 +672,15 @@ void EncodeMethodSignature(BlobBuilder signatureBuilder, MethodSignature sig, Em signatureDataEmitter.Pop(); } + void EncodeFieldSignature(BlobBuilder signatureBuilder, TypeDesc fieldType, EmbeddedSignatureDataEmitter signatureDataEmitter) + { + signatureDataEmitter.Push(); + BlobEncoder signatureEncoder = new BlobEncoder(signatureBuilder); + signatureEncoder.FieldSignature(); + EncodeType(signatureBuilder, fieldType, signatureDataEmitter); + signatureDataEmitter.Pop(); + } + public UserStringHandle GetUserStringHandle(string userString) { return _metadataBuilder.GetOrAddUserString(userString); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExternSymbolMappedField.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExternSymbolMappedField.cs index 2ee25f4dc7c3b..8a4bce713efe4 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExternSymbolMappedField.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExternSymbolMappedField.cs @@ -26,6 +26,7 @@ public ExternSymbolMappedField(TypeDesc fieldType, string symbolName) public override DefType OwningType => _fieldType.Context.SystemModule.GetGlobalModuleType(); public override TypeDesc FieldType => _fieldType; + public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; public override bool IsStatic => true; diff --git a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/ILTestAssembly/Signature.il b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/ILTestAssembly/Signature.il index 32e307b7036c8..5a528fda34d77 100644 --- a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/ILTestAssembly/Signature.il +++ b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/ILTestAssembly/Signature.il @@ -39,6 +39,8 @@ { ret } + + .field private bool modreq([CoreTestAssembly]System.Void) fieldWithModOpt } .class private auto ansi beforefieldinit Atom diff --git a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/SignatureTests.cs b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/SignatureTests.cs index ac8d2bc168372..23e1a9f58cfe2 100644 --- a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/SignatureTests.cs +++ b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/SignatureTests.cs @@ -197,6 +197,35 @@ public void TestSerializedSignatureWithReferenceToMDIntArray() Assert.Equal(typeInLookupContext, int32ArrayFromLookup); } + [Fact] + public void TestSerializedSignatureWithReferenceToFieldWithModOpt() + { + + MetadataType modOptTester = _testModule.GetType("", "ModOptTester"); + FieldDesc fieldWithModOpt = modOptTester.GetFields().Single(m => string.Equals(m.Name, "fieldWithModOpt")); + + // Create assembly with reference to interesting method + TypeSystemMetadataEmitter metadataEmitter = new TypeSystemMetadataEmitter(new System.Reflection.AssemblyName("Lookup"), _context); + var token = metadataEmitter.GetFieldRef(fieldWithModOpt); + MemoryStream peStream = new MemoryStream(); + metadataEmitter.SerializeToStream(peStream); + + peStream.Seek(0, SeekOrigin.Begin); + + // Create new TypeSystemContext with just created assembly inside + var lookupContext = new TestTypeSystemContext(TargetArchitecture.X64); + var systemModule = lookupContext.CreateModuleForSimpleName("CoreTestAssembly"); + lookupContext.SetSystemModule(systemModule); + + lookupContext.CreateModuleForSimpleName("Lookup", peStream); + + // Use generated assembly to trigger a load through the token created above and verify that it loads correctly + var ilLookupModule = (EcmaModule)lookupContext.GetModuleForSimpleName("Lookup"); + FieldDesc fieldFound = ilLookupModule.GetField(token); + + Assert.Equal("fieldWithModOpt", fieldFound.Name); + } + [Fact] public void TestMDArrayFunctionReading() { diff --git a/src/coreclr/tools/dotnet-pgo/MibcEmitter.cs b/src/coreclr/tools/dotnet-pgo/MibcEmitter.cs index a498bfd9e21d5..e99fc610d86ca 100644 --- a/src/coreclr/tools/dotnet-pgo/MibcEmitter.cs +++ b/src/coreclr/tools/dotnet-pgo/MibcEmitter.cs @@ -215,6 +215,8 @@ private static void AddAssembliesAssociatedWithMethod(MethodDesc method, HashSet public static int GenerateMibcFile(TypeSystemContext tsc, FileInfo outputFileName, IEnumerable methodsToAttemptToPlaceIntoProfileData, bool validate, bool uncompressed) { TypeSystemMetadataEmitter emitter = new TypeSystemMetadataEmitter(new AssemblyName(outputFileName.Name), tsc); + emitter.InjectSystemPrivateCanon(); + emitter.AllowUseOfAddGlobalMethod(); SortedDictionary groups = new SortedDictionary(); StringBuilder mibcGroupNameBuilder = new StringBuilder(); diff --git a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemContext.cs b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemContext.cs index bb32521c0b750..31a5caee14c23 100644 --- a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemContext.cs +++ b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemContext.cs @@ -153,8 +153,8 @@ public TypeRefTypeSystemContext(IEnumerable refReaders) } else { - var fieldType = ecmaSigParse.ParseFieldSignature(); - ownerType.GetOrAddField(name, fieldType); + var fieldType = ecmaSigParse.ParseFieldSignature(out var embeddedSigData); + ownerType.GetOrAddField(name, fieldType, embeddedSigData); } } diff --git a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemField.cs b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemField.cs index 5f261b4932c3f..a380db86080bc 100644 --- a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemField.cs +++ b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemField.cs @@ -15,12 +15,14 @@ class TypeRefTypeSystemField : FieldDesc TypeRefTypeSystemType _type; string _name; TypeDesc _fieldType; + EmbeddedSignatureData[] _embeddedSignatureData; - public TypeRefTypeSystemField(TypeRefTypeSystemType type, string name, TypeDesc fieldType) + public TypeRefTypeSystemField(TypeRefTypeSystemType type, string name, TypeDesc fieldType, EmbeddedSignatureData[] embeddedSigData) { _type = type; _name = name; _fieldType = fieldType; + _embeddedSignatureData = embeddedSigData; } public override string Name => _name; @@ -28,6 +30,8 @@ public TypeRefTypeSystemField(TypeRefTypeSystemType type, string name, TypeDesc public override TypeDesc FieldType => _fieldType; + public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => _embeddedSignatureData; + public override bool IsStatic => throw new NotImplementedException(); public override bool IsInitOnly => throw new NotImplementedException(); diff --git a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemType.cs b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemType.cs index 6b5689805e93c..af3bb5ae72c24 100644 --- a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemType.cs +++ b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemType.cs @@ -119,12 +119,12 @@ public MethodDesc GetOrAddMethod(string name, MethodSignature signature) return method; } - public FieldDesc GetOrAddField(string name, TypeDesc fieldType) + public FieldDesc GetOrAddField(string name, TypeDesc fieldType, EmbeddedSignatureData[] embeddedSigData) { FieldDesc fld = GetField(name); if (fld == null) { - TypeRefTypeSystemField newField = new TypeRefTypeSystemField(this, name, fieldType); + TypeRefTypeSystemField newField = new TypeRefTypeSystemField(this, name, fieldType, embeddedSigData); fld = newField; _fields.Add(newField); }