Skip to content

Support IDynamicInterfaceCastable with shared generic code #72909

@MichalStrehovsky

Description

@MichalStrehovsky

Below snippet will fail with a NullRef while trying to do generic lookup in IInterfaceCastableImpl. This is because we didn't provide generic context.

The implementation strategy will be somewhere along the lines of:

  • When generating the sealed vtable, add a delta (like we do for fat function pointers) to canonical entries on IDynamicCastable implementations so that we know more is needed at runtime.
  • Do something to the file format so that we can express "the index of the interface through which implementation is provided" to cover [DynIntfCastableImpl] interface IFooImpl : ISomething<object>, ISomething<string> { } when both ISomething provide default implementations.
  • Whenever a IDynamicCastable implementation is looked up at runtime and the found method has the delta bit set, create a thunkpool thunk that puts the "interface through which implementation is provided" in the TLS slot.
  • Make a cache for the thunkpool thunks.
  • Update the shared generic helper to take the value from the TLS slot.

This is a bunch of work.

It's unclear to me if anyone uses IDynIntfCast with generics. It doesn't work great with generics. E.g. interface variance is broken.

using System;
using System.Runtime.InteropServices;

var s = (IInterface<string>)new CastableClass<IInterface<string>, IInterfaceCastableImpl<string>>();
s.GetCookie();

class CastableClass<TInterface, TImpl> : IDynamicInterfaceCastable
{
    RuntimeTypeHandle IDynamicInterfaceCastable.GetInterfaceImplementation(RuntimeTypeHandle interfaceType)
        => typeof(TImpl).TypeHandle;
    bool IDynamicInterfaceCastable.IsInterfaceImplemented(RuntimeTypeHandle interfaceType, bool throwIfNotImplemented)
        => true;
}

interface IInterface<out T>
{
    string GetCookie();
}

[DynamicInterfaceCastableImplementation]
interface IInterfaceCastableImpl<T> : IInterface<T>
{
    string IInterface<T>.GetCookie() => typeof(T).ToString();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-NativeAOT-coreclrin-prThere is an active PR which will close this issue when it is merged

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions