Skip to content

Commit 8bcd03c

Browse files
authored
[browser] cleanup for emscripten main in a web worker (#92280)
1 parent ed0e8d4 commit 8bcd03c

File tree

15 files changed

+173
-99
lines changed

15 files changed

+173
-99
lines changed

src/mono/wasm/runtime/dotnet.d.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,14 @@ type MonoConfig = {
181181
extensions?: {
182182
[name: string]: any;
183183
};
184+
/**
185+
* This is current working directory for the runtime on the virtual file system. Default is "/".
186+
*/
187+
virtualWorkingDirectory?: string;
188+
/**
189+
* This is the arguments to the Main() method of the program. Default is [].
190+
*/
191+
applicationArguments?: string[];
184192
};
185193
type ResourceExtensions = {
186194
[extensionName: string]: ResourceList;
@@ -369,8 +377,8 @@ type DotnetModuleConfig = {
369377
exports?: string[];
370378
} & Partial<EmscriptenModule>;
371379
type APIType = {
372-
runMain: (mainAssemblyName: string, args: string[]) => Promise<number>;
373-
runMainAndExit: (mainAssemblyName: string, args: string[]) => Promise<number>;
380+
runMain: (mainAssemblyName: string, args?: string[]) => Promise<number>;
381+
runMainAndExit: (mainAssemblyName: string, args?: string[]) => Promise<number>;
374382
setEnvironmentVariable: (name: string, value: string) => void;
375383
getAssemblyExports(assemblyName: string): Promise<any>;
376384
setModuleImports(moduleName: string, moduleImports: any): void;

src/mono/wasm/runtime/es6/dotnet.es6.lib.js

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ function setup(linkerSetup) {
2020
const pthreadReplacements = {};
2121
const dotnet_replacements = {
2222
fetch: globalThis.fetch,
23+
ENVIRONMENT_IS_WORKER,
2324
require,
2425
updateMemoryViews,
2526
pthreadReplacements,
@@ -35,12 +36,23 @@ function setup(linkerSetup) {
3536
const ENVIRONMENT_IS_PTHREAD = false;
3637
#endif
3738

39+
ENVIRONMENT_IS_WORKER = dotnet_replacements.ENVIRONMENT_IS_WORKER;
40+
Module.__dotnet_runtime.initializeReplacements(dotnet_replacements);
41+
updateMemoryViews = dotnet_replacements.updateMemoryViews;
42+
noExitRuntime = dotnet_replacements.noExitRuntime;
43+
fetch = dotnet_replacements.fetch;
44+
require = dotnet_replacements.require;
45+
_scriptDir = __dirname = scriptDirectory = dotnet_replacements.scriptDirectory;
46+
#if USE_PTHREADS
47+
PThread.loadWasmModuleToWorker = pthreadReplacements.loadWasmModuleToWorker;
48+
PThread.threadInitTLS = pthreadReplacements.threadInitTLS;
49+
PThread.allocateUnusedWorker = pthreadReplacements.allocateUnusedWorker;
50+
#endif
3851
Module.__dotnet_runtime.passEmscriptenInternals({
3952
isPThread: ENVIRONMENT_IS_PTHREAD,
4053
quit_, ExitStatus,
4154
...linkerSetup
4255
});
43-
Module.__dotnet_runtime.initializeReplacements(dotnet_replacements);
4456

4557
#if USE_PTHREADS
4658
if (ENVIRONMENT_IS_PTHREAD) {
@@ -52,17 +64,6 @@ function setup(linkerSetup) {
5264
#if USE_PTHREADS
5365
}
5466
#endif
55-
56-
updateMemoryViews = dotnet_replacements.updateMemoryViews;
57-
noExitRuntime = dotnet_replacements.noExitRuntime;
58-
fetch = dotnet_replacements.fetch;
59-
require = dotnet_replacements.require;
60-
_scriptDir = __dirname = scriptDirectory = dotnet_replacements.scriptDirectory;
61-
#if USE_PTHREADS
62-
PThread.loadWasmModuleToWorker = pthreadReplacements.loadWasmModuleToWorker;
63-
PThread.threadInitTLS = pthreadReplacements.threadInitTLS;
64-
PThread.allocateUnusedWorker = pthreadReplacements.allocateUnusedWorker;
65-
#endif
6667
}
6768

6869
const DotnetSupportLib = {

src/mono/wasm/runtime/globals.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
/* eslint-disable @typescript-eslint/triple-slash-reference */
55
/// <reference path="./types/v8.d.ts" />
6+
/// <reference path="./types/sidecar.d.ts" />
67
/// <reference path="./types/node.d.ts" />
78

89
import gitHash from "consts:gitHash";
@@ -14,10 +15,14 @@ import type { GlobalObjects, EmscriptenInternals, RuntimeHelpers, LoaderHelpers,
1415
export let Module: DotnetModuleInternal;
1516
export let INTERNAL: any;
1617

18+
// keep in sync with src\mono\wasm\runtime\loader\globals.ts and src\mono\wasm\test-main.js
1719
export const ENVIRONMENT_IS_NODE = typeof process == "object" && typeof process.versions == "object" && typeof process.versions.node == "string";
18-
export const ENVIRONMENT_IS_WORKER = typeof importScripts == "function";
19-
export const ENVIRONMENT_IS_WEB = typeof window == "object" || (ENVIRONMENT_IS_WORKER && !ENVIRONMENT_IS_NODE);
20-
export const ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
20+
export const ENVIRONMENT_IS_WEB_WORKER = typeof importScripts == "function";
21+
export const ENVIRONMENT_IS_SIDECAR = ENVIRONMENT_IS_WEB_WORKER && typeof dotnetSidecar !== "undefined"; // sidecar is emscripten main running in a web worker
22+
export const ENVIRONMENT_IS_WORKER = ENVIRONMENT_IS_WEB_WORKER && !ENVIRONMENT_IS_SIDECAR; // we redefine what ENVIRONMENT_IS_WORKER, we replace it in emscripten internals, so that sidecar works
23+
export const ENVIRONMENT_IS_WEB = typeof window == "object" || (ENVIRONMENT_IS_WEB_WORKER && !ENVIRONMENT_IS_NODE);
24+
export const ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE;
25+
2126
// these are imported and re-exported from emscripten internals
2227
export let ENVIRONMENT_IS_PTHREAD: boolean;
2328
export let exportedRuntimeAPI: RuntimeAPI = null as any;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ async function getCacheToUseIfEnabled(config: MonoConfig): Promise<Cache | null>
154154

155155
// cache integrity is compromised if the first request has been served over http (except localhost)
156156
// in this case, we want to disable caching and integrity validation
157-
if (window.isSecureContext === false) {
157+
if (globalThis.isSecureContext === false) {
158158
return null;
159159
}
160160

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ function logOnExit(exit_code: number, reason: any) {
174174
// tell xharness WasmTestMessagesProcessor we are done.
175175
// note this sends last few bytes into the same WS
176176
mono_log_info_no_prefix("WASM EXIT " + exit_code);
177+
consoleWebSocket.onclose = null;
178+
consoleWebSocket.close(1000, "exit_code:" + exit_code + ": " + reason);
177179
}
178180
else {
179181
globalThis.setTimeout(stop_when_ws_buffer_empty, 100);

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

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,51 @@
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+
/* eslint-disable @typescript-eslint/triple-slash-reference */
5+
/// <reference path="../types/sidecar.d.ts" />
6+
47
import { exceptions, simd } from "wasm-feature-detect";
58

69
import gitHash from "consts:gitHash";
710

8-
import type { AssetEntryInternal, GlobalObjects, LoaderHelpers, RuntimeHelpers } from "../types/internal";
11+
import type { AssetEntryInternal, DotnetModuleInternal, GlobalObjects, LoaderHelpers, MonoConfigInternal, RuntimeHelpers } from "../types/internal";
912
import type { MonoConfig, RuntimeAPI } from "../types";
1013
import { assert_runtime_running, is_exited, is_runtime_running, mono_exit } from "./exit";
1114
import { assertIsControllablePromise, createPromiseController, getPromiseController } from "./promise-controller";
1215
import { mono_download_assets, resolve_single_asset_path, retrieve_asset_download } from "./assets";
1316
import { setup_proxy_console } from "./logging";
1417
import { invokeLibraryInitializers } from "./libraryInitializers";
15-
import { hasDebuggingEnabled } from "./config";
18+
import { deep_merge_config, hasDebuggingEnabled } from "./config";
1619
import { logDownloadStatsToConsole, purgeUnusedCacheEntriesAsync } from "./assetsCache";
1720

21+
// if we are the first script loaded in the web worker, we are expected to become the sidecar
22+
if (typeof importScripts === "function" && !globalThis.onmessage) {
23+
(globalThis as any).dotnetSidecar = true;
24+
}
25+
26+
// keep in sync with src\mono\wasm\runtime\globals.ts and src\mono\wasm\test-main.js
1827
export const ENVIRONMENT_IS_NODE = typeof process == "object" && typeof process.versions == "object" && typeof process.versions.node == "string";
19-
export const ENVIRONMENT_IS_WORKER = typeof importScripts == "function";
20-
export const ENVIRONMENT_IS_WEB = typeof window == "object" || (ENVIRONMENT_IS_WORKER && !ENVIRONMENT_IS_NODE);
21-
export const ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
28+
export const ENVIRONMENT_IS_WEB_WORKER = typeof importScripts == "function";
29+
export const ENVIRONMENT_IS_SIDECAR = ENVIRONMENT_IS_WEB_WORKER && typeof dotnetSidecar !== "undefined"; // sidecar is emscripten main running in a web worker
30+
export const ENVIRONMENT_IS_WORKER = ENVIRONMENT_IS_WEB_WORKER && !ENVIRONMENT_IS_SIDECAR; // we redefine what ENVIRONMENT_IS_WORKER, we replace it in emscripten internals, so that sidecar works
31+
export const ENVIRONMENT_IS_WEB = typeof window == "object" || (ENVIRONMENT_IS_WEB_WORKER && !ENVIRONMENT_IS_NODE);
32+
export const ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE;
2233

2334
export let runtimeHelpers: RuntimeHelpers = {} as any;
2435
export let loaderHelpers: LoaderHelpers = {} as any;
2536
export let exportedRuntimeAPI: RuntimeAPI = {} as any;
2637
export let INTERNAL: any = {};
2738
export let _loaderModuleLoaded = false; // please keep it in place also as rollup guard
2839

40+
export const monoConfig: MonoConfigInternal = {} as any;
41+
export const emscriptenModule: DotnetModuleInternal = {
42+
config: monoConfig
43+
} as any;
2944
export const globalObjectsRoot: GlobalObjects = {
3045
mono: {},
3146
binding: {},
3247
internal: INTERNAL,
33-
module: {},
48+
module: emscriptenModule,
3449
loaderHelpers,
3550
runtimeHelpers,
3651
api: exportedRuntimeAPI,
@@ -56,7 +71,7 @@ export function setLoaderGlobals(
5671

5772
Object.assign(globalObjects.module, {
5873
disableDotnet6Compatibility: true,
59-
config: { environmentVariables: {} }
74+
config: deep_merge_config(monoConfig, { environmentVariables: {} }),
6075
});
6176
Object.assign(runtimeHelpers, {
6277
mono_wasm_bindings_is_ready: false,

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ export function init_globalization() {
4747

4848
export function getIcuResourceName(config: MonoConfig): string | null {
4949
if (config.resources?.icu && config.globalizationMode != GlobalizationMode.Invariant) {
50-
const culture = config.applicationCulture || (ENVIRONMENT_IS_WEB ? (navigator.languages && navigator.languages[0]) : Intl.DateTimeFormat().resolvedOptions().locale);
50+
// TODO: when starting on sidecar, we should pass default culture from UI thread
51+
const culture = config.applicationCulture || (ENVIRONMENT_IS_WEB ? (globalThis.navigator && globalThis.navigator.languages && globalThis.navigator.languages[0]) : Intl.DateTimeFormat().resolvedOptions().locale);
5152

5253
const icuFiles = Object.keys(config.resources.icu);
5354

0 commit comments

Comments
 (0)