From eae5b172c3cb2e3697ef4e0164696c26bb35d984 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Fri, 19 Jul 2024 13:17:45 -0400 Subject: [PATCH 1/2] [mono][aot] Emit marhsalling exception when dealing with MONO_MARSHAL_CONV_OBJECT_IUNKNOWN This change prevents the aot compiler from erroring out when dealing with COM types that were not marked with MarshalAs attributes. In most scenarios that we support, we want to allow pinvokes to aot compile as in cases like anything COM interop, will end up erroring out if you try to use it. Fixes https://github.com/dotnet/runtime/issues/104463 --- src/mono/mono/metadata/marshal-shared.c | 5 +++ .../PInvokeTableGeneratorTests.cs | 38 +++++++++++++++++++ src/mono/wasm/Wasm.Build.Tests/README.md | 2 +- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/metadata/marshal-shared.c b/src/mono/mono/metadata/marshal-shared.c index 508b823d6324fe..75d95a799ef817 100644 --- a/src/mono/mono/metadata/marshal-shared.c +++ b/src/mono/mono/metadata/marshal-shared.c @@ -1225,6 +1225,11 @@ mono_marshal_shared_emit_object_to_ptr_conv (MonoMethodBuilder *mb, MonoType *ty mono_mb_emit_byte (mb, CEE_STIND_I); break; } + case MONO_MARSHAL_CONV_OBJECT_IUNKNOWN: { + char *msg = g_strdup_printf ("Marshaling not supported for COM type MONO_MARSHAL_CONV_OBJECT_IUNKNOWN."); + mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg); + break; + } default: { g_error ("marshalling conversion %d not implemented", conv); diff --git a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs index 0daa8d0984920e..a887d731d76384 100644 --- a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs @@ -719,6 +719,39 @@ void GenerateSourceFiles(string outputPath, int baseArg) return (buildArgs, output); } + private void EnsureComInteropCompiles(BuildArgs buildArgs, RunHost host, string id) + { + string programText = @" + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + using System.Runtime.InteropServices.ComTypes; + + public static int Main(string[] args) + { + var s = new STGMEDIUM(); + ReleaseStgMedium(ref s); + return 42; + } + + [DllImport(""ole32.dll"")] + internal static extern void ReleaseStgMedium(ref STGMEDIUM medium); + "; + + (string libraryDir, string output) = BuildProject(buildArgs, + id: id, + new BuildProjectOptions( + InitProject: () => + { + File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), programText); + }, + Publish: buildArgs.AOT, + // Verbosity: "diagnostic", + DotnetWasmFromRuntimePack: true)); + + Assert.Contains("Generated app bundle at " + libraryDir, output); + } + private void EnsureWasmAbiRulesAreFollowed(BuildArgs buildArgs, RunHost host, string id) { string programText = @" @@ -885,6 +918,11 @@ public void EnsureWasmAbiRulesAreFollowedInAOT(BuildArgs buildArgs, RunHost host public void EnsureWasmAbiRulesAreFollowedInInterpreter(BuildArgs buildArgs, RunHost host, string id) => EnsureWasmAbiRulesAreFollowed(buildArgs, host, id); + [Theory] + [BuildAndRun(host: RunHost.Chrome, aot: true)] + public void EnsureComInteropCompilesInAOT(BuildArgs buildArgs, RunHost host, string id) => + EnsureComInteropCompiles(buildArgs, host, id); + [Theory] [BuildAndRun(host: RunHost.Chrome, aot: false)] public void UCOWithSpecialCharacters(BuildArgs buildArgs, RunHost host, string id) diff --git a/src/mono/wasm/Wasm.Build.Tests/README.md b/src/mono/wasm/Wasm.Build.Tests/README.md index 5e334d0985c9e9..19fcaa84cf3c3a 100644 --- a/src/mono/wasm/Wasm.Build.Tests/README.md +++ b/src/mono/wasm/Wasm.Build.Tests/README.md @@ -14,7 +14,7 @@ being generated. - Running: -Linux/macOS: `$ make -C src/mono/wasm run-build-tests` +Linux/macOS: `$ make -C src/mono/(browser|wasi) run-build-tests` Windows: `.\dotnet.cmd build .\src\mono\wasm\Wasm.Build.Tests\Wasm.Build.Tests.csproj -c Release -t:Test -p:TargetOS=browser -p:TargetArchitecture=wasm` - Specific tests can be run via `XUnitClassName`, and `XUnitMethodName` From e353cdbec883ebddbf1bb90354f7cc647592409c Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Mon, 22 Jul 2024 16:24:29 -0400 Subject: [PATCH 2/2] Fix test to actually create the project --- .../PInvokeTableGeneratorTests.cs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs index a887d731d76384..eb0959fcdb6425 100644 --- a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs @@ -727,17 +727,23 @@ private void EnsureComInteropCompiles(BuildArgs buildArgs, RunHost host, string using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; - public static int Main(string[] args) + public class Test { - var s = new STGMEDIUM(); - ReleaseStgMedium(ref s); - return 42; + public static int Main(string[] args) + { + var s = new STGMEDIUM(); + ReleaseStgMedium(ref s); + return 42; + } + + [DllImport(""ole32.dll"")] + internal static extern void ReleaseStgMedium(ref STGMEDIUM medium); } - [DllImport(""ole32.dll"")] - internal static extern void ReleaseStgMedium(ref STGMEDIUM medium); "; + buildArgs = ExpandBuildArgs(buildArgs); + (string libraryDir, string output) = BuildProject(buildArgs, id: id, new BuildProjectOptions( @@ -746,7 +752,6 @@ public static int Main(string[] args) File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), programText); }, Publish: buildArgs.AOT, - // Verbosity: "diagnostic", DotnetWasmFromRuntimePack: true)); Assert.Contains("Generated app bundle at " + libraryDir, output);