diff --git a/src/coreclr/hosts/corerun/CMakeLists.txt b/src/coreclr/hosts/corerun/CMakeLists.txt
index 509cdf95b09af3..b3613dcf767a05 100644
--- a/src/coreclr/hosts/corerun/CMakeLists.txt
+++ b/src/coreclr/hosts/corerun/CMakeLists.txt
@@ -61,7 +61,7 @@ else()
set(JS_SYSTEM_NATIVE_BROWSER
"${STATIC_LIB_DESTINATION}/libSystem.Native.Browser.js")
set(JS_SYSTEM_BROWSER_UTILS
- "${STATIC_LIB_DESTINATION}/libSystem.Browser.Utils.js")
+ "${STATIC_LIB_DESTINATION}/libSystem.Native.Browser.Utils.js")
set(JS_CORE_RUN
"${CMAKE_CURRENT_SOURCE_DIR}/wasm/libCorerun.extpost.js")
set_target_properties(corerun PROPERTIES
diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
index 30cb047bc02ba2..4b649df6a6b8b7 100644
--- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
+++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
@@ -271,8 +271,8 @@
-
-
+
+
diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Locale.CoreCLR.cs b/src/libraries/Common/src/Interop/Browser/Interop.Locale.CoreCLR.cs
index df35ebf640f4dd..290dc72fcd28dd 100644
--- a/src/libraries/Common/src/Interop/Browser/Interop.Locale.CoreCLR.cs
+++ b/src/libraries/Common/src/Interop/Browser/Interop.Locale.CoreCLR.cs
@@ -8,7 +8,7 @@ internal static partial class Interop
{
internal static unsafe partial class JsGlobalization
{
- [LibraryImport(Libraries.JavaScriptNative, EntryPoint = "SystemJS_GetLocaleInfo")]
+ [LibraryImport(Libraries.SystemBrowserNative, EntryPoint = "SystemJS_GetLocaleInfo")]
public static unsafe partial nint GetLocaleInfo(char* locale, int localeLength, char* culture, int cultureLength, char* buffer, int bufferLength, out int resultLength);
}
}
diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Locale.cs b/src/libraries/Common/src/Interop/Browser/Interop.Locale.Mono.cs
similarity index 100%
rename from src/libraries/Common/src/Interop/Browser/Interop.Locale.cs
rename to src/libraries/Common/src/Interop/Browser/Interop.Locale.Mono.cs
diff --git a/src/libraries/Common/src/Interop/Unix/Interop.Libraries.cs b/src/libraries/Common/src/Interop/Unix/Interop.Libraries.cs
index 1ea74c7c6aaff5..493c0113259762 100644
--- a/src/libraries/Common/src/Interop/Unix/Interop.Libraries.cs
+++ b/src/libraries/Common/src/Interop/Unix/Interop.Libraries.cs
@@ -13,8 +13,9 @@ internal static partial class Libraries
internal const string CryptoNative = "libSystem.Security.Cryptography.Native.OpenSsl";
internal const string CompressionNative = "libSystem.IO.Compression.Native";
internal const string GlobalizationNative = "libSystem.Globalization.Native";
+ internal const string JavaScriptNative = "libSystem.Runtime.InteropServices.JavaScript.Native";
internal const string IOPortsNative = "libSystem.IO.Ports.Native";
internal const string HostPolicy = "libhostpolicy";
- internal const string JavaScriptNative = "libSystem.JavaScript.Native";
+ internal const string SystemBrowserNative = "libSystem.Native.Browser";
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
index f8cf9733e24181..80981a2f3acaef 100644
--- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
+++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
@@ -1378,8 +1378,8 @@
Common\Interop\Browser\Interop.Locale.CoreCLR.cs
-
- Common\Interop\Browser\Interop.Locale.cs
+
+ Common\Interop\Browser\Interop.Locale.Mono.cs
Common\Interop\Interop.Calendar.cs
diff --git a/src/libraries/externals.csproj b/src/libraries/externals.csproj
index d689529b137efa..b83b9ac3e0810a 100644
--- a/src/libraries/externals.csproj
+++ b/src/libraries/externals.csproj
@@ -86,8 +86,8 @@
-
-
+
+
diff --git a/src/native/corehost/browserhost/CMakeLists.txt b/src/native/corehost/browserhost/CMakeLists.txt
index 7c4bdfd3b3eb77..6173bee1ef0bd2 100644
--- a/src/native/corehost/browserhost/CMakeLists.txt
+++ b/src/native/corehost/browserhost/CMakeLists.txt
@@ -79,7 +79,7 @@ LIST(APPEND NATIVE_LIBS
set(JS_SYSTEM_NATIVE_BROWSER
"${SHARED_LIB_DESTINATION}/libSystem.Native.Browser.js")
set(JS_SYSTEM_BROWSER_UTILS
- "${SHARED_LIB_DESTINATION}/libSystem.Browser.Utils.js")
+ "${SHARED_LIB_DESTINATION}/libSystem.Native.Browser.Utils.js")
set(JS_SYSTEM_RUNTIME_INTEROPSERVICES_JAVASCRIPT_NATIVE
"${SHARED_LIB_DESTINATION}/libSystem.Runtime.InteropServices.JavaScript.Native.js")
set(JS_BROWSER_HOST
diff --git a/src/native/corehost/browserhost/ReadMe.md b/src/native/corehost/browserhost/ReadMe.md
index c84b888122e964..042b5d9ee763a5 100644
--- a/src/native/corehost/browserhost/ReadMe.md
+++ b/src/native/corehost/browserhost/ReadMe.md
@@ -17,7 +17,7 @@ Implements native part of the CoreCLR host and exposes it as an internal JavaScr
It is **Emscripten application** statically linked from libraries.
- `libSystem.Native.Browser.js` linked -> `dotnet.native.js`
-- `libSystem.Browser.Utils.js` linked -> `dotnet.native.js`
+- `libSystem.Native.Browser.Utils.js` linked -> `dotnet.native.js`
- `libSystem.Runtime.InteropServices.JavaScript.Native.js` linked -> `dotnet.native.js`
- `libSystem.Native.Browser.a` linked -> `dotnet.native.wasm`
- `libSystem.Runtime.InteropServices.JavaScript.Native.a` linked -> `dotnet.native.wasm`
diff --git a/src/native/corehost/browserhost/browserhost.cpp b/src/native/corehost/browserhost/browserhost.cpp
index 1350d13ad59b7d..14d26f295d1df6 100644
--- a/src/native/corehost/browserhost/browserhost.cpp
+++ b/src/native/corehost/browserhost/browserhost.cpp
@@ -68,7 +68,7 @@ static const void* pinvoke_override(const char* library_name, const char* entry_
{
return SystemResolveDllImport(entry_point_name);
}
- if (strcmp(library_name, "libSystem.JavaScript.Native") == 0)
+ if (strcmp(library_name, "libSystem.Native.Browser") == 0)
{
return SystemJSResolveDllImport(entry_point_name);
}
diff --git a/src/native/corehost/browserhost/libBrowserHost.footer.js b/src/native/corehost/browserhost/libBrowserHost.footer.js
index 8d89fdd829395f..dfedd5ce7875b4 100644
--- a/src/native/corehost/browserhost/libBrowserHost.footer.js
+++ b/src/native/corehost/browserhost/libBrowserHost.footer.js
@@ -45,12 +45,15 @@
!config.environmentVariables) {
throw new Error("Invalid runtime config, cannot initialize the runtime.");
}
- const assemblyPaths = config.resources.assembly.map(a => a.virtualPath);
- const coreAssemblyPaths = config.resources.coreAssembly.map(a => a.virtualPath);
- ENV[HOST_PROPERTY_TRUSTED_PLATFORM_ASSEMBLIES] = config.environmentVariables[HOST_PROPERTY_TRUSTED_PLATFORM_ASSEMBLIES] = [...coreAssemblyPaths, ...assemblyPaths].join(":");
- 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;
+ const assemblyPaths = config.resources.assembly.map(a => "/" + a.virtualPath);
+ const coreAssemblyPaths = config.resources.coreAssembly.map(a => "/" + a.virtualPath);
+ config.environmentVariables[HOST_PROPERTY_TRUSTED_PLATFORM_ASSEMBLIES] = [...coreAssemblyPaths, ...assemblyPaths].join(":");
+ config.environmentVariables[HOST_PROPERTY_NATIVE_DLL_SEARCH_DIRECTORIES] = config.virtualWorkingDirectory;
+ config.environmentVariables[HOST_PROPERTY_APP_PATHS] = config.virtualWorkingDirectory;
+ config.environmentVariables[HOST_PROPERTY_ENTRY_ASSEMBLY_NAME] = config.mainAssemblyName;
+ for (const key in config.environmentVariables) {
+ ENV[key] = config.environmentVariables[key];
+ }
if (ENVIRONMENT_IS_NODE) {
Module.preInit = [() => {
diff --git a/src/native/corehost/browserhost/loader/assets.ts b/src/native/corehost/browserhost/loader/assets.ts
new file mode 100644
index 00000000000000..c214e61b8f4a5b
--- /dev/null
+++ b/src/native/corehost/browserhost/loader/assets.ts
@@ -0,0 +1,129 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+import type { LoadBootResourceCallback, JsModuleExports, JsAsset, AssemblyAsset, PdbAsset, WasmAsset, IcuAsset, EmscriptenModuleInternal, InstantiateWasmSuccessCallback } from "./types";
+
+import { dotnetAssert, dotnetGetInternals, dotnetBrowserHostExports, dotnetUpdateInternals } from "./cross-module";
+import { getIcuResourceName } from "./icu";
+import { getLoaderConfig } from "./config";
+import { BrowserHost_InitializeCoreCLR } from "./run";
+import { createPromiseCompletionSource } from "./promise-completion-source";
+import { locateFile } from "./bootstrap";
+import { fetchLike } from "./polyfills";
+
+const nativeModulePromiseController = createPromiseCompletionSource(() => {
+ dotnetUpdateInternals(dotnetGetInternals());
+});
+let wasmBinaryPromise: any = undefined;
+
+// WASM-TODO: retry logic
+// WASM-TODO: throttling logic
+// WASM-TODO: invokeLibraryInitializers
+// WASM-TODO: webCIL
+// WASM-TODO: downloadOnly - blazor render mode auto pre-download. Really no start.
+// WASM-TODO: no-cache, force-cache, integrity
+// WASM-TODO: LoadBootResourceCallback
+// WASM-TODO: fail fast for missing WASM features - SIMD, EH, BigInt detection
+
+export async function createRuntime(downloadOnly: boolean, loadBootResource?: LoadBootResourceCallback): Promise {
+ if (loadBootResource) throw new Error("TODO: loadBootResource is not implemented yet");
+ const config = getLoaderConfig();
+ if (!config.resources || !config.resources.coreAssembly || !config.resources.coreAssembly.length) throw new Error("Invalid config, resources is not set");
+
+ const nativeModulePromise = loadJSModule(config.resources.jsModuleNative[0]);
+ const runtimeModulePromise = loadJSModule(config.resources.jsModuleRuntime[0]);
+ const wasmNativePromise = fetchWasm(config.resources.wasmNative[0]);
+
+ const coreAssembliesPromise = Promise.all(config.resources.coreAssembly.map(fetchDll));
+ const coreVfsPromise = Promise.all((config.resources.coreVfs || []).map(fetchVfs));
+ const assembliesPromise = Promise.all(config.resources.assembly.map(fetchDll));
+ const vfsPromise = Promise.all((config.resources.vfs || []).map(fetchVfs));
+ const icuResourceName = getIcuResourceName(config);
+ const icuDataPromise = icuResourceName ? Promise.all((config.resources.icu || []).filter(asset => asset.name === icuResourceName).map(fetchIcu)) : Promise.resolve([]);
+
+ const nativeModule = await nativeModulePromise;
+ const modulePromise = nativeModule.dotnetInitializeModule(dotnetGetInternals());
+ nativeModulePromiseController.propagateFrom(modulePromise);
+
+ const runtimeModule = await runtimeModulePromise;
+ const runtimeModuleReady = runtimeModule.dotnetInitializeModule(dotnetGetInternals());
+
+ await nativeModulePromiseController.promise;
+ await coreAssembliesPromise;
+ await coreVfsPromise;
+ await vfsPromise;
+ await icuDataPromise;
+ await wasmNativePromise; // this is just to propagate errors
+ if (!downloadOnly) {
+ BrowserHost_InitializeCoreCLR();
+ }
+
+ await assembliesPromise;
+ await runtimeModuleReady;
+}
+
+async function loadJSModule(asset: JsAsset): Promise {
+ if (asset.name && !asset.resolvedUrl) {
+ asset.resolvedUrl = locateFile(asset.name);
+ }
+ if (!asset.resolvedUrl) throw new Error("Invalid config, resources is not set");
+ return await import(/* webpackIgnore: true */ asset.resolvedUrl);
+}
+
+function fetchWasm(asset: WasmAsset): Promise {
+ if (asset.name && !asset.resolvedUrl) {
+ asset.resolvedUrl = locateFile(asset.name);
+ }
+ if (!asset.resolvedUrl) throw new Error("Invalid config, resources is not set");
+ wasmBinaryPromise = fetchLike(asset.resolvedUrl);
+ return wasmBinaryPromise;
+}
+
+export async function instantiateWasm(imports: WebAssembly.Imports, successCallback: InstantiateWasmSuccessCallback): Promise {
+ if (wasmBinaryPromise instanceof globalThis.Response === false || !WebAssembly.instantiateStreaming) {
+ const res = await wasmBinaryPromise;
+ const data = await res.arrayBuffer();
+ const module = await WebAssembly.compile(data);
+ const instance = await WebAssembly.instantiate(module, imports);
+ successCallback(instance, module);
+ } else {
+ const res = await WebAssembly.instantiateStreaming(wasmBinaryPromise, imports);
+ successCallback(res.instance, res.module);
+ }
+}
+
+async function fetchIcu(asset: IcuAsset): Promise {
+ if (asset.name && !asset.resolvedUrl) {
+ asset.resolvedUrl = locateFile(asset.name);
+ }
+ const bytes = await fetchBytes(asset);
+ await nativeModulePromiseController.promise;
+ dotnetBrowserHostExports.loadIcuData(bytes);
+}
+
+async function fetchDll(asset: AssemblyAsset): Promise {
+ if (asset.name && !asset.resolvedUrl) {
+ asset.resolvedUrl = locateFile(asset.name);
+ }
+ const bytes = await fetchBytes(asset);
+ await nativeModulePromiseController.promise;
+
+ dotnetBrowserHostExports.registerDllBytes(bytes, asset);
+}
+
+async function fetchVfs(asset: AssemblyAsset): Promise {
+ if (asset.name && !asset.resolvedUrl) {
+ asset.resolvedUrl = locateFile(asset.name);
+ }
+ const bytes = await fetchBytes(asset);
+ await nativeModulePromiseController.promise;
+
+ dotnetBrowserHostExports.installVfsFile(bytes, asset);
+}
+
+async function fetchBytes(asset: WasmAsset | AssemblyAsset | PdbAsset | IcuAsset): Promise {
+ dotnetAssert.check(asset && asset.resolvedUrl, "Bad asset.resolvedUrl");
+ const response = await fetchLike(asset.resolvedUrl);
+ const buffer = await response.arrayBuffer();
+ return new Uint8Array(buffer);
+}
diff --git a/src/native/corehost/browserhost/loader/bootstrap.ts b/src/native/corehost/browserhost/loader/bootstrap.ts
index 4083099ad56d75..b2f7843759065e 100644
--- a/src/native/corehost/browserhost/loader/bootstrap.ts
+++ b/src/native/corehost/browserhost/loader/bootstrap.ts
@@ -1,13 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-import type { LoadBootResourceCallback, JsModuleExports, JsAsset, AssemblyAsset, PdbAsset, WasmAsset, IcuAsset, EmscriptenModuleInternal, LoaderConfig, DotnetHostBuilder } from "./types";
-import { dotnetAssert, dotnetGetInternals, dotnetBrowserHostExports, dotnetUpdateInternals } from "./cross-module";
+import { type LoaderConfig, type DotnetHostBuilder, GlobalizationMode } from "./types";
import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL } from "./per-module";
-import { getIcuResourceName } from "./icu";
-import { getLoaderConfig } from "./config";
-import { BrowserHost_InitializeCoreCLR } from "./run";
-import { createPromiseCompletionSource } from "./promise-completion-source";
import { nodeFs } from "./polyfills";
const scriptUrlQuery = /*! webpackIgnore: true */import.meta.url;
@@ -16,110 +11,7 @@ const modulesUniqueQuery = queryIndex > 0 ? scriptUrlQuery.substring(queryIndex)
const scriptUrl = normalizeFileUrl(scriptUrlQuery);
const scriptDirectory = normalizeDirectoryUrl(scriptUrl);
-const nativeModulePromiseController = createPromiseCompletionSource(() => {
- dotnetUpdateInternals(dotnetGetInternals());
-});
-
-// WASM-TODO: retry logic
-// WASM-TODO: throttling logic
-// WASM-TODO: invokeLibraryInitializers
-// WASM-TODO: webCIL
-// WASM-TODO: downloadOnly - blazor render mode auto pre-download. Really no start.
-
-export async function createRuntime(downloadOnly: boolean, loadBootResource?: LoadBootResourceCallback): Promise {
- const config = getLoaderConfig();
- if (!config.resources || !config.resources.coreAssembly || !config.resources.coreAssembly.length) throw new Error("Invalid config, resources is not set");
-
- const nativeModulePromise = loadJSModule(config.resources.jsModuleNative[0], loadBootResource);
- const runtimeModulePromise = loadJSModule(config.resources.jsModuleRuntime[0], loadBootResource);
- const coreAssembliesPromise = Promise.all(config.resources.coreAssembly.map(fetchDll));
- const coreVfsPromise = Promise.all((config.resources.coreVfs || []).map(fetchVfs));
- const assembliesPromise = Promise.all(config.resources.assembly.map(fetchDll));
- const vfsPromise = Promise.all((config.resources.vfs || []).map(fetchVfs));
- const icuResourceName = getIcuResourceName(config);
- const icuDataPromise = icuResourceName ? Promise.all((config.resources.icu || []).filter(asset => asset.name === icuResourceName).map(fetchIcu)) : Promise.resolve([]);
- // WASM-TODO fetchWasm(config.resources.wasmNative[0]);// start loading early, no await
-
- const nativeModule = await nativeModulePromise;
- const modulePromise = nativeModule.dotnetInitializeModule(dotnetGetInternals());
- nativeModulePromiseController.propagateFrom(modulePromise);
-
- const runtimeModule = await runtimeModulePromise;
- const runtimeModuleReady = runtimeModule.dotnetInitializeModule(dotnetGetInternals());
-
- await nativeModulePromiseController.promise;
- await coreAssembliesPromise;
- await coreVfsPromise;
- await vfsPromise;
- await icuDataPromise;
- if (!downloadOnly) {
- BrowserHost_InitializeCoreCLR();
- }
-
- await assembliesPromise;
- await runtimeModuleReady;
-}
-
-async function loadJSModule(asset: JsAsset, loadBootResource?: LoadBootResourceCallback): Promise {
- if (loadBootResource) throw new Error("TODO: loadBootResource is not implemented yet");
- if (asset.name && !asset.resolvedUrl) {
- asset.resolvedUrl = locateFile(asset.name);
- }
- if (!asset.resolvedUrl) throw new Error("Invalid config, resources is not set");
- return await import(/* webpackIgnore: true */ asset.resolvedUrl);
-}
-
-async function fetchIcu(asset: IcuAsset): Promise {
- if (asset.name && !asset.resolvedUrl) {
- asset.resolvedUrl = locateFile(asset.name);
- }
- const bytes = await fetchBytes(asset);
- await nativeModulePromiseController.promise;
- dotnetBrowserHostExports.loadIcuData(bytes);
-}
-
-async function fetchDll(asset: AssemblyAsset): Promise {
- if (asset.name && !asset.resolvedUrl) {
- asset.resolvedUrl = locateFile(asset.name);
- }
- const bytes = await fetchBytes(asset);
- await nativeModulePromiseController.promise;
-
- dotnetBrowserHostExports.registerDllBytes(bytes, asset);
-}
-
-async function fetchVfs(asset: AssemblyAsset): Promise {
- if (asset.name && !asset.resolvedUrl) {
- asset.resolvedUrl = locateFile(asset.name);
- }
- const bytes = await fetchBytes(asset);
- await nativeModulePromiseController.promise;
-
- dotnetBrowserHostExports.installVfsFile(bytes, asset);
-}
-
-async function fetchBytes(asset: WasmAsset | AssemblyAsset | PdbAsset | IcuAsset): Promise {
- dotnetAssert.check(asset && asset.resolvedUrl, "Bad asset.resolvedUrl");
- if (ENVIRONMENT_IS_NODE) {
- const { promises: fs } = await import("fs");
- const { fileURLToPath } = await import(/*! webpackIgnore: true */"url");
- const isFileUrl = asset.resolvedUrl!.startsWith("file://");
- if (isFileUrl) {
- asset.resolvedUrl = fileURLToPath(asset.resolvedUrl!);
- }
- const buffer = await fs.readFile(asset.resolvedUrl!);
- return new Uint8Array(buffer);
- } else {
- const response = await fetch(asset.resolvedUrl!);
- if (!response.ok) {
- throw new Error(`Failed to load ${asset.resolvedUrl} with ${response.status} ${response.statusText}`);
- }
- const buffer = await response.arrayBuffer();
- return new Uint8Array(buffer);
- }
-}
-
-function locateFile(path: string) {
+export function locateFile(path: string) {
if ("URL" in globalThis) {
return new URL(path, scriptDirectory).toString();
}
@@ -192,17 +84,34 @@ export async function findResources(dotnet: DotnetHostBuilder): Promise {
const json = await fs.promises.readFile(runtimeConfigName, { encoding: "utf8" });
runtimeConfig = JSON.parse(json);
}
+ const icus = files
+ .filter(file => file.startsWith("icudt") && file.endsWith(".dat"))
+ .map(filename => {
+ // filename without path
+ const name = filename.substring(filename.lastIndexOf("/") + 1);
+ return { virtualPath: name, name };
+ });
+
+ const environmentVariables: { [key: string]: string } = {};
+ let globalizationMode = GlobalizationMode.All;
+ if (!icus.length) {
+ globalizationMode = GlobalizationMode.Invariant;
+ environmentVariables["DOTNET_SYSTEM_GLOBALIZATION_INVARIANT"] = "1";
+ }
const config: LoaderConfig = {
mainAssemblyName,
runtimeConfig,
+ globalizationMode,
virtualWorkingDirectory: mountedDir,
+ environmentVariables,
resources: {
jsModuleNative: [{ name: "dotnet.native.js" }],
jsModuleRuntime: [{ name: "dotnet.runtime.js" }],
wasmNative: [{ name: "dotnet.native.wasm", }],
coreAssembly: [{ virtualPath: mountedDir + "/System.Private.CoreLib.dll", name: "System.Private.CoreLib.dll" },],
assembly: assemblies,
+ icu: icus,
}
};
dotnet.withConfig(config);
diff --git a/src/native/corehost/browserhost/loader/dotnet.d.ts b/src/native/corehost/browserhost/loader/dotnet.d.ts
index bb4e95306d7729..17df552d1ac178 100644
--- a/src/native/corehost/browserhost/loader/dotnet.d.ts
+++ b/src/native/corehost/browserhost/loader/dotnet.d.ts
@@ -773,10 +773,6 @@ declare global {
function getDotnetRuntime(runtimeId: number): RuntimeAPI | undefined;
}
-declare global {
- function getDotnetRuntime(runtimeId: number): RuntimeAPI | undefined;
- const dotnetSidecar: boolean | undefined;
-}
declare const createDotnetRuntime: CreateDotnetRuntimeType;
export { GlobalizationMode, createDotnetRuntime as default, dotnet, exit };
diff --git a/src/native/corehost/browserhost/loader/dotnet.ts b/src/native/corehost/browserhost/loader/dotnet.ts
index f9fc7fe6d1138c..6a1b68cf62618e 100644
--- a/src/native/corehost/browserhost/loader/dotnet.ts
+++ b/src/native/corehost/browserhost/loader/dotnet.ts
@@ -23,5 +23,7 @@ await initPolyfillsAsync();
export const dotnet: DotnetHostBuilder | undefined = new HostBuilder() as DotnetHostBuilder;
export { exit };
+dotnet.withConfig(/*! dotnetBootConfig */{});
+
// Auto-start when in Node.js or Shell environment
selfHostNodeJS(dotnet!).catch();
diff --git a/src/native/corehost/browserhost/loader/host-builder.ts b/src/native/corehost/browserhost/loader/host-builder.ts
index 4114eaa1aeec65..465f60ae7fbd7d 100644
--- a/src/native/corehost/browserhost/loader/host-builder.ts
+++ b/src/native/corehost/browserhost/loader/host-builder.ts
@@ -5,7 +5,7 @@ import type { DotnetHostBuilder, LoaderConfig, RuntimeAPI, LoadBootResourceCallb
import { Module, dotnetApi } from "./cross-module";
import { getLoaderConfig, mergeLoaderConfig, validateLoaderConfig } from "./config";
-import { createRuntime } from "./bootstrap";
+import { createRuntime } from "./assets";
import { exit } from "./exit";
let applicationArguments: string[] | undefined = [];
diff --git a/src/native/corehost/browserhost/loader/icu.ts b/src/native/corehost/browserhost/loader/icu.ts
index 1e0d9359d4a518..6aef6afa31e86d 100644
--- a/src/native/corehost/browserhost/loader/icu.ts
+++ b/src/native/corehost/browserhost/loader/icu.ts
@@ -33,6 +33,7 @@ export function getIcuResourceName(config: LoaderConfig): string | null {
}
config.globalizationMode = GlobalizationMode.Invariant;
+ config.environmentVariables!["DOTNET_SYSTEM_GLOBALIZATION_INVARIANT"] = "1";
return null;
}
diff --git a/src/native/corehost/browserhost/loader/index.ts b/src/native/corehost/browserhost/loader/index.ts
index 63eb64cdd35c5a..241edb02e9b234 100644
--- a/src/native/corehost/browserhost/loader/index.ts
+++ b/src/native/corehost/browserhost/loader/index.ts
@@ -3,7 +3,8 @@
import type {
LoggerType, AssertType, RuntimeAPI, LoaderExports,
- NativeBrowserExportsTable, LoaderExportsTable, RuntimeExportsTable, InternalExchange, BrowserHostExportsTable, InteropJavaScriptExportsTable, BrowserUtilsExportsTable
+ NativeBrowserExportsTable, LoaderExportsTable, RuntimeExportsTable, InternalExchange, BrowserHostExportsTable, InteropJavaScriptExportsTable, BrowserUtilsExportsTable,
+ EmscriptenModuleInternal
} from "./types";
import { InternalExchangeIndex } from "../types";
@@ -19,6 +20,7 @@ import { check, error, info, warn, debug } from "./logging";
import { dotnetAssert, dotnetLoaderExports, dotnetLogger, dotnetUpdateInternals, dotnetUpdateInternalsSubscriber } from "./cross-module";
import { rejectRunMainPromise, resolveRunMainPromise, getRunMainPromise } from "./run";
import { createPromiseCompletionSource, getPromiseCompletionSource, isControllablePromise } from "./promise-completion-source";
+import { instantiateWasm } from "./assets";
export function dotnetInitializeModule(): RuntimeAPI {
@@ -71,6 +73,12 @@ export function dotnetInitializeModule(): RuntimeAPI {
};
Object.assign(dotnetAssert, assert);
+ // emscripten extension point
+ const localModule: Partial = {
+ instantiateWasm,
+ };
+ Object.assign(dotnetApi.Module!, localModule);
+
internals[InternalExchangeIndex.LoaderExportsTable] = loaderExportsToTable(dotnetLogger, dotnetAssert, dotnetLoaderExports);
dotnetUpdateInternals(internals, dotnetUpdateInternalsSubscriber);
return dotnetApi as RuntimeAPI;
diff --git a/src/native/libs/Common/JavaScript/CMakeLists.txt b/src/native/libs/Common/JavaScript/CMakeLists.txt
index a4a5842dbd7d5e..b01a16cef84b98 100644
--- a/src/native/libs/Common/JavaScript/CMakeLists.txt
+++ b/src/native/libs/Common/JavaScript/CMakeLists.txt
@@ -12,14 +12,17 @@ set(ROLLUP_TS_SOURCES
"${CLR_SRC_NATIVE_DIR}/rollup.config.defines.js"
"${CLR_SRC_NATIVE_DIR}/rollup.config.plugins.js"
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/libBrowserHost.footer.js"
- "${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/libSystem.Browser.Utils.footer.js"
+ "${CLR_SRC_NATIVE_DIR}/corehost/browserhost/sample/dotnet.boot.js"
+ "${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/libSystem.Native.Browser.Utils.footer.js"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/libSystem.Native.Browser.extpost.js"
"${CLR_SRC_NATIVE_DIR}/libs/System.Native.Browser/libSystem.Native.Browser.footer.js"
"${CLR_SRC_NATIVE_DIR}/libs/System.Runtime.InteropServices.JavaScript.Native/libSystem.Runtime.InteropServices.JavaScript.Native.footer.js"
+
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/host/cross-linked.ts"
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/host/host.ts"
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/host/index.ts"
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/host/types.ts"
+ "${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/assets.ts"
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/bootstrap.ts"
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/config.ts"
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/cross-module.ts"
@@ -27,6 +30,7 @@ set(ROLLUP_TS_SOURCES
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/dotnet.ts"
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/exit.ts"
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/host-builder.ts"
+ "${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/icu.ts"
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/index.ts"
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/lib-initializers.ts"
"${CLR_SRC_NATIVE_DIR}/corehost/browserhost/loader/logging.ts"
@@ -87,8 +91,8 @@ set(ROLLUP_OUTPUTS
"${STATIC_LIB_DESTINATION}/libBrowserHost.js.map"
"${STATIC_LIB_DESTINATION}/libSystem.Native.Browser.js"
"${STATIC_LIB_DESTINATION}/libSystem.Native.Browser.js.map"
- "${STATIC_LIB_DESTINATION}/libSystem.Browser.Utils.js"
- "${STATIC_LIB_DESTINATION}/libSystem.Browser.Utils.js.map"
+ "${STATIC_LIB_DESTINATION}/libSystem.Native.Browser.Utils.js"
+ "${STATIC_LIB_DESTINATION}/libSystem.Native.Browser.Utils.js.map"
"${STATIC_LIB_DESTINATION}/dotnet.runtime.js"
"${STATIC_LIB_DESTINATION}/dotnet.runtime.js.map"
"${STATIC_LIB_DESTINATION}/dotnet.diagnostics.js"
diff --git a/src/native/libs/Common/JavaScript/cross-linked/index.ts b/src/native/libs/Common/JavaScript/cross-linked/index.ts
index 59daab0da57af1..2700568e6bada0 100644
--- a/src/native/libs/Common/JavaScript/cross-linked/index.ts
+++ b/src/native/libs/Common/JavaScript/cross-linked/index.ts
@@ -4,7 +4,7 @@
import type { AssertType, EmscriptenModuleInternal, LoggerType, LoaderExports, InternalExchange, InternalExchangeSubscriber, RuntimeAPI, BrowserUtilsExports, NativePointer, CharPtr, VoidPtr, RuntimeExports } from "../types";
// we want to use the cross-module symbols defined in closure of dotnet.native.js
-// which are installed there by libSystem.Browser.Utils.footer.js
+// which are installed there by libSystem.Native.Browser.Utils.footer.js
// see also `reserved` in `rollup.config.defines.js`
declare global {
export const dotnetApi: RuntimeAPI;
diff --git a/src/native/libs/Common/JavaScript/cross-module/index.ts b/src/native/libs/Common/JavaScript/cross-module/index.ts
index 2ad7099edae221..d0821b10cc09cd 100644
--- a/src/native/libs/Common/JavaScript/cross-module/index.ts
+++ b/src/native/libs/Common/JavaScript/cross-module/index.ts
@@ -156,6 +156,7 @@ export function dotnetUpdateInternalsSubscriber() {
stringToUTF16Ptr: table[2],
stringToUTF8Ptr: table[3],
zeroRegion: table[4],
+ isSharedArrayBuffer: table[5],
};
Object.assign(interop, interopLocal);
}
diff --git a/src/native/libs/Common/JavaScript/per-module/index.ts b/src/native/libs/Common/JavaScript/per-module/index.ts
index 532437903bcd19..8858f9084f1885 100644
--- a/src/native/libs/Common/JavaScript/per-module/index.ts
+++ b/src/native/libs/Common/JavaScript/per-module/index.ts
@@ -3,7 +3,7 @@
export const ENVIRONMENT_IS_NODE = typeof process == "object" && typeof process.versions == "object" && typeof process.versions.node == "string";
export const ENVIRONMENT_IS_WEB_WORKER = typeof importScripts == "function";
-export const ENVIRONMENT_IS_SIDECAR = ENVIRONMENT_IS_WEB_WORKER && typeof dotnetSidecar !== "undefined"; // sidecar is emscripten main running in a web worker
+export const ENVIRONMENT_IS_SIDECAR = ENVIRONMENT_IS_WEB_WORKER && typeof (globalThis as any).dotnetSidecar !== "undefined"; // sidecar is emscripten main running in a web worker
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
export const ENVIRONMENT_IS_WEB = typeof window == "object" || (ENVIRONMENT_IS_WEB_WORKER && !ENVIRONMENT_IS_NODE);
export const ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE;
diff --git a/src/native/libs/Common/JavaScript/types/exchange.ts b/src/native/libs/Common/JavaScript/types/exchange.ts
index 5222954bc0595a..fcb988b447ee97 100644
--- a/src/native/libs/Common/JavaScript/types/exchange.ts
+++ b/src/native/libs/Common/JavaScript/types/exchange.ts
@@ -5,7 +5,7 @@ import type { installVfsFile, registerDllBytes, loadIcuData } from "../../../../
import type { check, error, info, warn, debug } from "../../../../corehost/browserhost/loader/logging";
import type { createPromiseCompletionSource, getPromiseCompletionSource, isControllablePromise } from "../../../../corehost/browserhost/loader/promise-completion-source";
import type { resolveRunMainPromise, rejectRunMainPromise, getRunMainPromise } from "../../../../corehost/browserhost/loader/run";
-import type { zeroRegion } from "../../../System.Native.Browser/utils/memory";
+import type { isSharedArrayBuffer, zeroRegion } from "../../../System.Native.Browser/utils/memory";
import type { stringToUTF16, stringToUTF16Ptr, stringToUTF8Ptr, utf16ToString } from "../../../System.Native.Browser/utils/strings";
export type RuntimeExports = {
@@ -78,6 +78,7 @@ export type BrowserUtilsExports = {
stringToUTF16Ptr: typeof stringToUTF16Ptr,
stringToUTF8Ptr: typeof stringToUTF8Ptr,
zeroRegion: typeof zeroRegion,
+ isSharedArrayBuffer: typeof isSharedArrayBuffer
}
export type BrowserUtilsExportsTable = [
@@ -86,4 +87,5 @@ export type BrowserUtilsExportsTable = [
typeof stringToUTF16Ptr,
typeof stringToUTF8Ptr,
typeof zeroRegion,
+ typeof isSharedArrayBuffer,
]
diff --git a/src/native/libs/Common/JavaScript/types/export-api.ts b/src/native/libs/Common/JavaScript/types/export-api.ts
index 90d65cc84dd041..59281204a5fe10 100644
--- a/src/native/libs/Common/JavaScript/types/export-api.ts
+++ b/src/native/libs/Common/JavaScript/types/export-api.ts
@@ -4,12 +4,6 @@
import type { CreateDotnetRuntimeType, DotnetHostBuilder, DotnetModuleConfig, ModuleAPI, LoaderConfig, IMemoryView, AssetEntry, GlobalizationMode, AssetBehaviors, RuntimeAPI, dotnet, exit } from "./public-api";
import type { EmscriptenModule } from "./emscripten";
-// Here, declare things that go in the global namespace, or augment existing declarations in the global namespace
-declare global {
- function getDotnetRuntime(runtimeId: number): RuntimeAPI | undefined;
- const dotnetSidecar: boolean | undefined;
-}
-
declare const createDotnetRuntime: CreateDotnetRuntimeType;
export default createDotnetRuntime;
diff --git a/src/native/libs/System.Native.Browser/ReadMe.md b/src/native/libs/System.Native.Browser/ReadMe.md
index 19b1cc2f2e823d..4005d0792d07f5 100644
--- a/src/native/libs/System.Native.Browser/ReadMe.md
+++ b/src/native/libs/System.Native.Browser/ReadMe.md
@@ -8,9 +8,9 @@ And a native library compiled by CMake into `libSystem.Native.Browser.a` as part
## Emscripten library
- `native/index` compiled -> `libSystem.Native.Browser.js` linked ->`dotnet.native.js`
- `libSystem.Native.Browser.footer.js` compiled -> `libSystem.Native.Browser.js` linked ->`dotnet.native.js`
-- `libSystem.Browser.Utils.footer.js` compiled -> `libSystem.Browser.Utils.js` linked ->`dotnet.native.js`
+- `libSystem.Native.Browser.Utils.footer.js` compiled -> `libSystem.Native.Browser.Utils.js` linked ->`dotnet.native.js`
- `libSystem.Native.Browser.extpost.js` linked ->`dotnet.native.js`
-- `ententrypoints.c` compiled -> `libSystem.Native.Browser.a` linked -> `dotnet.native.wasm`
+- `entrypoints.c` compiled -> `libSystem.Native.Browser.a` linked -> `dotnet.native.wasm`
## Build
TypeScript is compiled by `src/native/rollup.config.js`
diff --git a/src/native/libs/System.Native.Browser/libSystem.Browser.Utils.footer.js b/src/native/libs/System.Native.Browser/libSystem.Native.Browser.Utils.footer.js
similarity index 100%
rename from src/native/libs/System.Native.Browser/libSystem.Browser.Utils.footer.js
rename to src/native/libs/System.Native.Browser/libSystem.Native.Browser.Utils.footer.js
diff --git a/src/native/libs/System.Native.Browser/native/crypto.ts b/src/native/libs/System.Native.Browser/native/crypto.ts
index db2d03832513d2..2143d94ad20b47 100644
--- a/src/native/libs/System.Native.Browser/native/crypto.ts
+++ b/src/native/libs/System.Native.Browser/native/crypto.ts
@@ -22,7 +22,7 @@ export function SystemJS_RandomBytes(bufferPtr: number, bufferLength: number): n
const targetView = memoryView.subarray(bufferPtr, bufferPtr + bufferLength);
// When threading is enabled, Chrome doesn't want SharedArrayBuffer to be passed to crypto APIs
- const needsCopy = false;//TODOHelpers.isSharedArrayBuffer(memoryView.buffer);
+ const needsCopy = dotnetBrowserUtilsExports.isSharedArrayBuffer(memoryView.buffer);
const targetBuffer = needsCopy
? new Uint8Array(bufferLength)
: targetView;
diff --git a/src/native/libs/System.Native.Browser/native/globalization-locale.ts b/src/native/libs/System.Native.Browser/native/globalization-locale.ts
index 76d770ff51a795..0687aa5b44c7c0 100644
--- a/src/native/libs/System.Native.Browser/native/globalization-locale.ts
+++ b/src/native/libs/System.Native.Browser/native/globalization-locale.ts
@@ -13,7 +13,7 @@ export function SystemJS_GetLocaleInfo(culture: number, cultureLength: number, l
if (!localeName && localeNameOriginal) {
// handle non-standard or malformed locales by forwarding the locale code
dotnetBrowserUtilsExports.stringToUTF16(dst, dst + 2 * localeNameOriginal.length, localeNameOriginal);
- dotnetApi.setHeapI32( dstLength, localeNameOriginal.length);
+ dotnetApi.setHeapI32(dstLength, localeNameOriginal.length);
return VoidPtrNull;
}
const cultureNameOriginal = dotnetBrowserUtilsExports.utf16ToString(culture, (culture + 2 * cultureLength));
@@ -79,8 +79,8 @@ export function SystemJS_GetLocaleInfo(culture: number, cultureLength: number, l
try {
locale = locale.toLocaleLowerCase().replace("_", "-");
if (locale.startsWith("zh-")) {
- // browser does not recognize "zh-chs" and "zh-cht" as equivalents of "zh-Hans" "zh-Hant", we are helping, otherwise
- // it would throw on getCanonicalLocales with "RangeError: Incorrect locale information provided"
+ // browser does not recognize "zh-chs" and "zh-cht" as equivalents of "zh-Hans" "zh-Hant", we are helping, otherwise
+ // it would throw on getCanonicalLocales with "RangeError: Incorrect locale information provided"
locale = locale.replace("-chs", "-Hans").replace("-cht", "-Hant");
}
const canonicalLocales = (Intl as any).getCanonicalLocales(locale);
diff --git a/src/native/libs/System.Native.Browser/utils/index.ts b/src/native/libs/System.Native.Browser/utils/index.ts
index 8328cb2b486a57..7e4cfa6577c8f4 100644
--- a/src/native/libs/System.Native.Browser/utils/index.ts
+++ b/src/native/libs/System.Native.Browser/utils/index.ts
@@ -10,6 +10,7 @@ import {
getHeapB32, getHeapB8, getHeapU8, getHeapU16, getHeapU32, getHeapI8, getHeapI16, getHeapI32, getHeapI52, getHeapU52, getHeapI64Big, getHeapF32, getHeapF64,
localHeapViewI8, localHeapViewI16, localHeapViewI32, localHeapViewI64Big, localHeapViewU8, localHeapViewU16, localHeapViewU32, localHeapViewF32, localHeapViewF64,
zeroRegion,
+ isSharedArrayBuffer,
} from "./memory";
import { stringToUTF16, stringToUTF16Ptr, stringToUTF8Ptr, utf16ToString } from "./strings";
import { exit, setEnvironmentVariable } from "./host";
@@ -41,6 +42,7 @@ export function dotnetInitializeModule(internals: InternalExchange): void {
stringToUTF16Ptr,
stringToUTF8Ptr,
zeroRegion,
+ isSharedArrayBuffer,
});
dotnetUpdateInternals(internals, dotnetUpdateInternalsSubscriber);
function browserUtilsExportsToTable(map: BrowserUtilsExports): BrowserUtilsExportsTable {
@@ -51,6 +53,7 @@ export function dotnetInitializeModule(internals: InternalExchange): void {
map.stringToUTF16Ptr,
map.stringToUTF8Ptr,
map.zeroRegion,
+ map.isSharedArrayBuffer,
];
}
}
diff --git a/src/native/libs/System.Native.Browser/utils/memory.ts b/src/native/libs/System.Native.Browser/utils/memory.ts
index bb6484c04be3e3..9b9fb60dd0c617 100644
--- a/src/native/libs/System.Native.Browser/utils/memory.ts
+++ b/src/native/libs/System.Native.Browser/utils/memory.ts
@@ -139,12 +139,12 @@ export function getHeapU16_local(localView: Uint16Array, offset: MemOffset): num
}
export function getHeapU32(offset: MemOffset): number {
- return Module.HEAPU32[offset >>> 2];
+ return Module.HEAPU32[offset >>> 2] >>> 0;
}
// does not check for growable heap
export function getHeapU32_local(localView: Uint32Array, offset: MemOffset): number {
- return localView[offset >>> 2];
+ return localView[offset >>> 2] >>> 0;
}
export function getHeapI8(offset: MemOffset): number {
diff --git a/src/native/rollup.config.js b/src/native/rollup.config.js
index c3ac696471176b..a0504349a19c18 100644
--- a/src/native/rollup.config.js
+++ b/src/native/rollup.config.js
@@ -74,8 +74,8 @@ const libBrowserUtils = configure({
output: [{
name: "libBrowserUtils",
format: "iife",
- file: staticLibDestination + "/libSystem.Browser.Utils.js",
- footer: await fs.readFile("./libs/System.Native.Browser/libSystem.Browser.Utils.footer.js"),
+ file: staticLibDestination + "/libSystem.Native.Browser.Utils.js",
+ footer: await fs.readFile("./libs/System.Native.Browser/libSystem.Native.Browser.Utils.footer.js"),
}],
terser: {
compress: {