diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs index 7a6f07a01c0e19..d8ae1363c73af2 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs @@ -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." diff --git a/src/tests/Interop/IDynamicInterfaceCastable/Program.cs b/src/tests/Interop/IDynamicInterfaceCastable/Program.cs index 73c84920352d15..94d56222a3675e 100644 --- a/src/tests/Interop/IDynamicInterfaceCastable/Program.cs +++ b/src/tests/Interop/IDynamicInterfaceCastable/Program.cs @@ -213,7 +213,7 @@ public class DynamicInterfaceCastable : IDynamicInterfaceCastable, IDirectlyImpl { private Dictionary interfaceToImplMap; - public DynamicInterfaceCastable(Dictionary interfaceToImplMap) + protected DynamicInterfaceCastable(Dictionary interfaceToImplMap) { this.interfaceToImplMap = interfaceToImplMap; } @@ -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 { + { typeof(ITest), typeof(ITestImpl) } + }) { } + } + [Fact] public static void ValidateBasicInterface() { Console.WriteLine($"Running {nameof(ValidateBasicInterface)}"); - object castableObj = new DynamicInterfaceCastable(new Dictionary { - { typeof(ITest), typeof(ITestImpl) } - }); + object castableObj = new DynamicInterfaceCastable_ValidateBasicInterface(); Console.WriteLine(" -- Validate cast"); @@ -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)); @@ -379,16 +385,22 @@ public static void ValidateBasicInterface() Assert.Same(castableObj, func()); } + class DynamicInterfaceCastable_ValidateGenericInterface : DynamicInterfaceCastable + { + public DynamicInterfaceCastable_ValidateGenericInterface() + : base(new Dictionary { + { typeof(ITestGeneric), typeof(ITestGenericIntImpl) }, + { typeof(ITestGeneric), typeof(ITestGenericImpl) }, + { typeof(ITestGeneric), typeof(ITestGenericImpl) }, + }) { } + } + [Fact] public static void ValidateGenericInterface() { Console.WriteLine($"Running {nameof(ValidateGenericInterface)}"); - object castableObj = new DynamicInterfaceCastable(new Dictionary { - { typeof(ITestGeneric), typeof(ITestGenericIntImpl) }, - { typeof(ITestGeneric), typeof(ITestGenericImpl) }, - { typeof(ITestGeneric), typeof(ITestGenericImpl) }, - }); + object castableObj = new DynamicInterfaceCastable_ValidateGenericInterface(); Console.WriteLine(" -- Validate cast"); @@ -442,15 +454,21 @@ public static void ValidateGenericInterface() Assert.Equal(expectedStr, funcVar(expectedStr)); } + class DynamicInterfaceCastable_ValidateOverriddenInterface : DynamicInterfaceCastable + { + public DynamicInterfaceCastable_ValidateOverriddenInterface() + : base(new Dictionary { + { typeof(ITest), typeof(IOverrideTestImpl) }, + { typeof(IOverrideTest), typeof(IOverrideTestImpl) }, + }) { } + } + [Fact] public static void ValidateOverriddenInterface() { Console.WriteLine($"Running {nameof(ValidateOverriddenInterface)}"); - object castableObj = new DynamicInterfaceCastable(new Dictionary { - { typeof(ITest), typeof(IOverrideTestImpl) }, - { typeof(IOverrideTest), typeof(IOverrideTestImpl) }, - }); + object castableObj = new DynamicInterfaceCastable_ValidateOverriddenInterface(); Console.WriteLine(" -- Validate cast"); @@ -476,14 +494,20 @@ public static void ValidateOverriddenInterface() Assert.Equal(IOverrideTestImpl.GetMyTypeReturnValue, funcGetType()); } + class DynamicInterfaceCastable_ValidateNotImplemented : DynamicInterfaceCastable + { + public DynamicInterfaceCastable_ValidateNotImplemented() + : base(new Dictionary { + { typeof(ITest), typeof(ITestImpl) } + }) { } + } + [Fact] public static void ValidateNotImplemented() { Console.WriteLine($"Running {nameof(ValidateNotImplemented)}"); - object castableObj = new DynamicInterfaceCastable(new Dictionary { - { 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); @@ -491,15 +515,21 @@ public static void ValidateNotImplemented() Assert.Equal(string.Format(DynamicInterfaceCastableException.ErrorFormat, typeof(INotImplemented)), ex.Message); } + class DynamicInterfaceCastable_ValidateDirectlyImplemented : DynamicInterfaceCastable + { + public DynamicInterfaceCastable_ValidateDirectlyImplemented() + : base(new Dictionary { + { typeof(ITest), typeof(ITestImpl) }, + { typeof(IDirectlyImplemented), typeof(IDirectlyImplementedImpl) }, + }) { } + } + [Fact] public static void ValidateDirectlyImplemented() { Console.WriteLine($"Running {nameof(ValidateDirectlyImplemented)}"); - object castableObj = new DynamicInterfaceCastable(new Dictionary { - { 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");