Fix remaining COM warnings in crossgen2 (#65297)
authorAndy Gocke <andy@commentout.net>
Thu, 3 Mar 2022 06:12:26 +0000 (22:12 -0800)
committerGitHub <noreply@github.com>
Thu, 3 Mar 2022 06:12:26 +0000 (22:12 -0800)
src/coreclr/tools/Common/TypeSystem/Ecma/SymbolReader/UnmanagedPdbSymbolReader.cs
src/coreclr/tools/aot/Directory.Build.props [new file with mode: 0644]
src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj
src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler.MetadataTransform.csproj
src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj
src/coreclr/tools/aot/ILCompiler.TypeSystem/ILCompiler.TypeSystem.csproj
src/coreclr/tools/aot/crossgen2/crossgen2.props

index 7742879..798db1e 100644 (file)
@@ -1,9 +1,14 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
+#nullable enable
+
 using System;
 using System.Collections.Generic;
 using System.Runtime.InteropServices;
+using System.Collections;
+using System.Diagnostics;
+using System.Runtime.InteropServices.ComTypes;
 
 #if !DISABLE_UNMANAGED_PDB_SYMBOLS
 using Microsoft.DiaSymReader;
@@ -30,69 +35,422 @@ namespace Internal.TypeSystem.Ecma
     /// </summary>
     public sealed class UnmanagedPdbSymbolReader : PdbSymbolReader
     {
-        [DllImport("mscoree.dll")]
-        private static extern int CLRCreateInstance([In] ref Guid clsid, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out ICLRMetaHost ppInterface);
+        private static int CLRCreateInstance(ref Guid clsid, ref Guid riid, out ClrMetaHostWrapperCache.ClrMetaHostRcw? ppInterface)
+        {
+            int hr = CLRCreateInstance(ref clsid, ref riid, out IntPtr ptr);
+            ppInterface = hr == 0
+                ? (ClrMetaHostWrapperCache.ClrMetaHostRcw)ClrMetaHostWrapperCache.Instance.GetOrCreateObjectForComInstance(ptr, CreateObjectFlags.UniqueInstance)
+                : null;
+            return hr;
+
+            [DllImport("mscoree.dll")]
+            static extern int CLRCreateInstance(ref Guid clsid, ref Guid riid, out IntPtr ptr);
+        }
 
-        [Guid("d332db9e-b9b3-4125-8207-a14884f53216")]
-        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
-        [ComVisible(true)]
         interface ICLRMetaHost
         {
+            public static readonly Guid IID = new Guid("d332db9e-b9b3-4125-8207-a14884f53216");
+
             [PreserveSig]
-            int GetRuntime([In, MarshalAs(UnmanagedType.LPWStr)] String pwzVersion, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out ICLRRuntimeInfo ppRuntime);
+            int GetRuntime(string pwzVersion, ref Guid riid, out CLRRuntimeInfoWrapperCache.ClrRuntimeInfoRcw? ppRuntime);
 
             // Don't need any other methods.
         }
 
-        [Guid("bd39d1d2-ba2f-486a-89b0-b4b0cb466891")]
-        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
-        [ComVisible(true)]
-        interface ICLRRuntimeInfo
+        private sealed class ClrMetaHostWrapperCache : ComWrappers
         {
-            void GetVersionString_Placeholder();
-            void GetRuntimeDirectory_Placeholder();
-            void IsLoaded_Placeholder();
-            void LoadErrorString_Placeholder();
-            void LoadLibrary_Placeholder();
-            void GetProcAddress_Placeholder();
+            public static readonly ClrMetaHostWrapperCache Instance = new ClrMetaHostWrapperCache();
+            private ClrMetaHostWrapperCache() { }
 
-            [PreserveSig]
-            int GetInterface([In] ref Guid rclsid, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.IUnknown)] out Object ppUnk);
+            protected override unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) => throw new NotImplementedException();
+            protected override object CreateObject(IntPtr externalComObject, CreateObjectFlags flags)
+            {
+                Debug.Assert(flags == CreateObjectFlags.UniqueInstance);
 
-            void IsLoadable_Placeholder();
-            void SetDefaultStartupFlags_Placeholder();
-            void GetDefaultStartupFlags_Placeholder();
+                var iid = ICLRMetaHost.IID;
+                if (Marshal.QueryInterface(externalComObject, ref iid, out IntPtr hostPtr) != 0)
+                {
+                    throw new ArgumentException("Expected ICLRMetaHost COM interface");
+                }
+                return new ClrMetaHostRcw(hostPtr);
+            }
+
+            protected override void ReleaseObjects(IEnumerable objects) => throw new NotImplementedException();
+
+            public unsafe class ClrMetaHostRcw : ICLRMetaHost, IDisposable
+            {
+                private bool _disposed;
+                private readonly IntPtr _inst;
+
+                public ClrMetaHostRcw(IntPtr inst)
+                {
+                    _inst = inst;
+                }
+                public int GetRuntime(string pwzVersion, ref Guid riid, out CLRRuntimeInfoWrapperCache.ClrRuntimeInfoRcw? ppRuntime)
+                {
+                    // ICLRMetaHost::GetRuntime() is 4th slot (0-based)
+                    var func = (delegate* unmanaged<IntPtr, char*, Guid*, IntPtr*, int>)(*(*(void***)_inst + 3));
+                    int hr;
+                    IntPtr runtimeInfoPtr;
+                    fixed (char* versionPtr = pwzVersion)
+                    fixed (Guid* riidPtr = &riid)
+                    {
+                        hr = func(_inst, versionPtr, riidPtr, &runtimeInfoPtr);
+                    }
+                    ppRuntime = hr == 0
+                        ? (CLRRuntimeInfoWrapperCache.ClrRuntimeInfoRcw)CLRRuntimeInfoWrapperCache.Instance.GetOrCreateObjectForComInstance(runtimeInfoPtr, CreateObjectFlags.UniqueInstance)
+                        : null;
+                    return hr;
+                }
+
+                public void Dispose()
+                {
+                    GC.SuppressFinalize(this);
+                    DisposeInternal();
+                }
+
+                private void DisposeInternal()
+                {
+                    if (_disposed)
+                        return;
+                    Marshal.Release(_inst);
+                    _disposed = true;
+                }
+
+                ~ClrMetaHostRcw()
+                {
+                    DisposeInternal();
+                }
+            }
+        }
+
+        interface ICLRRuntimeInfo
+        {
+            int GetInterface(ref Guid rclsid, ref Guid riid, out MetaDataDispenserWrapperCache.MetaDataDispenserRcw? ppUnk);
 
-            [PreserveSig]
             int BindAsLegacyV2Runtime();
 
             // Don't need any other methods.
         }
 
