From 2514d2db78849d0ce750d2822d7f1565872ec934 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 1 Oct 2025 10:59:31 +0200 Subject: [PATCH 1/6] fix corerun --- src/native/corehost/browserhost/host/index.ts | 3 ++- .../System.Native.Browser/libSystem.Native.Browser.extpost.js | 4 +++- src/native/libs/System.Native.Browser/utils/index.ts | 3 ++- .../interop/index.ts | 3 ++- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/native/corehost/browserhost/host/index.ts b/src/native/corehost/browserhost/host/index.ts index 0bd7c1dc9ce2a3..f6af4b2ec64b14 100644 --- a/src/native/corehost/browserhost/host/index.ts +++ b/src/native/corehost/browserhost/host/index.ts @@ -12,7 +12,8 @@ export function dotnetInitializeModule(internals: InternalExchange): void { runMain, runMainAndExit, }; - Object.assign(internals[InternalExchangeIndex.RuntimeAPI], runtimeApiLocal); + const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI] = internals[InternalExchangeIndex.RuntimeAPI] || {} as RuntimeAPI; + Object.assign(runtimeApi, runtimeApiLocal); internals[InternalExchangeIndex.BrowserHostExportsTable] = browserHostExportsToTable({ registerDllBytes, diff --git a/src/native/libs/System.Native.Browser/libSystem.Native.Browser.extpost.js b/src/native/libs/System.Native.Browser/libSystem.Native.Browser.extpost.js index 0d44606a466fde..2666a3b8974e7b 100644 --- a/src/native/libs/System.Native.Browser/libSystem.Native.Browser.extpost.js +++ b/src/native/libs/System.Native.Browser/libSystem.Native.Browser.extpost.js @@ -4,10 +4,12 @@ /* eslint-disable no-undef */ /* eslint-disable space-before-function-paren */ +/* eslint-disable @typescript-eslint/no-unused-vars */ var fetch = fetch || undefined; var dotnetNativeModuleLoaded = false; var dotnetInternals = null; export function dotnetInitializeModule(internals) { if (dotnetNativeModuleLoaded) throw new Error("Native module already loaded"); dotnetInternals = internals; dotnetNativeModuleLoaded = true; - return createDotnetRuntime(dotnetInternals[0/*InternalExchangeIndex.RuntimeAPI*/].Module); + const runtimeApi = internals[0] = internals[0/*InternalExchangeIndex.RuntimeAPI*/] || {}; + return createDotnetRuntime(runtimeApi.Module || {}); } diff --git a/src/native/libs/System.Native.Browser/utils/index.ts b/src/native/libs/System.Native.Browser/utils/index.ts index 423c7c6a48de4f..01e7d281f17a83 100644 --- a/src/native/libs/System.Native.Browser/utils/index.ts +++ b/src/native/libs/System.Native.Browser/utils/index.ts @@ -22,7 +22,8 @@ export function dotnetInitializeModule(internals: InternalExchange): void { getHeapB32, getHeapB8, getHeapU8, getHeapU16, getHeapU32, getHeapI8, getHeapI16, getHeapI32, getHeapI52, getHeapU52, getHeapI64Big, getHeapF32, getHeapF64, localHeapViewI8, localHeapViewI16, localHeapViewI32, localHeapViewI64Big, localHeapViewU8, localHeapViewU16, localHeapViewU32, localHeapViewF32, localHeapViewF64, }; - Object.assign(internals[InternalExchangeIndex.RuntimeAPI], runtimeApiLocal); + const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI] = internals[InternalExchangeIndex.RuntimeAPI] || {} as RuntimeAPI; + Object.assign(runtimeApi, runtimeApiLocal); internals[InternalExchangeIndex.BrowserUtilsExportsTable] = browserUtilsExportsToTable({ utf16ToString, diff --git a/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/index.ts b/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/index.ts index 456255251f5d5b..3e730d3c4fde93 100644 --- a/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/index.ts +++ b/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/index.ts @@ -11,7 +11,8 @@ export function dotnetInitializeModule(internals: InternalExchange): void { getAssemblyExports, setModuleImports, }; - Object.assign(internals[InternalExchangeIndex.RuntimeAPI], runtimeApiLocal); + const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI] = internals[InternalExchangeIndex.RuntimeAPI] || {} as RuntimeAPI; + Object.assign(runtimeApi, runtimeApiLocal); internals[InternalExchangeIndex.RuntimeExportsTable] = runtimeExportsToTable({ }); From c73c719fcfcd5eb78f3b41b14b3a2ff60624d6c6 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 1 Oct 2025 12:43:00 +0200 Subject: [PATCH 2/6] improve when the "browser-wasm windows Debug AllSubsets_CoreCLR " is triggered --- .../common/evaluate-default-paths.yml | 20 ++++++++++++++++--- .../common/templates/wasm-runtime-tests.yml | 2 +- eng/pipelines/runtime.yml | 4 +++- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/eng/pipelines/common/evaluate-default-paths.yml b/eng/pipelines/common/evaluate-default-paths.yml index 80fd14756e59c0..2510dc7318bd4b 100644 --- a/eng/pipelines/common/evaluate-default-paths.yml +++ b/eng/pipelines/common/evaluate-default-paths.yml @@ -53,6 +53,7 @@ parameters: ] _wasm_src_native: [ src/coreclr/vm/wasm/* + src/coreclr/hosts/* src/native/minipal/* src/native/libs/CMakeLists.txt src/native/libs/configure.cmake @@ -61,7 +62,7 @@ parameters: src/native/libs/System.Globalization.Native/* src/native/libs/System.IO.Compression.Native/* src/native/libs/System.Native/* - src/native/corehost/browserhost/* + src/native/corehost/* src/native/libs/Common/JavaScript/* src/native/libs/System.Native.Browser/* src/native/libs/System.Runtime.InteropServices.JavaScript.Native/* @@ -270,8 +271,8 @@ jobs: - ${{ parameters._const_paths._always_exclude }} - ${{ parameters._const_paths._perf_pipeline_specific_only }} - # wasm/runtimetests need to be run - - subset: wasm_runtimetests + # wasm/runtimetests mono need to be run + - subset: wasm_mono_runtimetests combined: true include: - src/tests/* @@ -292,6 +293,19 @@ jobs: - ${{ parameters._const_paths._always_exclude }} - ${{ parameters._const_paths._perf_pipeline_specific_only }} + # wasm/runtimetests coreCLR need to be run + - subset: wasm_coreclr_runtimetests + combined: true + include: + - src/tests/* + - src/coreclr/* + - ${{ parameters._const_paths._wasm_src_native }} + exclude: + - src/mono/* + - ${{ parameters._const_paths._wasm_pipelines }} + - ${{ parameters._const_paths._always_exclude }} + - ${{ parameters._const_paths._perf_pipeline_specific_only }} + # Wasm except Wasm.build.Tests, Wasi.build.Tests and debugger - subset: wasm_specific_except_wbt_dbg combined: true diff --git a/eng/pipelines/common/templates/wasm-runtime-tests.yml b/eng/pipelines/common/templates/wasm-runtime-tests.yml index 510607830f0850..8f84bdb93038db 100644 --- a/eng/pipelines/common/templates/wasm-runtime-tests.yml +++ b/eng/pipelines/common/templates/wasm-runtime-tests.yml @@ -29,7 +29,7 @@ jobs: or( eq(variables['wasmDarcDependenciesChanged'], true), eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_illink.containsChange'], true), - eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_wasm_runtimetests.containsChange'], true)) + eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_wasm_mono_runtimetests.containsChange'], true)) ] jobParameters: testGroup: innerloop diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 722aaea283431a..64db126cf99cde 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -115,7 +115,9 @@ extends: timeoutInMinutes: 120 condition: >- or( - eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_non_mono_and_wasm.containsChange'], true), + eq(variables['wasmDarcDependenciesChanged'], true), + eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_illink.containsChange'], true), + eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_wasm_coreclr_runtimetests.containsChange'], true), eq(variables['isRollingBuild'], true)) # From 01f83090d1a45e944642132189515ed83fd015df Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 1 Oct 2025 20:20:13 +0200 Subject: [PATCH 3/6] fix exchange problems, more assets --- src/coreclr/hosts/corerun/libCorerun.pre.js | 8 ++-- src/native/corehost/browserhost/host/index.ts | 4 +- .../corehost/browserhost/loader/bootstrap.ts | 2 +- .../corehost/browserhost/loader/index.ts | 17 ++++---- .../Common/JavaScript/cross-module/index.ts | 40 ++++++++----------- .../libSystem.Native.Browser.extpost.js | 3 +- .../libs/System.Native.Browser/utils/index.ts | 4 +- .../interop/index.ts | 4 +- 8 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/coreclr/hosts/corerun/libCorerun.pre.js b/src/coreclr/hosts/corerun/libCorerun.pre.js index 13aefa18b76e91..6f203949f2e6df 100644 --- a/src/coreclr/hosts/corerun/libCorerun.pre.js +++ b/src/coreclr/hosts/corerun/libCorerun.pre.js @@ -1,9 +1,9 @@ -var dotnetInternals = { - runtimeApi: { +var dotnetInternals = [ + { Module: Module, }, - updates: [], -}; + [], +]; Module.preRun = () => { // copy all node/shell env variables to emscripten env if (globalThis.process && globalThis.process.env) { diff --git a/src/native/corehost/browserhost/host/index.ts b/src/native/corehost/browserhost/host/index.ts index f6af4b2ec64b14..6c6783eea93693 100644 --- a/src/native/corehost/browserhost/host/index.ts +++ b/src/native/corehost/browserhost/host/index.ts @@ -8,11 +8,13 @@ import { } from "./cross-linked"; // ensure ambient symbols are declared import { runMain, runMainAndExit, registerDllBytes } from "./host"; export function dotnetInitializeModule(internals: InternalExchange): void { + if (!Array.isArray(internals)) throw new Error("Expected internals to be an array"); const runtimeApiLocal: Partial = { runMain, runMainAndExit, }; - const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI] = internals[InternalExchangeIndex.RuntimeAPI] || {} as RuntimeAPI; + const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI]; + if (typeof runtimeApi !== "object") throw new Error("Expected internals to have RuntimeAPI"); Object.assign(runtimeApi, runtimeApiLocal); internals[InternalExchangeIndex.BrowserHostExportsTable] = browserHostExportsToTable({ diff --git a/src/native/corehost/browserhost/loader/bootstrap.ts b/src/native/corehost/browserhost/loader/bootstrap.ts index 2d0f3e5805ca2f..bbf6042498b990 100644 --- a/src/native/corehost/browserhost/loader/bootstrap.ts +++ b/src/native/corehost/browserhost/loader/bootstrap.ts @@ -16,7 +16,7 @@ const scriptUrl = normalizeFileUrl(scriptUrlQuery); const scriptDirectory = normalizeDirectoryUrl(scriptUrl); const nativeModulePromiseController = createPromiseController(() => { - dotnetUpdateInternals(); + dotnetUpdateInternals(dotnetGetInternals()); }); // WASM-TODO: retry logic diff --git a/src/native/corehost/browserhost/loader/index.ts b/src/native/corehost/browserhost/loader/index.ts index a400af1aadacba..92002a3b56df66 100644 --- a/src/native/corehost/browserhost/loader/index.ts +++ b/src/native/corehost/browserhost/loader/index.ts @@ -16,7 +16,7 @@ import { exit } from "./exit"; import { invokeLibraryInitializers } from "./lib-initializers"; import { check, error, info, warn } from "./logging"; -import { dotnetAssert, dotnetInternals, dotnetLoaderExports, dotnetLogger, dotnetUpdateInternals, dotnetUpdateInternalsSubscriber } from "./cross-module"; +import { dotnetAssert, dotnetLoaderExports, dotnetLogger, dotnetUpdateInternals, dotnetUpdateInternalsSubscriber } from "./cross-module"; import { rejectRunMainPromise, resolveRunMainPromise, getRunMainPromise } from "./run"; export function dotnetInitializeModule(): RuntimeAPI { @@ -42,14 +42,13 @@ export function dotnetInitializeModule(): RuntimeAPI { dotnetApi as RuntimeAPI, //0 [], //1 netLoaderConfig, //2 - null as any as LoaderExportsTable, //3 - null as any as RuntimeExportsTable, //4 - null as any as BrowserHostExportsTable, //5 - null as any as InteropJavaScriptExportsTable, //6 - null as any as NativeBrowserExportsTable, //7 - null as any as BrowserUtilsExportsTable, //8 + undefined as any as LoaderExportsTable, //3 + undefined as any as RuntimeExportsTable, //4 + undefined as any as BrowserHostExportsTable, //5 + undefined as any as InteropJavaScriptExportsTable, //6 + undefined as any as NativeBrowserExportsTable, //7 + undefined as any as BrowserUtilsExportsTable, //8 ]; - Object.assign(dotnetInternals, internals); const loaderFunctions: LoaderExports = { getRunMainPromise, rejectRunMainPromise, @@ -67,7 +66,7 @@ export function dotnetInitializeModule(): RuntimeAPI { }; Object.assign(dotnetAssert, assert); - dotnetInternals[InternalExchangeIndex.LoaderExportsTable] = loaderExportsToTable(dotnetLogger, dotnetAssert, dotnetLoaderExports); + internals[InternalExchangeIndex.LoaderExportsTable] = loaderExportsToTable(dotnetLogger, dotnetAssert, dotnetLoaderExports); dotnetUpdateInternals(internals, dotnetUpdateInternalsSubscriber); return dotnetApi as RuntimeAPI; diff --git a/src/native/libs/Common/JavaScript/cross-module/index.ts b/src/native/libs/Common/JavaScript/cross-module/index.ts index 2ae1a97c5aa80d..7d235e538920b4 100644 --- a/src/native/libs/Common/JavaScript/cross-module/index.ts +++ b/src/native/libs/Common/JavaScript/cross-module/index.ts @@ -22,17 +22,17 @@ import type { DotnetModuleInternal, InternalExchange, RuntimeExports, LoaderExports, RuntimeAPI, LoggerType, AssertType, BrowserHostExports, InteropJavaScriptExports, LoaderExportsTable, RuntimeExportsTable, BrowserHostExportsTable, InteropJavaScriptExportsTable, NativeBrowserExports, NativeBrowserExportsTable, InternalExchangeSubscriber, BrowserUtilsExports, BrowserUtilsExportsTable, VoidPtr, CharPtr, NativePointer } from "../types"; import { InternalExchangeIndex } from "../types"; +let dotnetInternals: InternalExchange; export let Module: DotnetModuleInternal; export let dotnetApi: RuntimeAPI; -export let dotnetLogger: LoggerType = {} as any; -export let dotnetAssert: AssertType = {} as any; -export let dotnetLoaderExports: LoaderExports = {} as any; -export let dotnetRuntimeExports: RuntimeExports = {} as any; -export let dotnetBrowserHostExports: BrowserHostExports = {} as any; -export let dotnetInteropJSExports: InteropJavaScriptExports = {} as any; -export let dotnetNativeBrowserExports: NativeBrowserExports = {} as any; -export let dotnetBrowserUtilsExports: BrowserUtilsExports = {} as any; -export let dotnetInternals: InternalExchange = {} as any; +export const dotnetLogger: LoggerType = {} as LoggerType; +export const dotnetAssert: AssertType = {} as AssertType; +export const dotnetLoaderExports: LoaderExports = {} as any; +export const dotnetRuntimeExports: RuntimeExports = {} as any; +export const dotnetBrowserHostExports: BrowserHostExports = {} as any; +export const dotnetInteropJSExports: InteropJavaScriptExports = {} as any; +export const dotnetNativeBrowserExports: NativeBrowserExports = {} as any; +export const dotnetBrowserUtilsExports: BrowserUtilsExports = {} as any; export const VoidPtrNull: VoidPtr = 0; export const CharPtrNull: CharPtr = 0; @@ -44,19 +44,21 @@ export function dotnetGetInternals(): InternalExchange { // this should be called when we want to dispatch new internal functions to other JS modules // subscriber parameter is the callback function with visibility to the current module's internal closure -export function dotnetUpdateInternals(internals?: InternalExchange, subscriber?: InternalExchangeSubscriber) { +export function dotnetUpdateInternals(internals: InternalExchange, subscriber?: InternalExchangeSubscriber) { + if (!Array.isArray(internals)) throw new Error("Expected internals to be an array"); + if (!Array.isArray(internals[InternalExchangeIndex.InternalUpdatesCallbacks])) throw new Error("Expected internal updates to be an array"); if (dotnetInternals === undefined) { - dotnetInternals = internals!; + dotnetInternals = internals; + } else if (dotnetInternals !== internals) { + throw new Error("Cannot replace internals"); } if (dotnetApi === undefined) { dotnetApi = dotnetInternals[InternalExchangeIndex.RuntimeAPI]; } - if (Module === undefined && dotnetApi) { + if (typeof dotnetApi !== "object") throw new Error("Expected internals to have RuntimeAPI"); + if (Module === undefined) { Module = dotnetApi.Module as any; } - if (dotnetInternals[InternalExchangeIndex.InternalUpdatesCallbacks] === undefined) { - dotnetInternals[InternalExchangeIndex.InternalUpdatesCallbacks] = []; - } const updates = dotnetInternals[InternalExchangeIndex.InternalUpdatesCallbacks]; if (subscriber && !updates.includes(subscriber)) { updates.push(subscriber); @@ -73,29 +75,21 @@ export function dotnetUpdateInternalsSubscriber() { */ if (Object.keys(dotnetLoaderExports).length === 0 && dotnetInternals[InternalExchangeIndex.LoaderExportsTable]) { - dotnetLoaderExports = {} as LoaderExports; - dotnetLogger = {} as LoggerType; - dotnetAssert = {} as AssertType; loaderExportsFromTable(dotnetInternals[InternalExchangeIndex.LoaderExportsTable], dotnetLogger, dotnetAssert, dotnetLoaderExports); } if (Object.keys(dotnetRuntimeExports).length === 0 && dotnetInternals[InternalExchangeIndex.RuntimeExportsTable]) { - dotnetRuntimeExports = {} as RuntimeExports; runtimeExportsFromTable(dotnetInternals[InternalExchangeIndex.RuntimeExportsTable], dotnetRuntimeExports); } if (Object.keys(dotnetBrowserHostExports).length === 0 && dotnetInternals[InternalExchangeIndex.BrowserHostExportsTable]) { - dotnetBrowserHostExports = {} as BrowserHostExports; browserHostExportsFromTable(dotnetInternals[InternalExchangeIndex.BrowserHostExportsTable], dotnetBrowserHostExports); } if (Object.keys(dotnetBrowserUtilsExports).length === 0 && dotnetInternals[InternalExchangeIndex.BrowserUtilsExportsTable]) { - dotnetBrowserUtilsExports = {} as BrowserUtilsExports; nativeHelperExportsFromTable(dotnetInternals[InternalExchangeIndex.BrowserUtilsExportsTable], dotnetBrowserUtilsExports); } if (Object.keys(dotnetInteropJSExports).length === 0 && dotnetInternals[InternalExchangeIndex.InteropJavaScriptExportsTable]) { - dotnetInteropJSExports = {} as InteropJavaScriptExports; interopJavaScriptExportsFromTable(dotnetInternals[InternalExchangeIndex.InteropJavaScriptExportsTable], dotnetInteropJSExports); } if (Object.keys(dotnetNativeBrowserExports).length === 0 && dotnetInternals[InternalExchangeIndex.NativeBrowserExportsTable]) { - dotnetNativeBrowserExports = {} as NativeBrowserExports; nativeBrowserExportsFromTable(dotnetInternals[InternalExchangeIndex.NativeBrowserExportsTable], dotnetNativeBrowserExports); } diff --git a/src/native/libs/System.Native.Browser/libSystem.Native.Browser.extpost.js b/src/native/libs/System.Native.Browser/libSystem.Native.Browser.extpost.js index 2666a3b8974e7b..bf84b9c25139a0 100644 --- a/src/native/libs/System.Native.Browser/libSystem.Native.Browser.extpost.js +++ b/src/native/libs/System.Native.Browser/libSystem.Native.Browser.extpost.js @@ -8,8 +8,9 @@ var fetch = fetch || undefined; var dotnetNativeModuleLoaded = false; var dotnetInternals = null; export function dotnetInitializeModule(internals) { if (dotnetNativeModuleLoaded) throw new Error("Native module already loaded"); - dotnetInternals = internals; dotnetNativeModuleLoaded = true; + if (!Array.isArray(internals)) throw new Error("Expected internals to be an array"); + dotnetInternals = internals; const runtimeApi = internals[0] = internals[0/*InternalExchangeIndex.RuntimeAPI*/] || {}; return createDotnetRuntime(runtimeApi.Module || {}); } diff --git a/src/native/libs/System.Native.Browser/utils/index.ts b/src/native/libs/System.Native.Browser/utils/index.ts index 01e7d281f17a83..749e86856169da 100644 --- a/src/native/libs/System.Native.Browser/utils/index.ts +++ b/src/native/libs/System.Native.Browser/utils/index.ts @@ -15,6 +15,7 @@ import { exit, setEnvironmentVariable } from "./host"; import { dotnetUpdateInternals, dotnetUpdateInternalsSubscriber } from "../utils/cross-module"; export function dotnetInitializeModule(internals: InternalExchange): void { + if (!Array.isArray(internals)) throw new Error("Expected internals to be an array"); const runtimeApiLocal: Partial = { setEnvironmentVariable, exit, @@ -22,7 +23,8 @@ export function dotnetInitializeModule(internals: InternalExchange): void { getHeapB32, getHeapB8, getHeapU8, getHeapU16, getHeapU32, getHeapI8, getHeapI16, getHeapI32, getHeapI52, getHeapU52, getHeapI64Big, getHeapF32, getHeapF64, localHeapViewI8, localHeapViewI16, localHeapViewI32, localHeapViewI64Big, localHeapViewU8, localHeapViewU16, localHeapViewU32, localHeapViewF32, localHeapViewF64, }; - const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI] = internals[InternalExchangeIndex.RuntimeAPI] || {} as RuntimeAPI; + const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI]; + if (typeof runtimeApi !== "object") throw new Error("Expected internals to have RuntimeAPI"); Object.assign(runtimeApi, runtimeApiLocal); internals[InternalExchangeIndex.BrowserUtilsExportsTable] = browserUtilsExportsToTable({ diff --git a/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/index.ts b/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/index.ts index 3e730d3c4fde93..199fdaeef77062 100644 --- a/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/index.ts +++ b/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/index.ts @@ -7,11 +7,13 @@ import { dotnetUpdateInternals, dotnetUpdateInternalsSubscriber } from "./cross- import { ENVIRONMENT_IS_NODE } from "./per-module"; export function dotnetInitializeModule(internals: InternalExchange): void { + if (!Array.isArray(internals)) throw new Error("Expected internals to be an array"); const runtimeApiLocal: Partial = { getAssemblyExports, setModuleImports, }; - const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI] = internals[InternalExchangeIndex.RuntimeAPI] || {} as RuntimeAPI; + const runtimeApi = internals[InternalExchangeIndex.RuntimeAPI]; + if (typeof runtimeApi !== "object") throw new Error("Expected internals to have RuntimeAPI"); Object.assign(runtimeApi, runtimeApiLocal); internals[InternalExchangeIndex.RuntimeExportsTable] = runtimeExportsToTable({ From 3e2ad8806cf2772ac30d2dee85a81d26b6ba652a Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 1 Oct 2025 21:23:24 +0200 Subject: [PATCH 4/6] more strict dotnetInitializeModule for dotnet.native.js --- .../libSystem.Native.Browser.extpost.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/native/libs/System.Native.Browser/libSystem.Native.Browser.extpost.js b/src/native/libs/System.Native.Browser/libSystem.Native.Browser.extpost.js index bf84b9c25139a0..539adb82b59f7a 100644 --- a/src/native/libs/System.Native.Browser/libSystem.Native.Browser.extpost.js +++ b/src/native/libs/System.Native.Browser/libSystem.Native.Browser.extpost.js @@ -11,6 +11,8 @@ export function dotnetInitializeModule(internals) { dotnetNativeModuleLoaded = true; if (!Array.isArray(internals)) throw new Error("Expected internals to be an array"); dotnetInternals = internals; - const runtimeApi = internals[0] = internals[0/*InternalExchangeIndex.RuntimeAPI*/] || {}; - return createDotnetRuntime(runtimeApi.Module || {}); + const runtimeApi = internals[0/*InternalExchangeIndex.RuntimeAPI*/]; + if (typeof runtimeApi !== "object") throw new Error("Expected internals to have RuntimeAPI"); + if (typeof runtimeApi.Module !== "object") throw new Error("Expected internals to have Module"); + return createDotnetRuntime(runtimeApi.Module); } From f18b9ce40dfa10b231db3e69eb121e76387e7b62 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 1 Oct 2025 21:26:22 +0200 Subject: [PATCH 5/6] set DOTNET_SYSTEM_GLOBALIZATION_INVARIANT --- src/coreclr/hosts/corerun/libCorerun.pre.js | 1 + src/coreclr/hosts/corewasmrun/libCorewasmrun.pre.js | 11 +++++++---- .../corehost/browserhost/libBrowserHost.footer.js | 3 +++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/coreclr/hosts/corerun/libCorerun.pre.js b/src/coreclr/hosts/corerun/libCorerun.pre.js index 6f203949f2e6df..fefba3db358fd1 100644 --- a/src/coreclr/hosts/corerun/libCorerun.pre.js +++ b/src/coreclr/hosts/corerun/libCorerun.pre.js @@ -11,4 +11,5 @@ Module.preRun = () => { ENV[key] = value; } } + ENV["DOTNET_SYSTEM_GLOBALIZATION_INVARIANT"] = "true"; }; \ No newline at end of file diff --git a/src/coreclr/hosts/corewasmrun/libCorewasmrun.pre.js b/src/coreclr/hosts/corewasmrun/libCorewasmrun.pre.js index f2dc1b77184106..50a7e3b2d47225 100644 --- a/src/coreclr/hosts/corewasmrun/libCorewasmrun.pre.js +++ b/src/coreclr/hosts/corewasmrun/libCorewasmrun.pre.js @@ -1,6 +1,9 @@ -var dotnetInternals = { - runtimeApi: { +var dotnetInternals = [ + { Module: Module, }, - updates: [], -}; + [], +]; +Module.preRun = () => { + ENV["DOTNET_SYSTEM_GLOBALIZATION_INVARIANT"] = "true"; +}; \ No newline at end of file diff --git a/src/native/corehost/browserhost/libBrowserHost.footer.js b/src/native/corehost/browserhost/libBrowserHost.footer.js index 6ecd94a32e3f79..3142c57443b754 100644 --- a/src/native/corehost/browserhost/libBrowserHost.footer.js +++ b/src/native/corehost/browserhost/libBrowserHost.footer.js @@ -51,6 +51,9 @@ ENV[HOST_PROPERTY_NATIVE_DLL_SEARCH_DIRECTORIES] = config.environmentVariables[HOST_PROPERTY_NATIVE_DLL_SEARCH_DIRECTORIES] = config.virtualWorkingDirectory; ENV[HOST_PROPERTY_APP_PATHS] = config.environmentVariables[HOST_PROPERTY_APP_PATHS] = config.virtualWorkingDirectory; ENV[HOST_PROPERTY_ENTRY_ASSEMBLY_NAME] = config.environmentVariables[HOST_PROPERTY_ENTRY_ASSEMBLY_NAME] = config.mainAssemblyName; + + // WASM-TODO: remove once globalization is loaded via ICU + ENV["DOTNET_SYSTEM_GLOBALIZATION_INVARIANT"] = "true"; } }, }, From 57cc176ab8e63954d0606a601255b83a22c34f4e Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 1 Oct 2025 22:13:09 +0200 Subject: [PATCH 6/6] dependencies --- src/native/corehost/browserhost/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/native/corehost/browserhost/CMakeLists.txt b/src/native/corehost/browserhost/CMakeLists.txt index dba42b11032e6f..a56a15655714c7 100644 --- a/src/native/corehost/browserhost/CMakeLists.txt +++ b/src/native/corehost/browserhost/CMakeLists.txt @@ -21,6 +21,9 @@ add_definitions(-DFEATURE_STATIC_HOST=1) add_executable(browserhost ${SOURCES}) set_target_properties(browserhost PROPERTIES OUTPUT_NAME dotnet.native) set(CMAKE_EXECUTABLE_SUFFIX ".js") +add_dependencies(browserhost System.Native.Browser-Rollup) +add_dependencies(browserhost System.Native.Browser-Static) +add_dependencies(browserhost System.Runtime.InteropServices.JavaScript.Native-Static) install(TARGETS browserhost DESTINATION corehost COMPONENT runtime) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/dotnet.native.wasm DESTINATION corehost COMPONENT runtime)