Add support for parsing and working with CustomModifiers in field signatures and...
authorDavid Wrighton <davidwr@microsoft.com>
Fri, 10 Jun 2022 23:14:44 +0000 (16:14 -0700)
committerGitHub <noreply@github.com>
Fri, 10 Jun 2022 23:14:44 +0000 (16:14 -0700)
- Update TypeSystemMetadataEmitter to be able to generate a field signature given an appropriate array of EmbeddedSignatureData[]
- Add api to FieldDesc to allow the custom modifier data to be handled using the same scheme as custom modifier data on method signatures
- Adjust TypeSystemMetadataEmitter to be able to generate metadata not just for the Mibc emitter
  - The current implementation has some default behavior around creating metadata that is in the constructor. Break that out into helper functions so that other scenarios don't need to run that code.
  - Add an entrypoint for generating metadata for an arbitrary TypeSystemEntity
  - Add a feature to allow it the ResolutionScope of a non-nested type to be managed specially. This will be needed by #68919

16 files changed:
src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutFieldDesc.cs
src/coreclr/tools/Common/TypeSystem/Common/FieldDesc.cs
src/coreclr/tools/Common/TypeSystem/Common/FieldForInstantiatedType.cs
src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs
src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs
src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs
src/coreclr/tools/Common/TypeSystem/Interop/IL/InlineArrayType.cs
src/coreclr/tools/Common/TypeSystem/Interop/IL/NativeStructType.cs
src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExternSymbolMappedField.cs
src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/ILTestAssembly/Signature.il
src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/SignatureTests.cs
src/coreclr/tools/dotnet-pgo/MibcEmitter.cs
src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemContext.cs
src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemField.cs
src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemType.cs

index 056cb26..b658f1d 100644 (file)
@@ -39,6 +39,8 @@ namespace Internal.Runtime.TypeLoader
             }
         }
 
+        public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null;
+
         public override bool HasRva
         {
             get
index ad44d48..23bd5ba 100644 (file)
@@ -45,6 +45,9 @@ namespace Internal.TypeSystem
             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;
index b51d556..fbc456a 100644 (file)
@@ -51,6 +51,11 @@ namespace Internal.TypeSystem
             }
         }
 
+        public override EmbeddedSignatureData[] GetEmbeddedSignatureData()
+        {
+            return _fieldDef.GetEmbeddedSignatureData();
+        }
+
         public override bool IsStatic
         {
             get
index b6d5e4f..6ba7907 100644 (file)
@@ -113,6 +113,19 @@ namespace Internal.TypeSystem.Ecma
             }
         }
 
+        // 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)
         {
index 2247f55..f2530ec 100644 (file)
@@ -471,6 +471,25 @@ namespace Internal.TypeSystem.Ecma
             return ParseType();
         }
 
+        public TypeDesc ParseFieldSignature(out EmbeddedSignatureData[] embeddedSigData)
+        {
+            try
+            {
+                _indexStack = new Stack<int>();
+                _indexStack.Push(1);
+                _indexStack.Push(0);
+                _embeddedSignatureDataList = new List<EmbeddedSignatureData>();
+                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)
index c2a44b0..5b49bfd 100644 (file)
@@ -56,6 +56,8 @@ namespace Internal.IL.Stubs
             }
         }
 
+        public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null;
+
         public override bool HasRva
         {
             get
index 4cf06e8..51ac01f 100644 (file)
@@ -441,6 +441,7 @@ namespace Internal.TypeSystem.Interop
                     return _owningType.ElementType;
                 }
             }
+            public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null;
 
             public override bool HasRva
             {
index bf5e0c6..1499874 100644 (file)
@@ -348,6 +348,8 @@ namespace Internal.TypeSystem.Interop
                 }
             }
 
