Skip to content

Commit af764fd

Browse files
authored
[release/8.0][browser] fix emscripten out/err overrides (#100818)
* backport of #100630 * fix * fix
1 parent f9feb68 commit af764fd

File tree

10 files changed

+67
-21
lines changed

10 files changed

+67
-21
lines changed

eng/testing/scenarios/BuildWasmAppsJobsList.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,5 @@ Wasm.Build.Tests.WasmRunOutOfAppBundleTests
4141
Wasm.Build.Tests.WasmSIMDTests
4242
Wasm.Build.Tests.WasmTemplateTests
4343
Wasm.Build.Tests.WorkloadTests
44-
Wasm.Build.Tests.TestAppScenarios.DownloadResourceProgressTests
44+
Wasm.Build.Tests.TestAppScenarios.ModuleConfigTests
4545
Wasm.Build.Tests.MT.Blazor.SimpleMultiThreadedTests

src/mono/sample/wasm/browser-advanced/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ try {
5959
console.log('user code Module.onDotnetReady');
6060
},
6161
postRun: () => { console.log('user code Module.postRun'); },
62+
out: (text) => { console.log("ADVANCED:" + text) },
6263
})
6364
.withResourceLoader((type, name, defaultUri, integrity, behavior) => {
6465
// loadBootResource could return string with unqualified name of resource. It assumes that we resolve it with document.baseURI

src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/DownloadResourceProgressTests.cs renamed to src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/ModuleConfigTests.cs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313

1414
namespace Wasm.Build.Tests.TestAppScenarios;
1515

16-
public class DownloadResourceProgressTests : AppTestBase
16+
public class ModuleConfigTests : AppTestBase
1717
{
18-
public DownloadResourceProgressTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext)
18+
public ModuleConfigTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext)
1919
: base(output, buildContext)
2020
{
2121
}
@@ -25,7 +25,7 @@ public DownloadResourceProgressTests(ITestOutputHelper output, SharedBuildPerTes
2525
[InlineData(true)]
2626
public async Task DownloadProgressFinishes(bool failAssemblyDownload)
2727
{
28-
CopyTestAsset("WasmBasicTestApp", $"DownloadResourceProgressTests_{failAssemblyDownload}");
28+
CopyTestAsset("WasmBasicTestApp", $"ModuleConfigTests_DownloadProgressFinishes_{failAssemblyDownload}");
2929
PublishProject("Debug");
3030

3131
var result = await RunSdkStyleApp(new(
@@ -54,4 +54,24 @@ public async Task DownloadProgressFinishes(bool failAssemblyDownload)
5454
: "The download progress test did emit unexpected message about failing download"
5555
);
5656
}
57+
58+
[Fact]
59+
public async Task OutErrOverrideWorks()
60+
{
61+
CopyTestAsset("WasmBasicTestApp", $"ModuleConfigTests_OutErrOverrideWorks");
62+
PublishProject("Debug");
63+
64+
var result = await RunSdkStyleApp(new(
65+
Configuration: "Debug",
66+
TestScenario: "OutErrOverrideWorks"
67+
));
68+
Assert.True(
69+
result.ConsoleOutput.Any(m => m.Contains("Emscripten out override works!")),
70+
"Emscripten out override doesn't work"
71+
);
72+
Assert.True(
73+
result.ConsoleOutput.Any(m => m.Contains("Emscripten err override works!")),
74+
"Emscripten err override doesn't work"
75+
);
76+
}
5777
}

src/mono/wasm/runtime/loader/assets.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { mono_exit } from "./exit";
1212
import { addCachedReponse, findCachedResponse } from "./assetsCache";
1313
import { getIcuResourceName } from "./icu";
1414
import { makeURLAbsoluteWithApplicationBase } from "./polyfills";
15+
import { mono_log_info } from "./logging";
1516

1617

1718
let throttlingPromise: PromiseAndController<void> | undefined;
@@ -545,7 +546,7 @@ async function start_asset_download_sources(asset: AssetEntryInternal): Promise<
545546
err.status = response.status;
546547
throw err;
547548
} else {
548-
loaderHelpers.out(`optional download '${response.url}' for ${asset.name} failed ${response.status} ${response.statusText}`);
549+
mono_log_info(`optional download '${response.url}' for ${asset.name} failed ${response.status} ${response.statusText}`);
549550
return undefined;
550551
}
551552
}

src/mono/wasm/runtime/loader/icu.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
import { mono_log_error } from "./logging";
45
import { GlobalizationMode, MonoConfig } from "../types";
56
import { ENVIRONMENT_IS_WEB, loaderHelpers } from "./globals";
67
import { mono_log_info, mono_log_debug } from "./logging";
@@ -18,7 +19,7 @@ export function init_globalization() {
1819
loaderHelpers.preferredIcuAsset = null;
1920
} else {
2021
const msg = "invariant globalization mode is inactive and no ICU data archives are available";
21-
loaderHelpers.err(`ERROR: ${msg}`);
22+
mono_log_error(`ERROR: ${msg}`);
2223
throw new Error(msg);
2324
}
2425
}

