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