From fb832a7949653e4e903bbcf50f111c8256977791 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Thu, 23 Apr 2026 12:07:28 +0200 Subject: [PATCH 1/2] Fix CoreCLR Emscripten out/err override for browser WASM Bridge user-provided out/err overrides to Emscripten's print/printErr in the CoreCLR loader, matching Mono's existing behavior. - Add print/printErr to EmscriptenModuleInternal type - Wire Module.out/err to Module.print/printErr before native module loads - Enable OutErrOverrideWorks test for CoreCLR Fixes #124945 --- .../wasm/Wasm.Build.Tests/ModuleConfigTests.cs | 2 +- src/native/libs/Common/JavaScript/loader/run.ts | 15 +++++++++++++++ .../libs/Common/JavaScript/types/internal.ts | 2 ++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/ModuleConfigTests.cs b/src/mono/wasm/Wasm.Build.Tests/ModuleConfigTests.cs index 8fd34df6ecdda0..717920233be1de 100644 --- a/src/mono/wasm/Wasm.Build.Tests/ModuleConfigTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/ModuleConfigTests.cs @@ -57,7 +57,7 @@ public async Task DownloadProgressFinishes(bool failAssemblyDownload) ); } - [ConditionalFact(typeof(BuildTestBase), nameof(IsMonoRuntime)), TestCategory("bundler-friendly")] + [Fact, TestCategory("bundler-friendly")] public async Task OutErrOverrideWorks() { Configuration config = Configuration.Debug; diff --git a/src/native/libs/Common/JavaScript/loader/run.ts b/src/native/libs/Common/JavaScript/loader/run.ts index cd8b4b26f7fa69..9bce7eddd731d6 100644 --- a/src/native/libs/Common/JavaScript/loader/run.ts +++ b/src/native/libs/Common/JavaScript/loader/run.ts @@ -35,6 +35,21 @@ export async function createRuntime(downloadOnly: boolean): Promise { const modulesAfterConfigLoadedPromises: [JsAsset, Promise][] = normalizeCollection(resources.modulesAfterConfigLoaded).map((a) => [a, callLibraryInitializerOnRuntimeConfigLoaded(a)]); await Promise.all(modulesAfterConfigLoadedPromises.map(([, p]) => p)); + // Wire user-provided out/err overrides to Emscripten's print/printErr. + // This must happen before the native module loads so Emscripten picks them up. + if (!Module.out) { + Module.out = console.log.bind(console); + } + if (!Module.err) { + Module.err = console.error.bind(console); + } + if (!Module.print) { + Module.print = Module.out; + } + if (!Module.printErr) { + Module.printErr = Module.err; + } + // after onConfigLoaded hooks that could install polyfills, our polyfills can be initialized await initPolyfills(); diff --git a/src/native/libs/Common/JavaScript/types/internal.ts b/src/native/libs/Common/JavaScript/types/internal.ts index e7fb15663219cf..aaac89fc35e2f4 100644 --- a/src/native/libs/Common/JavaScript/types/internal.ts +++ b/src/native/libs/Common/JavaScript/types/internal.ts @@ -46,6 +46,8 @@ export type EmscriptenInternals = { export type EmscriptenModuleInternal = EmscriptenModule & DotnetModuleConfig & { runtimeKeepalivePush(): void; runtimeKeepalivePop(): void; + print(message: string): void; + printErr(message: string): void; instantiateWasm?: InstantiateWasmCallBack; onAbort?: (reason: any, extraJson?: string) => void; onExit?: (code: number) => void; From 7a8cf6131673f4ef5dedc871d36714dc1aa8c4a7 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Fri, 24 Apr 2026 00:02:33 +0200 Subject: [PATCH 2/2] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/native/libs/Common/JavaScript/loader/run.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/native/libs/Common/JavaScript/loader/run.ts b/src/native/libs/Common/JavaScript/loader/run.ts index 9bce7eddd731d6..25347cedbc061e 100644 --- a/src/native/libs/Common/JavaScript/loader/run.ts +++ b/src/native/libs/Common/JavaScript/loader/run.ts @@ -38,9 +38,11 @@ export async function createRuntime(downloadOnly: boolean): Promise { // Wire user-provided out/err overrides to Emscripten's print/printErr. // This must happen before the native module loads so Emscripten picks them up. if (!Module.out) { + // eslint-disable-next-line no-console Module.out = console.log.bind(console); } if (!Module.err) { + // eslint-disable-next-line no-console Module.err = console.error.bind(console); } if (!Module.print) {