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][non-icu] HybridGlobalization change case #84019

Merged
merged 25 commits into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e9b6ebb
Enabled `HybridGlobalization` mode.
ilonatommy Mar 28, 2023
1fb1e22
Enabled non-icu change case.
ilonatommy Mar 28, 2023
c8e80ee
Tests.
ilonatommy Mar 28, 2023
738c702
Revert not connected changes.
ilonatommy Mar 28, 2023
f397168
Fix: Add the new file to the project.
ilonatommy Mar 28, 2023
d4de126
Fix: this PR is for Browser, so add it to condition.
ilonatommy Mar 28, 2023
7a1b55c
Fixed calls to js.
ilonatommy Mar 28, 2023
30c7039
Trying to fix CI.
ilonatommy Mar 28, 2023
f6f9fcf
False is default, redundant lines.
ilonatommy Mar 28, 2023
a8ef060
Trying to fix the CI.
ilonatommy Mar 28, 2023
76abac8
Remove redundant code.
ilonatommy Mar 28, 2023
376d12d
This PR is partial solution, this file will be added in a follow-up.
ilonatommy Mar 28, 2023
ceee24a
Fix for EAT lib tests.
ilonatommy Mar 29, 2023
9afe416
We do not trim anything for Hybrid currently.
ilonatommy Mar 29, 2023
4349310
Check if functions invoked only in specific modes.
ilonatommy Mar 30, 2023
ab8fb10
Change confusing name + move the common property to the main part of …
ilonatommy Mar 30, 2023
89cbb73
Applied @mkhamoyan's suggestion.
ilonatommy Mar 30, 2023
de57dec
Fix previous commit: missing directive.
ilonatommy Mar 30, 2023
9066e11
Fix previous commit: missing directive.
ilonatommy Mar 30, 2023
1d15645
It's not IOS-connected.
ilonatommy Mar 30, 2023
52935e3
Merge branch 'main' into hg-change-case
ilonatommy Mar 30, 2023
c082aea
Move hybrid tests to correct dir + separate ios and wasm + update sln.
ilonatommy Mar 31, 2023
1f8d4f9
Invariant and hybrid cannot be both true.
ilonatommy Mar 31, 2023
1aea9a8
Remove old version of hybrid tests proj.
ilonatommy Mar 31, 2023
ef626b4
Applied @kg's review.
ilonatommy Apr 3, 2023
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
1 change: 0 additions & 1 deletion docs/workflow/trimming/feature-switches.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ configurations but their defaults might vary as any SDK can set the defaults dif
| EnableUnsafeBinaryFormatterSerialization | System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization | BinaryFormatter serialization support is trimmed when set to false |
| EventSourceSupport | System.Diagnostics.Tracing.EventSource.IsSupported | Any EventSource related code or logic is trimmed when set to false |
| InvariantGlobalization | System.Globalization.Invariant | All globalization specific code and data is trimmed when set to true |
| HybridGlobalization | System.Globalization.Hybrid | Loading ICU + native implementations |
| PredefinedCulturesOnly | System.Globalization.PredefinedCulturesOnly | Don't allow creating a culture for which the platform does not have data |
| UseSystemResourceKeys | System.Resources.UseSystemResourceKeys | Any localizable resources for system assemblies is trimmed when set to true |
| HttpActivityPropagationSupport | System.Net.Http.EnableActivityPropagation | Any dependency related to diagnostics support for System.Net.Http is trimmed when set to false |
Expand Down
1 change: 1 addition & 0 deletions eng/testing/tests.browser.targets
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@
<_WasmPropertyNames Include="EmccLinkOptimizationFlag" />
<_WasmPropertyNames Include="WasmIncludeFullIcuData" />
<_WasmPropertyNames Include="WasmIcuDataFileName" />
<_WasmPropertyNames Include="HybridGlobalization" />
</ItemGroup>
</Target>

