facebook / hermes

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

Partial async generator support present in Hermes isn't spec compliant #1380

Closed leotm closed 2 weeks ago

leotm commented 3 weeks ago

Bug Description

Hermes git revision (if applicable): hermes-2023-03-07-RNv0.71.4-ee25883ea34374f687883a641c8101ac0d292fc6 React Native version: 71.17 OS: Android (running on macOS) Platform (most likely one of arm64-v8a, armeabi-v7a, x86, x86_64): arm64-v8a

Steps To Reproduce

Attempt to access async iterator proto

code example:

async function* AsyncGeneratorFunctionInstance() {}
const AsyncGeneratorFunction = Object.getPrototypeOf(
  AsyncGeneratorFunctionInstance,
).constructor
const AsyncGenerator = AsyncGeneratorFunction.prototype;

const asyncIterable = {
  async *[Symbol.asyncIterator]() {},
};
var results = [
  typeof asyncIterable[Symbol.asyncIterator].prototype.__proto__ === 'object', // it's an object even in Hermes, but looks a different shape
  typeof AsyncGenerator.prototype, // undefined on hermes
  asyncIterable[Symbol.asyncIterator].prototype.__proto__ === AsyncGenerator.prototype, // true in other engines
  asyncIterable[Symbol.asyncIterator].prototype.__proto__.__proto__ // null in Hermes, object with an iterator fn in other engines
];

// Node 18.18.2
// console.log(Object.getOwnPropertyDescriptors(asyncIterable[Symbol.asyncIterator].prototype.__proto__.__proto__))
// {
//   [Symbol(Symbol.asyncIterator)]: {
//     value: [Function: [Symbol.asyncIterator]],
//     writable: true,
//     enumerable: false,
//     configurable: true
//   }
// }

throw JSON.stringify(results);

The Expected Behavior

Other engines: [true,"object",true,{}] Hermes: [true,"undefined",false,null]

tmikov commented 2 weeks ago

Sorry, Hermes has no async iterator support at the moment (though we will add it to Static Hermes). I think you are essentially testing a Babel transformation.

leotm commented 2 weeks ago

thanks for clarifying ^ and great news it will be in Static Hermes 🎉

my mistaken assumption was node_modules/react-native/Libraries/Core/InitializeCore.js is running Babel-free

for anyone else to run in the React Native environment w/o Babel you could

new Function('{var}', String.raw`
  // my code (should be same result as Hermes CLI/REPL)
`)({var: 1});

or the usual way

// babel.config.js
module.exports = {
  ignore: [/myFile\.cjs/],
  presets: ['module:metro-react-native-babel-preset'],
};

or outside the React Native environment, directly via the Hermes CLI or building the static_h branch for latest

otherwise yes in this example we can see inspecting the bundle Babel transforms with few helpers

coming from various transform plugins in the preset

Babel REPL example with preset: here