+            public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null;
+
             public override bool HasRva
             {
                 get
index 5a47094..46110f2 100644 (file)
@@ -18,14 +18,18 @@ namespace Internal.TypeSystem
         MetadataBuilder _metadataBuilder;
         BlobBuilder _ilBuilder;
         MethodBodyStreamEncoder _methodBodyStream;
+        Dictionary<string, AssemblyReferenceHandle> _assemblyRefNameHandles = new Dictionary<string, AssemblyReferenceHandle>();
         Dictionary<IAssemblyDesc, AssemblyReferenceHandle> _assemblyRefs = new Dictionary<IAssemblyDesc, AssemblyReferenceHandle>();
         Dictionary<TypeDesc, EntityHandle> _typeRefs = new Dictionary<TypeDesc, EntityHandle>();
         Dictionary<MethodDesc, EntityHandle> _methodRefs = new Dictionary<MethodDesc, EntityHandle>();
+        Dictionary<FieldDesc, EntityHandle> _fieldRefs = new Dictionary<FieldDesc, EntityHandle>();
         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 @@ namespace Internal.TypeSystem
             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 @@ namespace Internal.TypeSystem
                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 @@ namespace Internal.TypeSystem
         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 @@ namespace Internal.TypeSystem
             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 @@ namespace Internal.TypeSystem
                 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<KeyValuePair<TypeSystemEntity, EntityHandle>> TypeSystemEntitiesKnown
+        {
+            get
             {
-                flags |= AssemblyFlags.WindowsRuntime;
-            }
+                foreach (var item in _typeRefs)
+                {
+                    yield return new KeyValuePair<TypeSystemEntity, EntityHandle>(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<TypeSystemEntity, EntityHandle>(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<TypeSystemEntity, EntityHandle>(item.Key, item.Value);
+                }
+            }
+        }
+
+        protected virtual EntityHandle GetNonNestedResolutionScope(MetadataType metadataType)
+        {
+            return GetAssemblyRef(metadataType.Module.Assembly);
         }
 
         public EntityHandle GetTypeRef(TypeDesc type)
@@ -144,7 +218,7 @@ namespace Internal.TypeSystem
                 if (metadataType.ContainingType == null)
                 {
                     // non-nested type
-                    resolutionScope = GetAssemblyRef(metadataType.Module.Assembly);
+                    resolutionScope = GetNonNestedResolutionScope(metadataType);
                 }
                 else
                 {
@@ -166,6 +240,58 @@ namespace Internal.TypeSystem
             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 @@ namespace Internal.TypeSystem
                 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 @@ namespace Internal.TypeSystem
             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 @@ namespace Internal.TypeSystem
             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);
index 2ee25f4..8a4bce7 100644 (file)
@@ -26,6 +26,7 @@ namespace ILCompiler
         public override DefType OwningType => _fieldType.Context.SystemModule.GetGlobalModuleType();
 
         public override TypeDesc FieldType => _fieldType;
+        public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null;
 
         public override bool IsStatic => true;
 
index 32e307b..5a528fd 100644 (file)
@@ -39,6 +39,8 @@
   {
      ret
   }
+
+  .field private bool modreq([CoreTestAssembly]System.Void) fieldWithModOpt
 }
 
 .class private auto ansi beforefieldinit Atom
index ac8d2bc..23e1a9f 100644 (file)
@@ -198,6 +198,35 @@ namespace TypeSystemTests
         }
 
         [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()
         {
             MetadataType mdArrayFunctionResolutionType = _testModule.GetType("", "MDArrayFunctionResolution");
index a498bfd..e99fc61 100644 (file)
@@ -215,6 +215,8 @@ namespace Microsoft.Diagnostics.Tools.Pgo
         public static int GenerateMibcFile(TypeSystemContext tsc, FileInfo outputFileName, IEnumerable<MethodProfileData> methodsToAttemptToPlaceIntoProfileData, bool validate, bool uncompressed)
         {
             TypeSystemMetadataEmitter emitter = new TypeSystemMetadataEmitter(new AssemblyName(outputFileName.Name), tsc);
+            emitter.InjectSystemPrivateCanon();
+            emitter.AllowUseOfAddGlobalMethod();
 
             SortedDictionary<string, MIbcGroup> groups = new SortedDictionary<string, MIbcGroup>();
             StringBuilder mibcGroupNameBuilder = new StringBuilder();
index bb32521..31a5cae 100644 (file)
@@ -153,8 +153,8 @@ namespace Microsoft.Diagnostics.Tools.Pgo.TypeRefTypeSystem
                     }
                     else
                     {
-                        var fieldType = ecmaSigParse.ParseFieldSignature();
-                        ownerType.GetOrAddField(name, fieldType);
+                        var fieldType = ecmaSigParse.ParseFieldSignature(out var embeddedSigData);
+                        ownerType.GetOrAddField(name, fieldType, embeddedSigData);
                     }
                 }
 
index 5f261b4..a380db8 100644 (file)
@@ -15,12 +15,14 @@ namespace Microsoft.Diagnostics.Tools.Pgo.TypeRefTypeSystem
         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 @@ namespace Microsoft.Diagnostics.Tools.Pgo.TypeRefTypeSystem
 
         public override TypeDesc FieldType => _fieldType;
 
+        public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => _embeddedSignatureData;
+
         public override bool IsStatic => throw new NotImplementedException();
 
         public override bool IsInitOnly => throw new NotImplementedException();
index 6b56898..af3bb5a 100644 (file)
@@ -119,12 +119,12 @@ namespace Microsoft.Diagnostics.Tools.Pgo.TypeRefTypeSystem
             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);
             }