react-native-windows
react-native-windows copied to clipboard
"hello from 0.78".toLocaleUpperCase() returns "uppered" string
Problem Description
"hello from 0.78".toLocaleUpperCase() returns "uppered" string not "HELLO FROM 0.78" what i was expecting and is returned in RNW 0.77.
Steps To Reproduce
Create HelloWorld 0.78
npx @react-native-community/cli init hello078 --version "0.78.2"
cd hello078
yarn add [email protected]
npx react-native init-windows --overwrite --template old/uwp-cs-app
add logs into app
const localeHello = 'hello world 0.78'.toLocaleUpperCase();
const hello = 'hello world 0.78'.toUpperCase();
console.log({hello, localeHello});
and log is
LOG {"hello": "HELLO WORLD 0.78", "localeHello": "uppered"}
Expected Results
LOG {"hello": "HELLO WORLD 0.78", "localeHello": "HELLO WORLD 0.78"}
CLI version
15.0.1
Environment
info Fetching system and libraries information...
System:
OS: Windows 10 10.0.19045
CPU: (12) x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
Memory: 17.64 GB / 31.90 GB
Binaries:
Node:
version: 20.18.0
path: C:\Program Files\nodejs\node.EXE
Yarn:
version: 1.22.19
path: C:\Program Files (x86)\Yarn\bin\yarn.CMD
npm:
version: 10.8.2
path: C:\Program Files\nodejs\npm.CMD
Watchman: Not Found
SDKs:
Android SDK: Not Found
Windows SDK:
AllowDevelopmentWithoutDevLicense: Enabled
AllowAllTrustedApps: Enabled
Versions:
- 10.0.18362.0
- 10.0.19041.0
- 10.0.22000.0
- 10.0.22621.0
- 10.0.26100.0
IDEs:
Android Studio: Not Found
Visual Studio:
- 17.14.36202.13 (Visual Studio Community 2022)
Languages:
Java: Not Found
Ruby:
version: 2.6.1
path: C:\Ruby26-x64\bin\ruby.EXE
npmPackages:
"@react-native-community/cli":
installed: 15.0.1
wanted: 15.0.1
react:
installed: 19.0.0
wanted: 19.0.0
react-native:
installed: 0.78.2
wanted: 0.78.2
react-native-windows:
installed: 0.78.6
wanted: 0.78.6
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: true
iOS:
hermesEnabled: Not found
newArchEnabled: Not found
Community Modules
No response
Target Platform Version
None
Target Device(s)
No response
Visual Studio Version
None
Build Configuration
None
Snack, code example, screenshot, or link to a repository
No response
Hermes in RNW 0.78 HelloWorld
https://www.nuget.org/packages/Microsoft.JavaScript.Hermes/0.0.0-2505.2001-0e4bc3b9
"dependencies": {
"native,Version=v0.0": {
"Microsoft.JavaScript.Hermes": {
"type": "Direct",
"requested": "[0.0.0-2505.2001-0e4bc3b9, )",
"resolved": "0.0.0-2505.2001-0e4bc3b9",
"contentHash": "VNSUBgaGzJ/KkK3Br0b9FORkCgKqke54hi48vG42xRACIlxN+uLFMz0hRo+KHogz+Fsn+ltXicGwQsDVpmaCMg=="
},
Hermes in RNW 0.77 HelloWorld
https://www.nuget.org/packages/Microsoft.JavaScript.Hermes/0.1.23
"dependencies": {
"UAP,Version=v10.0.17763": {
"Microsoft.JavaScript.Hermes": {
"type": "Direct",
"requested": "[0.1.23, )",
"resolved": "0.1.23",
"contentHash": "cA9t1GjY4Yo0JD1AfA//e1lOwk48hLANfuX6GXrikmEBNZVr2TIX5ONJt5tqCnpZyLz6xGiPDgTfFNKbSfb21g=="
},
and no issue in RNW 0.77.
Related to this i think https://github.com/microsoft/hermes-windows/issues/136 even i do not understand why it worked in older Hermes on RNW 0.77.
// Not yet implemented. Tracked by // https://github.com/microsoft/hermes-windows/issues/87
https://github.com/microsoft/hermes-windows/blob/8e37c0d6307f34db27331312ab56840ce017e5c8/lib/Platform/Intl/PlatformIntlWindows.cpp#L235
I do not understand. Does RNW 0.77 has totally different Hermes (more than only older) than 0.78 or what is case? Why Hermes versioning changed so dramatically?
When testing console.log(String.prototype.toLocaleUpperCase.toString()); in RNW 0.77 and 0.78 both gives result as LOG function toLocaleUpperCase() { [native code] }, so both uses Hermes api for this call i think.
@TatianaKapos may have some idea what has happened between 0.77-0.78?
Wild idea is that convertCase is not anymore called in https://github.com/microsoft/hermes-windows/blob/8e37c0d6307f34db27331312ab56840ce017e5c8/lib/VM/JSLib/String.cpp#L971 because HERMES_ENABLE_INTL is enabled now.
Hi! Thanks for all this great information, I think you are definitely on the right track and saved us lots of time! :)
We turned on HERMES_ENABLE_INTL because there were asks for Intl's DatetimeFormat, I believe that was in 0.1.27. Currently 0.77 is on 0.1.23 and 0.78 is on 0.0.0-2505.2001-0e4bc3b9 (which is well past the date we turned HERMES_ENABLE_INTL on and includes a big jump on catching up our hermes version).
If you're getting "uppered" as a result, it's reaching that stub Intl method, which is wrong. In my mind that should only be reached from specifying Intl.toLocaleUpperCase. This is probably an easy fix of fixing the flag you linked above to still use the older version of toLocaleUpperCase until we implement the Intl version.
Tagging @vmoroz and @satkh as they are currently working on that project.
Workaround is to use a version of hermes < 1.27.0, I believe RNW 0.78.5 is on a lower version of hermes
Testing workaround
I had some challenges to get Hermes 0.1.26 to work with Hello World RNW 0.78 app.
I set <HermesVersion>0.1.26</HermesVersion> flag into into ExperimentalFeature.prop. Then i had to create new packages.lock.json file by calling nuget restore -forceEvaluate in NuGet Package Manager console.
I get error on Hello World app start Exception thrown at 0x0000000000000000 in hello078default.exe: 0xC0000005: Access violation executing location 0x0000000000000000.
0000000000000000() Unknown
> Microsoft.ReactNative.dll!Microsoft::NodeApiJsi::ApiFuncResolver<Microsoft::NodeApiJsi::JSRuntimeApi,enum napi_status (__cdecl*)(jsr_config_s *,bool),&Microsoft::NodeApiJsi::`anonymous namespace'::JSRuntimeApiNames::jsr_config_set_explicit_microtasks,952>::stub(jsr_config_s * <args_0>, bool <args_1>) Line 36 C++
Microsoft.ReactNative.dll!Microsoft::ReactNative::HermesRuntimeHolder::initRuntime() Line 328 C++
Microsoft.ReactNative.dll!Microsoft::ReactNative::HermesRuntimeHolder::getRuntime::__l2::<lambda_1>::operator()() Line 363 C++
[External Code]
Microsoft.ReactNative.dll!Microsoft::ReactNative::HermesRuntimeHolder::getRuntime() Line 363 C++
Microsoft.ReactNative.dll!facebook::react::`anonymous namespace'::OJSIExecutorFactory::createJSExecutor(std::shared_ptr<facebook::react::ExecutorDelegate> delegate, std::shared_ptr<facebook::react::MessageQueueThread> jsQueue) Line 232 C++
Microsoft.ReactNative.dll!facebook::react::NativeToJsBridge::NativeToJsBridge(facebook::react::JSExecutorFactory * jsExecutorFactory, std::shared_ptr<facebook::react::ModuleRegistry> registry, std::shared_ptr<facebook::react::MessageQueueThread> jsQueue, std::shared_ptr<facebook::react::InstanceCallback> callback) Line 114 C++
[External Code]
Microsoft.ReactNative.dll!facebook::react::Instance::initializeBridge::__l2::<lambda_1>::operator()() Line 63 C++
[External Code]
Microsoft.ReactNative.dll!Mso::React::MessageDispatchQueue::tryFunc(const std::function<void __cdecl(void)> & func) Line 41 C++
Microsoft.ReactNative.dll!Mso::React::MessageDispatchQueue::runOnQueueSync::__l2::<lambda_1>::operator()() Line 72 C++
Microsoft.ReactNative.dll!Mso::FunctorRef<void __cdecl(void)>::FunctorRefWrapper<`Mso::React::MessageDispatchQueue::runOnQueueSync'::`2'::<lambda_1>>::Invoke() Line 186 C++
Microsoft.ReactNative.dll!Mso::FunctorRef<void __cdecl(void)>::operator()() Line 158 C++
Microsoft.ReactNative.dll!Mso::React::MessageDispatchQueue::runSync::__l2::<lambda_1>::operator()() Line 56 C++
Microsoft.ReactNative.dll!Mso::DispatchTaskImpl<`Mso::React::MessageDispatchQueue::runSync'::`2'::<lambda_1>,`Mso::React::MessageDispatchQueue::runSync'::`2'::<lambda_2>>::Invoke() Line 748 C++
Microsoft.ReactNative.dll!Mso::QueueService::InvokeTask(Mso::Functor<void __cdecl(void)> && task, std::optional<std::chrono::time_point<std::chrono::steady_clock,std::chrono::duration<__int64,std::ratio<1,1000000000>>>> endTime) Line 206 C++
Microsoft.ReactNative.dll!Mso::LooperScheduler::RunLoop(const Mso::WeakPtr<Mso::LooperScheduler> & weakSelf) Line 57 C++
Microsoft.ReactNative.dll!Mso::LooperScheduler::{ctor}::__l1::<lambda_34_>::operator()() Line 37 C++
[External Code]
Crash on this line in HermesRuntimeHolder.cpp
CRASH_ON_ERROR(api.jsr_config_set_explicit_microtasks(
config,
facebook::react::ReactNativeFeatureFlags::enableBridgelessArchitecture() &&
!facebook::react::ReactNativeFeatureFlags::disableEventLoopOnBridgeless()));
Microtask game in with this PR https://github.com/microsoft/react-native-windows/issues/14133
"dependencies": {
"native,Version=v0.0": {
"Microsoft.JavaScript.Hermes": {
"type": "Direct",
"requested": "[0.1.26, )",
"resolved": "0.1.26",
"contentHash": "PmcQPrKiSuZ0qKBcy2aUdzafeSxQmamnZCVX5J8Dkpc3Bjfaas/ED4zWOZBzJBnggBN4bEbowcq1guDPDP75/w=="
},
Hello World build and start with this <HermesVersion>0.0.0-2506.4001-8e37c0d6</HermesVersion> latest Hermes but there is still the toLocaleUpperCase issue . I cannot get it to run on older Hermes.
https://www.nuget.org/packages/Microsoft.JavaScript.Hermes/0.0.0-2506.4001-8e37c0d6
There's a mismatch between the local RNW implementations and what's in the upstream Hermes implementation. What's available upstream should be more comprehensive by this point. We need someone to look at the difference and navigate the differences.
Believe the string "uppered" is coming from this: https://github.com/microsoft/hermes-windows/blob/8e37c0d6307f34db27331312ab56840ce017e5c8/lib/Platform/Intl/PlatformIntlDummy.cpp#L32
@vineethkuttan, Vlad says you have some context on this and might be looking at it. Assigning this to you.
Look into the flag Tatiana mentioned to help understand why this might have changed 77 to 78:
If you're getting "uppered" as a result, it's reaching that stub Intl method, which is wrong. In my mind that should only be reached from specifying
Intl.toLocaleUpperCase. This is probably an easy fix of fixing the flag you linked above to still use the older version oftoLocaleUpperCaseuntil we implement the Intl version.
Issue is in hermes-windows https://github.com/microsoft/hermes-windows/issues not in react-native-windows. Should issue be created to hermes-windows to get fixed soon?
EDIT: https://github.com/microsoft/hermes-windows/issues/244
I think that we are forced to use RNW 0.77.x because it is last release that use working Hermes. Newer RNW versions uses newer Hermes where HERMES_ENABLE_INTL flag is enabled and it then uses some mock functions.
Some mocks now in use:
https://github.com/microsoft/hermes-windows/blob/8e37c0d6307f34db27331312ab56840ce017e5c8/lib/Platform/Intl/PlatformIntlWindows.cpp#L235
https://github.com/microsoft/hermes-windows/blob/8e37c0d6307f34db27331312ab56840ce017e5c8/lib/Platform/Intl/PlatformIntlWindows.cpp#L226
https://github.com/microsoft/hermes-windows/blob/8e37c0d6307f34db27331312ab56840ce017e5c8/lib/Platform/Intl/PlatformIntlWindows.cpp#L254
https://github.com/microsoft/hermes-windows/blob/8e37c0d6307f34db27331312ab56840ce017e5c8/lib/Platform/Intl/PlatformIntlWindows.cpp#L1011
and what else that new flag does...
@sreehari-rajan