Skip to content

Fix async arrow non simple params bug#2030

Open
micleo2 wants to merge 1 commit into
facebook:250829098.0.0-stablefrom
micleo2:async-fix-250829098.0.0-stable
Open

Fix async arrow non simple params bug#2030
micleo2 wants to merge 1 commit into
facebook:250829098.0.0-stablefrom
micleo2:async-fix-250829098.0.0-stable

Conversation

@micleo2

@micleo2 micleo2 commented May 21, 2026

Copy link
Copy Markdown
Contributor

Summary:
Add missing logic in async arrow functions for non simple parameters. This logic is copied over from the existing codepath in genBasicFunction.

Reviewed By: avp

Differential Revision: D81596715

fbshipit-source-id: ac3accf710f3d32db24743674e590700beb18bb0

Summary:
Add missing logic in async arrow functions for non simple parameters.
This logic is copied over from the existing codepath in
`genBasicFunction`.

Reviewed By: avp

Differential Revision: D81596715

fbshipit-source-id: ac3accf710f3d32db24743674e590700beb18bb0
@meta-cla meta-cla Bot added the CLA Signed Do not delete this pull request or issue due to inactivity. label May 21, 2026
ramonclaudio added a commit to ramonclaudio/react-native that referenced this pull request Jun 3, 2026
## Summary:

Three Babel plugins added to `@react-native/babel-preset` that work
around runtime codegen bugs in the bundled Hermes V1 (250829098.0.13,
branch cut 2025-08-29) by rewriting source patterns before they reach
the engine. Each plugin papers over a different bug that is fixed on
Hermes `static_h` but has not been backported to the V1 stable branch
(verified absent through the .0.15 stable tip; the only in-flight graft,
facebook/hermes#2030, is still open).

- `fix-hermes-v1-async-arrow-non-simple-params`:
  facebook/hermes#1761 (fixed in static_h by 68bfb3a48b31, 2025-09-11).
  Async arrow functions with destructured, defaulted, or rest parameters
  silently resolve `await` with `undefined` while the function body
  continues executing in the background. The plugin rewrites the params
  to a simple identifier with inline destructuring so Hermes never sees
  the buggy shape. Gated on `isHermesProfile && preserveAsync` since
  `plugin-transform-async-to-generator` rewrites the pattern away when
  `preserveAsync` is false.

- `fix-hermes-v1-class-in-finally`:
  Fixed in static_h by 1e94fbe0ebb4 (2026-02-12). Class declarations
  inside a `finally` block trip Hermes V1's variable caching path. The
  plugin wraps them in an IIFE so the class lives in its own scope, and
  preserves the inferred name of a class expression bound to a plain
  identifier.

- `fix-hermes-v1-super-in-object-accessor`:
  Fixed in static_h by 18a963465944 (2025-11-04). Object-literal getters
  and setters using `super.x` trip the `genFunctionExpression` home
  object path, which segfaults hermesc at compile time. The plugin marks
  the accessor as computed with a string key, covering identifier,
  string, and numeric keys.

All three gate on `isHermesProfile` and bail out fast on the common
case. The plugins are a direct port of work by @kitten (Phil Pluckthun,
Expo team) in `babel-preset-expo` (expo/expo#45601, MIT licensed). All
plugin design and implementation credit belongs to him. This PR carries
his work over to `@react-native/babel-preset` so bare React Native
consumers benefit from the same fix.

## Changelog:

[GENERAL] [FIXED] - Work around three Hermes V1 source-level codegen bugs in `@react-native/babel-preset` (async-arrow non-simple params, class-in-finally, super-in-object-accessor)

## Test Plan:

- 21 inline-snapshot test cases across three new test files verify the transformed output, the fast-bail behavior on irrelevant patterns, and the numeric-key and class-name edge cases.
- `yarn jest packages/react-native-babel-preset` clean (76 tests, 27 snapshots).
- Full repo `yarn test` clean (278 suites, 5692 tests passed, 1857 snapshots).
- `yarn lint`, `yarn format-check`, `yarn flow-check`, `yarn test-typescript`, `yarn featureflags --verify-unchanged`, `yarn build-types --validate` all clean.
- Existing `transform-snapshot-test` passes byte-identical: the kitchen-sink fixture has none of the buggy patterns so the new plugins do not change its output for any profile.
- Compiled the bug patterns through the bundled compiler (hermes-compiler 250829098.0.14): `get x() { return super.x }` and `get 0() { return super.x }` both segfault hermesc, while the transformed computed-key output compiles clean.
- Device repro at ramonclaudio/hermes-1761-repro: 55/55 PASS on iPhone 17 Pro / iOS 26.5 in Debug and Release.

## Caveats:

`fix-hermes-v1-class-in-finally` rewrites block-scoped `class`
declarations inside `finally` blocks to function-scoped `var`
initializers, matching the babel-preset-expo source. Observable only
when code in the same `finally` references the class before its
declaration or relies on its block scoping (rare). The same plugin shape
has shipped in `babel-preset-expo` and Expo SDK 56 without reported
regressions, but flagging in case Meta's internal test fleet surfaces an
edge case the OSS suite does not catch.

## References:

- facebook/hermes#1761 (root-cause issue, fixed in static_h)
- facebook/hermes#2030 (in-flight graft of the async-arrow fix onto the V1 stable branch, still open)
- expo/expo#45601 (source of the ported plugins, by @kitten)
- expo/expo#45592 (user-facing bug report on SDK 56 preview)

Co-authored-by: Phil Pluckthun <phil@kitten.sh>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed Do not delete this pull request or issue due to inactivity.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant