From 481fa72c362c9c9f5a36e2b4829f9857add3de90 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Wed, 17 Mar 2021 16:23:42 -0400 Subject: [PATCH 01/15] initial icu sharding --- .../Directory.Build.props | 8 +++++ .../pal_icushim_static.c | 32 +++++++++++------- src/mono/mono/metadata/mono-config.c | 1 + src/mono/sample/wasm/console/Program.cs | 5 +++ src/mono/wasm/build/WasmApp.targets | 16 ++++++--- src/mono/wasm/runtime/library_mono.js | 8 ++--- src/tasks/WasmAppBuilder/WasmAppBuilder.cs | 33 ++++++++++++++++--- 7 files changed, 79 insertions(+), 24 deletions(-) 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 e01cf16aae410c..e26409dba4ac0c 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props @@ -185,6 +185,14 @@ + + + + + + + + diff --git a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_static.c b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_static.c index c81ce59e50acad..085e34e2e930b0 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_static.c +++ b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_static.c @@ -47,7 +47,7 @@ static void U_CALLCONV icu_trace_data(const void* context, int32_t fnNumber, int #ifdef __EMSCRIPTEN__ #include -static int32_t load_icu_data(void* pData); +static int32_t load_icu_data(void* pData, int32_t type); EMSCRIPTEN_KEEPALIVE const char* mono_wasm_get_icudt_name(const char* culture); @@ -56,11 +56,11 @@ EMSCRIPTEN_KEEPALIVE const char* mono_wasm_get_icudt_name(const char* culture) return GlobalizationNative_GetICUDTName(culture); } -EMSCRIPTEN_KEEPALIVE int32_t mono_wasm_load_icu_data(void* pData); +EMSCRIPTEN_KEEPALIVE int32_t mono_wasm_load_icu_data(void* pData, int32_t type); -EMSCRIPTEN_KEEPALIVE int32_t mono_wasm_load_icu_data(void* pData) +EMSCRIPTEN_KEEPALIVE int32_t mono_wasm_load_icu_data(void* pData, int32_t type) { - return load_icu_data(pData); + return load_icu_data(pData, type); } @@ -77,22 +77,30 @@ void mono_wasm_link_icu_shim(void) #endif -static int32_t load_icu_data(void* pData) +static int32_t load_icu_data(void* pData, int32_t type) { UErrorCode status = 0; - udata_setCommonData(pData, &status); + if (type == 0) { + udata_setAppData(NULL, pData, &status); + } + if (type == 1) { + udata_setCommonData(pData, &status); + } if (U_FAILURE(status)) { - log_icu_error("udata_setCommonData", status); + if (type) + log_icu_error("udata_setCommonData", status); + else + log_icu_error("udata_setAppData", status); return 0; } else { -#if defined(ICU_TRACING) +// #if defined(ICU_TRACING) // see https://github.com/unicode-org/icu/blob/master/docs/userguide/icu_data/tracing.md - utrace_setFunctions(0, 0, 0, icu_trace_data); - utrace_setLevel(UTRACE_VERBOSE); -#endif + utrace_setFunctions(0, 0, 0, icu_trace_data); + utrace_setLevel(UTRACE_VERBOSE); +// #endif isDataSet = 1; return 1; } @@ -146,7 +154,7 @@ int32_t GlobalizationNative_LoadICUData(const char* path) fclose(fp); - if (load_icu_data(icu_data) == 0) { + if (load_icu_data(icu_data, strcasecmp("icudt.dat", path)) == 0) { log_shim_error("ICU BAD EXIT %d.", ret); return ret; } diff --git a/src/mono/mono/metadata/mono-config.c b/src/mono/mono/metadata/mono-config.c index b55c76e67b34d7..5d4a7d96a2f619 100644 --- a/src/mono/mono/metadata/mono-config.c +++ b/src/mono/mono/metadata/mono-config.c @@ -22,6 +22,7 @@ #include "mono/metadata/object-internals.h" #include "mono/utils/mono-logger-internals.h" +#define ICU_TRACING 1 #if defined(TARGET_PS3) #define CONFIG_OS "CellOS" #elif defined(__linux__) diff --git a/src/mono/sample/wasm/console/Program.cs b/src/mono/sample/wasm/console/Program.cs index 6af1fa68e82d42..eded9e1f0490b2 100644 --- a/src/mono/sample/wasm/console/Program.cs +++ b/src/mono/sample/wasm/console/Program.cs @@ -3,6 +3,7 @@ using System; using System.Threading.Tasks; +using System.Globalization; public class Test { @@ -10,6 +11,10 @@ public static async Task Main(string[] args) { await Task.Delay(1); Console.WriteLine("Hello World!"); + TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles"); + Console.WriteLine(tz.DisplayName); + Console.WriteLine(tz.StandardName); + Console.WriteLine(tz.DaylightName); for (int i = 0; i < args.Length; i++) { Console.WriteLine($"args[{i}] = {args[i]}"); } diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index 287f963beabd76..e4992b93357bd0 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -360,18 +360,26 @@ - icudt.dat - <_HasDotnetWasm Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.wasm'">true <_HasDotnetJs Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.js'">true + efigs,zones + + + + + + + + + - + @@ -382,7 +390,7 @@ InvariantGlobalization="$(InvariantGlobalization)" SatelliteAssemblies="@(WasmSatelliteAssemblies)" FilesToIncludeInFileSystem="@(WasmFilesToIncludeInFileSystem)" - IcuDataFileName="$(WasmIcuDataFileName)" + IcuShardData="$(IcuData)" RemoteSources="@(WasmRemoteSources)" ExtraFilesToDeploy="@(WasmExtraFilesToDeploy)" ExtraConfig="@(WasmExtraConfig)" diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 8ea48beafe72dc..7e052b45cab01d 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -1581,7 +1581,7 @@ var MonoSupportLib = { } } else if (asset.behavior === "icu") { - if (this.mono_wasm_load_icu_data (offset)) + if (this.mono_wasm_load_icu_data (offset, +(asset.data_type == "common"))) ctx.num_icu_assets_loaded_successfully += 1; else console.error ("Error loading ICU asset", asset.name); @@ -1683,9 +1683,9 @@ var MonoSupportLib = { // @offset must be the address of an ICU data archive in the native heap. // returns true on success. - mono_wasm_load_icu_data: function (offset) { - var fn = Module.cwrap ('mono_wasm_load_icu_data', 'number', ['number']); - var ok = (fn (offset)) === 1; + mono_wasm_load_icu_data: function (offset, type) { + var fn = Module.cwrap ('mono_wasm_load_icu_data', 'number', ['number', 'number']); + var ok = (fn (offset, type)) === 1; if (ok) this.num_icu_assets_loaded_successfully++; return ok; diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs index de7c0e3741b74b..6632275c6b9e1f 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -41,7 +41,8 @@ public class WasmAppBuilder : Task // full list of ICU data files we produce can be found here: // https://github.com/dotnet/icu/tree/maint/maint-67/icu-filters - public string? IcuDataFileName { get; set; } + // public ITaskItem[]? IcuDataFileNames { get; set; } + public string? IcuShardData { get; set; } public int DebugLevel { get; set; } public ITaskItem[]? SatelliteAssemblies { get; set; } @@ -119,14 +120,17 @@ private class IcuData : AssetEntry public IcuData(string name) : base(name, "icu") {} [JsonPropertyName("load_remote")] public bool LoadRemote { get; set; } + [JsonPropertyName("data_type")] + public string? DataType { get; set; } } public override bool Execute () { if (!File.Exists(MainJS)) throw new ArgumentException($"File MainJS='{MainJS}' doesn't exist."); - if (!InvariantGlobalization && string.IsNullOrEmpty(IcuDataFileName)) - throw new ArgumentException("IcuDataFileName property shouldn't be empty if InvariantGlobalization=false"); + if (!InvariantGlobalization && string.IsNullOrEmpty(IcuShardData)) + // if (!InvariantGlobalization && IcuShardData == null) + throw new ArgumentException("IcuShardData property shouldn't be empty if InvariantGlobalization=false"); if (Assemblies?.Length == 0) { @@ -226,7 +230,28 @@ public override bool Execute () } if (!InvariantGlobalization) - config.Assets.Add(new IcuData(IcuDataFileName!) { LoadRemote = RemoteSources?.Length > 0 }); + { + string[] icuConfig = IcuShardData!.ToLower().Split(','); + string[] localeFilters = new string[]{ "efigs", "en", "zh", "cjk", "no_cjk" }; + string[] nonLocaleSpecific = new string[]{ "currency", "normalization" }; + string? localeFilter = Array.Find(icuConfig, x => (Array.IndexOf(localeFilters, x)) > -1); + foreach (var icu in icuConfig) + { + string? icuDataFileName; + if (icu == localeFilter) + { + icuDataFileName = $"icudt_{icu}_base.dat"; + } else + { + icuDataFileName = (localeFilter is null) || (Array.IndexOf(nonLocaleSpecific, icu) > -1) ? $"icudt_{icu}.dat" : $"icudt_{localeFilter}_{icu}.dat"; + } + config.Assets.Add(new IcuData(icuDataFileName) { LoadRemote = RemoteSources?.Length > 0, DataType="common" }); + } + // foreach (ITaskItem item in IcuDataFileNames!) + // { + // config.Assets.Add(new IcuData(item!.ItemSpec) { LoadRemote = RemoteSources?.Length > 0, "common" }); + // } + } config.Assets.Add(new VfsEntry ("dotnet.timezones.blat") { VirtualPath = "/usr/share/zoneinfo/"}); From 64743ac936059de1cd3b077a3d8d54dbb4e324aa Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Wed, 21 Apr 2021 22:32:19 -0400 Subject: [PATCH 02/15] integrate icu dictionary with icu data loading --- .../Directory.Build.props | 11 ++++- src/mono/sample/wasm/wasm.mk | 4 +- src/mono/wasm/build/WasmApp.targets | 15 ++----- src/mono/wasm/runtime-test.js | 10 +++-- src/mono/wasm/runtime/library_mono.js | 43 ++++++++++++++++--- src/tasks/WasmAppBuilder/WasmAppBuilder.cs | 38 ++++------------ 6 files changed, 67 insertions(+), 54 deletions(-) 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 e26409dba4ac0c..8376cae563cc14 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props @@ -185,16 +185,25 @@ + + + - + + + + + + + diff --git a/src/mono/sample/wasm/wasm.mk b/src/mono/sample/wasm/wasm.mk index 1858ca37911824..01c3242b78cf5c 100644 --- a/src/mono/sample/wasm/wasm.mk +++ b/src/mono/sample/wasm/wasm.mk @@ -23,8 +23,8 @@ run-browser: echo "The tool dotnet-serve could not be found. Install with: $(DOTNET) tool install --global dotnet-serve"; \ exit 1; \ else \ - $(DOTNET) serve -d bin/$(CONFIG)/AppBundle -p 8000; \ + $(DOTNET) serve --directory ./bin/$(CONFIG)/AppBundle -p 8000; \ fi run-console: - cd bin/$(CONFIG)/AppBundle && ~/.jsvu/v8 --expose_wasm runtime.js -- $(DOTNET_MONO_LOG_LEVEL) --run Wasm.Console.Sample.dll + cd bin/$(CONFIG)/AppBundle && ~/.jsvu/v8 --expose_wasm runtime.js -- $(DOTNET_MONO_LOG_LEVEL) --enable-sharding=true --run Wasm.Console.Sample.dll diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index e4992b93357bd0..d0df11fc2aa9d5 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -362,24 +362,15 @@ <_HasDotnetWasm Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.wasm'">true <_HasDotnetJs Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.js'">true - efigs,zones + $(MicrosoftNetCoreAppRuntimePackRidNativeDir)icu_dictionary.json - - - - - - - - - - + @@ -390,7 +381,7 @@ InvariantGlobalization="$(InvariantGlobalization)" SatelliteAssemblies="@(WasmSatelliteAssemblies)" FilesToIncludeInFileSystem="@(WasmFilesToIncludeInFileSystem)" - IcuShardData="$(IcuData)" + IcuDictionary="$(IcuDictionaryPath)" RemoteSources="@(WasmRemoteSources)" ExtraFilesToDeploy="@(WasmExtraFilesToDeploy)" ExtraConfig="@(WasmExtraConfig)" diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index 74aa1083c033d1..fd5ae329a14978 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -2,7 +2,6 @@ // // Run runtime tests under a JS shell or a browser // - //glue code to deal with the differences between chrome, ch, d8, jsc and sm. var is_browser = typeof window != "undefined"; @@ -142,7 +141,6 @@ function inspect_object (o) { } return r; } - // Preprocess arguments var args = testArguments; console.info("Arguments: " + testArguments); @@ -151,6 +149,7 @@ setenv = {}; runtime_args = []; enable_gc = true; enable_zoneinfo = false; +enable_sharding = false; working_dir='/'; while (args !== undefined && args.length > 0) { if (args [0].startsWith ("--profile=")) { @@ -177,6 +176,10 @@ while (args !== undefined && args.length > 0) { var arg = args [0].substring ("--working-dir=".length); working_dir = arg; args = args.slice (1); + } else if (args [0].startsWith ("--enable-sharding=")) { + var arg = args [0].substring ("--enable-sharding=".length); + enable_sharding = arg; + args = args.slice (1); } else { break; } @@ -229,7 +232,6 @@ var Module = { if (!enable_gc) { Module.ccall ('mono_wasm_enable_on_demand_gc', 'void', ['number'], [0]); } - config.loaded_cb = function () { let wds = FS.stat (working_dir); if (wds === undefined || !FS.isDir (wds.mode)) { @@ -279,6 +281,8 @@ var Module = { }) } }; + if (enable_sharding) + config.application_culture = Intl.DateTimeFormat().resolvedOptions().locale; MONO.mono_load_runtime_and_bcl_args (config); }, diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 7e052b45cab01d..4235f62654237c 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -1135,6 +1135,38 @@ var MonoSupportLib = { return res; }, + _get_shard_name: function (fileList) { + var name_lengths = fileList.map(x => x.split("_").length); + var shard_ix = name_lengths.indexOf(Math.max(...name_lengths)); + return fileList[shard_ix]; + }, + + _get_list_of_icu_files: function (dictionary, culture, feature_shards=true) { + var icu_files = [] + if (culture == null || culture.length < 2) { + icu_files = [dictionary.complete]; + } else { + var parent_culture = culture.split('-')[0]; + var files = dictionary[parent_culture]; + if (!feature_shards) { + icu_files = [files.full]; + } else { + icu_files = files.essentials; + icu_files.push(this._get_shard_name(files.coll)); + icu_files.push(this._get_shard_name(files.locales)); + } + } + + icu_assets = []; + icu_files.forEach(file => icu_assets.push({ + "behavior": "icu", + "name": file, + "load_remote": false, + "data_type": "common" + })); + return icu_assets; + }, + mono_wasm_get_details: function (objectId, args={}) { let id = this._parse_object_id (objectId, true); @@ -1521,10 +1553,8 @@ var MonoSupportLib = { var bytes = new Uint8Array (blob); if (ctx.tracing) console.log ("MONO_WASM: Loaded:", asset.name, "size", bytes.length, "from", url); - var virtualName = asset.virtual_path || asset.name; var offset = null; - switch (asset.behavior) { case "resource": case "assembly": @@ -1534,7 +1564,6 @@ var MonoSupportLib = { offset = this.mono_wasm_load_bytes_into_heap (bytes); ctx.loaded_assets[virtualName] = [offset, bytes.length]; break; - case "vfs": // FIXME var lastSlash = virtualName.lastIndexOf("/"); @@ -1660,6 +1689,7 @@ var MonoSupportLib = { // "icu": load ICU globalization data from any runtime assets with behavior "icu". // "invariant": operate in invariant globalization mode. // "auto" (default): if "icu" behavior assets are present, use ICU, otherwise invariant. + // application_culture: (optional) current browser culture // diagnostic_tracing: (optional) enables diagnostic log messages during startup mono_load_runtime_and_bcl_args: function (args) { try { @@ -1751,7 +1781,8 @@ var MonoSupportLib = { throw new Error ("Invalid args (runtime_asset_sources was replaced by remote_sources)"); if (!args.loaded_cb) throw new Error ("loaded_cb not provided"); - + + args.assets = args.assets.concat(this._get_list_of_icu_files(args.icu_dictionary, args.application_culture)); var ctx = { tracing: args.diagnostic_tracing || false, pending_count: args.assets.length, @@ -1795,11 +1826,10 @@ var MonoSupportLib = { } }; - args.assets.forEach (function (asset) { + args.assets.forEach((asset) => { var attemptNextSource; var sourceIndex = 0; var sourcesList = asset.load_remote ? args.remote_sources : [""]; - var handleFetchResponse = function (response) { if (!response.ok) { try { @@ -1874,7 +1904,6 @@ var MonoSupportLib = { attemptNextSource (); } }; - attemptNextSource (); }); }, diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs index 6632275c6b9e1f..7dee24f2ab6131 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -41,8 +41,7 @@ public class WasmAppBuilder : Task // full list of ICU data files we produce can be found here: // https://github.com/dotnet/icu/tree/maint/maint-67/icu-filters - // public ITaskItem[]? IcuDataFileNames { get; set; } - public string? IcuShardData { get; set; } + public string? IcuDictionary { get; set; } public int DebugLevel { get; set; } public ITaskItem[]? SatelliteAssemblies { get; set; } @@ -128,9 +127,8 @@ public override bool Execute () { if (!File.Exists(MainJS)) throw new ArgumentException($"File MainJS='{MainJS}' doesn't exist."); - if (!InvariantGlobalization && string.IsNullOrEmpty(IcuShardData)) - // if (!InvariantGlobalization && IcuShardData == null) - throw new ArgumentException("IcuShardData property shouldn't be empty if InvariantGlobalization=false"); + if (!InvariantGlobalization && string.IsNullOrEmpty(IcuDictionary)) + throw new ArgumentException("IcuDictionary property shouldn't be empty if InvariantGlobalization=false"); if (Assemblies?.Length == 0) { @@ -229,30 +227,6 @@ public override bool Execute () } } - if (!InvariantGlobalization) - { - string[] icuConfig = IcuShardData!.ToLower().Split(','); - string[] localeFilters = new string[]{ "efigs", "en", "zh", "cjk", "no_cjk" }; - string[] nonLocaleSpecific = new string[]{ "currency", "normalization" }; - string? localeFilter = Array.Find(icuConfig, x => (Array.IndexOf(localeFilters, x)) > -1); - foreach (var icu in icuConfig) - { - string? icuDataFileName; - if (icu == localeFilter) - { - icuDataFileName = $"icudt_{icu}_base.dat"; - } else - { - icuDataFileName = (localeFilter is null) || (Array.IndexOf(nonLocaleSpecific, icu) > -1) ? $"icudt_{icu}.dat" : $"icudt_{localeFilter}_{icu}.dat"; - } - config.Assets.Add(new IcuData(icuDataFileName) { LoadRemote = RemoteSources?.Length > 0, DataType="common" }); - } - // foreach (ITaskItem item in IcuDataFileNames!) - // { - // config.Assets.Add(new IcuData(item!.ItemSpec) { LoadRemote = RemoteSources?.Length > 0, "common" }); - // } - } - config.Assets.Add(new VfsEntry ("dotnet.timezones.blat") { VirtualPath = "/usr/share/zoneinfo/"}); if (RemoteSources?.Length > 0) @@ -271,6 +245,12 @@ public override bool Execute () config.Extra[name] = valueObject; } + if (!InvariantGlobalization) + { + string? icuDictionary = File.ReadAllText(IcuDictionary!); + config.Extra["icu_dictionary"] = JsonSerializer.Deserialize>(icuDictionary!); + } + string monoConfigPath = Path.Join(AppDir, "mono-config.js"); using (var sw = File.CreateText(monoConfigPath)) { From bc78621b89628e5ce824880a18ff393d8a3c884a Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Wed, 21 Apr 2021 22:46:32 -0400 Subject: [PATCH 03/15] remove unnecessary files in platform manifest --- .../pkg/sfx/Microsoft.NETCore.App/Directory.Build.props | 1 - 1 file changed, 1 deletion(-) 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 8376cae563cc14..aa5bf723582335 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props @@ -197,7 +197,6 @@ - From 5b9cd96368c7da079a8102c6cfc5fe99b6c60ad7 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Wed, 21 Apr 2021 22:52:14 -0400 Subject: [PATCH 04/15] revert unnecessary changes --- .../Unix/System.Globalization.Native/pal_icushim_static.c | 8 ++++---- src/mono/mono/metadata/mono-config.c | 1 - src/mono/sample/wasm/console/Program.cs | 5 ----- src/mono/wasm/runtime-test.js | 3 +++ src/mono/wasm/runtime/library_mono.js | 6 +++++- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_static.c b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_static.c index 085e34e2e930b0..2bc5b4dfa5173e 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_static.c +++ b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_static.c @@ -96,11 +96,11 @@ static int32_t load_icu_data(void* pData, int32_t type) return 0; } else { -// #if defined(ICU_TRACING) +#if defined(ICU_TRACING) // see https://github.com/unicode-org/icu/blob/master/docs/userguide/icu_data/tracing.md - utrace_setFunctions(0, 0, 0, icu_trace_data); - utrace_setLevel(UTRACE_VERBOSE); -// #endif + utrace_setFunctions(0, 0, 0, icu_trace_data); + utrace_setLevel(UTRACE_VERBOSE); +#endif isDataSet = 1; return 1; } diff --git a/src/mono/mono/metadata/mono-config.c b/src/mono/mono/metadata/mono-config.c index 5d4a7d96a2f619..b55c76e67b34d7 100644 --- a/src/mono/mono/metadata/mono-config.c +++ b/src/mono/mono/metadata/mono-config.c @@ -22,7 +22,6 @@ #include "mono/metadata/object-internals.h" #include "mono/utils/mono-logger-internals.h" -#define ICU_TRACING 1 #if defined(TARGET_PS3) #define CONFIG_OS "CellOS" #elif defined(__linux__) diff --git a/src/mono/sample/wasm/console/Program.cs b/src/mono/sample/wasm/console/Program.cs index eded9e1f0490b2..6af1fa68e82d42 100644 --- a/src/mono/sample/wasm/console/Program.cs +++ b/src/mono/sample/wasm/console/Program.cs @@ -3,7 +3,6 @@ using System; using System.Threading.Tasks; -using System.Globalization; public class Test { @@ -11,10 +10,6 @@ public static async Task Main(string[] args) { await Task.Delay(1); Console.WriteLine("Hello World!"); - TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles"); - Console.WriteLine(tz.DisplayName); - Console.WriteLine(tz.StandardName); - Console.WriteLine(tz.DaylightName); for (int i = 0; i < args.Length; i++) { Console.WriteLine($"args[{i}] = {args[i]}"); } diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index fd5ae329a14978..caabd753da58cf 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -3,6 +3,7 @@ // Run runtime tests under a JS shell or a browser // //glue code to deal with the differences between chrome, ch, d8, jsc and sm. + var is_browser = typeof window != "undefined"; // if the engine doesn't provide a console @@ -141,6 +142,7 @@ function inspect_object (o) { } return r; } + // Preprocess arguments var args = testArguments; console.info("Arguments: " + testArguments); @@ -232,6 +234,7 @@ var Module = { if (!enable_gc) { Module.ccall ('mono_wasm_enable_on_demand_gc', 'void', ['number'], [0]); } + config.loaded_cb = function () { let wds = FS.stat (working_dir); if (wds === undefined || !FS.isDir (wds.mode)) { diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 4235f62654237c..57392a7461567d 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -1553,8 +1553,10 @@ var MonoSupportLib = { var bytes = new Uint8Array (blob); if (ctx.tracing) console.log ("MONO_WASM: Loaded:", asset.name, "size", bytes.length, "from", url); + var virtualName = asset.virtual_path || asset.name; var offset = null; + switch (asset.behavior) { case "resource": case "assembly": @@ -1564,6 +1566,7 @@ var MonoSupportLib = { offset = this.mono_wasm_load_bytes_into_heap (bytes); ctx.loaded_assets[virtualName] = [offset, bytes.length]; break; + case "vfs": // FIXME var lastSlash = virtualName.lastIndexOf("/"); @@ -1826,7 +1829,7 @@ var MonoSupportLib = { } }; - args.assets.forEach((asset) => { + args.assets.forEach (function (asset) { var attemptNextSource; var sourceIndex = 0; var sourcesList = asset.load_remote ? args.remote_sources : [""]; @@ -1904,6 +1907,7 @@ var MonoSupportLib = { attemptNextSource (); } }; + attemptNextSource (); }); }, From c8c40516b093c35ef17d1fa336aee2fc56e337b3 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Thu, 22 Apr 2021 13:08:14 -0400 Subject: [PATCH 05/15] add explanations and add try catch in WasmAppBuilder --- src/mono/wasm/runtime/library_mono.js | 8 ++++++++ src/tasks/WasmAppBuilder/WasmAppBuilder.cs | 24 +++++++++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 57392a7461567d..fff33b64102fde 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -1136,7 +1136,15 @@ var MonoSupportLib = { }, _get_shard_name: function (fileList) { + // Assumes that all filter files follow the naming convention: + // icudt__.json + // The more descriptors in a file name (separated by _) the granular the shard data is. + + // Get a list of file name descriptor length var name_lengths = fileList.map(x => x.split("_").length); + + // Choose the file with the most number of descriptors + // Assuming that we want the most condensed version available var shard_ix = name_lengths.indexOf(Math.max(...name_lengths)); return fileList[shard_ix]; }, diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs index 7dee24f2ab6131..1b84d0bc3a1589 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -125,10 +125,15 @@ public IcuData(string name) : base(name, "icu") {} public override bool Execute () { - if (!File.Exists(MainJS)) - throw new ArgumentException($"File MainJS='{MainJS}' doesn't exist."); + if (!File.Exists(MainJS)) { + Log.LogError($"File MainJS='{MainJS}' doesn't exist."); + return false; + } if (!InvariantGlobalization && string.IsNullOrEmpty(IcuDictionary)) - throw new ArgumentException("IcuDictionary property shouldn't be empty if InvariantGlobalization=false"); + { + Log.LogError("IcuDictionary property shouldn't be empty if InvariantGlobalization=false"); + return false; + } if (Assemblies?.Length == 0) { @@ -247,8 +252,17 @@ public override bool Execute () if (!InvariantGlobalization) { - string? icuDictionary = File.ReadAllText(IcuDictionary!); - config.Extra["icu_dictionary"] = JsonSerializer.Deserialize>(icuDictionary!); + try + { + string? icuDictionary = File.ReadAllText(IcuDictionary!); + config.Extra["icu_dictionary"] = JsonSerializer.Deserialize>(icuDictionary!); + } + catch (Exception e) + { + Log.LogError($"Error with opening ICU Dictionary"); + return false; + } + } string monoConfigPath = Path.Join(AppDir, "mono-config.js"); From e4cdcce354702711a7d80ce079dab1cf874ffe64 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Mon, 26 Apr 2021 15:36:42 -0400 Subject: [PATCH 06/15] add some tests for sharding, move sharding switch to WasmApp.targets --- src/mono/sample/wasm/console/Makefile | 5 + src/mono/sample/wasm/wasm.mk | 2 +- src/mono/wasm/build/WasmApp.targets | 6 ++ src/mono/wasm/runtime-test.js | 16 ++-- src/mono/wasm/runtime/library_mono.js | 8 +- src/tasks/WasmAppBuilder/WasmAppBuilder.cs | 3 +- .../Wasm.Build.Tests/ICUShardingTests.cs | 93 +++++++++++++++++++ 7 files changed, 117 insertions(+), 16 deletions(-) create mode 100644 src/tests/BuildWasmApps/Wasm.Build.Tests/ICUShardingTests.cs diff --git a/src/mono/sample/wasm/console/Makefile b/src/mono/sample/wasm/console/Makefile index d68cd314be01af..95e212ee50c5e8 100644 --- a/src/mono/sample/wasm/console/Makefile +++ b/src/mono/sample/wasm/console/Makefile @@ -1,4 +1,5 @@ TOP=../../../../.. +CULTURE=en-us include ../wasm.mk @@ -10,6 +11,10 @@ ifneq ($(V),) DOTNET_MONO_LOG_LEVEL=--setenv=MONO_LOG_LEVEL=debug endif +ifneq ($(SHARD),) +override MSBUILD_ARGS+=/p:EnableSharding=true /p:ICUDefaultCulture=$(CULTURE) +endif + PROJECT_NAME=Wasm.Console.Sample.csproj run: run-console diff --git a/src/mono/sample/wasm/wasm.mk b/src/mono/sample/wasm/wasm.mk index 01c3242b78cf5c..a691bce716a809 100644 --- a/src/mono/sample/wasm/wasm.mk +++ b/src/mono/sample/wasm/wasm.mk @@ -27,4 +27,4 @@ run-browser: fi run-console: - cd bin/$(CONFIG)/AppBundle && ~/.jsvu/v8 --expose_wasm runtime.js -- $(DOTNET_MONO_LOG_LEVEL) --enable-sharding=true --run Wasm.Console.Sample.dll + cd bin/$(CONFIG)/AppBundle && ~/.jsvu/v8 --expose_wasm runtime.js -- $(DOTNET_MONO_LOG_LEVEL) --run Wasm.Console.Sample.dll diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index d0df11fc2aa9d5..fdb28474cd2676 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -351,6 +351,7 @@ false + en-us @@ -374,6 +375,11 @@ + + + + + 0) { if (args [0].startsWith ("--profile=")) { @@ -178,10 +176,6 @@ while (args !== undefined && args.length > 0) { var arg = args [0].substring ("--working-dir=".length); working_dir = arg; args = args.slice (1); - } else if (args [0].startsWith ("--enable-sharding=")) { - var arg = args [0].substring ("--enable-sharding=".length); - enable_sharding = arg; - args = args.slice (1); } else { break; } @@ -284,9 +278,13 @@ var Module = { }) } }; - if (enable_sharding) - config.application_culture = Intl.DateTimeFormat().resolvedOptions().locale; - + if (config.enable_sharding) { + if (config.default_culture != null) { + config.application_culture = config.default_culture; + } else { + config.application_culture = Intl.DateTimeFormat().resolvedOptions().locale; + } + } MONO.mono_load_runtime_and_bcl_args (config); }, }; diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index fff33b64102fde..3175bff6f4299f 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -1154,14 +1154,15 @@ var MonoSupportLib = { if (culture == null || culture.length < 2) { icu_files = [dictionary.complete]; } else { - var parent_culture = culture.split('-')[0]; + var parent_culture = culture.includes('-') ? culture.split('-')[0] : culture; + console.log(parent_culture) var files = dictionary[parent_culture]; if (!feature_shards) { icu_files = [files.full]; } else { - icu_files = files.essentials; - icu_files.push(this._get_shard_name(files.coll)); + icu_files.push(...files.essentials.reverse()); icu_files.push(this._get_shard_name(files.locales)); + icu_files.push(this._get_shard_name(files.coll)); } } @@ -1564,7 +1565,6 @@ var MonoSupportLib = { var virtualName = asset.virtual_path || asset.name; var offset = null; - switch (asset.behavior) { case "resource": case "assembly": diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs index 1b84d0bc3a1589..0d30b669f1f310 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -259,10 +259,9 @@ public override bool Execute () } catch (Exception e) { - Log.LogError($"Error with opening ICU Dictionary"); + Log.LogError($"Error with opening ICU Dictionary {e.Message}"); return false; } - } string monoConfigPath = Path.Join(AppDir, "mono-config.js"); diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/ICUShardingTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/ICUShardingTests.cs new file mode 100644 index 00000000000000..8e5b7190303f7b --- /dev/null +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/ICUShardingTests.cs @@ -0,0 +1,93 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.IO; +using System.Collections.Generic; +using Xunit; +using Xunit.Abstractions; +using System.Globalization; + +#nullable enable + +namespace Wasm.Build.Tests +{ + public class ICUShardingTests : BuildTestBase + { + public ICUShardingTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) + : base(output, buildContext) + { + } + + public static IEnumerable ICUShardingTestData(bool enableSharding, RunHost host) + => ConfigWithAOTData(false) + .Multiply( + new object?[] { enableSharding, "en", "en-GB", false}, //EFIGS + new object?[] { enableSharding, "en", "zh", true}, //EFIGS + new object?[] { enableSharding, "es-ES", "am-ET", true}, //EFIGS + new object?[] { enableSharding, "es", "fr-FR", true}, //EFIGS + new object?[] { enableSharding, "zh", "zh-Hans", false}, //CJK + new object?[] { enableSharding, "ko", "zh-Hans", false}, //CJK + new object?[] { enableSharding, "ja-JP", "es-ES", true}, //CJK //this one should have thrown + new object?[] { enableSharding, "am-ET", "de-DE", false}, //no_CJK + new object?[] { enableSharding, "am-ET", "ko", true}, //no_CJK + new object?[] { enableSharding, "am-ET", "ja-JP", true}, //no_CJK + new object?[] { enableSharding, "am-ET", "vi-VN", false}, //no_CJK + new object?[] { enableSharding, null, "zh-Hans", true}) //ALL + .WithRunHosts(host) + .UnwrapItemsAsArrays(); + + [Theory] + [MemberData(nameof(ICUShardingTestData), parameters: new object[] { true, RunHost.All })] + public void ShardingTests(BuildArgs buildArgs, bool enableSharding, string defaultCulture, string testCulture, bool expectToThrow, RunHost host, string id) + => TestICUSharding(buildArgs, enableSharding, defaultCulture, testCulture, expectToThrow, host, id); + + void TestICUSharding(BuildArgs buildArgs, + bool enableSharding, + string defaultCulture, + string testCulture, + bool expectToThrow, + RunHost host, + string id, + bool? dotnetWasmFromRuntimePack=null) + { + string projectName = $"sharding_{enableSharding}_{defaultCulture}_{testCulture}"; + string programText = $@" + using System; + using System.Globalization; + using System.Threading.Tasks; + + public class TestClass {{ + public static int Main() + {{ + try {{ + var culture = new CultureInfo(""{testCulture}"", false); + Console.WriteLine(culture.Name); + }} + catch {{ + Console.WriteLine(""Culture Not Found""); + }} + + return 42; + }} + }}"; + + buildArgs = buildArgs with { ProjectName = projectName, ProjectFileContents = programText }; + buildArgs = GetBuildArgsWith(buildArgs, extraProperties: $"{enableSharding}{defaultCulture}"); + if (dotnetWasmFromRuntimePack == null) + dotnetWasmFromRuntimePack = !(buildArgs.AOT || buildArgs.Config == "Release"); + + BuildProject(buildArgs, + initProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), programText), + id: id, + dotnetWasmFromRuntimePack: dotnetWasmFromRuntimePack); + + string expectedOutputString = expectToThrow == true || enableSharding == false + ? "Culture Not Found" + : $"{CultureInfo.GetCultureInfo(testCulture).Name}"; + + RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 42, + test: output => Assert.Contains(expectedOutputString, output), host: host, id: id); + } + } +} \ No newline at end of file From 8bc27301a11b0d0c062d025ef9e07c1a1d4a10d7 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Tue, 4 May 2021 15:17:40 -0400 Subject: [PATCH 07/15] Add test case for invariant globalization --- src/mono/wasm/runtime/library_mono.js | 6 +- .../Wasm.Build.Tests/ICUShardingTests.cs | 73 ++++++++++++------- .../InvariantGlobalizationTests.cs | 8 ++ 3 files changed, 60 insertions(+), 27 deletions(-) diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 3175bff6f4299f..abe487b0368d48 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -1151,6 +1151,8 @@ var MonoSupportLib = { _get_list_of_icu_files: function (dictionary, culture, feature_shards=true) { var icu_files = [] + if (dictionary === undefined) + return null; if (culture == null || culture.length < 2) { icu_files = [dictionary.complete]; } else { @@ -1793,7 +1795,9 @@ var MonoSupportLib = { if (!args.loaded_cb) throw new Error ("loaded_cb not provided"); - args.assets = args.assets.concat(this._get_list_of_icu_files(args.icu_dictionary, args.application_culture)); + var icu_files = this._get_list_of_icu_files(args.icu_dictionary, args.application_culture); + if (icu_files != null) + args.assets = args.assets.concat(icu_files); var ctx = { tracing: args.diagnostic_tracing || false, pending_count: args.assets.length, diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/ICUShardingTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/ICUShardingTests.cs index 8e5b7190303f7b..7745daf0d36723 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/ICUShardingTests.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/ICUShardingTests.cs @@ -19,53 +19,72 @@ public ICUShardingTests(ITestOutputHelper output, SharedBuildPerTestClassFixture { } - public static IEnumerable ICUShardingTestData(bool enableSharding, RunHost host) - => ConfigWithAOTData(false) + public static IEnumerable ICUShardingTestData_EFIGS(bool aot, RunHost host) + => ConfigWithAOTData(aot) .Multiply( - new object?[] { enableSharding, "en", "en-GB", false}, //EFIGS - new object?[] { enableSharding, "en", "zh", true}, //EFIGS - new object?[] { enableSharding, "es-ES", "am-ET", true}, //EFIGS - new object?[] { enableSharding, "es", "fr-FR", true}, //EFIGS - new object?[] { enableSharding, "zh", "zh-Hans", false}, //CJK - new object?[] { enableSharding, "ko", "zh-Hans", false}, //CJK - new object?[] { enableSharding, "ja-JP", "es-ES", true}, //CJK //this one should have thrown - new object?[] { enableSharding, "am-ET", "de-DE", false}, //no_CJK - new object?[] { enableSharding, "am-ET", "ko", true}, //no_CJK - new object?[] { enableSharding, "am-ET", "ja-JP", true}, //no_CJK - new object?[] { enableSharding, "am-ET", "vi-VN", false}, //no_CJK - new object?[] { enableSharding, null, "zh-Hans", true}) //ALL + new object?[] { "en", "en-GB", false}, + new object?[] { "es", "fr-FR", false}, + new object?[] { "en", "zh", true}, + new object?[] {"es-ES", "am-ET", true}) + .WithRunHosts(host) + .UnwrapItemsAsArrays(); + + public static IEnumerable ICUShardingTestData_CJK(bool aot, RunHost host) + => ConfigWithAOTData(aot) + .Multiply( + new object?[] { "zh", "zh-Hans", false}, + new object?[] { "ko", "en-US", false}, + new object?[] { "ja-JP", "es-ES", true}, + new object?[] { "ja-JP", "fr-FR", true}) + .WithRunHosts(host) + .UnwrapItemsAsArrays(); + + public static IEnumerable ICUShardingTestData_no_CJK(bool aot, RunHost host) + => ConfigWithAOTData(aot) + .Multiply( + new object?[] { "am-ET", "de-DE", false}, + new object?[] { "am-ET", "vi-VN", false}, + new object?[] { "am-ET", "ko", true}, + new object?[] { "am-ET", "ja-JP", true}) .WithRunHosts(host) .UnwrapItemsAsArrays(); [Theory] - [MemberData(nameof(ICUShardingTestData), parameters: new object[] { true, RunHost.All })] - public void ShardingTests(BuildArgs buildArgs, bool enableSharding, string defaultCulture, string testCulture, bool expectToThrow, RunHost host, string id) - => TestICUSharding(buildArgs, enableSharding, defaultCulture, testCulture, expectToThrow, host, id); + [MemberData(nameof(ICUShardingTestData_EFIGS), parameters: new object[] { true, RunHost.All })] + [MemberData(nameof(ICUShardingTestData_EFIGS), parameters: new object[] { false, RunHost.All })] + [MemberData(nameof(ICUShardingTestData_CJK), parameters: new object[] { true, RunHost.All })] + [MemberData(nameof(ICUShardingTestData_CJK), parameters: new object[] { false, RunHost.All })] + [MemberData(nameof(ICUShardingTestData_no_CJK), parameters: new object[] { true, RunHost.All })] + [MemberData(nameof(ICUShardingTestData_no_CJK), parameters: new object[] { false, RunHost.All })] + public void ShardingTests(BuildArgs buildArgs, string defaultCulture, string testCulture, bool expectToThrow, RunHost host, string id) + => TestICUSharding(buildArgs, defaultCulture, testCulture, expectToThrow, host, id); void TestICUSharding(BuildArgs buildArgs, - bool enableSharding, string defaultCulture, string testCulture, bool expectToThrow, RunHost host, string id, + string projectContents="", bool? dotnetWasmFromRuntimePack=null) { - string projectName = $"sharding_{enableSharding}_{defaultCulture}_{testCulture}"; + string projectName = $"sharding_{defaultCulture}_{testCulture}"; string programText = $@" using System; using System.Globalization; - using System.Threading.Tasks; + using System.Text; public class TestClass {{ public static int Main() {{ try {{ var culture = new CultureInfo(""{testCulture}"", false); - Console.WriteLine(culture.Name); + string s = new string( new char[] {{'\u0063', '\u0301', '\u0327', '\u00BE'}}); + string normalized = s.Normalize(); + Console.WriteLine($""{{culture.NativeName}} - {{culture.NumberFormat.CurrencySymbol}} - {{normalized.IsNormalized(NormalizationForm.FormC)}}""); }} - catch {{ - Console.WriteLine(""Culture Not Found""); + catch (CultureNotFoundException e){{ + Console.WriteLine($""Culture Not Found {{e.Message}}""); }} return 42; @@ -73,7 +92,7 @@ public static int Main() }}"; buildArgs = buildArgs with { ProjectName = projectName, ProjectFileContents = programText }; - buildArgs = GetBuildArgsWith(buildArgs, extraProperties: $"{enableSharding}{defaultCulture}"); + buildArgs = GetBuildArgsWith(buildArgs, extraProperties: $"true{defaultCulture}"); if (dotnetWasmFromRuntimePack == null) dotnetWasmFromRuntimePack = !(buildArgs.AOT || buildArgs.Config == "Release"); @@ -82,9 +101,11 @@ public static int Main() id: id, dotnetWasmFromRuntimePack: dotnetWasmFromRuntimePack); - string expectedOutputString = expectToThrow == true || enableSharding == false + var culture = CultureInfo.GetCultureInfo(testCulture); + + string expectedOutputString = expectToThrow == true ? "Culture Not Found" - : $"{CultureInfo.GetCultureInfo(testCulture).Name}"; + : $"{culture.NativeName} - {culture.NumberFormat.CurrencySymbol} - True"; RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 42, test: output => Assert.Contains(expectedOutputString, output), host: host, id: id); diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/InvariantGlobalizationTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/InvariantGlobalizationTests.cs index 6d01f20a8420e8..6bb84032fd170b 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/InvariantGlobalizationTests.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/InvariantGlobalizationTests.cs @@ -33,6 +33,14 @@ public InvariantGlobalizationTests(ITestOutputHelper output, SharedBuildPerTestC public void AOT_InvariantGlobalization(BuildArgs buildArgs, bool? invariantGlobalization, RunHost host, string id) => TestInvariantGlobalization(buildArgs, invariantGlobalization, host, id); + + [Theory] + [MemberData(nameof(InvariantGlobalizationTestData), parameters: new object[] { /*aot*/ false, RunHost.All })] + [MemberData(nameof(InvariantGlobalizationTestData), parameters: new object[] { /*aot*/ true, RunHost.All })] + public void Invariant_WithSharding(BuildArgs buildArgs, bool? invariantGlobalization, RunHost host, string id) + => TestInvariantGlobalization(buildArgs, invariantGlobalization, host, id, + extraProperties: "true"); + // TODO: What else should we use to verify a relinked build? [Theory] [MemberData(nameof(InvariantGlobalizationTestData), parameters: new object[] { /*aot*/ false, RunHost.All })] From ebc8e01ec5f9998895d3a97517903a0cc61bf992 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Wed, 5 May 2021 13:49:08 -0400 Subject: [PATCH 08/15] Add checks for sharding property --- .../Directory.Build.props | 35 ++++++++++--------- src/tasks/WasmAppBuilder/WasmAppBuilder.cs | 29 +++++++++------ 2 files changed, 37 insertions(+), 27 deletions(-) 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 faa0903d43a9a6..96aab771b1856a 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props @@ -205,24 +205,8 @@ - - - - - - - - - - - - - - - - @@ -239,6 +223,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs index 87d53e673d088e..faa56b02b43123 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -129,11 +129,11 @@ public override bool Execute () Log.LogError($"File MainJS='{MainJS}' doesn't exist."); return false; } - if (!InvariantGlobalization && string.IsNullOrEmpty(IcuDictionary)) - { - Log.LogError("IcuDictionary property shouldn't be empty if InvariantGlobalization=false"); - return false; - } + // if (!InvariantGlobalization && string.IsNullOrEmpty(IcuDictionary)) + // { + // Log.LogError("IcuDictionary property shouldn't be empty if InvariantGlobalization=false"); + // return false; + // } if (Assemblies?.Length == 0) { @@ -252,15 +252,22 @@ public override bool Execute () if (!InvariantGlobalization) { - try + if (!string.IsNullOrEmpty(IcuDictionary!)) { - string? icuDictionary = File.ReadAllText(IcuDictionary!); - config.Extra["icu_dictionary"] = JsonSerializer.Deserialize>(icuDictionary!); + try + { + string? icuDictionary = File.ReadAllText(IcuDictionary!); + config.Extra["icu_dictionary"] = JsonSerializer.Deserialize>(icuDictionary!); + } + catch (Exception e) + { + Log.LogError($"Error with opening ICU Dictionary {e.Message}"); + return false; + } } - catch (Exception e) + else { - Log.LogError($"Error with opening ICU Dictionary {e.Message}"); - return false; + config.Assets.Add(new IcuData("icudt.dat") { LoadRemote = RemoteSources?.Length > 0 }); } } From 99597b6b0d2e2fee14e8412a0d2b97de9364b312 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Wed, 19 May 2021 17:59:17 -0400 Subject: [PATCH 09/15] wip --- src/mono/sample/wasm/console/Program.cs | 3 ++ src/mono/wasm/Makefile | 2 +- src/mono/wasm/build/WasmApp.props | 2 + src/mono/wasm/build/WasmApp.targets | 5 +- src/mono/wasm/runtime-test.js | 6 +++ src/mono/wasm/runtime/library_mono.js | 58 ++++++++++++---------- src/tasks/WasmAppBuilder/WasmAppBuilder.cs | 42 ++++++++-------- 7 files changed, 66 insertions(+), 52 deletions(-) diff --git a/src/mono/sample/wasm/console/Program.cs b/src/mono/sample/wasm/console/Program.cs index 6af1fa68e82d42..5ec6927d8ef705 100644 --- a/src/mono/sample/wasm/console/Program.cs +++ b/src/mono/sample/wasm/console/Program.cs @@ -3,12 +3,15 @@ using System; using System.Threading.Tasks; +using System.Globalization; public class Test { public static async Task Main(string[] args) { await Task.Delay(1); + CultureInfo cr = CultureInfo.GetCultureInfo("zh"); + Console.WriteLine(cr.CompareInfo); Console.WriteLine("Hello World!"); for (int i = 0; i < args.Length; i++) { Console.WriteLine($"args[{i}] = {args[i]}"); diff --git a/src/mono/wasm/Makefile b/src/mono/wasm/Makefile index f8a44275297ea7..c9e828ce937df8 100644 --- a/src/mono/wasm/Makefile +++ b/src/mono/wasm/Makefile @@ -187,7 +187,7 @@ run-tests-%: EMSDK_PATH=$(EMSDK_PATH) PATH="$(JSVU):$(PATH)" $(DOTNET) build $(TOP)/src/libraries/$*/tests/ /t:Test $(_MSBUILD_WASM_BUILD_ARGS) $(MSBUILD_ARGS) run-build-tests: - PATH="$(JSVU):$(PATH)" $(DOTNET) build $(TOP)/src/tests/BuildWasmApps/Wasm.Build.Tests/ /t:Test $(_MSBUILD_WASM_BUILD_ARGS) $(MSBUILD_ARGS) + PATH="$(JSVU):$(PATH)" $(DOTNET) build $(TOP)/src/tests/BuildWasmApps/Wasm.Build.Tests/ /t:Test $(_MSBUILD_WASM_BUILD_ARGS) $(MSBUILD_ARGS) /p:XUnitMethodName=Wasm.Build.Tests.InvariantGlobalizationTests.Invariant_WithSharding run-browser-tests-%: PATH="$(GECKODRIVER):$(CHROMEDRIVER):$(PATH)" XHARNESS_COMMAND="test-browser --browser=$(XHARNESS_BROWSER)" $(DOTNET) build $(TOP)/src/libraries/$*/tests/ /t:Test $(_MSBUILD_WASM_BUILD_ARGS) $(MSBUILD_ARGS) diff --git a/src/mono/wasm/build/WasmApp.props b/src/mono/wasm/build/WasmApp.props index c2c716734f7c89..26edafbcc64bcd 100644 --- a/src/mono/wasm/build/WasmApp.props +++ b/src/mono/wasm/build/WasmApp.props @@ -7,4 +7,6 @@ Publish _BeforeWasmBuildApp;_WasmResolveReferences;_WasmBuildNative;_WasmGenerateAppBundle;_AfterWasmBuildApp + + diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index a619f13e42c8ac..d607a8cfb5ce99 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -316,14 +316,14 @@ <_HasDotnetWasm Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.wasm'">true <_HasDotnetJs Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.js'">true - $(MicrosoftNetCoreAppRuntimePackRidNativeDir)icu_dictionary.json - + + @@ -340,7 +340,6 @@ InvariantGlobalization="$(InvariantGlobalization)" SatelliteAssemblies="@(WasmSatelliteAssemblies)" FilesToIncludeInFileSystem="@(WasmFilesToIncludeInFileSystem)" - IcuDictionary="$(IcuDictionaryPath)" RemoteSources="@(WasmRemoteSources)" ExtraFilesToDeploy="@(WasmExtraFilesToDeploy)" ExtraConfig="@(WasmExtraConfig)" diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index 0a97e355c9b94c..347d8cc8f40501 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -2,6 +2,9 @@ // // Run runtime tests under a JS shell or a browser // + +const { config } = require("node:process"); + //glue code to deal with the differences between chrome, ch, d8, jsc and sm. var is_browser = typeof window != "undefined"; @@ -204,6 +207,7 @@ function loadScript (url) } loadScript ("mono-config.js"); +loadScript ("icu_dictionary.js") var Module = { mainScriptUrlOrBlob: "dotnet.js", @@ -278,7 +282,9 @@ var Module = { }) } }; + if (config.enable_sharding) { + config.icu_dictionary = dictionary; if (config.default_culture != null) { config.application_culture = config.default_culture; } else { diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 4d257c88cc923e..44562c88787a17 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -1143,46 +1143,50 @@ var MonoSupportLib = { return res; }, - _get_shard_name: function (fileList) { - // Assumes that all filter files follow the naming convention: - // icudt__.json - // The more descriptors in a file name (separated by _) the granular the shard data is. - - // Get a list of file name descriptor length - var name_lengths = fileList.map(x => x.split("_").length); - - // Choose the file with the most number of descriptors - // Assuming that we want the most condensed version available - var shard_ix = name_lengths.indexOf(Math.max(...name_lengths)); - return fileList[shard_ix]; + _get_shard_name: function (shards, culture) { + // Get shard name that culture belongs to + for (var name in shards) { + if (culture.match(shards[name])) + return name + } }, - _get_list_of_icu_files: function (dictionary, culture, feature_shards=true) { + _get_list_of_icu_files: function (dictionary, culture, feature_shards=true, features="") { + console.log(dictionary) var icu_files = [] if (dictionary === undefined) return null; if (culture == null || culture.length < 2) { - icu_files = [dictionary.complete]; + icu_files = [dictionary.full]; } else { - var parent_culture = culture.includes('-') ? culture.split('-')[0] : culture; - console.log(parent_culture) - var files = dictionary[parent_culture]; + var shard_name = this._get_shard_name(dictionary.shards, culture) + var files = dictionary.packs[shard_name]; if (!feature_shards) { - icu_files = [files.full]; + icu_files = files.full; } else { - icu_files.push(...files.essentials.reverse()); - icu_files.push(this._get_shard_name(files.locales)); - icu_files.push(this._get_shard_name(files.coll)); + // Get base files first + files[files.extends].forEach(feature => icu_files.push(...files[files.extends][feature])) + + // Adding shard specific core files such as collation and locales + icu_files.push(...files["core"]) + + // Add any additional features + if (features != "") { + features = features.split(","); + features.forEach(feat => { + icu_files.push(...files[feat]) + }) + } } } - + console.log(JSON.stringify(icu_files)) icu_assets = []; icu_files.forEach(file => icu_assets.push({ - "behavior": "icu", - "name": file, - "load_remote": false, - "data_type": "common" - })); + "behavior": "icu", + "name": file, + "load_remote": false, + "data_type": "common" + })); return icu_assets; }, diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs index faa56b02b43123..d220858e87f8ac 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -41,7 +41,7 @@ public class WasmAppBuilder : Task // full list of ICU data files we produce can be found here: // https://github.com/dotnet/icu/tree/maint/maint-67/icu-filters - public string? IcuDictionary { get; set; } + // public string? IcuDictionary { get; set; } public int DebugLevel { get; set; } public ITaskItem[]? SatelliteAssemblies { get; set; } @@ -250,26 +250,26 @@ public override bool Execute () config.Extra[name] = valueObject; } - if (!InvariantGlobalization) - { - if (!string.IsNullOrEmpty(IcuDictionary!)) - { - try - { - string? icuDictionary = File.ReadAllText(IcuDictionary!); - config.Extra["icu_dictionary"] = JsonSerializer.Deserialize>(icuDictionary!); - } - catch (Exception e) - { - Log.LogError($"Error with opening ICU Dictionary {e.Message}"); - return false; - } - } - else - { - config.Assets.Add(new IcuData("icudt.dat") { LoadRemote = RemoteSources?.Length > 0 }); - } - } + // if (!InvariantGlobalization) + // { + // if (!string.IsNullOrEmpty(IcuDictionary!)) + // { + // try + // { + // string? icuDictionary = File.ReadAllText(IcuDictionary!); + // config.Extra["icu_dictionary"] = JsonSerializer.Deserialize>(icuDictionary!); + // } + // catch (Exception e) + // { + // Log.LogError($"Error with opening ICU Dictionary {e.Message}"); + // return false; + // } + // } + // else + // { + // config.Assets.Add(new IcuData("icudt.dat") { LoadRemote = RemoteSources?.Length > 0 }); + // } + // } string monoConfigPath = Path.Combine(AppDir, "mono-config.js"); using (var sw = File.CreateText(monoConfigPath)) From 22d1c3234931090e95bdf52f5a56c27b4ac77848 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Fri, 21 May 2021 09:39:30 -0400 Subject: [PATCH 10/15] [wip] change data loading in library_mono.js to match changes in dotnet/icu, load ICU.DataFiles.props file generated by the icu --- src/mono/wasm/build/ICU.DataFiles.props | 20 ++++++++++++++++++++ src/mono/wasm/build/WasmApp.props | 1 - src/mono/wasm/build/WasmApp.targets | 2 +- src/mono/wasm/runtime-test.js | 3 --- src/mono/wasm/runtime/library_mono.js | 9 +++++---- src/tasks/WasmAppBuilder/WasmAppBuilder.cs | 21 --------------------- 6 files changed, 26 insertions(+), 30 deletions(-) create mode 100644 src/mono/wasm/build/ICU.DataFiles.props diff --git a/src/mono/wasm/build/ICU.DataFiles.props b/src/mono/wasm/build/ICU.DataFiles.props new file mode 100644 index 00000000000000..30d99ab076213b --- /dev/null +++ b/src/mono/wasm/build/ICU.DataFiles.props @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/mono/wasm/build/WasmApp.props b/src/mono/wasm/build/WasmApp.props index 08a02d9607a264..614df0f048f375 100644 --- a/src/mono/wasm/build/WasmApp.props +++ b/src/mono/wasm/build/WasmApp.props @@ -15,6 +15,5 @@ _AfterWasmBuildApp - diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index 70d353da9c5465..13bcc3cd23aa24 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -99,7 +99,6 @@ - @@ -595,4 +594,5 @@ EMSCRIPTEN_KEEPALIVE void mono_wasm_load_profiler_aot (const char *desc) { mono_ WasmAssembliesToBundle: @(WasmAssembliesToBundle) WasmAssembliesFinal: @(WasmAssembliesFinal)" /> + diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index 347d8cc8f40501..7a22723537c9f2 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -2,9 +2,6 @@ // // Run runtime tests under a JS shell or a browser // - -const { config } = require("node:process"); - //glue code to deal with the differences between chrome, ch, d8, jsc and sm. var is_browser = typeof window != "undefined"; diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 44562c88787a17..8a1235ec81c60f 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -1152,7 +1152,6 @@ var MonoSupportLib = { }, _get_list_of_icu_files: function (dictionary, culture, feature_shards=true, features="") { - console.log(dictionary) var icu_files = [] if (dictionary === undefined) return null; @@ -1160,13 +1159,15 @@ var MonoSupportLib = { icu_files = [dictionary.full]; } else { var shard_name = this._get_shard_name(dictionary.shards, culture) - var files = dictionary.packs[shard_name]; + var packs = dictionary.packs; + var files = packs[shard_name]; if (!feature_shards) { icu_files = files.full; } else { // Get base files first - files[files.extends].forEach(feature => icu_files.push(...files[files.extends][feature])) - + for (var feature in packs[files.extends]) { + icu_files.push(...packs[files.extends][feature]); + } // Adding shard specific core files such as collation and locales icu_files.push(...files["core"]) diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs index d220858e87f8ac..35826acaa5a881 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -250,27 +250,6 @@ public override bool Execute () config.Extra[name] = valueObject; } - // if (!InvariantGlobalization) - // { - // if (!string.IsNullOrEmpty(IcuDictionary!)) - // { - // try - // { - // string? icuDictionary = File.ReadAllText(IcuDictionary!); - // config.Extra["icu_dictionary"] = JsonSerializer.Deserialize>(icuDictionary!); - // } - // catch (Exception e) - // { - // Log.LogError($"Error with opening ICU Dictionary {e.Message}"); - // return false; - // } - // } - // else - // { - // config.Assets.Add(new IcuData("icudt.dat") { LoadRemote = RemoteSources?.Length > 0 }); - // } - // } - string monoConfigPath = Path.Combine(AppDir, "mono-config.js"); using (var sw = File.CreateText(monoConfigPath)) { From ff4c37ee5ca93bb7310ea4a12fce7d8ec07a7bda Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Tue, 25 May 2021 12:46:36 -0400 Subject: [PATCH 11/15] [wip] getting shard loading to work --- .../Directory.Build.props | 19 --------------- src/mono/wasm/build/ICU.DataFiles.props | 5 +++- src/mono/wasm/build/WasmApp.targets | 1 - src/mono/wasm/runtime/library_mono.js | 23 ++++++++++++------- src/tasks/WasmAppBuilder/WasmAppBuilder.cs | 2 +- .../Wasm.Build.Tests/ICUShardingTests.cs | 4 ++-- 6 files changed, 22 insertions(+), 32 deletions(-) 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 9683b7d97b34f8..ac2d3cc1a02246 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props @@ -225,25 +225,6 @@ - - - - - - - - - - - - - - - - - - - diff --git a/src/mono/wasm/build/ICU.DataFiles.props b/src/mono/wasm/build/ICU.DataFiles.props index 30d99ab076213b..7aafbec6079de1 100644 --- a/src/mono/wasm/build/ICU.DataFiles.props +++ b/src/mono/wasm/build/ICU.DataFiles.props @@ -15,6 +15,9 @@ - + + + + \ No newline at end of file diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index 13bcc3cd23aa24..64d8a0affdc4a5 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -594,5 +594,4 @@ EMSCRIPTEN_KEEPALIVE void mono_wasm_load_profiler_aot (const char *desc) { mono_ WasmAssembliesToBundle: @(WasmAssembliesToBundle) WasmAssembliesFinal: @(WasmAssembliesFinal)" /> - diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 8a1235ec81c60f..7314145556802d 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -1145,8 +1145,9 @@ var MonoSupportLib = { _get_shard_name: function (shards, culture) { // Get shard name that culture belongs to + var parent_culture = culture.includes('-') ? culture.split('-')[0] : culture; for (var name in shards) { - if (culture.match(shards[name])) + if (parent_culture.match(shards[name])) return name } }, @@ -1180,14 +1181,19 @@ var MonoSupportLib = { } } } - console.log(JSON.stringify(icu_files)) icu_assets = []; - icu_files.forEach(file => icu_assets.push({ - "behavior": "icu", - "name": file, - "load_remote": false, - "data_type": "common" - })); + icu_files.forEach(file => { + var type = "common"; + // if (file.includes("locales")) + // type = "app"; + icu_assets.push({ + "behavior": "icu", + "name": file, + "load_remote": false, + "data_type": type + }) + }); + console.log(JSON.stringify(icu_assets)) return icu_assets; }, @@ -1611,6 +1617,7 @@ var MonoSupportLib = { var virtualName = asset.virtual_path || asset.name; var offset = null; + switch (asset.behavior) { case "resource": case "assembly": diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs index 35826acaa5a881..60d73c5867e773 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -41,7 +41,6 @@ public class WasmAppBuilder : Task // full list of ICU data files we produce can be found here: // https://github.com/dotnet/icu/tree/maint/maint-67/icu-filters - // public string? IcuDictionary { get; set; } public int DebugLevel { get; set; } public ITaskItem[]? SatelliteAssemblies { get; set; } @@ -129,6 +128,7 @@ public override bool Execute () Log.LogError($"File MainJS='{MainJS}' doesn't exist."); return false; } + // if (!InvariantGlobalization && string.IsNullOrEmpty(IcuDictionary)) // { // Log.LogError("IcuDictionary property shouldn't be empty if InvariantGlobalization=false"); diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/ICUShardingTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/ICUShardingTests.cs index 7745daf0d36723..14cd8d97bf93ed 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/ICUShardingTests.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/ICUShardingTests.cs @@ -81,7 +81,7 @@ public static int Main() var culture = new CultureInfo(""{testCulture}"", false); string s = new string( new char[] {{'\u0063', '\u0301', '\u0327', '\u00BE'}}); string normalized = s.Normalize(); - Console.WriteLine($""{{culture.NativeName}} - {{culture.NumberFormat.CurrencySymbol}} - {{normalized.IsNormalized(NormalizationForm.FormC)}}""); + Console.WriteLine($""{{culture.NativeName}} - {{culture.NumberFormat.CurrencySymbol}} - {{culture.DateTimeFormat.FullDateTimePattern}} - {{normalized.IsNormalized(NormalizationForm.FormC)}}""); }} catch (CultureNotFoundException e){{ Console.WriteLine($""Culture Not Found {{e.Message}}""); @@ -105,7 +105,7 @@ public static int Main() string expectedOutputString = expectToThrow == true ? "Culture Not Found" - : $"{culture.NativeName} - {culture.NumberFormat.CurrencySymbol} - True"; + : $"{culture.NativeName} - {culture.NumberFormat.CurrencySymbol} - {culture.DateTimeFormat.FullDateTimePattern} - True"; RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 42, test: output => Assert.Contains(expectedOutputString, output), host: host, id: id); From 35c1b56c95c0dcc7e3d83a72c7fe028f2c46faba Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Wed, 26 May 2021 19:52:03 -0400 Subject: [PATCH 12/15] load ICU.DataFile.props from icu lib dir --- src/mono/wasm/build/WasmApp.props | 1 - src/mono/wasm/wasm.proj | 2 +- src/tests/BuildWasmApps/Wasm.Build.Tests/ICUShardingTests.cs | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mono/wasm/build/WasmApp.props b/src/mono/wasm/build/WasmApp.props index 614df0f048f375..6f496caa81e087 100644 --- a/src/mono/wasm/build/WasmApp.props +++ b/src/mono/wasm/build/WasmApp.props @@ -15,5 +15,4 @@ _AfterWasmBuildApp - diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 8f958e8e2f0a15..78e54d2d448fad 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -123,6 +123,7 @@ $(MonoArtifactsPath)include/mono-2.0 $(RepoRoot)src\libraries\Native\Unix\System.Native + @@ -136,7 +137,6 @@ - diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/ICUShardingTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/ICUShardingTests.cs index 14cd8d97bf93ed..ed64ef28dd6753 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/ICUShardingTests.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/ICUShardingTests.cs @@ -81,7 +81,7 @@ public static int Main() var culture = new CultureInfo(""{testCulture}"", false); string s = new string( new char[] {{'\u0063', '\u0301', '\u0327', '\u00BE'}}); string normalized = s.Normalize(); - Console.WriteLine($""{{culture.NativeName}} - {{culture.NumberFormat.CurrencySymbol}} - {{culture.DateTimeFormat.FullDateTimePattern}} - {{normalized.IsNormalized(NormalizationForm.FormC)}}""); + Console.WriteLine($""{{culture.NativeName}} - {{culture.NumberFormat.CurrencySymbol}} - {{culture.DateTimeFormat.FullDateTimePattern}} - {{culture.CompareInfo.LCID}} - {{normalized.IsNormalized(NormalizationForm.FormC)}}""); }} catch (CultureNotFoundException e){{ Console.WriteLine($""Culture Not Found {{e.Message}}""); @@ -105,7 +105,7 @@ public static int Main() string expectedOutputString = expectToThrow == true ? "Culture Not Found" - : $"{culture.NativeName} - {culture.NumberFormat.CurrencySymbol} - {culture.DateTimeFormat.FullDateTimePattern} - True"; + : $"{culture.NativeName} - {culture.NumberFormat.CurrencySymbol} - {culture.DateTimeFormat.FullDateTimePattern} - {culture.CompareInfo.LCID} - True"; RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 42, test: output => Assert.Contains(expectedOutputString, output), host: host, id: id); From 4baa7525288386b51291c2b996ccfbc4d5da2429 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Tue, 1 Jun 2021 09:43:00 -0400 Subject: [PATCH 13/15] move icu_dictionary.js declaration to ICU.DataFiles.props --- .../pal_icushim_static.c | 2 +- src/mono/wasm/build/ICU.DataFiles.props | 23 ------------------- src/mono/wasm/build/WasmApp.targets | 1 - 3 files changed, 1 insertion(+), 25 deletions(-) delete mode 100644 src/mono/wasm/build/ICU.DataFiles.props diff --git a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_static.c b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_static.c index 2bc5b4dfa5173e..5c2c462cbb5c36 100644 --- a/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_static.c +++ b/src/libraries/Native/Unix/System.Globalization.Native/pal_icushim_static.c @@ -154,7 +154,7 @@ int32_t GlobalizationNative_LoadICUData(const char* path) fclose(fp); - if (load_icu_data(icu_data, strcasecmp("icudt.dat", path)) == 0) { + if (load_icu_data(icu_data, strstr(path, "app") == NULL) == 0) { log_shim_error("ICU BAD EXIT %d.", ret); return ret; } diff --git a/src/mono/wasm/build/ICU.DataFiles.props b/src/mono/wasm/build/ICU.DataFiles.props deleted file mode 100644 index 7aafbec6079de1..00000000000000 --- a/src/mono/wasm/build/ICU.DataFiles.props +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index 64d8a0affdc4a5..fe17050c3e909f 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -355,7 +355,6 @@ - From 4f22f2311e6ee9e145da83945455159a3ca8d466 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Tue, 1 Jun 2021 11:13:16 -0400 Subject: [PATCH 14/15] move icu dictionary loading under conditional --- src/mono/wasm/runtime-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index 7a22723537c9f2..cdd1255a92d512 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -204,7 +204,6 @@ function loadScript (url) } loadScript ("mono-config.js"); -loadScript ("icu_dictionary.js") var Module = { mainScriptUrlOrBlob: "dotnet.js", @@ -281,6 +280,7 @@ var Module = { }; if (config.enable_sharding) { + loadScript ("icu_dictionary.js"); config.icu_dictionary = dictionary; if (config.default_culture != null) { config.application_culture = config.default_culture; From 331f45204ed825016c74654b74bbb5b61feb14d3 Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Tue, 1 Jun 2021 18:47:28 -0400 Subject: [PATCH 15/15] more fixes for full icu scenario --- src/mono/wasm/build/WasmApp.targets | 1 + src/mono/wasm/runtime-test.js | 6 ++---- src/mono/wasm/runtime/library_mono.js | 5 ++--- src/mono/wasm/wasm.proj | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index 688431ca28fb69..f49cc81f25b3ba 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -131,6 +131,7 @@ + diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index cdd1255a92d512..d11efc9dde1ea5 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -204,7 +204,7 @@ function loadScript (url) } loadScript ("mono-config.js"); - +loadScript ("icu_dictionary.js"); var Module = { mainScriptUrlOrBlob: "dotnet.js", @@ -278,10 +278,8 @@ var Module = { }) } }; - + config.icu_dictionary = dictionary; if (config.enable_sharding) { - loadScript ("icu_dictionary.js"); - config.icu_dictionary = dictionary; if (config.default_culture != null) { config.application_culture = config.default_culture; } else { diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 7314145556802d..6959e87d253fb0 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -1156,8 +1156,8 @@ var MonoSupportLib = { var icu_files = [] if (dictionary === undefined) return null; - if (culture == null || culture.length < 2) { - icu_files = [dictionary.full]; + if (culture === undefined || culture.length < 2 ) { + icu_files = [dictionary.packs.full]; } else { var shard_name = this._get_shard_name(dictionary.shards, culture) var packs = dictionary.packs; @@ -1193,7 +1193,6 @@ var MonoSupportLib = { "data_type": type }) }); - console.log(JSON.stringify(icu_assets)) return icu_assets; }, diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 1c12c100844572..67867c9778afcd 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -197,7 +197,7 @@ $(MonoArtifactsPath)include/mono-2.0 $(RepoRoot)src\libraries\Native\Unix\System.Native - +