Skip to content

Commit e60d9a3

Browse files
authored
[browser] fix emscripten out/err overrides (#100630)
1 parent 22d1288 commit e60d9a3

File tree

10 files changed

+66
-20
lines changed

10 files changed

+66
-20
lines changed

eng/testing/scenarios/BuildWasmAppsJobsList.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Wasm.Build.Tests.TestAppScenarios.AppSettingsTests
3636
Wasm.Build.Tests.TestAppScenarios.LazyLoadingTests
3737
Wasm.Build.Tests.TestAppScenarios.LibraryInitializerTests
3838
Wasm.Build.Tests.TestAppScenarios.SatelliteLoadingTests
39-
Wasm.Build.Tests.TestAppScenarios.DownloadResourceProgressTests
39+
Wasm.Build.Tests.TestAppScenarios.ModuleConfigTests
4040
Wasm.Build.Tests.TestAppScenarios.SignalRClientTests
4141
Wasm.Build.Tests.WasmBuildAppTest
4242
Wasm.Build.Tests.WasmNativeDefaultsTests

src/mono/browser/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;
@@ -536,7 +537,7 @@ async function start_asset_download_sources (asset: AssetEntryInternal): Promise
536537
err.status = response.status;
537538
throw err;
538539
} else {
539-
loaderHelpers.out(`optional download '${response.url}' for ${asset.name} failed ${response.status} ${response.statusText}`);
540+
mono_log_info(`optional download '${response.url}' for ${asset.name} failed ${response.status} ${response.statusText}`);
540541
return undefined;
541542
}
542543
}

src/mono/browser/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/browser/runtime/loader/run.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ async function initializeModules (es6Modules: [RuntimeModuleExportsInternal, Nat
437437
const { default: emscriptenFactory } = es6Modules[1];
438438
setRuntimeGlobals(globalObjectsRoot);
439439
initializeExports(globalObjectsRoot);
440-
await configureRuntimeStartup();
440+
await configureRuntimeStartup(emscriptenModule);
441441
loaderHelpers.runtimeModuleLoaded.promise_control.resolve();
442442

443443
emscriptenFactory((originalModule: EmscriptenModuleInternal) => {

src/mono/browser/runtime/startup.ts

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,23 @@ import { nativeAbort, nativeExit } from "./run";
3535
import { mono_wasm_init_diagnostics } from "./diagnostics";
3636
import { replaceEmscriptenPThreadInit } from "./pthreads/worker-thread";
3737

38-
export async function configureRuntimeStartup (): Promise<void> {
38+
export async function configureRuntimeStartup (module: DotnetModuleInternal): Promise<void> {
39+
if (!module.out) {
40+
// eslint-disable-next-line no-console
41+
module.out = console.log.bind(console);
42+
}
43+
if (!module.err) {
44+
// eslint-disable-next-line no-console
45+
module.err = console.error.bind(console);
46+
}
47+
if (!module.print) {
48+
module.print = module.out;
49+
}
50+
if (!module.printErr) {
51+
module.printErr = module.err;
52+
}
53+
loaderHelpers.out = module.print;
54+
loaderHelpers.err = module.printErr;
3955
await init_polyfills_async();
4056
}
4157

@@ -49,17 +65,6 @@ export function configureEmscriptenStartup (module: DotnetModuleInternal): void
4965
module.locateFile = module.__locateFile = (path) => loaderHelpers.scriptDirectory + path;
5066
}
5167

52-
if (!module.out) {
53-
// eslint-disable-next-line no-console
54-
module.out = console.log.bind(console);
55-
}
56-
57-
if (!module.err) {
58-
// eslint-disable-next-line no-console
59-
module.err = console.error.bind(console);
60-
}
61-
loaderHelpers.out = module.out;
62-
loaderHelpers.err = module.err;
6368
module.mainScriptUrlOrBlob = loaderHelpers.scriptUrl;// this is needed by worker threads
6469

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

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,8 @@ export declare interface EmscriptenModuleInternal {
431431
runtimeKeepalivePop(): void;
432432
maybeExit(): void;
433433
__emscripten_thread_init(pthread_ptr: PThreadPtr, isMainBrowserThread: number, isMainRuntimeThread: number, canBlock: number): void;
434+
print(message: string): void;
435+
printErr(message: string): void;
434436
}
435437

436438
/// A PromiseController encapsulates a Promise together with easy access to its resolve and reject functions.
@@ -460,7 +462,7 @@ export type initializeExportsType = (globalObjects: GlobalObjects) => RuntimeAPI
460462
export type initializeReplacementsType = (replacements: EmscriptenReplacements) => void;
461463
export type afterInitializeType = (module: EmscriptenModuleInternal) => void;
462464
export type configureEmscriptenStartupType = (module: DotnetModuleInternal) => void;
463-
export type configureRuntimeStartupType = () => Promise<void>;
465+
export type configureRuntimeStartupType = (module: DotnetModuleInternal) => Promise<void>;
464466
export type configureWorkerStartupType = (module: DotnetModuleInternal) => Promise<void>
465467

466468

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ try {
6464
console.log('user code Module.onDotnetReady');
6565
},
6666
postRun: () => { console.log('user code Module.postRun'); },
67+
out: (text) => { console.log("ADVANCED:" + text) },
6768
})
6869
.withResourceLoader((type, name, defaultUri, integrity, behavior) => {
6970
// 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 RunSdkStyleAppForPublish(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 RunSdkStyleAppForPublish(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/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
@@ -66,6 +66,18 @@ switch (testCase) {
6666
}
6767
});
6868
break;
69+
case "OutErrOverrideWorks":
70+
dotnet.withModuleConfig({
71+
out: (message) => {
72+
console.log("Emscripten out override works!");
73+
console.log(message)
74+
},
75+
err: (message) => {
76+
console.error("Emscripten err override works!");
77+
console.error(message)
78+
},
79+
});
80+
break;
6981
}
7082

7183
const { getAssemblyExports, getConfig, INTERNAL } = await dotnet.create();
@@ -97,6 +109,9 @@ try {
97109
case "DownloadResourceProgressTest":
98110
exit(0);
99111
break;
112+
case "OutErrOverrideWorks":
113+
dotnet.run();
114+
break;
100115
case "DebugLevelTest":
101116
testOutput("WasmDebugLevel: " + config.debugLevel);
102117
exit(0);

0 commit comments

Comments
 (0)