facebook / hermes

A JavaScript engine optimized for running React Native.
https://hermesengine.dev/
MIT License
9.71k stars 622 forks source link

top-level await not supported #1481

Open wcandillon opened 1 month ago

wcandillon commented 1 month ago

Bug Description

The following JS file parses correctly in v8: https://firebasestorage.googleapis.com/v0/b/start-react-native.appspot.com/o/three.webgpu.js?alt=media&token=af0f4434-e789-43cd-89a9-8996fa9e534d With Hermes, it throws the following syntax error:

./bin/hermes three.webgpu.js
three.webgpu.js:36252:22: error: unexpected token after assignment expression
        isAvailable = await navigator.gpu.requestAdapter();

I assume that this means that the await syntax is not supported by Hermes?

tmikov commented 1 month ago

It is supported. To confirm, I just ran this:

$ cat test.js
async function foo() {
    isAvailable = await navigator.gpu.requestAdapter();
}

print(foo());

$ hermes test.js
[object Object]
tmikov commented 1 month ago

Looking at the link, this is top level await from ES2022. Hermes does not support that yet.

wcandillon commented 1 month ago

should this issue stay open until it is support or is this tracked somewhere else?

tmikov commented 1 month ago

@wcandillon, unfortunately, the situation is more complex than it appears. Top-level await is not just a syntactic feature; it fundamentally alters how the module system operates. It tightly integrates with the module system, requiring the event loop to run during module initialization. Moreover, any module that transitively depends on an async module becomes implicitly asynchronous. This change is a very very big deal.

In React Native apps, the module system isn't provided by Hermes but by Metro or another packager, meaning it operates outside of the JavaScript VM. This separation makes native support for top-level await in React Native much more challenging, if not impossible.

For Hermes to support top-level await, it would need to include its own packaging system and effectively replace the functionality of existing packagers like Metro, which would dramatically change the React Native build process. This impacts far more than just Hermes.

I hope this clarifies why we haven't added support for top-level await yet. It's difficult to justify prioritizing something that currently can't be utilized in practice.

For additional context, Hermes previously included its own module system, but due to lack of adoption, we eventually removed it.

With all of that said, we will implement top-level await, because it is required to unleash the optimization power of Static Hermes.