facebook / hermes

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

Importing files suppress `async generators are unsupported` errors #1389

Closed leotm closed 1 week ago

leotm commented 2 weeks ago

Bug Description

Hermes suppresses async generators are unsupported errors in imported files

https://github.com/facebook/hermes/blob/7991309805159967d2b045fbe722f1aad2d43409/lib/AST/SemanticValidator.cpp#L798-L800

OS: Android, iOS Platform : arm64-v8a (macOS, M2)

Steps To Reproduce

npx react-native@latest init RN07119 --version 0.71.19

npx react-native@latest init RN07214 --version 0.72.14

// file.cjs
async function* foo() {
  yield await Promise.resolve('a');
  yield await Promise.resolve('b');
  yield await Promise.resolve('c'); // remove this yield to see error in sim/emu
};
function bar() {}; // remove this fn to see error in sim/emu

// Try this example wrapped in a new Function(String.raw``)() to see error

// Hot reload any change to see error in Metro
// [Error: Exception in HostFunction: Compiling JS failed: 2:3:async generators are unsupported Buffer size 665 starts with: 5f5f642866756e6374696f6e2028676c]
// babel.config.js
module.exports = {
  ignore: [/file\.cjs/],
  presets: ['module:metro-react-native-babel-preset'],
};
// e.g. index.js, App.tsx, node_modules/react-native/Libraries/Core/InitializeCore.js
require('./file.cjs');

The Expected Behavior

Error async generators are unsupported (Android, iOS)

tmikov commented 2 weeks ago

I am not sure I understand the problem. What are "imported files"?

Hermes, in the way it is currently used by React Native, has no concept of modules or imported files. It sees a single source file that has been transformed by Babel and packaged by Metro. If that file contains async generators, Hermes will report an error.

leotm commented 1 week ago

i see ^ i mean files ignored by Babel, required or imported like

simple cases (stripping part of the example) report the Hermes error correctly to sim/emu but more complex usage (full example, or ses.cjs) doesn't unless e.g. called in a new Function(String.raw``)() which is strange

leotm commented 1 week ago

good point i suppose it's not Hermes side, since Metro hot reload outputs correctly to console [Error: Exception in HostFunction: Compiling JS failed: 2:3:async generators are unsupported Buffer size 665 starts with: 5f5f642866756e6374696f6e2028676c] so Hermes reports the single source file error correctly to Metro each change also https://github.com/facebook/hermes/commit/8239e82977410dc7dfdaa5432549e98e5e6b19f2 hasn't changed in nearly a year

i'll close here to fix either RN side or Metro side since the bug is failing to propagate the Hermes error to sim/emu with beyond simple usage of async generators

leotm commented 1 week ago

also Metro doesn't fail with the Hermes error during bundling when requiring our example file.cjs ./gradlew :app:installDebug or ./gradlew :app:installRelease both modes bundle ok

but e.g. adding var test = foo; to reference the unsupported async generator causes the release bundling to fail, correctly outputting the Hermes error async generators are unsupported

Hermes, in the way it is currently used by React Native, has no concept of modules or imported files. It sees a single source file that has been transformed by Babel and packaged by Metro. If that file contains async generators, Hermes will report an error.

since defining an async generator fn alone (no var to reference it) should be enough for Hermes to recognise it in the source file and report an error (despite being unused)

looks like another Metro bug? since both debug and release bundling should be failing with a defined async generator in the source file