From 6a06ab1b35791dce74154cbe930e38476d675b66 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Thu, 24 Apr 2025 11:29:09 -0700 Subject: [PATCH 1/6] Disable COM interop ctor calls when COM interop feature isn't supported. --- src/coreclr/vm/ecall.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/vm/ecall.cpp b/src/coreclr/vm/ecall.cpp index 993a1299c3ee01..219f08485e5110 100644 --- a/src/coreclr/vm/ecall.cpp +++ b/src/coreclr/vm/ecall.cpp @@ -336,11 +336,10 @@ PCODE ECall::GetFCallImpl(MethodDesc * pMD, BOOL * pfSharedOrDynamicFCallImpl /* return CoreLibBinder::GetMethod(METHOD__DELEGATE__CONSTRUCT_DELEGATE)->GetMultiCallableAddrOfCode(); } +#ifdef FEATURE_COMINTEROP // COM imported classes have special constructors if (pMT->IsComObjectType() -#ifdef FEATURE_COMINTEROP && (g_pBaseCOMObject == NULL || pMT != g_pBaseCOMObject) -#endif // FEATURE_COMINTEROP ) { if (pfSharedOrDynamicFCallImpl) @@ -352,6 +351,7 @@ PCODE ECall::GetFCallImpl(MethodDesc * pMD, BOOL * pfSharedOrDynamicFCallImpl /* // FCComCtor does not need to be in the fcall hashtable since it does not erect frame. return GetEEFuncEntryPoint(FCComCtor); } +#endif // FEATURE_COMINTEROP if (!pMD->GetModule()->IsSystem()) COMPlusThrow(kSecurityException, BFA_ECALLS_MUST_BE_IN_SYS_MOD); From bedaa138e69cc5d6f964ef822e61b9d9aae3d66b Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Thu, 24 Apr 2025 14:07:42 -0700 Subject: [PATCH 2/6] Feedback --- src/coreclr/vm/ecall.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/coreclr/vm/ecall.cpp b/src/coreclr/vm/ecall.cpp index 219f08485e5110..5ef72d5323e1ac 100644 --- a/src/coreclr/vm/ecall.cpp +++ b/src/coreclr/vm/ecall.cpp @@ -338,9 +338,7 @@ PCODE ECall::GetFCallImpl(MethodDesc * pMD, BOOL * pfSharedOrDynamicFCallImpl /* #ifdef FEATURE_COMINTEROP // COM imported classes have special constructors - if (pMT->IsComObjectType() - && (g_pBaseCOMObject == NULL || pMT != g_pBaseCOMObject) - ) + if (pMT->IsComObjectType() && pMT != g_pBaseCOMObject) { if (pfSharedOrDynamicFCallImpl) *pfSharedOrDynamicFCallImpl = TRUE; @@ -351,6 +349,11 @@ PCODE ECall::GetFCallImpl(MethodDesc * pMD, BOOL * pfSharedOrDynamicFCallImpl /* // FCComCtor does not need to be in the fcall hashtable since it does not erect frame. return GetEEFuncEntryPoint(FCComCtor); } +#else // !FEATURE_COMINTEROP + // This code path is taken when a class marked with ComInterop is being created. + // If we get here and ComInterop isn't suppported, throw. + if (pMT->IsComObjectType()) + COMPlusThrow(kPlatformNotSupportedException, IDS_EE_ERROR_COM); #endif // FEATURE_COMINTEROP if (!pMD->GetModule()->IsSystem()) From e80a00f6bed003dfb46ae81ffd1e96d0c093d28b Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Thu, 24 Apr 2025 14:08:45 -0700 Subject: [PATCH 3/6] Fix comment. --- src/coreclr/vm/ecall.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/vm/ecall.cpp b/src/coreclr/vm/ecall.cpp index 5ef72d5323e1ac..ca48e537c0aab4 100644 --- a/src/coreclr/vm/ecall.cpp +++ b/src/coreclr/vm/ecall.cpp @@ -350,8 +350,8 @@ PCODE ECall::GetFCallImpl(MethodDesc * pMD, BOOL * pfSharedOrDynamicFCallImpl /* return GetEEFuncEntryPoint(FCComCtor); } #else // !FEATURE_COMINTEROP - // This code path is taken when a class marked with ComInterop is being created. - // If we get here and ComInterop isn't suppported, throw. + // This code path is taken when a class marked with ComImport is being created. + // If we get here and COM interop isn't suppported, throw. if (pMT->IsComObjectType()) COMPlusThrow(kPlatformNotSupportedException, IDS_EE_ERROR_COM); #endif // FEATURE_COMINTEROP From e298e936bc6518a3c52dc84cb3c4f2e026df6370 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Thu, 24 Apr 2025 16:03:10 -0700 Subject: [PATCH 4/6] Add test --- .../CompilerServices/RuntimeHelpersTests.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs index 8c9f6ea247c580..986f23d16473eb 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs @@ -127,6 +127,15 @@ static GenericHasCctor() } } + // This class is used to test the PrepareMethod API with COM interop on non-Windows platforms. + [ComImport] + [Guid("00000000-0000-0000-0000-000000000000")] + class ComClass + { + [MethodImpl(MethodImplOptions.InternalCall)] + public extern void Func(); + } + [Fact] public static void PrepareMethod() { @@ -139,6 +148,11 @@ public static void PrepareMethod() { Assert.ThrowsAny(() => RuntimeHelpers.PrepareMethod(typeof(IList).GetMethod("Add").MethodHandle)); } + + if (PlatformDetection.IsNotWindows) + { + Assert.Throws(() => RuntimeHelpers.PrepareMethod(typeof(ComClass).GetMethod("Func").MethodHandle)); + } } [Fact] From 85719adba07e035385463c901ace05218d12cb6b Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Thu, 24 Apr 2025 18:09:50 -0700 Subject: [PATCH 5/6] Update src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs Co-authored-by: Jan Kotas --- .../Runtime/CompilerServices/RuntimeHelpersTests.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs index 986f23d16473eb..dd5ee9be118bd8 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs @@ -149,9 +149,14 @@ public static void PrepareMethod() Assert.ThrowsAny(() => RuntimeHelpers.PrepareMethod(typeof(IList).GetMethod("Add").MethodHandle)); } - if (PlatformDetection.IsNotWindows) + try + { + // This is expected to either succeed or throw PlatformNotSupportedException depending on the platform + // and runtime flavor + RuntimeHelpers.PrepareMethod(typeof(ComClass).GetMethod("Func").MethodHandle); + } + catch (PlatformNotSupportedException) { - Assert.Throws(() => RuntimeHelpers.PrepareMethod(typeof(ComClass).GetMethod("Func").MethodHandle)); } } From 9d7bbf50ea85cdfc5e5d056abb9d5e5ed4ff842e Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Fri, 25 Apr 2025 13:31:22 -0700 Subject: [PATCH 6/6] Fix test on Windows. --- .../Runtime/CompilerServices/RuntimeHelpersTests.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs index dd5ee9be118bd8..347c01b7a3c410 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Runtime/CompilerServices/RuntimeHelpersTests.cs @@ -127,10 +127,17 @@ static GenericHasCctor() } } + [ComImport] + [Guid("00000000-0000-0000-0000-000000000000")] + interface ComInterface + { + void Func(); + } + // This class is used to test the PrepareMethod API with COM interop on non-Windows platforms. [ComImport] [Guid("00000000-0000-0000-0000-000000000000")] - class ComClass + class ComClass : ComInterface { [MethodImpl(MethodImplOptions.InternalCall)] public extern void Func();