Skip to content

Commit

Permalink
[ILLink] Add correct ImplementingType to DIM cache in TypeMapInfo (#9…
Browse files Browse the repository at this point in the history
…8513)

Adds the correc
  • Loading branch information
jtschuster committed Feb 22, 2024
1 parent 71344ce commit 9da5359
Showing 1 changed file with 19 additions and 12 deletions.
31 changes: 19 additions & 12 deletions src/tools/illink/src/linker/Linker/TypeMapInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ void MapInterfaceMethodsInTypeHierarchy (TypeDefinition type)
}

// Look for a default implementation last.
FindAndAddDefaultInterfaceImplementations (type, resolvedInterfaceMethod);
FindAndAddDefaultInterfaceImplementations (type, type, resolvedInterfaceMethod);
}
}
}
Expand Down Expand Up @@ -279,26 +279,33 @@ void AnnotateMethods (MethodDefinition @base, MethodDefinition @override, Interf
return context.TryResolve (type)?.BaseType;
}

// Returns a list of default implementations of the given interface method on this type.
// Note that this returns a list to potentially cover the diamond case (more than one
// most specific implementation of the given interface methods). ILLink needs to preserve
// all the implementations so that the proper exception can be thrown at runtime.
void FindAndAddDefaultInterfaceImplementations (TypeDefinition type, MethodDefinition interfaceMethod)
/// <summary>
/// Returns a list of default implementations of the given interface method on this type.
/// Note that this returns a list to potentially cover the diamond case (more than one
/// most specific implementation of the given interface methods). ILLink needs to preserve
/// all the implementations so that the proper exception can be thrown at runtime.
/// </summary>
/// <param name="type">The type that implements (directly or via a base interface) the declaring interface of <paramref name="interfaceMethod"/></param>
/// <param name="interfaceMethod">The method to find a default implementation for</param>
/// <param name="implOfInterface">
/// The InterfaceImplementation on <paramref name="type"/> that points to the DeclaringType of <paramref name="interfaceMethod"/>.
/// </param>
void FindAndAddDefaultInterfaceImplementations (TypeDefinition typeThatImplementsInterface, TypeDefinition typeThatMayHaveDIM, MethodDefinition interfaceMethodToBeImplemented)
{
// Go over all interfaces, trying to find a method that is an explicit MethodImpl of the
// interface method in question.

foreach (var interfaceImpl in type.Interfaces) {
foreach (var interfaceImpl in typeThatMayHaveDIM.Interfaces) {
var potentialImplInterface = context.TryResolve (interfaceImpl.InterfaceType);
if (potentialImplInterface == null)
continue;

bool foundImpl = false;

foreach (var potentialImplMethod in potentialImplInterface.Methods) {
if (potentialImplMethod == interfaceMethod &&
if (potentialImplMethod == interfaceMethodToBeImplemented &&
!potentialImplMethod.IsAbstract) {
AddDefaultInterfaceImplementation (interfaceMethod, type, (interfaceImpl, potentialImplMethod));
AddDefaultInterfaceImplementation (interfaceMethodToBeImplemented, typeThatImplementsInterface, (interfaceImpl, potentialImplMethod));
foundImpl = true;
break;
}
Expand All @@ -308,8 +315,8 @@ void FindAndAddDefaultInterfaceImplementations (TypeDefinition type, MethodDefin

// This method is an override of something. Let's see if it's the method we are looking for.
foreach (var @override in potentialImplMethod.Overrides) {
if (context.TryResolve (@override) == interfaceMethod) {
AddDefaultInterfaceImplementation (interfaceMethod, type, (interfaceImpl, @potentialImplMethod));
if (context.TryResolve (@override) == interfaceMethodToBeImplemented) {
AddDefaultInterfaceImplementation (interfaceMethodToBeImplemented, typeThatImplementsInterface, (interfaceImpl, potentialImplMethod));
foundImpl = true;
break;
}
Expand All @@ -323,7 +330,7 @@ void FindAndAddDefaultInterfaceImplementations (TypeDefinition type, MethodDefin
// We haven't found a MethodImpl on the current interface, but one of the interfaces
// this interface requires could still provide it.
if (!foundImpl) {
FindAndAddDefaultInterfaceImplementations (potentialImplInterface, interfaceMethod);
FindAndAddDefaultInterfaceImplementations (typeThatImplementsInterface, potentialImplInterface, interfaceMethodToBeImplemented);
}
}
}
Expand Down

0 comments on commit 9da5359

Please sign in to comment.