react-native-windows icon indicating copy to clipboard operation
react-native-windows copied to clipboard

"hello from 0.78".toLocaleUpperCase() returns "uppered" string

Open tero-paananen opened this issue 5 months ago • 9 comments
trafficstars

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

tero-paananen avatar Jun 05 '25 10:06 tero-paananen

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.

tero-paananen avatar Jun 05 '25 10:06 tero-paananen

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.

tero-paananen avatar Jun 05 '25 11:06 tero-paananen

// 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?

tero-paananen avatar Jun 05 '25 11:06 tero-paananen

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.

tero-paananen avatar Jun 06 '25 11:06 tero-paananen

@TatianaKapos may have some idea what has happened between 0.77-0.78?

tero-paananen avatar Jun 06 '25 11:06 tero-paananen

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.

tero-paananen avatar Jun 06 '25 11:06 tero-paananen

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

TatianaKapos avatar Jun 06 '25 20:06 TatianaKapos

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

tero-paananen avatar Jun 09 '25 06:06 tero-paananen

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 of toLocaleUpperCase until we implement the Intl version.

chrisglein avatar Jun 09 '25 17:06 chrisglein

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

tero-paananen avatar Jul 28 '25 09:07 tero-paananen

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...

tero-paananen avatar Sep 01 '25 12:09 tero-paananen

@sreehari-rajan

vineethkuttan avatar Sep 02 '25 06:09 vineethkuttan