src/mono/wasm/runtime/loader/run.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ async function initializeModules(es6Modules: [RuntimeModuleExportsInternal, Nati
458458
const { default: emscriptenFactory } = es6Modules[1];
459459
setRuntimeGlobals(globalObjectsRoot);
460460
initializeExports(globalObjectsRoot);
461-
await configureRuntimeStartup();
461+
await configureRuntimeStartup(globalObjectsRoot.module);
462462
loaderHelpers.runtimeModuleLoaded.promise_control.resolve();
463463

464464
emscriptenFactory((originalModule: EmscriptenModuleInternal) => {

src/mono/wasm/runtime/startup.ts

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,23 @@ import { assertNoProxies } from "./gc-handles";
3939
// default size if MonoConfig.pthreadPoolSize is undefined
4040
const MONO_PTHREAD_POOL_SIZE = 4;
4141

42-
export async function configureRuntimeStartup(): Promise<void> {
42+
export async function configureRuntimeStartup (module: DotnetModuleInternal): Promise<void> {
43+
if (!module.out) {
44+
// eslint-disable-next-line no-console
45+
module.out = console.log.bind(console);
46+
}
47+
if (!module.err) {
48+
// eslint-disable-next-line no-console
49+
module.err = console.error.bind(console);
50+
}
51+
if (!module.print) {
52+
module.print = module.out;
53+
}
54+
if (!module.printErr) {
55+
module.printErr = module.err;
56+
}
57+
loaderHelpers.out = module.print;
58+
loaderHelpers.err = module.printErr;
4359
await init_polyfills_async();
4460
await checkMemorySnapshotSize();
4561
}
@@ -54,17 +70,6 @@ export function configureEmscriptenStartup(module: DotnetModuleInternal): void {
5470
module.locateFile = module.__locateFile = (path) => loaderHelpers.scriptDirectory + path;
5571
}
5672

57-
if (!module.out) {
58-
// eslint-disable-next-line no-console
59-
module.out = console.log.bind(console);
60-
}
61-
62-
if (!module.err) {
63-
// eslint-disable-next-line no-console
64-
module.err = console.error.bind(console);
65-
}
66-
loaderHelpers.out = module.out;
67-
loaderHelpers.err = module.err;
6873
module.mainScriptUrlOrBlob = loaderHelpers.scriptUrl;// this is needed by worker threads
6974

7075
// these all could be overridden on DotnetModuleConfig, we are chaing them to async below, as opposed to emscripten

src/mono/wasm/runtime/types/internal.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,8 @@ export declare interface EmscriptenModuleInternal {
464464
runtimeKeepalivePush(): void;
465465
runtimeKeepalivePop(): void;
466466
maybeExit(): void;
467+
print(message: string): void;
468+
printErr(message: string): void;
467469
}
468470

469471
/// A PromiseController encapsulates a Promise together with easy access to its resolve and reject functions.
@@ -492,7 +494,7 @@ export type setGlobalObjectsType = (globalObjects: GlobalObjects) => void;
492494
export type initializeExportsType = (globalObjects: GlobalObjects) => RuntimeAPI;
493495
export type initializeReplacementsType = (replacements: EmscriptenReplacements) => void;
494496
export type configureEmscriptenStartupType = (module: DotnetModuleInternal) => void;
495-
export type configureRuntimeStartupType = () => Promise<void>;
497+
export type configureRuntimeStartupType = (module: DotnetModuleInternal) => Promise<void>;
496498
export type configureWorkerStartupType = (module: DotnetModuleInternal) => Promise<void>
497499

498500

@@ -508,4 +510,4 @@ export type RuntimeModuleExportsInternal = {
508510

509511
export type NativeModuleExportsInternal = {
510512
default: (unificator: Function) => EmscriptenModuleInternal
511-
}
513+
}

src/mono/wasm/testassets/WasmBasicTestApp/App/Common/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
System.Console.WriteLine("WasmBasicTestApp");
5+
System.Console.Error.WriteLine("WasmBasicTestApp stderr");

src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@ switch (testCase) {
6363
}
6464
});
6565
break;
66+
case "OutErrOverrideWorks":
67+
dotnet.withModuleConfig({
68+
out: (message) => {
69+
console.log("Emscripten out override works!");
70+
console.log(message)
71+
},
72+
err: (message) => {
73+
console.error("Emscripten err override works!");
74+
console.error(message)
75+
},
76+
});
77+
break;
6678
}
6779

6880
const { getAssemblyExports, getConfig, INTERNAL } = await dotnet.create();
@@ -94,6 +106,9 @@ try {
94106
case "DownloadResourceProgressTest":
95107
exit(0);
96108
break;
109+
case "OutErrOverrideWorks":
110+
dotnet.run();
111+
break;
97112
default:
98113
console.error(`Unknown test case: ${testCase}`);
99114
exit(3);

0 commit comments

Comments
 (0)