From f9951aa51fb8fbeecb064fea1c1e60ef8ebb740f Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Thu, 11 Apr 2024 15:42:35 +0200 Subject: [PATCH] test --- eng/testing/linker/trimmingTests.targets | 2 +- .../src/System/Globalization/CultureData.cs | 8 ++++++++ .../src/System/Globalization/GlobalizationMode.cs | 6 ++++++ .../TrimmingTests/InvariantGlobalizationTrue.cs | 13 +++++++------ src/mono/browser/runtime/assets.ts | 5 ++--- src/mono/browser/runtime/icu.ts | 10 ++++++++-- src/mono/browser/runtime/startup.ts | 3 +++ 7 files changed, 35 insertions(+), 12 deletions(-) diff --git a/eng/testing/linker/trimmingTests.targets b/eng/testing/linker/trimmingTests.targets index 926bafa52cfef4..70e072844484b8 100644 --- a/eng/testing/linker/trimmingTests.targets +++ b/eng/testing/linker/trimmingTests.targets @@ -156,7 +156,7 @@ - + diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs index 189ce06de70335..6c91bba74bd413 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -630,7 +630,11 @@ private static CultureData CreateCultureWithInvariantData() // all available calendar type(s). The first one is the default calendar invariant._waCalendars = new CalendarId[] { CalendarId.GREGORIAN }; +#if TARGET_BROWSER + if (!GlobalizationMode.InvariantFast) +#else if (!GlobalizationMode.Invariant) +#endif { // Store for specific data about each calendar invariant._calendars = new CalendarData[CalendarData.MAX_CALENDARS]; @@ -648,7 +652,11 @@ private static CultureData CreateCultureWithInvariantData() invariant._iDefaultMacCodePage = 10000; // default macintosh code page invariant._iDefaultEbcdicCodePage = 037; // default EBCDIC code page +#if TARGET_BROWSER + if (GlobalizationMode.InvariantFast) +#else if (GlobalizationMode.Invariant) +#endif { invariant._sLocalizedCountry = invariant._sNativeCountry; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs index 314bb33692dc76..b13312ae54a957 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs @@ -25,6 +25,12 @@ private static partial class Settings // This allows for the whole Settings nested class to be trimmed when Invariant=true, and allows for the Settings // static cctor (on Unix) to be preserved when Invariant=false. internal static bool Invariant => Settings.Invariant; + +#if TARGET_BROWSER + // same as GlobalizationMode.Invariant but doesn't trigger ICU load in GlobalizationMode.Settings.cctor during runtime startup + internal static bool InvariantFast { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.Invariant", "DOTNET_SYSTEM_GLOBALIZATION_INVARIANT"); +#endif + #if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS || TARGET_BROWSER internal static bool Hybrid => Settings.Hybrid; #endif diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/TrimmingTests/InvariantGlobalizationTrue.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/TrimmingTests/InvariantGlobalizationTrue.cs index fe878e3a7459d8..0f9628341e0467 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/TrimmingTests/InvariantGlobalizationTrue.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/TrimmingTests/InvariantGlobalizationTrue.cs @@ -27,12 +27,13 @@ static int Main(string[] args) { return -3; } - + // Ensure the internal GlobalizationMode class is trimmed correctly. Type globalizationMode = GetCoreLibType("System.Globalization.GlobalizationMode"); - if (OperatingSystem.IsWindows()) + if (OperatingSystem.IsWindows() || OperatingSystem.IsBrowser()) { + string allowedMember = OperatingSystem.IsWindows() ? "UseNls" : "InvariantFast"; foreach (MemberInfo member in globalizationMode.GetMembers(allStatics)) { // properties and their backing getter methods are OK @@ -41,8 +42,8 @@ static int Main(string[] args) continue; } - // Windows still contains a static cctor and a backing field for UseNls. - if (member is ConstructorInfo || (member is FieldInfo field && field.Name.Contains("UseNls"))) + // Windows still contains a static cctor and a backing field for UseNls or InvariantFast. + if (member is ConstructorInfo || (member is FieldInfo field && field.Name.Contains(allowedMember))) { continue; } @@ -52,10 +53,10 @@ static int Main(string[] args) return -4; } } - // On non Windows platforms, the full type is trimmed. + // On non Windows platforms, the full type is trimmed, unless it's Browser where we use FastInvariant for lazy ICU loading else if (globalizationMode is not null) { - Console.WriteLine("It is expected to have System.Globalization.GlobalizationMode type trimmed in non-Windows platforms"); + Console.WriteLine("It is expected to have System.Globalization.GlobalizationMode type trimmed in non-Windows and non-Browser platforms"); return -5; } diff --git a/src/mono/browser/runtime/assets.ts b/src/mono/browser/runtime/assets.ts index 318750ad672589..19e887e298fb7f 100644 --- a/src/mono/browser/runtime/assets.ts +++ b/src/mono/browser/runtime/assets.ts @@ -4,7 +4,7 @@ import type { AssetEntryInternal } from "./types/internal"; import cwraps from "./cwraps"; -import { mono_wasm_load_icu_data } from "./icu"; +import { mono_wasm_prepare_icu_data } from "./icu"; import { Module, loaderHelpers, mono_assert, runtimeHelpers } from "./globals"; import { mono_log_info, mono_log_debug, parseSymbolMapFile } from "./logging"; import { mono_wasm_load_bytes_into_heap_persistent } from "./memory"; @@ -85,8 +85,7 @@ export function instantiate_asset (asset: AssetEntry, url: string, bytes: Uint8A } else if (asset.behavior === "pdb") { cwraps.mono_wasm_add_assembly(virtualName, offset!, bytes.length); } else if (asset.behavior === "icu") { - if (!mono_wasm_load_icu_data(offset!)) - Module.err(`Error loading ICU asset ${asset.name}`); + mono_wasm_prepare_icu_data(offset!); } else if (asset.behavior === "resource") { cwraps.mono_wasm_add_satellite_assembly(virtualName, asset.culture || "", offset!, bytes.length); } diff --git a/src/mono/browser/runtime/icu.ts b/src/mono/browser/runtime/icu.ts index 16b23871f98718..4f3d792a56fb80 100644 --- a/src/mono/browser/runtime/icu.ts +++ b/src/mono/browser/runtime/icu.ts @@ -4,8 +4,14 @@ import cwraps from "./cwraps"; import { VoidPtr } from "./types/emscripten"; + +let icuDataOffset: VoidPtr | null = null; // @offset must be the address of an ICU data archive in the native heap. // returns true on success. -export function mono_wasm_load_icu_data (offset: VoidPtr): boolean { - return (cwraps.mono_wasm_load_icu_data(offset)) === 1; +export function mono_wasm_prepare_icu_data (offset: VoidPtr) { + icuDataOffset = offset; +} + +export function mono_wasm_load_icu_data (): boolean { + return (cwraps.mono_wasm_load_icu_data(icuDataOffset!)) === 1; } diff --git a/src/mono/browser/runtime/startup.ts b/src/mono/browser/runtime/startup.ts index b89522caff198a..38119db564f75e 100644 --- a/src/mono/browser/runtime/startup.ts +++ b/src/mono/browser/runtime/startup.ts @@ -34,6 +34,7 @@ import { runtimeList } from "./exports"; import { nativeAbort, nativeExit } from "./run"; import { mono_wasm_init_diagnostics } from "./diagnostics"; import { replaceEmscriptenPThreadInit } from "./pthreads/worker-thread"; +import { mono_wasm_load_icu_data } from "./icu"; export async function configureRuntimeStartup (module: DotnetModuleInternal): Promise { if (!module.out) { @@ -307,6 +308,8 @@ async function onRuntimeInitializedAsync (userOnRuntimeInitialized: () => void) await start_runtime(); } + mono_wasm_load_icu_data(); + if (WasmEnableThreads) { await runtimeHelpers.afterIOStarted.promise; }