-        [Guid("809c652e-7396-11d2-9771-00a0c9b4d50c")]
-        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
-        [ComVisible(true)]
-        private interface IMetaDataDispenser
+        private class CLRRuntimeInfoWrapperCache : ComWrappers
         {
-            void DefineScope_Placeholder();
+            public static readonly CLRRuntimeInfoWrapperCache Instance = new CLRRuntimeInfoWrapperCache();
+            private CLRRuntimeInfoWrapperCache() { }
 
-            [PreserveSig]
-            int OpenScope([In, MarshalAs(UnmanagedType.LPWStr)] String szScope, [In] Int32 dwOpenFlags, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.IUnknown)] out Object punk);
+            protected override unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) => throw new NotImplementedException();
+            protected override object CreateObject(IntPtr externalComObject, CreateObjectFlags flags)
+            {
+                Debug.Assert(flags == CreateObjectFlags.UniqueInstance);
+
+                return new ClrRuntimeInfoRcw(externalComObject);
+            }
+            protected override void ReleaseObjects(IEnumerable objects) => throw new NotImplementedException();
+
+            public unsafe sealed record ClrRuntimeInfoRcw(IntPtr Inst) : ICLRRuntimeInfo, IDisposable
+            {
+                /// <summary>
+                /// List of offsets of methods in the vtable (0-based). First three are from IUnknown.
+                /// </summary>
+                private enum VtableOffset
+                {
+                    GetInterface = 9,
+                    BindAsLegacyV2Runtime = 13
+                }
+
+                private bool _disposed = false;
+
+                public int GetInterface(ref Guid rclsid, ref Guid riid, out MetaDataDispenserWrapperCache.MetaDataDispenserRcw? ppUnk)
+                {
+                    var func = (delegate* unmanaged<IntPtr, Guid*, Guid*, IntPtr*, int>)(*(*(void***)Inst + (int)VtableOffset.GetInterface));
+                    IntPtr outPtr;
+                    int hr;
+                    fixed (Guid* rclsidPtr = &rclsid)
+                    fixed (Guid* riidPtr = &riid)
+                    {
+                        hr = func(Inst, rclsidPtr, riidPtr, &outPtr);
+                    }
+                    ppUnk = hr == 0
+                        ? (MetaDataDispenserWrapperCache.MetaDataDispenserRcw)MetaDataDispenserWrapperCache.Instance.GetOrCreateObjectForComInstance(outPtr, CreateObjectFlags.UniqueInstance)
+                        : null;
+                    return hr;
+                }
+
+                [PreserveSig]
+                public int BindAsLegacyV2Runtime()
+                {
+                    var func = (delegate* unmanaged<IntPtr, int>)(*(*(void***)Inst + (int)VtableOffset.BindAsLegacyV2Runtime));
+                    return func(Inst);
+                }
+
+                public void Dispose()
+                {
+                    DisposeInternal();
+                    GC.SuppressFinalize(this);
+                }
+
+                private void DisposeInternal()
+                {
+                    if (_disposed)
+                    {
+                        return;
+                    }
+                    _disposed = true;
+                    Marshal.Release(Inst);
+                }
+
+                ~ClrRuntimeInfoRcw()
+                {
+                    DisposeInternal();
+                }
+            }
+        }
+
+        private interface IMetaDataDispenser
+        {
+            int OpenScope(string szScope, int dwOpenFlags, ref Guid riid, out MetadataImportRcw? punk);
 
             // Don't need any other methods.
         }
 
