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