From 78f699fd50f74ee59f485ed8652665be289b991d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Fri, 22 Aug 2025 14:14:02 +0200 Subject: [PATCH 01/10] Use lightweight marshal for enums --- src/mono/mono/component/marshal-ilgen-stub.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mono/mono/component/marshal-ilgen-stub.c b/src/mono/mono/component/marshal-ilgen-stub.c index 277261c6b6dde5..d4a853851ada09 100644 --- a/src/mono/mono/component/marshal-ilgen-stub.c +++ b/src/mono/mono/component/marshal-ilgen-stub.c @@ -44,6 +44,10 @@ stub_emit_marshal_ilgen (EmitMarshalContext* m, int argnum, MonoType* t, case MONO_TYPE_FNPTR: return lightweight_cb->emit_marshal_scalar (m, argnum, t, spec, conv_arg, conv_arg_type, action); default: + MonoClass *klass = m_type_data_get_klass_unchecked (t); // aka MONO_TYPE_ 17 + if (m_class_is_enumtype (klass) == 1) + return lightweight_cb->emit_marshal_scalar (m, argnum, t, spec, conv_arg, conv_arg_type, action); + emit_throw_exception (lightweight_cb, m->mb, "System", "ApplicationException", g_strdup("Cannot marshal nonblittlable types without marshal-ilgen.")); break; From 7f38799650d7ea7e082d9838d72ae00eaf6a9142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Fri, 22 Aug 2025 14:14:54 +0200 Subject: [PATCH 02/10] Wasm build test --- .../wasm/Wasm.Build.Tests/NativeBuildTests.cs | 13 ++++++++++ .../App/ZipArchiveInteropTest.cs | 24 +++++++++++++++++++ .../WasmBasicTestApp/App/wwwroot/main.js | 4 ++++ 3 files changed, 41 insertions(+) create mode 100644 src/mono/wasm/testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs diff --git a/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs b/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs index 87b6c0cf0929ec..7ebd61212e6c5d 100644 --- a/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs @@ -102,5 +102,18 @@ public void NativeBuildIsRequired(Configuration config, bool aot) (string _, string output) = PublishProject(info, config, new PublishOptions(ExpectSuccess: false, AOT: aot)); Assert.Contains("WasmBuildNative is required", output); } + + [Fact, TestCategory("bundler-friendly")] + public async Task ZipArchiveInteropTest() + { + Configuration config = Configuration.Debug; + ProjectInfo info = CopyTestAsset(config, false, TestAsset.WasmBasicTestApp, "ZipArchiveInteropTest", extraProperties: "true"); + BuildProject(info, config); + RunResult result = await RunForPublishWithWebServer(new BrowserRunOptions(config, TestScenario: "ZipArchiveInteropTest")); + Assert.Collection( + result.TestOutput, + m => Assert.Equal("Zip file created successfully.", m) + ); + } } } diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs new file mode 100644 index 00000000000000..1ea41662621fd5 --- /dev/null +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs @@ -0,0 +1,24 @@ +// 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.IO.Compression; +using System.Globalization; +using System.Threading.Tasks; +using System.Resources; +using System.Runtime.InteropServices.JavaScript; + +public partial class ZipArchiveInteropTest +{ + [JSExport] + public static void Run() + { + using var zipFileStream = new MemoryStream(); + using var zipArchive = new ZipArchive(zipFileStream, ZipArchiveMode.Create); + + var entry = zipArchive.CreateEntry("sample.txt"); + entry.Open().WriteAsync(Encoding.UTF8.GetBytes("Sample text content")); + + TestOutput.WriteLine("Zip file created successfully."); + } +} diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js index 90595ef290f8e3..7a9d1ebc4a5ad7 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js @@ -223,6 +223,10 @@ try { case "LibraryInitializerTest": exit(0); break; + case "ZipArchiveInteropTest": + exports.ZipArchiveInteropTest.Run(); + exit(0); + break; case "AppSettingsTest": exports.AppSettingsTest.Run(); exit(0); From 8402497be0df307f62a8f891d286840a8e62fba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Fri, 22 Aug 2025 14:33:28 +0200 Subject: [PATCH 03/10] Fix --- src/mono/mono/component/marshal-ilgen-stub.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/component/marshal-ilgen-stub.c b/src/mono/mono/component/marshal-ilgen-stub.c index d4a853851ada09..e94ff00d46a7ca 100644 --- a/src/mono/mono/component/marshal-ilgen-stub.c +++ b/src/mono/mono/component/marshal-ilgen-stub.c @@ -43,7 +43,7 @@ stub_emit_marshal_ilgen (EmitMarshalContext* m, int argnum, MonoType* t, case MONO_TYPE_U8: case MONO_TYPE_FNPTR: return lightweight_cb->emit_marshal_scalar (m, argnum, t, spec, conv_arg, conv_arg_type, action); - default: + default: { MonoClass *klass = m_type_data_get_klass_unchecked (t); // aka MONO_TYPE_ 17 if (m_class_is_enumtype (klass) == 1) return lightweight_cb->emit_marshal_scalar (m, argnum, t, spec, conv_arg, conv_arg_type, action); @@ -52,6 +52,7 @@ stub_emit_marshal_ilgen (EmitMarshalContext* m, int argnum, MonoType* t, g_strdup("Cannot marshal nonblittlable types without marshal-ilgen.")); break; } + } return 0; } From ee19b89937f33b85574625177803651ddfe1b055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Fri, 22 Aug 2025 18:57:08 +0200 Subject: [PATCH 04/10] Fix test app build --- .../testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs index 1ea41662621fd5..f53528baf810b9 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using System.Resources; using System.Runtime.InteropServices.JavaScript; +using System.Text; public partial class ZipArchiveInteropTest { From fb4e2258edadcd304937ad04f929006670c13d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Mon, 25 Aug 2025 13:36:13 +0200 Subject: [PATCH 05/10] Fix test app build --- .../testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs index f53528baf810b9..297cbfd18a3c8e 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.IO; using System.IO.Compression; using System.Globalization; using System.Threading.Tasks; From a813ab1b3cc2ca43f9e8d8344209e5d4bb30f3ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Mon, 25 Aug 2025 17:54:22 +0200 Subject: [PATCH 06/10] Fix test asserts --- src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs b/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs index 7ebd61212e6c5d..8c5534501bf774 100644 --- a/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs @@ -108,7 +108,7 @@ public async Task ZipArchiveInteropTest() { Configuration config = Configuration.Debug; ProjectInfo info = CopyTestAsset(config, false, TestAsset.WasmBasicTestApp, "ZipArchiveInteropTest", extraProperties: "true"); - BuildProject(info, config); + BuildProject(info, config, new BuildOptions(ExpectedFileType: NativeFilesType.Relinked)); RunResult result = await RunForPublishWithWebServer(new BrowserRunOptions(config, TestScenario: "ZipArchiveInteropTest")); Assert.Collection( result.TestOutput, From e495df4e7e9f7643ba6cfa333af7b79278e56bfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Tue, 26 Aug 2025 15:21:39 +0200 Subject: [PATCH 07/10] Fix test case --- src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs b/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs index 8c5534501bf774..1c6c6a059c22a7 100644 --- a/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs @@ -108,8 +108,8 @@ public async Task ZipArchiveInteropTest() { Configuration config = Configuration.Debug; ProjectInfo info = CopyTestAsset(config, false, TestAsset.WasmBasicTestApp, "ZipArchiveInteropTest", extraProperties: "true"); - BuildProject(info, config, new BuildOptions(ExpectedFileType: NativeFilesType.Relinked)); - RunResult result = await RunForPublishWithWebServer(new BrowserRunOptions(config, TestScenario: "ZipArchiveInteropTest")); + BuildProject(info, config, new BuildOptions(AssertAppBundle: false)); + RunResult result = await RunForBuildWithDotnetRun(new BrowserRunOptions(config, TestScenario: "ZipArchiveInteropTest")); Assert.Collection( result.TestOutput, m => Assert.Equal("Zip file created successfully.", m) From a35ef2a9d9ba7fa0f9313f81abc9c0a7814f2824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Tue, 26 Aug 2025 22:30:17 +0200 Subject: [PATCH 08/10] Build tests are not JS bundler friendly --- src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs b/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs index 1c6c6a059c22a7..6716d4d350a298 100644 --- a/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs @@ -103,7 +103,7 @@ public void NativeBuildIsRequired(Configuration config, bool aot) Assert.Contains("WasmBuildNative is required", output); } - [Fact, TestCategory("bundler-friendly")] + [Fact] public async Task ZipArchiveInteropTest() { Configuration config = Configuration.Debug; From 11ccd90432ec187512fde8b16593f15545a0d272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Wed, 27 Aug 2025 09:26:02 +0200 Subject: [PATCH 09/10] Update src/mono/mono/component/marshal-ilgen-stub.c Co-authored-by: Larry Ewing --- src/mono/mono/component/marshal-ilgen-stub.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mono/mono/component/marshal-ilgen-stub.c b/src/mono/mono/component/marshal-ilgen-stub.c index e94ff00d46a7ca..d6d0fdd960de32 100644 --- a/src/mono/mono/component/marshal-ilgen-stub.c +++ b/src/mono/mono/component/marshal-ilgen-stub.c @@ -44,8 +44,7 @@ stub_emit_marshal_ilgen (EmitMarshalContext* m, int argnum, MonoType* t, case MONO_TYPE_FNPTR: return lightweight_cb->emit_marshal_scalar (m, argnum, t, spec, conv_arg, conv_arg_type, action); default: { - MonoClass *klass = m_type_data_get_klass_unchecked (t); // aka MONO_TYPE_ 17 - if (m_class_is_enumtype (klass) == 1) + if (m_class_is_enumtype (m_type_data_get_klass_unchecked (t))) return lightweight_cb->emit_marshal_scalar (m, argnum, t, spec, conv_arg, conv_arg_type, action); emit_throw_exception (lightweight_cb, m->mb, "System", "ApplicationException", From d5469da97d2d82e1202cd0760e3480a7ad1a22fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Tue, 2 Sep 2025 14:48:16 +0200 Subject: [PATCH 10/10] Update src/mono/wasm/testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../WasmBasicTestApp/App/ZipArchiveInteropTest.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs index 297cbfd18a3c8e..d7ba8014cd7135 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/ZipArchiveInteropTest.cs @@ -13,13 +13,16 @@ public partial class ZipArchiveInteropTest { [JSExport] - public static void Run() + public static async Task Run() { using var zipFileStream = new MemoryStream(); using var zipArchive = new ZipArchive(zipFileStream, ZipArchiveMode.Create); var entry = zipArchive.CreateEntry("sample.txt"); - entry.Open().WriteAsync(Encoding.UTF8.GetBytes("Sample text content")); + using (var entryStream = entry.Open()) + { + await entryStream.WriteAsync(Encoding.UTF8.GetBytes("Sample text content")); + } TestOutput.WriteLine("Zip file created successfully."); }