-        [DllImport("ole32.dll")]
-        private static extern int CoCreateInstance(ref Guid rclsid, IntPtr pUnkOuter,
+        private sealed class MetaDataDispenserWrapperCache : ComWrappers
+        {
+            public static readonly MetaDataDispenserWrapperCache Instance = new MetaDataDispenserWrapperCache();
+            private MetaDataDispenserWrapperCache() { }
+
+            protected override unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) => throw new NotImplementedException();
+            protected override object CreateObject(IntPtr externalComObject, CreateObjectFlags flags)
+            {
+                Debug.Assert(flags == CreateObjectFlags.UniqueInstance);
+
+                return new MetaDataDispenserRcw(externalComObject);
+            }
+            protected override void ReleaseObjects(IEnumerable objects) => throw new NotImplementedException();
+
+            public sealed unsafe record MetaDataDispenserRcw(IntPtr Inst) : IMetaDataDispenser, IDisposable
+            {
+                private bool _disposed = false;
+
+                /// <remarks>
+                /// <paramref="punk" /> is simply a boxed IntPtr, because we don't need an RCW.
+                /// </remarks>
+                public int OpenScope(string szScope, int dwOpenFlags, ref Guid riid, out MetadataImportRcw? pUnk)
+                {
+                    // IMetaDataDispenserRcw::OpenScope is slot 5 (0-based)
+                    var func = (delegate* unmanaged<IntPtr, char*, int, Guid*, IntPtr*, int>)(*(*(void***)Inst + 4));
+                    IntPtr outPtr;
+                    int hr;
+                    fixed (char* szScopePtr = szScope)
+                    fixed (Guid* riidPtr = &riid)
+                    {
+                        hr = func(Inst, szScopePtr, dwOpenFlags, riidPtr, &outPtr);
+                    }
+                    pUnk = hr == 0 ? new MetadataImportRcw(outPtr) : null;
+                    return hr;
+                }
+
+                public void Dispose()
+                {
+                    DisposeInternal();
+                    GC.SuppressFinalize(this);
+                }
+
+                private void DisposeInternal()
+                {
+                    if (_disposed)
+                    {
+                        return;
+                    }
+                    _disposed = true;
+                    Marshal.Release(Inst);
+                }
+
+                ~MetaDataDispenserRcw()
+                {
+                    DisposeInternal();
+                }
+            }
+        }
+
+
+        private sealed class CoCreateWrapperCache : ComWrappers
+        {
+            public static readonly CoCreateWrapperCache Instance = new CoCreateWrapperCache();
+            private CoCreateWrapperCache() { }
+
+            protected override unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) => throw new NotImplementedException();
+            protected override SymUnmanagedBinderRcw? CreateObject(IntPtr externalComObject, CreateObjectFlags flags)
+            {
+                Debug.Assert(flags == CreateObjectFlags.UniqueInstance);
+
+                var iid = new Guid("AA544D42-28CB-11d3-BD22-0000F80849BD");
+                if (Marshal.QueryInterface(externalComObject, ref iid, out IntPtr ppv) != 0)
+                {
+                    return null;
+                }
+                return new SymUnmanagedBinderRcw(ppv);
+            }
+            protected override void ReleaseObjects(IEnumerable objects) => throw new NotImplementedException();
+
+            public unsafe record SymUnmanagedBinderRcw(IntPtr Inst) : ISymUnmanagedBinder
+            {
+                private bool _disposed = false;
+
+                public int GetReaderForFile(MetadataImportRcw metadataImporter, string fileName, string searchPath, out SymUnmanagedReaderWrapperCache.SymUnmanagedReaderRcw? reader)
+                {
+                    // ISymUnmanagedBinder::GetReaderForFile is slot 4 (0-based)
+                    var func = (delegate* unmanaged<IntPtr, IntPtr, char*, char*, IntPtr*, int>)(*(*(void***)Inst + 3));
+                    int hr;
+                    IntPtr readerPtr;
+                    fixed (char* fileNamePtr = fileName)
+                    fixed (char* searchPathPtr = searchPath)
+                    {
+                        hr = func(Inst, metadataImporter.Ptr, fileNamePtr, searchPathPtr, &readerPtr);
+                    }
+                    reader = hr == 0
+                        ? (SymUnmanagedReaderWrapperCache.SymUnmanagedReaderRcw)SymUnmanagedReaderWrapperCache.Instance.GetOrCreateObjectForComInstance(readerPtr, CreateObjectFlags.UniqueInstance)
+                        : null;
+                    return hr;
+                }
+                public int GetReaderFromStream(object metadataImporter, object stream, out ISymUnmanagedReader reader) => throw new NotImplementedException();
+
+                public void Dispose()
+                {
+                    DisposeInternal();
+                    GC.SuppressFinalize(this);
+                }
+
+                private void DisposeInternal()
+                {
+                    if (_disposed)
+                    {
+                        return;
+                    }
+                    _disposed = true;
+                    Marshal.Release(Inst);
+                }
+
+                ~SymUnmanagedBinderRcw()
+                {
+                    DisposeInternal();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Wrapper for an IMetaDataImport instance.
+        /// </summary>
+        private sealed record MetadataImportRcw(IntPtr Ptr) : IDisposable
+        {
+            private bool _disposed = false;
+
+            public void Dispose()
+            {
+                DisposeInternal();
+                GC.SuppressFinalize(this);
+            }
+            private void DisposeInternal()
+            {
+                if (_disposed)
+                    return;
+                Marshal.Release(Ptr);
+                _disposed = true;
+            }
+            ~MetadataImportRcw()
+            {
+                DisposeInternal();
+            }
+        }
+
+        interface ISymUnmanagedReader
+        {
+            int GetMethod(int methodToken, out ISymUnmanagedMethod method);
+            // No more members are used
+        }
+
+        private sealed class SymUnmanagedReaderWrapperCache : ComWrappers
+        {
+            public static readonly SymUnmanagedReaderWrapperCache Instance = new SymUnmanagedReaderWrapperCache();
+            private SymUnmanagedReaderWrapperCache() { }
+
+            protected override unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count) => throw new NotImplementedException();
+            protected override object CreateObject(IntPtr externalComObject, CreateObjectFlags flags)
+            {
+                Debug.Assert(flags == CreateObjectFlags.UniqueInstance);
+                return new SymUnmanagedReaderRcw(externalComObject);
+            }
+            protected override void ReleaseObjects(IEnumerable objects) => throw new NotImplementedException();
+
+            /// <summary>
+            /// Caveat: implements only the few interface methods currently needed for crossgen2.
+            /// </summary>
+            public sealed record SymUnmanagedReaderRcw(IntPtr Inst) : ISymUnmanagedReader
+            {
+                private bool _disposed = false;
+
+                // This is not actually called in any code path right now. Rather than implement this
+                // without testing, it's been lefted throwing an exception. If this code path is ever
+                // reached, it can be implemented and tested.
+                public int GetMethod(int methodToken, out ISymUnmanagedMethod method) => throw new NotImplementedException();
+
+                public void Dispose()
+                {
+                    DisposeInternal();
+                    GC.SuppressFinalize(this);
+                }
+
+                private void DisposeInternal()
+                {
+                    if (_disposed)
+                    {
+                        return;
+                    }
+                    _disposed = true;
+                    Marshal.Release(Inst);
+                }
+
+                ~SymUnmanagedReaderRcw()
+                {
+                    DisposeInternal();
+                }
+            }
+        }
+
+        private interface ISymUnmanagedBinder
+        {
+            int GetReaderForFile(
+                MetadataImportRcw importer,
+                string filename,
+                string searchPath,
+                out SymUnmanagedReaderWrapperCache.SymUnmanagedReaderRcw? symReader);
+        }
+
+        private static int CoCreateInstance(ref Guid rclsid, IntPtr pUnkOuter,
                                            Int32 dwClsContext,
                                            ref Guid riid,
-                                           [MarshalAs(UnmanagedType.Interface)] out object ppv);
+                                           out CoCreateWrapperCache.SymUnmanagedBinderRcw? ppv)
+        {
+            Debug.Assert(rclsid == SymBinderIID);
+            int hr = CoCreateInstance(ref rclsid, pUnkOuter, dwClsContext, ref riid, out IntPtr ppvPtr);
+            ppv = hr == 0
+                ? (CoCreateWrapperCache.SymUnmanagedBinderRcw)CoCreateWrapperCache.Instance.GetOrCreateObjectForComInstance(ppvPtr, CreateObjectFlags.UniqueInstance)
+                : null;
+            return hr;
+
+            [DllImport("ole32.dll")]
+            static extern int CoCreateInstance(ref Guid rclsid, IntPtr pUnkOuter,
+                                            Int32 dwClsContext,
+                                            ref Guid riid,
+                                            out IntPtr ppv);
+        }
 
         private void ThrowExceptionForHR(int hr)
         {
             Marshal.ThrowExceptionForHR(hr, new IntPtr(-1));
         }
 
