Skip to content

Conversation

@tmikov
Copy link
Contributor

@tmikov tmikov commented Dec 20, 2025

Summary:
ECMAScript requires that builtin functions return "[native code]" from
toString(). Many libraries (e.g., Babel) check for this string to detect
builtins and alter their behavior accordingly.

Previously, JS-implemented builtins from InternalJavaScript and extensions
would return "[bytecode]" (since their source is not available), causing
these library heuristics to fail.

Add a new funcsAreBuiltins flag to RuntimeModuleFlags that causes
Function.prototype.toString() to return "[native code]" for all functions
in the module. Set the flag when loading internal bytecode and extensions
bytecode.

Subtle logic for InternalJavaScript (Promise):
The funcsAreBuiltins flag for InternalJavaScript is set conditionally based
on hasMicrotaskQueue(). This is intentional:

Some React Native versions detect whether to use the VM's microtask queue by
checking Promise.toString().includes("[native code]"). When microtask queue
is disabled but Promise still reports as "[native code]", RN incorrectly
assumes the engine queue is enabled and skips its own queue implementation.

By making funcsAreBuiltins conditional:

  • Microtask queue enabled: Promise shows "[native code]" (behaves like native)
  • Microtask queue disabled: Promise shows "[bytecode]" (RN uses its own queue)

This ensures the RN heuristic produces correct results.

Note: The hermes CLI defaults to microtask queue enabled, so existing tests
continue to pass without modification.

Extensions always have funcsAreBuiltins=true since they don't affect the
microtask queue detection logic.

Differential Revision: D89523668

Summary:
ECMAScript requires that builtin functions return "[native code]" from
toString(). Many libraries (e.g., Babel) check for this string to detect
builtins and alter their behavior accordingly.

Previously, JS-implemented builtins from InternalJavaScript and extensions
would return "[bytecode]" (since their source is not available), causing
these library heuristics to fail.

Add a new funcsAreBuiltins flag to RuntimeModuleFlags that causes
Function.prototype.toString() to return "[native code]" for all functions
in the module. Set the flag when loading internal bytecode and extensions
bytecode.

**Subtle logic for InternalJavaScript (Promise):**
The funcsAreBuiltins flag for InternalJavaScript is set conditionally based
on hasMicrotaskQueue(). This is intentional:

Some React Native versions detect whether to use the VM's microtask queue by
checking Promise.toString().includes("[native code]"). When microtask queue
is disabled but Promise still reports as "[native code]", RN incorrectly
assumes the engine queue is enabled and skips its own queue implementation.

By making funcsAreBuiltins conditional:
- Microtask queue enabled: Promise shows "[native code]" (behaves like native)
- Microtask queue disabled: Promise shows "[bytecode]" (RN uses its own queue)

This ensures the RN heuristic produces correct results.

Note: The hermes CLI defaults to microtask queue enabled, so existing tests
continue to pass without modification.

Extensions always have funcsAreBuiltins=true since they don't affect the
microtask queue detection logic.

Differential Revision: D89523668
@meta-cla meta-cla bot added the CLA Signed Do not delete this pull request or issue due to inactivity. label Dec 20, 2025
@meta-codesync
Copy link

meta-codesync bot commented Dec 20, 2025

@tmikov has exported this pull request. If you are a Meta employee, you can view the originating Diff in D89523668.

@meta-codesync
Copy link

meta-codesync bot commented Dec 22, 2025

This pull request has been merged in 79e312b.

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. fb-exported Merged meta-exported

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants