Skip to content

Support IDynamicInterfaceCastable with shared generic code #72909

Closed
@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

    Projects

    Status

    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions