diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp
index 8e29a10fd33a4..312afabe00e6b 100644
--- a/src/coreclr/src/vm/jitinterface.cpp
+++ b/src/coreclr/src/vm/jitinterface.cpp
@@ -12425,7 +12425,13 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr,
#if !defined(TARGET_X86)
if (ftn->HasUnmanagedCallersOnlyAttribute())
{
- COMDelegate::ThrowIfInvalidUnmanagedCallersOnlyUsage(ftn);
+ // If the stub was generated by the runtime, don't validate
+ // it for UnmanagedCallersOnlyAttribute usage. There are cases
+ // where the validation doesn't handle all of the cases we can
+ // permit during stub generation (e.g. Vector2 returns).
+ if (!ftn->IsILStub())
+ COMDelegate::ThrowIfInvalidUnmanagedCallersOnlyUsage(ftn);
+
flags.Set(CORJIT_FLAGS::CORJIT_FLAG_REVERSE_PINVOKE);
}
#endif // !TARGET_X86
diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets
index 34cbd7c21ef44..1dfa29befe813 100644
--- a/src/coreclr/tests/issues.targets
+++ b/src/coreclr/tests/issues.targets
@@ -21,15 +21,6 @@
https://github.com/dotnet/runtime/issues/35798
-
- https://github.com/dotnet/runtime/issues/35798
-
-
- https://github.com/dotnet/runtime/issues/35798
-
-
- https://github.com/dotnet/runtime/issues/35798
-
diff --git a/src/coreclr/tests/src/Interop/PInvoke/Vector2_3_4/Vector2_3_4.cs b/src/coreclr/tests/src/Interop/PInvoke/Vector2_3_4/Vector2_3_4.cs
index ab724068b60c4..5d390bbd5ddbb 100644
--- a/src/coreclr/tests/src/Interop/PInvoke/Vector2_3_4/Vector2_3_4.cs
+++ b/src/coreclr/tests/src/Interop/PInvoke/Vector2_3_4/Vector2_3_4.cs
@@ -22,7 +22,7 @@ public static int Main()
}
catch (System.Exception ex)
{
- Console.WriteLine(ex.ToString());
+ Console.WriteLine(ex);
return 101;
}
return 100;
@@ -30,6 +30,7 @@ public static int Main()
private static void RunVector2Tests()
{
+ Console.WriteLine($"Running {nameof(RunVector2Tests)}... ");
float X = StartingIntValue;
float Y = StartingIntValue + 1;
float Z = StartingIntValue + 232;
@@ -68,9 +69,10 @@ private static void RunVector2Tests()
return newVector;
}));
}
-
+
private static void RunVector3Tests()
{
+ Console.WriteLine($"Running {nameof(RunVector3Tests)}... ");
float X = StartingIntValue;
float Y = StartingIntValue + 1;
float Z = StartingIntValue + 232;
@@ -112,6 +114,7 @@ private static void RunVector3Tests()
private static void RunVector4Tests()
{
+ Console.WriteLine($"Running {nameof(RunVector4Tests)}... ");
float X = StartingIntValue;
float Y = StartingIntValue + 1;
float Z = StartingIntValue + 232;
diff --git a/src/coreclr/tests/src/Interop/UnmanagedCallersOnly/UnmanagedCallersOnlyTest.cs b/src/coreclr/tests/src/Interop/UnmanagedCallersOnly/UnmanagedCallersOnlyTest.cs
index cb3cded544982..6c0acc1eab94e 100644
--- a/src/coreclr/tests/src/Interop/UnmanagedCallersOnly/UnmanagedCallersOnlyTest.cs
+++ b/src/coreclr/tests/src/Interop/UnmanagedCallersOnly/UnmanagedCallersOnlyTest.cs
@@ -270,9 +270,10 @@ void CallAsDelegate()
}
[UnmanagedCallersOnly]
- public void CallbackNonStatic()
+ public int CallbackNonStatic(int val)
{
Assert.Fail($"Instance functions with attribute {nameof(UnmanagedCallersOnlyAttribute)} are invalid");
+ return -1;
}
public static void NegativeTest_NonStaticMethod()
@@ -284,9 +285,14 @@ void TestUnmanagedCallersOnlyNonStatic()
{
.locals init ([0] native int ptr)
IL_0000: nop
- IL_0001: ldftn void CallbackNonStatic()
+ IL_0001: ldftn int CallbackNonStatic(int)
IL_0007: stloc.0
- IL_0008: ret
+
+ IL_0008: ldloc.0
+ IL_0009: ldc.i4 local
+ IL_000e: call bool UnmanagedCallersOnlyDll::CallManagedProc(native int, int)
+
+ IL_0013: ret
}
*/
DynamicMethod testUnmanagedCallersOnly = new DynamicMethod("TestUnmanagedCallersOnlyNonStatic", null, null, typeof(Program).Module);
@@ -297,8 +303,13 @@ .locals init ([0] native int ptr)
// Get native function pointer of the callback
il.Emit(OpCodes.Ldftn, typeof(Program).GetMethod(nameof(CallbackNonStatic)));
il.Emit(OpCodes.Stloc_0);
+ il.Emit(OpCodes.Ldloc_0);
+ int n = 12345;
+ il.Emit(OpCodes.Ldc_I4, n);
+ il.Emit(OpCodes.Call, typeof(UnmanagedCallersOnlyDll).GetMethod("CallManagedProc"));
il.Emit(OpCodes.Ret);
+
var testNativeMethod = (NativeMethodInvoker)testUnmanagedCallersOnly.CreateDelegate(typeof(NativeMethodInvoker));
// Try invoking method
@@ -306,9 +317,10 @@ .locals init ([0] native int ptr)
}
[UnmanagedCallersOnly]
- public static void CallbackMethodNonBlittable(bool x1)
+ public static int CallbackMethodNonBlittable(bool x1)
{
Assert.Fail($"Functions with attribute {nameof(UnmanagedCallersOnlyAttribute)} cannot have non-blittable arguments");
+ return -1;
}
public static void NegativeTest_NonBlittable()
@@ -320,9 +332,14 @@ void TestUnmanagedCallersOnlyNonBlittable()
{
.locals init ([0] native int ptr)
IL_0000: nop
- IL_0001: ldftn void CallbackMethodNonBlittable(bool)
+ IL_0001: ldftn int CallbackMethodNonBlittable(bool)
IL_0007: stloc.0
- IL_0008: ret
+
+ IL_0008: ldloc.0
+ IL_0009: ldc.i4 local
+ IL_000e: call bool UnmanagedCallersOnlyDll::CallManagedProc(native int, int)
+
+ IL_0013: ret
}
*/
DynamicMethod testUnmanagedCallersOnly = new DynamicMethod("TestUnmanagedCallersOnlyNonBlittable", null, null, typeof(Program).Module);
@@ -333,8 +350,13 @@ .locals init ([0] native int ptr)
// Get native function pointer of the callback
il.Emit(OpCodes.Ldftn, typeof(Program).GetMethod(nameof(CallbackMethodNonBlittable)));
il.Emit(OpCodes.Stloc_0);
+ il.Emit(OpCodes.Ldloc_0);
+ int n = 12345;
+ il.Emit(OpCodes.Ldc_I4, n);
+ il.Emit(OpCodes.Call, typeof(UnmanagedCallersOnlyDll).GetMethod("CallManagedProc"));
il.Emit(OpCodes.Ret);
+
var testNativeMethod = (NativeMethodInvoker)testUnmanagedCallersOnly.CreateDelegate(typeof(NativeMethodInvoker));
// Try invoking method
@@ -342,9 +364,10 @@ .locals init ([0] native int ptr)
}
[UnmanagedCallersOnly]
- public static void CallbackMethodGeneric(T arg)
+ public static int CallbackMethodGeneric(T arg)
{
Assert.Fail($"Functions with attribute {nameof(UnmanagedCallersOnlyAttribute)} cannot have generic arguments");
+ return -1;
}
public static void NegativeTest_NonInstantiatedGenericArguments()
@@ -388,7 +411,12 @@ .locals init ([0] native int ptr)
IL_0000: nop
IL_0001: ldftn void CallbackMethodGeneric(int)
IL_0007: stloc.0
- IL_0008: ret
+
+ IL_0008: ldloc.0
+ IL_0009: ldc.i4 local
+ IL_000e: call bool UnmanagedCallersOnlyDll::CallManagedProc(native int, int)
+
+ IL_0013: ret
}
*/
DynamicMethod testUnmanagedCallersOnly = new DynamicMethod("TestUnmanagedCallersOnlyInstGenericArguments", null, null, typeof(Program).Module);
@@ -399,8 +427,13 @@ .locals init ([0] native int ptr)
// Get native function pointer of the instantiated generic callback
il.Emit(OpCodes.Ldftn, typeof(Program).GetMethod(nameof(CallbackMethodGeneric)).MakeGenericMethod(new [] { typeof(int) }));
il.Emit(OpCodes.Stloc_0);
+ il.Emit(OpCodes.Ldloc_0);
+ int n = 12345;
+ il.Emit(OpCodes.Ldc_I4, n);
+ il.Emit(OpCodes.Call, typeof(UnmanagedCallersOnlyDll).GetMethod("CallManagedProc"));
il.Emit(OpCodes.Ret);
+
var testNativeMethod = (NativeMethodInvoker)testUnmanagedCallersOnly.CreateDelegate(typeof(NativeMethodInvoker));
// Try invoking method
@@ -425,9 +458,14 @@ void TestUnmanagedCallersOnlyInstGenericType()
{
.locals init ([0] native int ptr)
IL_0000: nop
- IL_0001: ldftn void GenericClass::CallbackMethod(int)
+ IL_0001: ldftn int GenericClass::CallbackMethod(int)
IL_0007: stloc.0
- IL_0008: ret
+
+ IL_0008: ldloc.0
+ IL_0009: ldc.i4 local
+ IL_000e: call bool UnmanagedCallersOnlyDll::CallManagedProc(native int, int)
+
+ IL_0013: ret
}
*/
DynamicMethod testUnmanagedCallersOnly = new DynamicMethod("TestUnmanagedCallersOnlyInstGenericClass", null, null, typeof(Program).Module);
@@ -438,8 +476,13 @@ .locals init ([0] native int ptr)
// Get native function pointer of the callback from the instantiated generic class.
il.Emit(OpCodes.Ldftn, typeof(GenericClass).GetMethod(nameof(GenericClass.CallbackMethod)));
il.Emit(OpCodes.Stloc_0);
+ il.Emit(OpCodes.Ldloc_0);
+ int n = 12345;
+ il.Emit(OpCodes.Ldc_I4, n);
+ il.Emit(OpCodes.Call, typeof(UnmanagedCallersOnlyDll).GetMethod("CallManagedProc"));
il.Emit(OpCodes.Ret);
+
var testNativeMethod = (NativeMethodInvoker)testUnmanagedCallersOnly.CreateDelegate(typeof(NativeMethodInvoker));
// Try invoking method