Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[browser] load core assemblies first #100141

Merged
merged 18 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion eng/testing/linker/trimmingTests.targets
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@
<Output TaskParameter="ExitCode" PropertyName="ExecutionExitCode" />
</Exec>

<Error Condition="'$(ExecutionExitCode)' != '100'" Text="Error: [Failed Test]: %(TestConsoleApps.ProjectCompileItems). The Command %(TestConsoleApps.TestCommand) return a non-success exit code." ContinueOnError="ErrorAndContinue" />
<Error Condition="'$(ExecutionExitCode)' != '100'" Text="Error: [Failed Test]: %(TestConsoleApps.ProjectCompileItems). The Command %(TestConsoleApps.TestCommand) return a non-success exit code $(ExecutionExitCode)." ContinueOnError="ErrorAndContinue" />
</Target>

<Target Name="Build" DependsOnTargets="ExecuteApplications" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,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)
pavelsavara marked this conversation as resolved.
Show resolved Hide resolved
#else
if (!GlobalizationMode.Invariant)
#endif
{
// Store for specific data about each calendar
invariant._calendars = new CalendarData[CalendarData.MAX_CALENDARS];
Expand All @@ -646,7 +650,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;
}
Expand Down Expand Up @@ -2228,7 +2236,11 @@ private string[] GetNativeDigits()

internal void GetNFIValues(NumberFormatInfo nfi)
{
#if TARGET_BROWSER
if (GlobalizationMode.InvariantFast || IsInvariantCulture)
#else
if (GlobalizationMode.Invariant || IsInvariantCulture)
#endif
{
nfi._positiveSign = _sPositiveSign!;
nfi._negativeSign = _sNegativeSign!;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ private static string GetIcuLoadFailureMessage()
if (OperatingSystem.IsBrowser() || OperatingSystem.IsAndroid() ||
OperatingSystem.IsIOS() || OperatingSystem.IsTvOS() || OperatingSystem.IsWatchOS())
{
return "Unable to load required ICU Globalization data. Please see https://aka.ms/dotnet-missing-libicu for more information";
return "Unable to load required ICU Globalization data. Please see https://aka.ms/dotnet-missing-libicu for more information.\n" + Environment.StackTrace;
pavelsavara marked this conversation as resolved.
Show resolved Hide resolved
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,13 @@ static int Main(string[] args)

return 100;
}

// 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
Expand All @@ -54,8 +55,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.
pavelsavara marked this conversation as resolved.
Show resolved Hide resolved
if (member is ConstructorInfo || (member is FieldInfo field && field.Name.Contains(allowedMember)))
{
continue;
}
Expand All @@ -65,10 +66,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;
}

Expand Down
2 changes: 2 additions & 0 deletions src/mono/browser/build/BrowserWasmApp.targets
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@
RuntimeAssetsLocation="$(WasmRuntimeAssetsLocation)"
CacheBootResources="$(BlazorCacheBootResources)"
RuntimeConfigJsonPath="$(_WasmRuntimeConfigFilePath)"
IsAot="$(RunAOTCompilation)"
IsMultiThreaded="$(WasmEnableThreads)"
>
<Output TaskParameter="FileWrites" ItemName="FileWrites" />
</WasmAppBuilder>
Expand Down
6 changes: 4 additions & 2 deletions src/mono/browser/runtime/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ export function instantiate_asset (asset: AssetEntry, url: string, bytes: Uint8A
if (fileName.startsWith("/"))
fileName = fileName.substring(1);
if (parentDirectory) {
if (!parentDirectory.startsWith("/"))
parentDirectory = "/" + parentDirectory;

mono_log_debug(`Creating directory '${parentDirectory}'`);

Module.FS_createPath(
Expand Down Expand Up @@ -85,8 +88,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_load_icu_data(offset!);
} else if (asset.behavior === "resource") {
cwraps.mono_wasm_add_satellite_assembly(virtualName, asset.culture || "", offset!, bytes.length);
}
Expand Down
5 changes: 5 additions & 0 deletions src/mono/browser/runtime/dotnet.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,10 @@ type ResourceExtensions = {
};
interface ResourceGroups {
hash?: string;
coreAssembly?: ResourceList;
assembly?: ResourceList;
lazyAssembly?: ResourceList;
corePdb?: ResourceList;
pdb?: ResourceList;
jsModuleWorker?: ResourceList;
jsModuleNative: ResourceList;
Expand All @@ -258,6 +260,9 @@ interface ResourceGroups {
modulesAfterConfigLoaded?: ResourceList;
modulesAfterRuntimeReady?: ResourceList;
extensions?: ResourceExtensions;
coreVfs?: {
[virtualPath: string]: ResourceList;
};
vfs?: {
[virtualPath: string]: ResourceList;
};
Expand Down
4 changes: 3 additions & 1 deletion src/mono/browser/runtime/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,16 @@ export function setRuntimeGlobals (globalObjects: GlobalObjects) {

const rh: Partial<RuntimeHelpers> = {
gitHash,
coreAssetsInMemory: createPromiseController<void>(),
allAssetsInMemory: createPromiseController<void>(),
dotnetReady: createPromiseController<any>(),
afterInstantiateWasm: createPromiseController<void>(),
beforePreInit: createPromiseController<void>(),
afterPreInit: createPromiseController<void>(),
afterPreRun: createPromiseController<void>(),
beforeOnRuntimeInitialized: createPromiseController<void>(),
afterMonoStarted: createPromiseController<GCHandle | undefined>(),
afterMonoStarted: createPromiseController<void>(),
afterDeputyReady: createPromiseController<GCHandle | undefined>(),
afterIOStarted: createPromiseController<void>(),
afterOnRuntimeInitialized: createPromiseController<void>(),
afterPostRun: createPromiseController<void>(),
Expand Down
8 changes: 4 additions & 4 deletions src/mono/browser/runtime/icu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import cwraps from "./cwraps";
import { VoidPtr } from "./types/emscripten";

// @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_load_icu_data (offset: VoidPtr) {
if (!cwraps.mono_wasm_load_icu_data(offset)) {
throw new Error("Failed to load ICU data");
}
}
Loading
Loading