Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,7 @@ private static IntPtr RhpCidResolve_Worker(object pObject, IntPtr pCell)
IntPtr pTargetCode = RhResolveDispatchWorker(pObject, (void*)pCell, ref cellInfo);
if (pTargetCode != IntPtr.Zero)
{
// We don't update the dispatch cell cache if this is IDynamicInterfaceCastable because this
// scenario is by-design dynamic. There is no guarantee that another instance with the same MethodTable
// as the one we just resolved would do the resolution the same way. We will need to ask again.
if (!pObject.GetMethodTable()->IsIDynamicInterfaceCastable)
{
return InternalCalls.RhpUpdateDispatchCellCache(pCell, pTargetCode, pObject.GetMethodTable(), ref cellInfo);
}
else
{
return pTargetCode;
}
return InternalCalls.RhpUpdateDispatchCellCache(pCell, pTargetCode, pObject.GetMethodTable(), ref cellInfo);
}

// "Valid method implementation was not found."
Expand Down
72 changes: 51 additions & 21 deletions src/tests/Interop/IDynamicInterfaceCastable/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ public class DynamicInterfaceCastable : IDynamicInterfaceCastable, IDirectlyImpl
{
private Dictionary<Type, Type> interfaceToImplMap;

public DynamicInterfaceCastable(Dictionary<Type, Type> interfaceToImplMap)
protected DynamicInterfaceCastable(Dictionary<Type, Type> interfaceToImplMap)
{
this.interfaceToImplMap = interfaceToImplMap;
}
Expand Down Expand Up @@ -347,14 +347,20 @@ public RuntimeTypeHandle GetInterfaceImplementation(RuntimeTypeHandle interfaceT
[ActiveIssue("https://github.com/dotnet/runtime/issues/55742", TestRuntimes.Mono)]
public class Program
{
class DynamicInterfaceCastable_ValidateBasicInterface : DynamicInterfaceCastable
{
public DynamicInterfaceCastable_ValidateBasicInterface()
: base(new Dictionary<Type, Type> {
{ typeof(ITest), typeof(ITestImpl) }
}) { }
}

[Fact]
public static void ValidateBasicInterface()
{
Console.WriteLine($"Running {nameof(ValidateBasicInterface)}");

object castableObj = new DynamicInterfaceCastable(new Dictionary<Type, Type> {
{ typeof(ITest), typeof(ITestImpl) }
});
object castableObj = new DynamicInterfaceCastable_ValidateBasicInterface();

Console.WriteLine(" -- Validate cast");

Expand All @@ -365,7 +371,7 @@ public static void ValidateBasicInterface()

Console.WriteLine(" -- Validate method call");
Assert.Same(castableObj, testObj.ReturnThis());
Assert.Equal(typeof(DynamicInterfaceCastable), testObj.GetMyType());
Assert.Equal(typeof(DynamicInterfaceCastable_ValidateBasicInterface), testObj.GetMyType());

Console.WriteLine(" -- Validate method call which calls methods using 'this'");
Assert.Equal(DynamicInterfaceCastable.ImplementedMethodReturnValue, testObj.CallImplemented(ImplementationToCall.Class));
Expand All @@ -379,16 +385,22 @@ public static void ValidateBasicInterface()
Assert.Same(castableObj, func());
}

class DynamicInterfaceCastable_ValidateGenericInterface : DynamicInterfaceCastable
{
public DynamicInterfaceCastable_ValidateGenericInterface()
: base(new Dictionary<Type, Type> {
{ typeof(ITestGeneric<int, int>), typeof(ITestGenericIntImpl) },
{ typeof(ITestGeneric<string, string>), typeof(ITestGenericImpl<string, string>) },
{ typeof(ITestGeneric<string, object>), typeof(ITestGenericImpl<object, string>) },
}) { }
}

[Fact]
public static void ValidateGenericInterface()
{
Console.WriteLine($"Running {nameof(ValidateGenericInterface)}");

object castableObj = new DynamicInterfaceCastable(new Dictionary<Type, Type> {
{ typeof(ITestGeneric<int, int>), typeof(ITestGenericIntImpl) },
{ typeof(ITestGeneric<string, string>), typeof(ITestGenericImpl<string, string>) },
{ typeof(ITestGeneric<string, object>), typeof(ITestGenericImpl<object, string>) },
});
object castableObj = new DynamicInterfaceCastable_ValidateGenericInterface();

Console.WriteLine(" -- Validate cast");

Expand Down Expand Up @@ -442,15 +454,21 @@ public static void ValidateGenericInterface()
Assert.Equal(expectedStr, funcVar(expectedStr));
}

class DynamicInterfaceCastable_ValidateOverriddenInterface : DynamicInterfaceCastable
{
public DynamicInterfaceCastable_ValidateOverriddenInterface()
: base(new Dictionary<Type, Type> {
{ typeof(ITest), typeof(IOverrideTestImpl) },
{ typeof(IOverrideTest), typeof(IOverrideTestImpl) },
}) { }
}

[Fact]
public static void ValidateOverriddenInterface()
{
Console.WriteLine($"Running {nameof(ValidateOverriddenInterface)}");

object castableObj = new DynamicInterfaceCastable(new Dictionary<Type, Type> {
{ typeof(ITest), typeof(IOverrideTestImpl) },
{ typeof(IOverrideTest), typeof(IOverrideTestImpl) },
});
object castableObj = new DynamicInterfaceCastable_ValidateOverriddenInterface();

Console.WriteLine(" -- Validate cast");

Expand All @@ -476,30 +494,42 @@ public static void ValidateOverriddenInterface()
Assert.Equal(IOverrideTestImpl.GetMyTypeReturnValue, funcGetType());
}

class DynamicInterfaceCastable_ValidateNotImplemented : DynamicInterfaceCastable
{
public DynamicInterfaceCastable_ValidateNotImplemented()
: base(new Dictionary<Type, Type> {
{ typeof(ITest), typeof(ITestImpl) }
}) { }
}

[Fact]
public static void ValidateNotImplemented()
{
Console.WriteLine($"Running {nameof(ValidateNotImplemented)}");

object castableObj = new DynamicInterfaceCastable(new Dictionary<Type, Type> {
{ typeof(ITest), typeof(ITestImpl) }
});
object castableObj = new DynamicInterfaceCastable_ValidateNotImplemented();

Assert.False(castableObj is INotImplemented, $"Should not be castable to {nameof(INotImplemented)} via is");
Assert.Null(castableObj as INotImplemented);
var ex = Assert.Throws<DynamicInterfaceCastableException>(() => { var _ = (INotImplemented)castableObj; });
Assert.Equal(string.Format(DynamicInterfaceCastableException.ErrorFormat, typeof(INotImplemented)), ex.Message);
}

class DynamicInterfaceCastable_ValidateDirectlyImplemented : DynamicInterfaceCastable
{
public DynamicInterfaceCastable_ValidateDirectlyImplemented()
: base(new Dictionary<Type, Type> {
{ typeof(ITest), typeof(ITestImpl) },
{ typeof(IDirectlyImplemented), typeof(IDirectlyImplementedImpl) },
}) { }
}

[Fact]
public static void ValidateDirectlyImplemented()
{
Console.WriteLine($"Running {nameof(ValidateDirectlyImplemented)}");

object castableObj = new DynamicInterfaceCastable(new Dictionary<Type, Type> {
{ typeof(ITest), typeof(ITestImpl) },
{ typeof(IDirectlyImplemented), typeof(IDirectlyImplementedImpl) },
});
object castableObj = new DynamicInterfaceCastable_ValidateDirectlyImplemented();

Console.WriteLine(" -- Validate cast");
Assert.True(castableObj is IDirectlyImplemented, $"Should be castable to {nameof(IDirectlyImplemented)} via is");
Expand Down
Loading