[browser] cleanup before memory snapshot (#83082)
authorPavel Savara <pavel.savara@gmail.com>
Wed, 8 Mar 2023 08:17:12 +0000 (09:17 +0100)
committerGitHub <noreply@github.com>
Wed, 8 Mar 2023 08:17:12 +0000 (09:17 +0100)
- moved get_preferred_icu_asset
- moved TZ detection
- moved runtimeHelpers.waitForDebugger
- added runtimeHelpers.updateGlobalBufferAndViews
- removed obsolete comments about blazor startup sequence
- removed diplicate calls mono_wasm_init_diagnostics (also previously blazor startup path)
- introduce DotnetModuleInternal instaed of anyModule

src/mono/wasm/runtime/assets.ts
src/mono/wasm/runtime/dotnet.d.ts
src/mono/wasm/runtime/exports.ts
src/mono/wasm/runtime/icu.ts
src/mono/wasm/runtime/imports.ts
src/mono/wasm/runtime/managed-exports.ts
src/mono/wasm/runtime/marshal.ts
src/mono/wasm/runtime/polyfills.ts
src/mono/wasm/runtime/startup.ts
src/mono/wasm/runtime/types.ts
src/mono/wasm/runtime/types/emscripten.ts

index d35abdbd59b6e830915612234833130a89ba5278..8ddc4ecda006cec719671a9e2459693fdf57b088 100644 (file)
@@ -46,35 +46,8 @@ const skipInstantiateByAssetTypes: {
     "dotnetwasm": true,
 };
 
-export function get_preferred_icu_asset(): string | null {
-    if (!runtimeHelpers.config.assets)
-        return null;
-
-    // By setting <WasmIcuDataFileName> user can define what ICU source file they want to load.
-    // There is no need to check application's culture when <WasmIcuDataFileName> is set.
-    // If it was not set, then we have 3 "icu" assets in config and we should choose
-    // only one for loading, the one that matches the application's locale.
-    const icuAssets = runtimeHelpers.config.assets.filter(a => a["behavior"] == "icu");
-    if (icuAssets.length === 1)
-        return icuAssets[0].name;
-
-    // reads the browsers locale / the OS's locale
-    const preferredCulture = ENVIRONMENT_IS_WEB ? navigator.language : Intl.DateTimeFormat().resolvedOptions().locale;
-    const prefix = preferredCulture.split("-")[0];
-    const CJK = "icudt_CJK.dat";
-    const EFIGS = "icudt_EFIGS.dat";
-    const OTHERS = "icudt_no_CJK.dat";
-
-    // not all "fr-*", "it-*", "de-*", "es-*" are in EFIGS, only the one that is mostly used
-    if (prefix == "en" || ["fr", "fr-FR", "it", "it-IT", "de", "de-DE", "es", "es-ES"].includes(preferredCulture))
-        return EFIGS;
-    if (["zh", "ko", "ja"].includes(prefix))
-        return CJK;
-    return OTHERS;
-}
-
-export function shouldLoadIcuAsset(asset: AssetEntryInternal, preferredIcuAsset: string | null): boolean {
-    return !(asset.behavior == "icu" && asset.name != preferredIcuAsset);
+export function shouldLoadIcuAsset(asset: AssetEntryInternal): boolean {
+    return !(asset.behavior == "icu" && asset.name != runtimeHelpers.preferredIcuAsset);
 }
 
 export function resolve_asset_path(behavior: AssetBehaviours) {
@@ -86,7 +59,6 @@ export function resolve_asset_path(behavior: AssetBehaviours) {
     return asset;
 }
 export async function mono_download_assets(): Promise<void> {
-    const preferredIcuAsset = get_preferred_icu_asset();
     if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: mono_download_assets");
     runtimeHelpers.maxParallelDownloads = runtimeHelpers.config.maxParallelDownloads || runtimeHelpers.maxParallelDownloads;
     runtimeHelpers.enableDownloadRetry = runtimeHelpers.config.enableDownloadRetry || runtimeHelpers.enableDownloadRetry;
@@ -101,10 +73,10 @@ export async function mono_download_assets(): Promise<void> {
             mono_assert(!asset.resolvedUrl || typeof asset.resolvedUrl === "string", "asset resolvedUrl could be string");
             mono_assert(!asset.hash || typeof asset.hash === "string", "asset resolvedUrl could be string");
             mono_assert(!asset.pendingDownload || typeof asset.pendingDownload === "object", "asset pendingDownload could be object");
-            if (!skipInstantiateByAssetTypes[asset.behavior] && shouldLoadIcuAsset(asset, preferredIcuAsset)) {
+            if (!skipInstantiateByAssetTypes[asset.behavior] && shouldLoadIcuAsset(asset)) {
                 expected_instantiated_assets_count++;
             }
-            if (!skipDownloadsByAssetTypes[asset.behavior] && shouldLoadIcuAsset(asset, preferredIcuAsset)) {
+            if (!skipDownloadsByAssetTypes[asset.behavior] && shouldLoadIcuAsset(asset)) {
                 expected_downloaded_assets_count++;
                 promises_of_assets.push(start_asset_download(asset));
             }
@@ -132,10 +104,10 @@ export async function mono_download_assets(): Promise<void> {
                     const headersOnly = skipBufferByAssetTypes[asset.behavior];
                     if (!headersOnly) {
                         mono_assert(asset.isOptional, "Expected asset to have the downloaded buffer");
-                        if (!skipDownloadsByAssetTypes[asset.behavior] && shouldLoadIcuAsset(asset, preferredIcuAsset)) {
+                        if (!skipDownloadsByAssetTypes[asset.behavior] && shouldLoadIcuAsset(asset)) {
                             expected_downloaded_assets_count--;
                         }
-                        if (!skipInstantiateByAssetTypes[asset.behavior] && shouldLoadIcuAsset(asset, preferredIcuAsset)) {
+                        if (!skipInstantiateByAssetTypes[asset.behavior] && shouldLoadIcuAsset(asset)) {
                             expected_instantiated_assets_count--;
                         }
                     } else {
index d6e84c710f1c41f4d4f7e3d2655ed9d7cc093ceb..7afa4bc064f44b906bc8134ef5ab5124a270bf8c 100644 (file)
@@ -58,14 +58,10 @@ declare interface EmscriptenModule {
     FS_createPath(parent: string, path: string, canRead?: boolean, canWrite?: boolean): string;
     FS_createDataFile(parent: string, name: string, data: TypedArray, canRead: boolean, canWrite: boolean, canOwn?: boolean): string;
     FS_readFile(filename: string, opts: any): any;
-    removeRunDependency(id: string): void;
-    addRunDependency(id: string): void;
     addFunction(fn: Function, signature: string): number;
-    getWasmTableEntry(index: number): any;
     stackSave(): VoidPtr;
     stackRestore(stack: VoidPtr): void;
     stackAlloc(size: number): VoidPtr;
-    ready: Promise<unknown>;
     instantiateWasm?: InstantiateWasmCallBack;
     preInit?: (() => any)[] | (() => any);
     preRun?: (() => any)[] | (() => any);
index 9a6e2ec5e52947a80f3b17c6994f1c23ba12f6ec..3c0842607d70e5e32d6c6e7ad641b9b62dffadd4 100644 (file)
@@ -8,7 +8,7 @@ import BuildConfiguration from "consts:configuration";
 import WasmEnableLegacyJsInterop from "consts:WasmEnableLegacyJsInterop";
 
 import { ENVIRONMENT_IS_PTHREAD, exportedRuntimeAPI, moduleExports, set_emscripten_entrypoint, set_imports_exports } from "./imports";
-import { DotnetModule, is_nullish, EarlyImports, EarlyExports, EarlyReplacements, RuntimeAPI, CreateDotnetRuntimeType } from "./types";
+import { is_nullish, EarlyImports, EarlyExports, EarlyReplacements, RuntimeAPI, CreateDotnetRuntimeType, DotnetModuleInternal } from "./types";
 import { configure_emscripten_startup, mono_wasm_pthread_worker_init } from "./startup";
 
 import { create_weak_ref } from "./weak-ref";
@@ -37,7 +37,7 @@ function initializeImportsAndExports(
     replacements: EarlyReplacements,
     callbackAPI: any
 ): RuntimeAPI {
-    const module = exports.module as DotnetModule;
+    const module = exports.module as DotnetModuleInternal;
     const globalThisAny = globalThis as any;
 
     // we want to have same instance of MONO, BINDING and Module in dotnet iife
index 4648cadbdf351a8b5b7c5145305da347211e38ec..69c7cbc179c2f483641c0c95cede5d4c509510c7 100644 (file)
@@ -50,3 +50,29 @@ export function mono_wasm_globalization_init(): void {
     }
 }
 
+export function get_preferred_icu_asset(): string | null {
+    if (!runtimeHelpers.config.assets)
+        return null;
+
+    // By setting <WasmIcuDataFileName> user can define what ICU source file they want to load.
+    // There is no need to check application's culture when <WasmIcuDataFileName> is set.
+    // If it was not set, then we have 3 "icu" assets in config and we should choose
+    // only one for loading, the one that matches the application's locale.
+    const icuAssets = runtimeHelpers.config.assets.filter(a => a["behavior"] == "icu");
+    if (icuAssets.length === 1)
+        return icuAssets[0].name;
+
+    // reads the browsers locale / the OS's locale
+    const preferredCulture = ENVIRONMENT_IS_WEB ? navigator.language : Intl.DateTimeFormat().resolvedOptions().locale;
+    const prefix = preferredCulture.split("-")[0];
+    const CJK = "icudt_CJK.dat";
+    const EFIGS = "icudt_EFIGS.dat";
+    const OTHERS = "icudt_no_CJK.dat";
+
+    // not all "fr-*", "it-*", "de-*", "es-*" are in EFIGS, only the one that is mostly used
+    if (prefix == "en" || ["fr", "fr-FR", "it", "it-IT", "de", "de-DE", "es", "es-ES"].includes(preferredCulture))
+        return EFIGS;
+    if (["zh", "ko", "ja"].includes(prefix))
+        return CJK;
+    return OTHERS;
+}
index d341f36818600cc71d51e114d082b1f0d491d3f2..fe2c2561747050045d761a8ad7cecbec5202ed4a 100644 (file)
@@ -6,10 +6,10 @@
 /// <reference path="./types/node.d.ts" />
 
 import type { CreateDotnetRuntimeType, DotnetModule, RuntimeAPI, EarlyExports, EarlyImports, ModuleAPI, RuntimeHelpers } from "./types";
-import type { EmscriptenModule } from "./types/emscripten";
+import type { EmscriptenModule, EmscriptenModuleInternal } from "./types/emscripten";
 
 // these are our public API (except internal)
-export let Module: EmscriptenModule & DotnetModule;
+export let Module: EmscriptenModule & DotnetModule & EmscriptenModuleInternal;
 export let INTERNAL: any;
 export let IMPORTS: any;
 
index 65186e4c0b270f9239cc6ce7cf2966c4b4081f3f..78d70169b57a62c867136a6dbf4976af5a93a2d5 100644 (file)
@@ -3,14 +3,13 @@
 
 import { GCHandle, MarshalerToCs, MarshalerToJs, MonoMethod, mono_assert } from "./types";
 import cwraps from "./cwraps";
-import { Module, runtimeHelpers, ENVIRONMENT_IS_PTHREAD } from "./imports";
+import { runtimeHelpers, ENVIRONMENT_IS_PTHREAD, Module } from "./imports";
 import { alloc_stack_frame, get_arg, get_arg_gc_handle, MarshalerType, set_arg_type, set_gc_handle } from "./marshal";
 import { invoke_method_and_handle_exception } from "./invoke-cs";
 import { marshal_array_to_cs_impl, marshal_exception_to_cs, marshal_intptr_to_cs } from "./marshal-to-cs";
 import { marshal_int32_to_js, marshal_string_to_js, marshal_task_to_js } from "./marshal-to-js";
 
 export function init_managed_exports(): void {
-    const anyModule = Module as any;
     const exports_fqn_asm = "System.Runtime.InteropServices.JavaScript";
     runtimeHelpers.runtime_interop_module = cwraps.mono_wasm_assembly_load(exports_fqn_asm);
     if (!runtimeHelpers.runtime_interop_module)
@@ -38,7 +37,7 @@ export function init_managed_exports(): void {
     mono_assert(get_managed_stack_trace_method, "Can't find GetManagedStackTrace method");
 
     runtimeHelpers.javaScriptExports.call_entry_point = (entry_point: MonoMethod, program_args?: string[]) => {
-        const sp = anyModule.stackSave();
+        const sp = Module.stackSave();
         try {
             const args = alloc_stack_frame(4);
             const res = get_arg(args, 1);
@@ -56,12 +55,12 @@ export function init_managed_exports(): void {
             }
             return promise;
         } finally {
-            anyModule.stackRestore(sp);
+            Module.stackRestore(sp);
         }
     };
     runtimeHelpers.javaScriptExports.release_js_owned_object_by_gc_handle = (gc_handle: GCHandle) => {
         mono_assert(gc_handle, "Must be valid gc_handle");
-        const sp = anyModule.stackSave();
+        const sp = Module.stackSave();
         try {
             const args = alloc_stack_frame(3);
             const arg1 = get_arg(args, 2);
@@ -69,22 +68,22 @@ export function init_managed_exports(): void {
             set_gc_handle(arg1, gc_handle);
             invoke_method_and_handle_exception(release_js_owned_object_by_gc_handle_method, args);
         } finally {
-            anyModule.stackRestore(sp);
+            Module.stackRestore(sp);
         }
     };
     runtimeHelpers.javaScriptExports.create_task_callback = () => {
-        const sp = anyModule.stackSave();
+        const sp = Module.stackSave();
         try {
             const args = alloc_stack_frame(2);
             invoke_method_and_handle_exception(create_task_callback_method, args);
             const res = get_arg(args, 1);
             return get_arg_gc_handle(res);
         } finally {
-            anyModule.stackRestore(sp);
+            Module.stackRestore(sp);
         }
     };
     runtimeHelpers.javaScriptExports.complete_task = (holder_gc_handle: GCHandle, error?: any, data?: any, res_converter?: MarshalerToCs) => {
-        const sp = anyModule.stackSave();
+        const sp = Module.stackSave();
         try {
             const args = alloc_stack_frame(5);
             const arg1 = get_arg(args, 2);
@@ -101,11 +100,11 @@ export function init_managed_exports(): void {
             }
             invoke_method_and_handle_exception(complete_task_method, args);
         } finally {
-            anyModule.stackRestore(sp);
+            Module.stackRestore(sp);
         }
     };
     runtimeHelpers.javaScriptExports.call_delegate = (callback_gc_handle: GCHandle, arg1_js: any, arg2_js: any, arg3_js: any, res_converter?: MarshalerToJs, arg1_converter?: MarshalerToCs, arg2_converter?: MarshalerToCs, arg3_converter?: MarshalerToCs) => {
-        const sp = anyModule.stackSave();
+        const sp = Module.stackSave();
         try {
             const args = alloc_stack_frame(6);
 
@@ -134,11 +133,11 @@ export function init_managed_exports(): void {
                 return res_converter(res);
             }
         } finally {
-            anyModule.stackRestore(sp);
+            Module.stackRestore(sp);
         }
     };
     runtimeHelpers.javaScriptExports.get_managed_stack_trace = (exception_gc_handle: GCHandle) => {
-        const sp = anyModule.stackSave();
+        const sp = Module.stackSave();
         try {
             const args = alloc_stack_frame(3);
 
@@ -150,18 +149,18 @@ export function init_managed_exports(): void {
             const res = get_arg(args, 1);
             return marshal_string_to_js(res);
         } finally {
-            anyModule.stackRestore(sp);
+            Module.stackRestore(sp);
         }
     };
 
     if (install_sync_context) {
         runtimeHelpers.javaScriptExports.install_synchronization_context = () => {
-            const sp = anyModule.stackSave();
+            const sp = Module.stackSave();
             try {
                 const args = alloc_stack_frame(2);
                 invoke_method_and_handle_exception(install_sync_context, args);
             } finally {
-                anyModule.stackRestore(sp);
+                Module.stackRestore(sp);
             }
         };
 
index 8d3134b867c3e98b80227248151db2e92fcc47fb..21917a62a1fe8a0865438252dd4f38f1796bab29 100644 (file)
@@ -41,8 +41,7 @@ export const JSMarshalerTypeSize = 32;
 export const JSMarshalerSignatureHeaderSize = 4 + 4; // without Exception and Result
 
 export function alloc_stack_frame(size: number): JSMarshalerArguments {
-    const anyModule = Module as any;
-    const args = anyModule.stackAlloc(JavaScriptMarshalerArgSize * size);
+    const args = Module.stackAlloc(JavaScriptMarshalerArgSize * size) as any;
     mono_assert(args && (<any>args) % 8 == 0, "Arg alignment");
     const exc = get_arg(args, 0);
     set_arg_type(exc, MarshalerType.None);
index 50e897a54ded46753a43143e674f37aa5319576e..78c305ae985cc3e920a4c4bc0fdddc6c364f2275 100644 (file)
@@ -13,7 +13,6 @@ let node_fs: any | undefined = undefined;
 let node_url: any | undefined = undefined;
 
 export function init_polyfills(replacements: EarlyReplacements): void {
-    const anyModule = Module as any;
 
     // performance.now() is used by emscripten and doesn't work in JSC
     if (typeof globalThis.performance === "undefined") {
@@ -123,7 +122,7 @@ export function init_polyfills(replacements: EarlyReplacements): void {
     }
 
     // require replacement
-    const imports = anyModule.imports = (Module.imports || {}) as DotnetModuleConfigImports;
+    const imports = Module.imports = (Module.imports || {}) as DotnetModuleConfigImports;
     const requireWrapper = (wrappedRequire: Function) => (name: string) => {
         const resolved = (<any>Module.imports)[name];
         if (resolved) {
@@ -146,20 +145,20 @@ export function init_polyfills(replacements: EarlyReplacements): void {
 
     // script location
     runtimeHelpers.scriptDirectory = replacements.scriptDirectory = detectScriptDirectory(replacements);
-    anyModule.mainScriptUrlOrBlob = replacements.scriptUrl;// this is needed by worker threads
+    Module.mainScriptUrlOrBlob = replacements.scriptUrl;// this is needed by worker threads
     if (BuildConfiguration === "Debug") {
         console.debug(`MONO_WASM: starting script ${replacements.scriptUrl}`);
         console.debug(`MONO_WASM: starting in ${runtimeHelpers.scriptDirectory}`);
     }
-    if (anyModule.__locateFile === anyModule.locateFile) {
+    if (Module.__locateFile === Module.locateFile) {
         // above it's our early version from dotnet.es6.pre.js, we could replace it with better
-        anyModule.locateFile = runtimeHelpers.locateFile = (path) => {
+        Module.locateFile = runtimeHelpers.locateFile = (path) => {
             if (isPathAbsolute(path)) return path;
             return runtimeHelpers.scriptDirectory + path;
         };
     } else {
         // we use what was given to us
-        runtimeHelpers.locateFile = anyModule.locateFile;
+        runtimeHelpers.locateFile = Module.locateFile!;
     }
 
     // prefer fetch_like over global fetch for assets
@@ -177,7 +176,7 @@ export function init_polyfills(replacements: EarlyReplacements): void {
 
     // memory
     const originalUpdateGlobalBufferAndViews = replacements.updateGlobalBufferAndViews;
-    replacements.updateGlobalBufferAndViews = (buffer: ArrayBufferLike) => {
+    runtimeHelpers.updateGlobalBufferAndViews = replacements.updateGlobalBufferAndViews = (buffer: ArrayBufferLike) => {
         originalUpdateGlobalBufferAndViews(buffer);
         afterUpdateGlobalBufferAndViews(buffer);
     };
index d554fae7c63889a573374e5906cea4b5fc9dfc5a..75b1b17f111ee197350991ade15e94cae1c79ccd 100644 (file)
@@ -4,11 +4,11 @@
 import BuildConfiguration from "consts:configuration";
 import MonoWasmThreads from "consts:monoWasmThreads";
 import WasmEnableLegacyJsInterop from "consts:WasmEnableLegacyJsInterop";
-import { CharPtrNull, DotnetModule, RuntimeAPI, MonoConfig, MonoConfigInternal } from "./types";
+import { CharPtrNull, DotnetModule, RuntimeAPI, MonoConfig, MonoConfigInternal, DotnetModuleInternal } from "./types";
 import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, INTERNAL, Module, runtimeHelpers } from "./imports";
 import cwraps, { init_c_exports } from "./cwraps";
 import { mono_wasm_raise_debug_event, mono_wasm_runtime_ready } from "./debug";
-import { mono_wasm_globalization_init } from "./icu";
+import { get_preferred_icu_asset, mono_wasm_globalization_init } from "./icu";
 import { toBase64StringImpl } from "./base64";
 import { mono_wasm_init_aot_profiler, mono_wasm_init_browser_profiler } from "./profiler";
 import { mono_on_abort, mono_exit } from "./run";
@@ -50,7 +50,7 @@ const MONO_PTHREAD_POOL_SIZE = 4;
 
 // we are making emscripten startup async friendly
 // emscripten is executing the events without awaiting it and so we need to block progress via PromiseControllers above
-export function configure_emscripten_startup(module: DotnetModule, exportedAPI: RuntimeAPI): void {
+export function configure_emscripten_startup(module: DotnetModuleInternal, exportedAPI: RuntimeAPI): void {
     const mark = startMeasure();
     // these all could be overridden on DotnetModuleConfig, we are chaing them to async below, as opposed to emscripten
     // when user set configSrc or config, we are running our default startup sequence.
@@ -125,15 +125,14 @@ async function instantiateWasmWorker(
     // wait for the config to arrive by message from the main thread
     await afterConfigLoaded.promise;
 
-    const anyModule = Module as any;
     normalizeConfig();
     replace_linker_placeholders(imports, export_linker());
 
     // Instantiate from the module posted from the main thread.
     // We can just use sync instantiation in the worker.
-    const instance = new WebAssembly.Instance(anyModule.wasmModule, imports);
+    const instance = new WebAssembly.Instance(Module.wasmModule!, imports);
     successCallback(instance, undefined);
-    anyModule.wasmModule = null;
+    Module.wasmModule = null;
 }
 
 function preInit(userPreInit: (() => void)[]) {
@@ -295,7 +294,6 @@ export function abort_startup(reason: any, should_exit: boolean): void {
     }
 }
 
-// runs in both blazor and non-blazor
 function mono_wasm_pre_init_essential(isWorker: boolean): void {
     if (!isWorker)
         Module.addRunDependency("mono_wasm_pre_init_essential");
@@ -318,7 +316,6 @@ function mono_wasm_pre_init_essential(isWorker: boolean): void {
         Module.removeRunDependency("mono_wasm_pre_init_essential");
 }
 
-// runs in both blazor and non-blazor
 async function mono_wasm_pre_init_essential_async(): Promise<void> {
     if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: mono_wasm_pre_init_essential_async");
     Module.addRunDependency("mono_wasm_pre_init_essential_async");
@@ -333,7 +330,6 @@ async function mono_wasm_pre_init_essential_async(): Promise<void> {
     Module.removeRunDependency("mono_wasm_pre_init_essential_async");
 }
 
-// runs just in non-blazor
 async function mono_wasm_pre_init_full(): Promise<void> {
     if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: mono_wasm_pre_init_full");
     Module.addRunDependency("mono_wasm_pre_init_full");
@@ -343,7 +339,6 @@ async function mono_wasm_pre_init_full(): Promise<void> {
     Module.removeRunDependency("mono_wasm_pre_init_full");
 }
 
-// runs just in non-blazor
 async function mono_wasm_before_user_runtime_initialized(): Promise<void> {
     if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: mono_wasm_before_user_runtime_initialized");
 
@@ -365,7 +360,6 @@ async function mono_wasm_before_user_runtime_initialized(): Promise<void> {
     }
 }
 
-// runs in both blazor and non-blazor
 async function mono_wasm_after_user_runtime_initialized(): Promise<void> {
     if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: mono_wasm_after_user_runtime_initialized");
     try {
@@ -386,10 +380,6 @@ async function mono_wasm_after_user_runtime_initialized(): Promise<void> {
                 }
             }
         }
-        // for Blazor, init diagnostics after their "onRuntimeInitalized" sets env variables, but before their postRun callback (which calls mono_wasm_load_runtime)
-        if (MonoWasmThreads) {
-            await mono_wasm_init_diagnostics();
-        }
 
         if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: Initializing mono runtime");
 
@@ -484,15 +474,7 @@ async function instantiate_wasm_module(
     Module.removeRunDependency("instantiate_wasm_module");
 }
 
-// runs just in non-blazor
 async function _apply_configuration_from_args() {
-    try {
-        const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
-        if (tz) mono_wasm_setenv("TZ", tz);
-    } catch {
-        console.info("MONO_WASM: failed to detect timezone, will fallback to UTC");
-    }
-
     // create /usr/share folder which is SpecialFolder.CommonApplicationData
     Module["FS_createPath"]("/", "usr", true, true);
     Module["FS_createPath"]("/", "usr/share", true, true);
@@ -514,7 +496,7 @@ async function _apply_configuration_from_args() {
     if (config.browserProfilerOptions)
         mono_wasm_init_browser_profiler(config.browserProfilerOptions);
 
-    // for non-Blazor, init diagnostics after environment variables are set
+    // init diagnostics after environment variables are set
     if (MonoWasmThreads) {
         await mono_wasm_init_diagnostics();
     }
@@ -536,7 +518,6 @@ export function mono_wasm_load_runtime(unused?: string, debugLevel?: number): vo
         }
         cwraps.mono_wasm_load_runtime(unused || "unused", debugLevel);
         endMeasure(mark, MeasuredBlock.loadRuntime);
-        runtimeHelpers.waitForDebugger = config.waitForDebugger;
 
         if (!runtimeHelpers.mono_wasm_bindings_is_ready) bindings_init();
     } catch (err: any) {
@@ -552,10 +533,10 @@ export function mono_wasm_load_runtime(unused?: string, debugLevel?: number): vo
 }
 
 export function bindings_init(): void {
-    if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: bindings_init");
     if (runtimeHelpers.mono_wasm_bindings_is_ready) {
         return;
     }
+    if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: bindings_init");
     runtimeHelpers.mono_wasm_bindings_is_ready = true;
     try {
         const mark = startMeasure();
@@ -588,7 +569,7 @@ export async function mono_wasm_load_config(configFilePath?: string): Promise<vo
     configLoaded = true;
     if (!configFilePath) {
         normalizeConfig();
-        afterConfigLoaded.promise_control.resolve(runtimeHelpers.config);
+        afterConfigLoaded.promise_control.resolve(config);
         return;
     }
     if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: mono_wasm_load_config");
@@ -609,7 +590,7 @@ export async function mono_wasm_load_config(configFilePath?: string): Promise<vo
 
         if (Module.onConfigLoaded) {
             try {
-                await Module.onConfigLoaded(<MonoConfig>runtimeHelpers.config);
+                await Module.onConfigLoaded(<MonoConfig>config);
                 normalizeConfig();
             }
             catch (err: any) {
@@ -617,7 +598,7 @@ export async function mono_wasm_load_config(configFilePath?: string): Promise<vo
                 throw err;
             }
         }
-        afterConfigLoaded.promise_control.resolve(runtimeHelpers.config);
+        afterConfigLoaded.promise_control.resolve(config);
     } catch (err) {
         const errMessage = `Failed to load config file ${configFilePath} ${err}`;
         abort_startup(errMessage, true);
@@ -640,13 +621,23 @@ function normalizeConfig() {
     if (config.diagnosticTracing === undefined && BuildConfiguration === "Debug") {
         config.diagnosticTracing = true;
     }
-    runtimeHelpers.diagnosticTracing = !!runtimeHelpers.config.diagnosticTracing;
+    runtimeHelpers.diagnosticTracing = !!config.diagnosticTracing;
 
     runtimeHelpers.enablePerfMeasure = !!config.browserProfilerOptions
         && globalThis.performance
         && typeof globalThis.performance.measure === "function";
-}
+    runtimeHelpers.preferredIcuAsset = get_preferred_icu_asset();
 
+    if (runtimeHelpers.timezone === undefined && config.environmentVariables["TZ"] === undefined) {
+        try {
+            runtimeHelpers.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone || null;
+            if (runtimeHelpers.timezone) config.environmentVariables["TZ"] = runtimeHelpers.timezone;
+        } catch {
+            console.info("MONO_WASM: failed to detect timezone, will fallback to UTC");
+        }
+    }
+    runtimeHelpers.waitForDebugger = config.waitForDebugger;
+}
 
 export function mono_wasm_asm_loaded(assembly_name: CharPtr, assembly_ptr: number, assembly_len: number, pdb_ptr: number, pdb_len: number): void {
     // Only trigger this codepath for assemblies loaded after app is ready
index c2d3ac17fa022d89e12adb5c33ad79a1986edfac..819f18ca6df5e024c0ccc50e75a8f8aeb7c5d5f6 100644 (file)
@@ -2,7 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 import { DotnetHostBuilder } from "./run-outer";
-import { CharPtr, EmscriptenModule, ManagedPointer, NativePointer, VoidPtr, Int32Ptr } from "./types/emscripten";
+import { CharPtr, EmscriptenModule, ManagedPointer, NativePointer, VoidPtr, Int32Ptr, EmscriptenModuleInternal } from "./types/emscripten";
 
 export type GCHandle = {
     __brand: "GCHandle"
@@ -229,6 +229,9 @@ export type RuntimeHelpers = {
     locateFile: (path: string, prefix?: string) => string,
     javaScriptExports: JavaScriptExports,
     loadedFiles: string[],
+    preferredIcuAsset: string | null,
+    timezone: string | null,
+    updateGlobalBufferAndViews: (buffer: ArrayBufferLike) => void
 }
 
 export type GlobalizationMode =
@@ -247,6 +250,7 @@ export type BrowserProfilerOptions = {
 
 // how we extended emscripten Module
 export type DotnetModule = EmscriptenModule & DotnetModuleConfig;
+export type DotnetModuleInternal = EmscriptenModule & DotnetModuleConfig & EmscriptenModuleInternal;
 
 export type DotnetModuleConfig = {
     disableDotnet6Compatibility?: boolean,
index 3cc8933fd809c5bbdb40f2492f373695ef7e7f73..81b89a1ba20a810481063d67700447c2b309961f 100644 (file)
@@ -50,16 +50,12 @@ export declare interface EmscriptenModule {
     FS_createPath(parent: string, path: string, canRead?: boolean, canWrite?: boolean): string;
     FS_createDataFile(parent: string, name: string, data: TypedArray, canRead: boolean, canWrite: boolean, canOwn?: boolean): string;
     FS_readFile(filename: string, opts: any): any;
-    removeRunDependency(id: string): void;
-    addRunDependency(id: string): void;
     addFunction(fn: Function, signature: string): number;
-    getWasmTableEntry(index: number): any;
     stackSave(): VoidPtr;
     stackRestore(stack: VoidPtr): void;
     stackAlloc(size: number): VoidPtr;
 
 
-    ready: Promise<unknown>;
     instantiateWasm?: InstantiateWasmCallBack;
     preInit?: (() => any)[] | (() => any);
     preRun?: (() => any)[] | (() => any);
@@ -68,6 +64,18 @@ export declare interface EmscriptenModule {
     onAbort?: { (error: any): void };
 }
 
+export declare interface EmscriptenModuleInternal {
+    __locateFile?: (path: string, prefix?: string) => string;
+    locateFile?: (path: string, prefix?: string) => string;
+    mainScriptUrlOrBlob?: string;
+    wasmModule: WebAssembly.Instance | null;
+    ready: Promise<unknown>;
+    getWasmTableEntry(index: number): any;
+    removeRunDependency(id: string): void;
+    addRunDependency(id: string): void;
+}
+
+
 export type InstantiateWasmSuccessCallback = (instance: WebAssembly.Instance, module: WebAssembly.Module | undefined) => void;
 export type InstantiateWasmCallBack = (imports: WebAssembly.Imports, successCallback: InstantiateWasmSuccessCallback) => any;