diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 89a0b5962e3f85..8d562d2fcd6ef2 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -3805,7 +3805,12 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs } else if ((m_method_is_virtual (del_imethod->method) && !m_method_is_static (del_imethod->method)) && !del->target && !m_class_is_valuetype (del_imethod->method->klass)) { // 'this' is passed dynamically, we need to recompute the target method // with each call - del_imethod = get_virtual_method (del_imethod, LOCAL_VAR (call_args_offset + MINT_STACK_SLOT_SIZE, MonoObject*)->vtable); + MonoObject *obj = LOCAL_VAR (call_args_offset + MINT_STACK_SLOT_SIZE, MonoObject*); + del_imethod = get_virtual_method (del_imethod, obj->vtable); + if (m_class_is_valuetype (obj->vtable->klass) && m_class_is_valuetype (del_imethod->method->klass)) { + // We are calling into a value type method, `this` needs to be unboxed + LOCAL_VAR (call_args_offset + MINT_STACK_SLOT_SIZE, gpointer) = mono_object_unbox_internal (obj); + } } else { del->interp_invoke_impl = del_imethod; } diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_79354/Runtime_79354.cs b/src/tests/JIT/Regression/JitBlue/Runtime_79354/Runtime_79354.cs new file mode 100644 index 00000000000000..8114d964526fc0 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_79354/Runtime_79354.cs @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Reflection; + +public interface IGetContents { + (string, int, string) GetContents(); +} + +public struct MyStruct : IGetContents { + public string s1; + public int a; + public string s2; + + public (string, int, string) GetContents() + { + return (s1, a, s2); + } +} + +public class Program { + + public delegate (string, int, string) MyDelegate(IGetContents arg); + + public static int Main(string[] args) + { + MyStruct str = new MyStruct(); + str.s1 = "test1"; + str.a = 42; + str.s2 = "test2"; + + MethodInfo mi = typeof(IGetContents).GetMethod("GetContents"); + MyDelegate func = (MyDelegate)mi.CreateDelegate(typeof(MyDelegate)); + + (string c1, int c2, string c3) = func(str); + if (c1 != "test1") + return 1; + if (c2 != 42) + return 2; + if (c3 != "test2") + return 3; + return 100; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_79354/Runtime_79354.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_79354/Runtime_79354.csproj new file mode 100644 index 00000000000000..75e7d24ec6fd6d --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_79354/Runtime_79354.csproj @@ -0,0 +1,9 @@ + + + Exe + True + + + + + diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 3b6ef72bff560b..cf842bd2967bd8 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -2911,6 +2911,9 @@ https://github.com/dotnet/runtime/issues/57350 + + https://github.com/dotnet/runtime/issues/57350 + https://github.com/dotnet/runtime/issues/57350