Expand Down
21 changes: 21 additions & 0 deletions src/libraries/System.Globalization/System.Globalization.sln
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{A93AFF96-DB2
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gen", "gen", "{0378EF1C-9838-4AD0-867D-506FB02F8BBB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hybrid.Tests", "tests\Hybrid\Hybrid.Tests.csproj", "{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}"
EndProject
ilonatommy marked this conversation as resolved.
Show resolved Hide resolved
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -244,6 +246,24 @@ Global
{41F80FEC-8515-455F-AC3E-D88B6CAAF8DA}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
{41F80FEC-8515-455F-AC3E-D88B6CAAF8DA}.Checked|x64.ActiveCfg = Debug|Any CPU
{41F80FEC-8515-455F-AC3E-D88B6CAAF8DA}.Checked|x86.ActiveCfg = Debug|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Debug|x64.ActiveCfg = Debug|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Debug|x64.Build.0 = Debug|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Debug|x86.ActiveCfg = Debug|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Debug|x86.Build.0 = Debug|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Release|Any CPU.Build.0 = Release|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Release|x64.ActiveCfg = Release|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Release|x64.Build.0 = Release|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Release|x86.ActiveCfg = Release|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Release|x86.Build.0 = Release|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Checked|Any CPU.Build.0 = Debug|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Checked|x64.ActiveCfg = Debug|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Checked|x64.Build.0 = Debug|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Checked|x86.ActiveCfg = Debug|Any CPU
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274}.Checked|x86.Build.0 = Debug|Any CPU
ilonatommy marked this conversation as resolved.
Show resolved Hide resolved
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -262,6 +282,7 @@ Global
{74CAB3C9-1AE1-467E-B139-35E7113F4660} = {0378EF1C-9838-4AD0-867D-506FB02F8BBB}
{12E788BB-7E58-4780-B52E-DB5A91A49DFF} = {0378EF1C-9838-4AD0-867D-506FB02F8BBB}
{F4A35959-8F1B-4CA9-B672-3ACFBDD54174} = {0378EF1C-9838-4AD0-867D-506FB02F8BBB}
{4134CD4D-1E8F-45D4-883C-B08A1DB5B274} = {C223E72F-FD21-43C3-AC7A-62BCF4A5C379}
EndGlobalSection
ilonatommy marked this conversation as resolved.
Show resolved Hide resolved
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {33E0B3D0-C6E1-4B75-A025-AE012AD424F7}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
<TestRuntime>true</TestRuntime>
<HybridGlobalization>true</HybridGlobalization>
</PropertyGroup>
<ItemGroup>
<Compile Include="System\Globalization\TextInfoTests.cs" />
</ItemGroup>
ilonatommy marked this conversation as resolved.
Show resolved Hide resolved
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TextInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TextInfo.Icu.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TextInfo.Nls.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TextInfo.WebAssembly.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\ThaiBuddhistCalendar.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TimeSpanFormat.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TimeSpanParse.cs" />
Expand Down Expand Up @@ -2596,4 +2597,4 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IUnaryPlusOperators.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IUnsignedNumber.cs" />
</ItemGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,15 @@ internal static partial class GlobalizationMode
private static partial class Settings
{
internal static bool Invariant { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.Invariant", "DOTNET_SYSTEM_GLOBALIZATION_INVARIANT");
#if TARGET_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
ilonatommy marked this conversation as resolved.
Show resolved Hide resolved
internal static bool Hybrid { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.Hybrid", "DOTNET_SYSTEM_GLOBALIZATION_HYBRID");
#endif
internal static bool PredefinedCulturesOnly { get; } = AppContextConfigHelper.GetBooleanConfig("System.Globalization.PredefinedCulturesOnly", "DOTNET_SYSTEM_GLOBALIZATION_PREDEFINED_CULTURES_ONLY", GlobalizationMode.Invariant);
}

// Note: Invariant=true and Invariant=false are substituted at different levels in the ILLink.Substitutions file.
// 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_OSX || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
internal static bool Hybrid => Settings.Hybrid;
#endif
internal static bool PredefinedCulturesOnly => Settings.PredefinedCulturesOnly;

private static bool TryGetAppLocalIcuSwitchValue([NotNullWhen(true)] out string? value) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// 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.Diagnostics;
using System.Runtime.CompilerServices;

namespace System.Globalization
{
internal static unsafe class TextInfoInterop
{
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern unsafe void ChangeCaseInvariantJS(out string exceptionMessage, char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern unsafe void ChangeCaseJS(out string exceptionMessage, in string culture, char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper);
}

public partial class TextInfo
{
internal unsafe void JsChangeCase(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool toUpper)
{
Debug.Assert(!GlobalizationMode.Invariant);
Debug.Assert(!GlobalizationMode.UseNls);
ilonatommy marked this conversation as resolved.
Show resolved Hide resolved
Debug.Assert(GlobalizationMode.Hybrid);

string exceptionMessage;
if (IsInvariant)
ilonatommy marked this conversation as resolved.
Show resolved Hide resolved
{
TextInfoInterop.ChangeCaseInvariantJS(out exceptionMessage, src, srcLen, dstBuffer, dstBufferCapacity, toUpper);
}
else
{
TextInfoInterop.ChangeCaseJS(out exceptionMessage, _cultureName, src, srcLen, dstBuffer, dstBufferCapacity, toUpper);
}
if (!string.IsNullOrEmpty(exceptionMessage))
throw new Exception(exceptionMessage);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -682,11 +682,14 @@ private unsafe void ChangeCaseCore(char* src, int srcLen, char* dstBuffer, int d
if (GlobalizationMode.UseNls)
{
NlsChangeCase(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper);
return;
}
else
if (GlobalizationMode.Hybrid)
{
IcuChangeCase(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper);
JsChangeCase(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper);
return;
}
IcuChangeCase(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper);
}

// Used in ToTitleCase():
Expand Down
10 changes: 9 additions & 1 deletion src/mono/wasm/build/WasmApp.targets
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
- $(WasmProfilers) - Profilers to use
- $(AOTProfilePath) - profile data file to be used for profile-guided optimization
- $(InvariantGlobalization) - Whenever to disable ICU. Defaults to false.
- $(HybridGlobalization) - Whenever to enable reduced ICU + native platform functions. Defaults to false and can be set only for InvariantGlobalization=false, WasmIncludeFullIcuData=false and empty WasmIcuDataFileName.

- $(WasmResolveAssembliesBeforeBuild) - Resolve the assembly dependencies. Defaults to false
- $(WasmAssemblySearchPaths) - used for resolving assembly dependencies
Expand Down Expand Up @@ -71,7 +72,7 @@
- $(WasmEnableExceptionHandling) - Enable support for the WASM Exception Handling feature.
- $(WasmEnableSIMD) - Enable support for the WASM SIMD feature.
- $(WasmEnableWebcil) - Enable conversion of assembly .dlls to .webcil
- $(WasmIncludeFullIcuData) - Loads full ICU data (icudt.dat). Defaults to false. Only applicable when InvariantGlobalization=false.
- $(WasmIncludeFullIcuData) - Loads full ICU data (icudt.dat). Defaults to false. Only applicable when InvariantGlobalization=false.
- $(WasmIcuDataFileName) - Name/path of ICU globalization file loaded to app. Only when InvariantGloblization=false and WasmIncludeFullIcuData=false.
- $(WasmAllowUndefinedSymbols) - Controls whether undefined symbols are allowed or not,
if true, appends 'allow-undefined' and sets 'ERROR_ON_UNDEFINED_SYMBOLS=0' as arguments for wasm-ld,
Expand Down Expand Up @@ -327,6 +328,7 @@

<Target Name="_GetWasmGenerateAppBundleDependencies">
<PropertyGroup>
<HybridGlobalization Condition="'$(InvariantGlobalization)' == 'true'">false</HybridGlobalization>
ilonatommy marked this conversation as resolved.
Show resolved Hide resolved
<_HasDotnetWasm Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.wasm'">true</_HasDotnetWasm>
<_HasDotnetJsWorker Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.worker.js'">true</_HasDotnetJsWorker>
<_HasDotnetJsSymbols Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.js.symbols'">true</_HasDotnetJsSymbols>
Expand All @@ -335,6 +337,11 @@
<_WasmIcuDataFileName Condition="'$(WasmIcuDataFileName)' != '' and !Exists('$(WasmIcuDataFileName)')">$(MicrosoftNetCoreAppRuntimePackRidNativeDir)$(WasmIcuDataFileName)</_WasmIcuDataFileName>
</PropertyGroup>

<PropertyGroup Condition="'$(HybridGlobalization)' == 'true' and '$(WasmIcuDataFileName)' == ''">
<!-- to be renamed to icudt_wasm.dat when the contents of the file get defined and it gets added to repo -->
<_WasmIcuDataFileName>$(MicrosoftNetCoreAppRuntimePackRidNativeDir)icudt.dat</_WasmIcuDataFileName>
</PropertyGroup>

<ItemGroup>
<!-- If dotnet.{wasm,js} weren't added already (eg. AOT can add them), then add the default ones -->
<WasmNativeAsset Include="$(MicrosoftNetCoreAppRuntimePackRidNativeDir)dotnet.wasm" Condition="'$(_HasDotnetWasm)' != 'true'" />
Expand Down Expand Up @@ -383,6 +390,7 @@
RuntimeArgsForHost="@(WasmMonoRuntimeArgs)"
DefaultHostConfig="$(DefaultWasmHostConfig)"
InvariantGlobalization="$(InvariantGlobalization)"
HybridGlobalization="$(HybridGlobalization)"
SatelliteAssemblies="@(_WasmSatelliteAssemblies)"
FilesToIncludeInFileSystem="@(WasmFilesToIncludeInFileSystem)"
IcuDataFileNames="@(WasmIcuDataFileNames)"
Expand Down
6 changes: 6 additions & 0 deletions src/mono/wasm/runtime/corebindings.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ extern void mono_wasm_typed_array_from_ref (int ptr, int begin, int end, int byt
extern void* mono_wasm_invoke_js_blazor (MonoString **exceptionMessage, void *callInfo, void* arg0, void* arg1, void* arg2);
#endif /* ENABLE_LEGACY_JS_INTEROP */

// HybridGlobalization
extern void mono_wasm_change_case_invariant(MonoString **exceptionMessage, const uint16_t* src, int32_t srcLength, uint16_t* dst, int32_t dstLength, mono_bool bToUpper);
ilonatommy marked this conversation as resolved.
Show resolved Hide resolved
extern void mono_wasm_change_case(MonoString **exceptionMessage, MonoString **culture, const uint16_t* src, int32_t srcLength, uint16_t* dst, int32_t dstLength, mono_bool bToUpper);

void bindings_initialize_internals (void)
{
mono_add_internal_call ("System.Runtime.InteropServices.JavaScript.JSSynchronizationContext::ScheduleBackgroundJob", mono_threads_schedule_background_job);
Expand Down Expand Up @@ -69,4 +73,6 @@ void bindings_initialize_internals (void)
// Blazor specific custom routines - see dotnet_support.js for backing code
mono_add_internal_call ("WebAssembly.JSInterop.InternalCalls::InvokeJS", mono_wasm_invoke_js_blazor);
#endif /* ENABLE_LEGACY_JS_INTEROP */
mono_add_internal_call ("System.Globalization.TextInfoInterop::ChangeCaseInvariantJS", mono_wasm_change_case_invariant);
mono_add_internal_call ("System.Globalization.TextInfoInterop::ChangeCaseJS", mono_wasm_change_case);
}
1 change: 1 addition & 0 deletions src/mono/wasm/runtime/dotnet.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ interface AssetEntry extends ResourceRequest {
type AssetBehaviours = "resource" | "assembly" | "pdb" | "heap" | "icu" | "vfs" | "dotnetwasm" | "js-module-threads" | "symbols";
type GlobalizationMode = "icu" | // load ICU globalization data from any runtime assets with behavior "icu".
"invariant" | // operate in invariant globalization mode.
"hybrid" | // operate in hybrid globalization mode with small ICU files, using native platform functions
"auto";
type DotnetModuleConfig = {
disableDotnet6Compatibility?: boolean;
Expand Down
4 changes: 3 additions & 1 deletion src/mono/wasm/runtime/es6/dotnet.es6.lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ let linked_functions = [
"mono_wasm_invoke_import",
"mono_wasm_bind_cs_function",
"mono_wasm_marshal_promise",

"mono_wasm_change_case_invariant",
"mono_wasm_change_case",

"icudt68_dat",
];

Expand Down
4 changes: 3 additions & 1 deletion src/mono/wasm/runtime/exports-linker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { mono_wasm_typed_array_to_array_ref } from "./net6-legacy/js-to-cs";
import { mono_wasm_typed_array_from_ref } from "./net6-legacy/buffers";
import {
mono_wasm_invoke_js_blazor, mono_wasm_invoke_js_with_args_ref, mono_wasm_get_object_property_ref, mono_wasm_set_object_property_ref,
mono_wasm_get_by_index_ref, mono_wasm_set_by_index_ref, mono_wasm_get_global_object_ref
mono_wasm_get_by_index_ref, mono_wasm_set_by_index_ref, mono_wasm_get_global_object_ref, mono_wasm_change_case_invariant, mono_wasm_change_case
} from "./net6-legacy/method-calls";

// the methods would be visible to EMCC linker
Expand Down Expand Up @@ -93,6 +93,8 @@ export function export_linker(): any {
mono_wasm_invoke_import,
mono_wasm_bind_cs_function,
mono_wasm_marshal_promise,
mono_wasm_change_case_invariant,
mono_wasm_change_case,

// threading exports, if threading is enabled
...mono_wasm_threads_exports,
Expand Down
6 changes: 5 additions & 1 deletion src/mono/wasm/runtime/icu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,12 @@ export function init_globalization() {
}

const invariantEnv = "DOTNET_SYSTEM_GLOBALIZATION_INVARIANT";
const hybridEnv = "DOTNET_SYSTEM_GLOBALIZATION_HYBRID";
const env_variables = runtimeHelpers.config.environmentVariables!;
if (env_variables[invariantEnv] === undefined && runtimeHelpers.invariantMode) {
if (env_variables[hybridEnv] === undefined && runtimeHelpers.config.globalizationMode === "hybrid") {
env_variables[hybridEnv] = "1";
}
else if (env_variables[invariantEnv] === undefined && runtimeHelpers.invariantMode) {
ilonatommy marked this conversation as resolved.
Show resolved Hide resolved
env_variables[invariantEnv] = "1";
}
if (env_variables["TZ"] === undefined) {
Expand Down
59 changes: 57 additions & 2 deletions src/mono/wasm/runtime/net6-legacy/method-calls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { get_js_obj, mono_wasm_get_jsobj_from_js_handle } from "../gc-handles";
import { Module, runtimeHelpers, INTERNAL } from "../imports";
import { wrap_error_root, wrap_no_error_root } from "../invoke-js";
import { _release_temp_frame } from "../memory";
import { setU16, _release_temp_frame } from "../memory";
import { mono_wasm_new_external_root, mono_wasm_new_root } from "../roots";
import { find_entry_point } from "../run";
import { conv_string_root, js_string_to_mono_string_root } from "../strings";
Expand Down Expand Up @@ -296,4 +296,59 @@ export function mono_wasm_invoke_js_blazor(exceptionMessage: Int32Ptr, callInfo:
exceptionRoot.release();
return 0;
}
}
}

export function mono_wasm_change_case_invariant(exceptionMessage: Int32Ptr, src: number, srcLength: number, dst: number, dstLength: number, toUpper: boolean) : void{
ilonatommy marked this conversation as resolved.
Show resolved Hide resolved
try{
const input = get_uft16_string(src, srcLength);
ilonatommy marked this conversation as resolved.
Show resolved Hide resolved
let result = toUpper ? input.toUpperCase() : input.toLowerCase();
ilonatommy marked this conversation as resolved.
Show resolved Hide resolved
// Unicode defines some codepoints which expand into multiple codepoints,
// originally we do not support this expansion
if (result.length > dstLength)
result = input;

for (let i = 0; i < result.length; i++)
setU16(dst + i*2, result.charCodeAt(i));
}
catch (ex: any) {
pass_exception_details(ex, exceptionMessage);
}
}

export function mono_wasm_change_case(exceptionMessage: Int32Ptr, culture: MonoStringRef, src: number, srcLength: number, dst: number, destLength: number, toUpper: boolean) : void{
const cultureRoot = mono_wasm_new_external_root<MonoString>(culture);
try{
const cultureName = conv_string_root(cultureRoot);
if (!cultureName)
throw new Error("Cannot change case, the culture name is null.");
const input = get_uft16_string(src, srcLength);
let result = toUpper ? input.toLocaleUpperCase(cultureName) : input.toLocaleLowerCase(cultureName);
if (result.length > destLength)
result = input;

for (let i = 0; i < destLength; i++)
setU16(dst + i*2, result.charCodeAt(i));
}
catch (ex: any) {
pass_exception_details(ex, exceptionMessage);
}
finally {
cultureRoot.release();
}
}

function get_uft16_string(ptr: number, length: number): string{
const view = new Uint16Array(Module.HEAPU16.buffer, ptr, length);
let string = "";
for (let i = 0; i < length; i++)
string += String.fromCharCode(view[i]);
return string;
}

function pass_exception_details(ex: any, exceptionMessage: Int32Ptr){
const exceptionJsString = ex.message + "\n" + ex.stack;
const exceptionRoot = mono_wasm_new_root<MonoString>();
js_string_to_mono_string_root(exceptionJsString, exceptionRoot);
exceptionRoot.copy_to_address(<any>exceptionMessage);
exceptionRoot.release();
}
Loading