+        private static readonly Guid SymBinderIID = new Guid(0x0a29ff9e, 0x7f9c, 0x4437, 0x8b, 0x11, 0xf4, 0x24, 0x49, 0x1e, 0x39, 0x31);
+
         static UnmanagedPdbSymbolReader()
         {
             if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
@@ -101,37 +459,41 @@ namespace Internal.TypeSystem.Ecma
                 {
                     Guid IID_IUnknown = new Guid(0x00000000, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
 
-                    ICLRMetaHost objMetaHost;
                     Guid CLSID_CLRMetaHost = new Guid(0x9280188d, 0x0e8e, 0x4867, 0xb3, 0x0c, 0x7f, 0xa8, 0x38, 0x84, 0xe8, 0xde);
                     Guid IID_CLRMetaHost = new Guid(0xd332db9e, 0xb9b3, 0x4125, 0x82, 0x07, 0xa1, 0x48, 0x84, 0xf5, 0x32, 0x16);
-                    if (CLRCreateInstance(ref CLSID_CLRMetaHost, ref IID_CLRMetaHost, out objMetaHost) < 0)
-                        return;
-
-                    ICLRRuntimeInfo objRuntime;
-                    Guid IID_CLRRuntimeInfo = new Guid(0xbd39d1d2, 0xba2f, 0x486a, 0x89, 0xb0, 0xb4, 0xb0, 0xcb, 0x46, 0x68, 0x91);
-                    if (objMetaHost.GetRuntime("v4.0.30319", ref IID_CLRRuntimeInfo, out objRuntime) < 0)
-                        return;
-
-                    // To get everything from the v4 runtime
-                    objRuntime.BindAsLegacyV2Runtime();
-
-                    // Create a COM Metadata dispenser
-                    object objDispenser;
-                    Guid CLSID_CorMetaDataDispenser = new Guid(0xe5cb7a31, 0x7512, 0x11d2, 0x89, 0xce, 0x00, 0x80, 0xc7, 0x92, 0xe5, 0xd8);
-                    if (objRuntime.GetInterface(ref CLSID_CorMetaDataDispenser, ref IID_IUnknown, out objDispenser) < 0)
-                        return;
-                    s_metadataDispenser = (IMetaDataDispenser)objDispenser;
-
-                    // Create a SymBinder
-                    object objBinder;
-                    Guid CLSID_CorSymBinder = new Guid(0x0a29ff9e, 0x7f9c, 0x4437, 0x8b, 0x11, 0xf4, 0x24, 0x49, 0x1e, 0x39, 0x31);
-                    if (CoCreateInstance(ref CLSID_CorSymBinder,
-                                         IntPtr.Zero, // pUnkOuter
-                                         1, // CLSCTX_INPROC_SERVER
-                                         ref IID_IUnknown,
-                                         out objBinder) < 0)
+                    if (CLRCreateInstance(ref CLSID_CLRMetaHost, ref IID_CLRMetaHost, out var objMetaHost) < 0)
                         return;
-                    s_symBinder = (ISymUnmanagedBinder)objBinder;
+                    Debug.Assert(objMetaHost is not null);
+                    using (objMetaHost)
+                    {
+                        Guid IID_CLRRuntimeInfo = new Guid(0xbd39d1d2, 0xba2f, 0x486a, 0x89, 0xb0, 0xb4, 0xb0, 0xcb, 0x46, 0x68, 0x91);
+                        if (objMetaHost.GetRuntime("v4.0.30319", ref IID_CLRRuntimeInfo, out var objRuntime) < 0)
+                            return;
+                        Debug.Assert(objRuntime is not null);
+                        using (objRuntime)
+                        {
+                            // To get everything from the v4 runtime
+                            objRuntime.BindAsLegacyV2Runtime();
+
+                            // Create a COM Metadata dispenser
+                            Guid CLSID_CorMetaDataDispenser = new Guid(0xe5cb7a31, 0x7512, 0x11d2, 0x89, 0xce, 0x00, 0x80, 0xc7, 0x92, 0xe5, 0xd8);
+                            if (objRuntime.GetInterface(ref CLSID_CorMetaDataDispenser, ref IID_IUnknown, out var objDispenser) < 0)
+                                return;
+                            Debug.Assert(objDispenser is not null);
+                            s_metadataDispenser = objDispenser;
+
+                            // Create a SymBinder
+                            Guid CLSID_CorSymBinder = SymBinderIID;
+                            if (CoCreateInstance(ref CLSID_CorSymBinder,
+                                                 IntPtr.Zero, // pUnkOuter
+                                                 1, // CLSCTX_INPROC_SERVER
+                                                 ref IID_IUnknown,
+                                                 out var objBinder) < 0)
+                                return;
+                            Debug.Assert(objBinder is not null);
+                            s_symBinder = objBinder;
+                        }
+                    }
                 }
                 catch
                 {
@@ -139,10 +501,10 @@ namespace Internal.TypeSystem.Ecma
             }
         }
 
-        private static IMetaDataDispenser s_metadataDispenser;
-        private static ISymUnmanagedBinder s_symBinder;
+        private readonly static MetaDataDispenserWrapperCache.MetaDataDispenserRcw? s_metadataDispenser;
+        private readonly static CoCreateWrapperCache.SymUnmanagedBinderRcw? s_symBinder;
 
-        public static PdbSymbolReader TryOpenSymbolReaderForMetadataFile(string metadataFileName, string searchPath)
+        public static PdbSymbolReader? TryOpenSymbolReaderForMetadataFile(string metadataFileName, string searchPath)
         {
             try
             {
@@ -153,15 +515,17 @@ namespace Internal.TypeSystem.Ecma
 
                 // Open an metadata importer on the given filename. We'll end up passing this importer straight
                 // through to the Binder.
-                object objImporter;
-                if (s_metadataDispenser.OpenScope(metadataFileName, 0x00000010 /* read only */, ref IID_IMetaDataImport, out objImporter) < 0)
-                    return null;
-
-                ISymUnmanagedReader reader;
-                if (s_symBinder.GetReaderForFile(objImporter, metadataFileName, searchPath, out reader) < 0)
+                if (s_metadataDispenser.OpenScope(metadataFileName, 0x00000010 /* read only */, ref IID_IMetaDataImport, out var objImporter) < 0)
                     return null;
+                Debug.Assert(objImporter is not null);
+                using (objImporter)
+                {
+                    if (s_symBinder.GetReaderForFile(objImporter, metadataFileName, searchPath, out var reader) < 0)
+                        return null;
+                    Debug.Assert(reader is not null);
 
-                return new UnmanagedPdbSymbolReader(reader);
+                    return new UnmanagedPdbSymbolReader(reader);
+                }
             }
             catch
             {
@@ -169,19 +533,19 @@ namespace Internal.TypeSystem.Ecma
             }
         }
 
-        private ISymUnmanagedReader _symUnmanagedReader;
+        private readonly SymUnmanagedReaderWrapperCache.SymUnmanagedReaderRcw _symUnmanagedReader;
 
-        private UnmanagedPdbSymbolReader(ISymUnmanagedReader symUnmanagedReader)
+        private UnmanagedPdbSymbolReader(SymUnmanagedReaderWrapperCache.SymUnmanagedReaderRcw symUnmanagedReader)
         {
             _symUnmanagedReader = symUnmanagedReader;
         }
 
         public override void Dispose()
         {
-            Marshal.ReleaseComObject(_symUnmanagedReader);
+            _symUnmanagedReader.Dispose();
         }
 
-        private Dictionary<ISymUnmanagedDocument, string> _urlCache;
+        private Dictionary<ISymUnmanagedDocument, string>? _urlCache;
 
         private string GetUrl(ISymUnmanagedDocument doc)
         {
@@ -190,8 +554,7 @@ namespace Internal.TypeSystem.Ecma
                 if (_urlCache == null)
                     _urlCache = new Dictionary<ISymUnmanagedDocument, string>();
 
-                string url;
-                if (_urlCache.TryGetValue(doc, out url))
+                if (_urlCache.TryGetValue(doc, out var url))
                     return url;
 
                 int urlLength;
@@ -279,11 +642,12 @@ namespace Internal.TypeSystem.Ecma
         // and names for all of them.  This assumes a CSC-like compiler that doesn't re-use
         // local slots in the same method across scopes.
         //
-        public override IEnumerable<ILLocalVariable> GetLocalVariableNamesForMethod(int methodToken)
+        public override IEnumerable<ILLocalVariable>? GetLocalVariableNamesForMethod(int methodToken)
         {
             ISymUnmanagedMethod symbolMethod;
             if (_symUnmanagedReader.GetMethod(methodToken, out symbolMethod) < 0)
                 return null;
+            Debug.Assert(symbolMethod is not null);
 
             ISymUnmanagedScope rootScope;
             ThrowExceptionForHR(symbolMethod.GetRootScope(out rootScope));
diff --git a/src/coreclr/tools/aot/Directory.Build.props b/src/coreclr/tools/aot/Directory.Build.props
new file mode 100644 (file)
index 0000000..5a5e0e9
--- /dev/null
@@ -0,0 +1,6 @@
+<Project>
+  <Import Project="../Directory.Build.props" />
+  <PropertyGroup>
+    <IsTrimmable>true</IsTrimmable>
+  </PropertyGroup>
+</Project>
index d2df0a8..fecbf93 100644 (file)
@@ -2,7 +2,7 @@
   <PropertyGroup>
     <OutputType>Library</OutputType>
     <AssemblyName>ILCompiler.Compiler</AssemblyName>
-    <TargetFramework>net5.0</TargetFramework>
+    <TargetFramework>net6.0</TargetFramework>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
     <Platforms>x64;x86</Platforms>
index 83ab345..1c2fee5 100644 (file)
@@ -2,7 +2,7 @@
   <PropertyGroup>
     <OutputType>Library</OutputType>
     <AssemblyName>ILCompiler.MetadataTransform</AssemblyName>
-    <TargetFramework>net5.0</TargetFramework>
+    <TargetFramework>net6.0</TargetFramework>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <DefineConstants>$(DefineConstants);NATIVEFORMAT_PUBLICWRITER;NETFX_45</DefineConstants>
     <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
index 879ff0b..4a3f843 100644 (file)
@@ -8,7 +8,7 @@
     <AssemblyKey>Open</AssemblyKey>
     <IsDotNetFrameworkProductAssembly>true</IsDotNetFrameworkProductAssembly>
     <!-- ILSpy requires this assembly to target netstandard2.0 -->
-    <TargetFramework>netstandard2.0</TargetFramework>
+    <TargetFrameworks>net6.0;netstandard2.0</TargetFrameworks>
     <CLSCompliant>false</CLSCompliant>
     <NoWarn>8002,NU1701</NoWarn>
     <RuntimeIdentifiers>win-x64;win-x86</RuntimeIdentifiers>
index bf9a627..9dd3fb3 100644 (file)
@@ -4,7 +4,7 @@
     <RootNamespace>Internal.TypeSystem</RootNamespace>
     <AssemblyName>ILCompiler.TypeSystem</AssemblyName>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-    <TargetFramework>netstandard2.0</TargetFramework>
+    <TargetFrameworks>net6.0</TargetFrameworks>
     <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
     <Platforms>x64;x86</Platforms>
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -17,6 +17,7 @@
          binaries are up to date and which are stale. -->
     <GenerateDependencyFile>false</GenerateDependencyFile>
     <Configurations>Debug;Release;Checked</Configurations>
+    <IsTrimmable>true</IsTrimmable>
   </PropertyGroup>
 
   <ItemGroup Label="Embedded Resources">
index 2d6e9df..a0d3107 100644 (file)
@@ -13,6 +13,8 @@
     <EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
     <Configurations>Debug;Release;Checked</Configurations>
     <ServerGarbageCollection>true</ServerGarbageCollection>
+    <!-- Trim all dependent assemblies as though they were all marked IsTrimmable. -->
+    <TrimmerDefaultAction>link</TrimmerDefaultAction>
   </PropertyGroup>
 
   <ItemGroup Label="Embedded Resources">