Description
Follow-up to #114355
Chatted about this offline with @MichalStrehovsky, opening this for tracking. This is a follow up to getting ILC to support folding ComInterfaceEntry
arrays. The only additional on top of that is to also make ILC capable of folding the IID values when they're read from an RVA field (specifically, from a ref
returning property that does a reinterpret-cast over an RVA field with the IID data), rather than just with a hardcoded Guid
constructor inline. The reason this would be beneficial for us is that while a lot of these arrays would be in generated projections, we also have quite a lot of manual (ie. handwritten) projected types as well in CsWinRT (for custom mapped types), and having to manually hardcode all those IIDs would be quite error prone and difficult to maintain. If we could just reuse our static IIDs instead (which we already have), it'd make that much simpler.
We'd basically need to support this:
public struct MyTypeVtableEntries
{
public ComInterfaceEntry IReferenceOfPoint;
public ComInterfaceEntry IStringable;
public ComInterfaceEntry IWeakReferenceSource;
public ComInterfaceEntry IMarshal;
public ComInterfaceEntry IAgileObject;
public ComInterfaceEntry IInspectable;
public ComInterfaceEntry IUnknown;
}
public static class MyTypeImpl
{
[FixedAddressValueType]
private static readonly MyTypeVtableEntries VtableEntries;
static MyTypeImpl()
{
Entries.IReferenceOfPoint.IID = WellKnownInterfaceIds.IID_IReferenceOfPoint;
Entries.IReferenceOfPoint.Vtable = PointReferenceImpl.AbiToProjectionVftablePtr;
Entries.IStringable.IID = WellKnownInterfaceIds.IID_IStringable;
Entries.IStringable.Vtable = IStringableImpl.AbiToProjectionVftablePtr;
Entries.IWeakReferenceSource.IID = WellKnownInterfaceIds.IID_IWeakReferenceSource;
Entries.IWeakReferenceSource.Vtable = IWeakReferenceSourceImpl.AbiToProjectionVftablePtr;
Entries.IMarshal.IID = WellKnownInterfaceIds.IID_IMarshal;
Entries.IMarshal.Vtable = IMarshalImpl.AbiToProjectionVftablePtr;
Entries.IAgileObject.IID = WellKnownInterfaceIds.IID_IAgileObject;
Entries.IAgileObject.Vtable = IUnknownImpl.AbiToProjectionVftablePtr;
Entries.IInspectable.IID = WellKnownInterfaceIds.IID_IInspectable;
Entries.IInspectable.Vtable = IInspectableImpl.AbiToProjectionVftablePtr;
Entries.IUnknown.IID = WellKnownInterfaceIds.IID_IUnknown;
Entries.IUnknown.Vtable = IUnknownImpl.AbiToProjectionVftablePtr;
}
}
Where all of those WellKnownInterfaceIds.IID_
values are properties just like this one:
internal static ref readonly Guid IID_IReferenceOfPoint
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
ReadOnlySpan<byte> data =
[
0x22, 0x4C, 0xF1, 0x84,
0x0A, 0xA0,
0x72, 0x52,
0x8D,
0x3D,
0x82,
0x11,
0x2E,
0x66,
0xDF,
0x00
];
return ref Unsafe.As<byte, Guid>(ref MemoryMarshal.GetReference(data));
}
}
The backing storage for those IIDs is guaranteed by Roslyn to already be an RVA field. We'd need ILC to recognize those reads and assignments to from these properties to the ComInterfaceEntry.IID
fields, and just copy the entire content inline into that MyTypeVtableEntries
buffer.
Metadata
Metadata
Assignees
Type
Projects
Status