Skip to content
This repository has been archived by the owner on Nov 1, 2020. It is now read-only.

Implement GetInterfaceMap #8144

Merged
merged 2 commits into from
May 24, 2020
Merged

Implement GetInterfaceMap #8144

merged 2 commits into from
May 24, 2020

Conversation

Suchiman
Copy link
Contributor

@Suchiman Suchiman commented May 9, 2020

@Suchiman
Copy link
Contributor Author

Suchiman commented May 9, 2020

The original code also says

// If the impl is null, then virtual stub dispatch is active.
RuntimeMethodHandleInternal classRtMethodHandle = GetTypeHandleInternal().GetInterfaceMethodImplementation(ifaceRtTypeHandle, ifaceRtMethodHandle);

but VSD is always active for interfaces and impl appears to be non null?

@Suchiman Suchiman force-pushed the GetInterfaceMap branch 3 times, most recently from 6c59a05 to f3a822f Compare May 18, 2020 02:45
@Suchiman
Copy link
Contributor Author

Ok, best of both worlds i hope. Not modifying existing code and no switches for now.
I don't suppose there's an easier / better way to get to the VirtualResolveData?

throw new ArgumentException(SR.Arg_MustBeInterface);
}

foreach (RuntimeTypeHandle iface in RuntimeAugments.TryGetImplementedInterfaces(typeHandle))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RuntimeAugments.IsAssignableFrom might be better because it also covers variance:

interface IFoo<in T>
{
    void Frob();
}



class Foo : IFoo<object>
{
    public void Frob() { }
}

class Program
{
    static void Main()
    {
        var m = typeof(Foo).GetInterfaceMap(typeof(IFoo<string>));
        Console.WriteLine(m.InterfaceMethods[0].DeclaringType);
        Console.WriteLine(m.TargetMethods[0].DeclaringType);
    }
}

Copy link
Contributor Author

@Suchiman Suchiman May 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the other hand, it bails on

interface IFoo<in T>
{
    void Frob();
}

class Foo<T> : IFoo<object>
{
    public void Frob() { }
}

class Program
{
    static void Main()
    {
        var m = typeof(Foo<>).GetInterfaceMap(typeof(IFoo<string>));
        Console.WriteLine(m.InterfaceMethods[0].DeclaringType);
        Console.WriteLine(m.TargetMethods[0].DeclaringType);
    }
}

due to

// Special case: Generic Type definitions are not assignable in a mrt sense
// in any way. Assignability of those types is handled by reflection logic.
// Call this case out first and here so that these only somewhat filled in
// types do not leak into the rest of the type casting logic.
if (pTargetType->IsGenericTypeDefinition || pSourceType->IsGenericTypeDefinition)

while CoreCLR does not.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add a comment that lists all known cases that CoreCLR handles, but this implementation does not?

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@jkotas jkotas merged commit 5416266 into dotnet:master May 24, 2020
@Suchiman Suchiman deleted the GetInterfaceMap branch May 24, 2020 18:03
@MichalStrehovsky
Copy link
Member

Thank you @Suchiman! I didn't expect we would be able to get this far without extra tables generated by the compiler.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants