Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordotnet-bot <dotnet-bot@microsoft.com>2022-03-10 23:39:10 +0300
committerdotnet-bot <dotnet-bot@microsoft.com>2022-03-10 23:39:10 +0300
commite92a00f300278556607da98acf53ab39e4ab13ba (patch)
tree71076256bbd982f5f626c3da7b8af414a1ba3b06
parent1188f73dd084e399c71cfb2eee68af0411e319bd (diff)
parent518c76ff21c28ff0643d8bed74dcbd1b6757d06d (diff)
Merge in 'release/6.0' changes
-rw-r--r--src/mono/mono/metadata/object.c2
-rw-r--r--src/mono/mono/mini/mini-exceptions.c13
-rw-r--r--src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github60486.cs190
-rw-r--r--src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github60486.csproj11
4 files changed, 213 insertions, 3 deletions
diff --git a/src/mono/mono/metadata/object.c b/src/mono/mono/metadata/object.c
index cbabe1f08fb..57b2f8374ea 100644
--- a/src/mono/mono/metadata/object.c
+++ b/src/mono/mono/metadata/object.c
@@ -1519,6 +1519,8 @@ build_imt_slots (MonoClass *klass, MonoVTable *vt, gpointer* imt, GSList *extra_
* add_imt_builder_entry anyway.
*/
method = mono_class_get_method_by_index (mono_class_get_generic_class (iface)->container_class, method_slot_in_interface);
+ if (m_method_is_static (method))
+ continue;
if (mono_method_get_imt_slot (method) != slot_num) {
vt_slot ++;
continue;
diff --git a/src/mono/mono/mini/mini-exceptions.c b/src/mono/mono/mini/mini-exceptions.c
index eea17726ba2..ce9c8799f20 100644
--- a/src/mono/mono/mini/mini-exceptions.c
+++ b/src/mono/mono/mini/mini-exceptions.c
@@ -827,7 +827,7 @@ mono_get_generic_info_from_stack_frame (MonoJitInfo *ji, MonoContext *ctx)
}
method = jinfo_get_method (ji);
- if (mono_method_get_context (method)->method_inst) {
+ if (mono_method_get_context (method)->method_inst || mini_method_is_default_method (method)) {
/* A MonoMethodRuntimeGenericContext* */
return info;
} else if ((method->flags & METHOD_ATTRIBUTE_STATIC) || m_class_is_valuetype (method->klass)) {
@@ -855,12 +855,13 @@ mono_get_generic_context_from_stack_frame (MonoJitInfo *ji, gpointer generic_inf
method = jinfo_get_method (ji);
g_assert (method->is_inflated);
- if (mono_method_get_context (method)->method_inst) {
+ if (mono_method_get_context (method)->method_inst || mini_method_is_default_method (method)) {
MonoMethodRuntimeGenericContext *mrgctx = (MonoMethodRuntimeGenericContext *)generic_info;
klass = mrgctx->class_vtable->klass;
context.method_inst = mrgctx->method_inst;
- g_assert (context.method_inst);
+ if (!mini_method_is_default_method (method))
+ g_assert (context.method_inst);
} else {
MonoVTable *vtable = (MonoVTable *)generic_info;
@@ -873,6 +874,12 @@ mono_get_generic_context_from_stack_frame (MonoJitInfo *ji, gpointer generic_inf
else
method_container_class = method->klass;
+ if (mini_method_is_default_method (method)) {
+ if (mono_class_is_ginst (klass) || mono_class_is_gtd (klass))
+ context.class_inst = mini_class_get_context (klass)->class_inst;
+ return context;
+ }
+
/* class might refer to a subclass of method's class */
while (!(klass == method->klass || (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->container_class == method_container_class))) {
klass = m_class_get_parent (klass);
diff --git a/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github60486.cs b/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github60486.cs
new file mode 100644
index 00000000000..fa751c14ee8
--- /dev/null
+++ b/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github60486.cs
@@ -0,0 +1,190 @@
+using System;
+using System.Runtime.CompilerServices;
+
+public interface IPublisher<out TData>
+{
+ event Action<TData> OnPublish;
+}
+
+public interface TestItf1<TT>
+{
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ void TestMethod1(IPublisher<TT> publisher, StackFrame[] expectedFrames)
+ {
+ StackFrame.Validate(Environment.StackTrace, expectedFrames);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ void TestMethod2(IPublisher<TT> publisher, StackFrame[] expectedFrames)
+ {
+ TestMethod3(this, publisher, expectedFrames);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ protected static void TestMethod3(TestItf1<TT> subscriber, IPublisher<TT> publisher, StackFrame[] expectedFrames)
+ {
+ StackFrame.Validate(Environment.StackTrace, expectedFrames);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ void TestMethod4(IPublisher<TT> publisher, StackFrame[] expectedFrames)
+ {
+ TestMethod3(this, publisher, expectedFrames);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ void TestMethod5(IPublisher<TT> publisher, StackFrame[] expectedFrames)
+ {
+ TestMethod3(this, publisher, expectedFrames);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ void TestMethod10(IPublisher<TT> publisher, StackFrame[] expectedFrames)
+ {
+ TestMethod3(this, publisher, expectedFrames);
+ }
+
+ void TestMethod11(IPublisher<TT> publisher, StackFrame[] expectedFrames);
+}
+
+public interface TestItf2<TT> : TestItf1<TT>
+{
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ void TestItf1<TT>.TestMethod5(IPublisher<TT> publisher, StackFrame[] expectedFrames)
+ {
+ TestMethod3(this, publisher, expectedFrames);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ void TestItf1<TT>.TestMethod10(IPublisher<TT> publisher, StackFrame[] expectedFrames)
+ {
+ TestMethod3(this, publisher, expectedFrames);
+ }
+}
+
+public interface TestItf3<TT> : TestItf1<TT>
+{
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ void TestMethod6(IPublisher<TT> publisher, StackFrame[] expectedFrames)
+ {
+ TestMethod3(this, publisher, expectedFrames);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ void TestMethod7(IPublisher<TT> publisher, StackFrame[] expectedFrames)
+ {
+ TestMethod8(this, publisher, expectedFrames);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ protected static void TestMethod8(TestItf1<TT> subscriber, IPublisher<TT> publisher, StackFrame[] expectedFrames)
+ {
+ StackFrame.Validate(Environment.StackTrace, expectedFrames);
+ }
+
+ void TestMethod9(IPublisher<TT> publisher, StackFrame[] expectedFrames);
+}
+
+public interface TestItf4<TT> : TestItf3<TT>
+{
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ void TestItf3<TT>.TestMethod9(IPublisher<TT> publisher, StackFrame[] expectedFrames)
+ {
+ TestMethod8(this, publisher, expectedFrames);
+ }
+}
+
+public class ProgramBase<TT> : TestItf4<TT>
+{
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public void TestMethod10(IPublisher<TT> publisher, StackFrame[] expectedFrames)
+ {
+ TestItf1<TT>.TestMethod3(this, publisher, expectedFrames);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public void TestMethod11(IPublisher<TT> publisher, StackFrame[] expectedFrames)
+ {
+ TestItf1<TT>.TestMethod3(this, publisher, expectedFrames);
+ }
+}
+
+public class Program : ProgramBase<InputData>, TestItf2<InputData>
+{
+ static int Main(string[] args)
+ {
+ new Program().Start();
+ return 100;
+ }
+
+ public void Start()
+ {
+ var t1 = this as TestItf1<InputData>;
+ t1.TestMethod1(null, new[] { new StackFrame("TestItf1`1", "TestMethod1") });
+ t1.TestMethod2(null, new[] { new StackFrame("TestItf1`1", "TestMethod3"), new StackFrame("TestItf1`1", "TestMethod2") });
+ t1.TestMethod4(null, new[] { new StackFrame("TestItf1`1", "TestMethod3"), new StackFrame("Program", "TestMethod4") });
+ t1.TestMethod5(null, new[] { new StackFrame("TestItf1`1", "TestMethod3"), new StackFrame(new[] { "TestItf2`1", "TestItf1" }, "TestMethod5") });
+
+ var t3 = this as TestItf3<InputData>;
+ t3.TestMethod6(null, new[] { new StackFrame("TestItf1`1", "TestMethod3"), new StackFrame("TestItf3`1", "TestMethod6") });
+ t3.TestMethod7(null, new[] { new StackFrame("TestItf3`1", "TestMethod8"), new StackFrame("TestItf3`1", "TestMethod7") });
+ t3.TestMethod9(null, new[] { new StackFrame("TestItf3`1", "TestMethod8"), new StackFrame(new[] { "TestItf4`1", "TestItf3" }, "TestMethod9") });
+
+ t1.TestMethod10(null, new[] { new StackFrame("TestItf1`1", "TestMethod3"), new StackFrame("ProgramBase`1", "TestMethod10") });
+ t1.TestMethod11(null, new[] { new StackFrame("TestItf1`1", "TestMethod3"), new StackFrame("ProgramBase`1", "TestMethod11") });
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public void TestMethod4(IPublisher<InputData> publisher, StackFrame[] expectedFrames)
+ {
+ TestItf1<InputData>.TestMethod3(this, publisher, expectedFrames);
+ }
+}
+
+public class InputData
+{
+ public int i;
+}
+
+public class StackFrame
+{
+ public string [] ClassName { get; set; }
+ public string MethodName { get; set; } = string.Empty;
+
+ public StackFrame(string [] className, string methodName)
+ {
+ ClassName = className;
+ MethodName = methodName;
+ }
+
+ public StackFrame(string className, string methodName)
+ {
+ ClassName = new string[] { className };
+ MethodName = methodName;
+ }
+
+ public static void Validate(string testStack, StackFrame[] expectedFrames)
+ {
+ int index = 1;
+
+ string[] lines = testStack.Split(
+ new string[] { Environment.NewLine },
+ StringSplitOptions.None
+ );
+
+ //Console.WriteLine(testStack);
+
+ foreach (var frame in expectedFrames)
+ {
+ var line = lines[index++].Trim();
+
+
+ if (!line.StartsWith($"at {frame.ClassName[0]}") || !line.Contains($".{frame.MethodName}") || (frame.ClassName.Length > 1 && !line.Contains($".{frame.ClassName[1]}")))
+ {
+ Console.WriteLine($"Expected {frame.ClassName}.{frame.MethodName} but got {line}");
+ Console.WriteLine(testStack);
+ Environment.Exit(1);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github60486.csproj b/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github60486.csproj
new file mode 100644
index 00000000000..aab61d4e449
--- /dev/null
+++ b/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github60486.csproj
@@ -0,0 +1,11 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="$(MSBuildProjectName).cs" />
+ </ItemGroup>
+</Project>