Skip to content

Backport new JSI improvements #1988

Merged
tsaichien merged 21 commits intofacebook:250829098.0.0-stablefrom
tsaichien:jsi-improvements
Apr 16, 2026
Merged

Backport new JSI improvements #1988
tsaichien merged 21 commits intofacebook:250829098.0.0-stablefrom
tsaichien:jsi-improvements

Conversation

@tsaichien
Copy link
Copy Markdown
Contributor

@tsaichien tsaichien commented Apr 15, 2026

Summary

Cherry pick 21 commits from static_h branch to support the JSI
IRuntime interface and add new JSI features for user ergonomics.

Test Plan

GHA

@meta-cla meta-cla bot added the CLA Signed Do not delete this pull request or issue due to inactivity. label Apr 15, 2026
… JSArrayBuffer

Summary:
Add a few new API for `ArrayBuffer` serialization and deserialization

Specially:
*  `getExternalDataContext`: for external buffers, get the Native State
context of the external data block. This allows the data lifetime to be
shared with the Serialized object via shared ptr
* `createWithInternalDataBlock`: creates `JSArrayBuffer` with a data
block. If there is an existing data attached, detach from it and replace
with the provided buffer.

Used in next serialization diff to deserialize JSArrayBuffers with
internal data blocks.

Reviewed By: fbmal7, dannysu

Differential Revision: D79815362

fbshipit-source-id: 9bdec5a0c365ae305f37c4f216b80396704fbf67
Summary:
Declare `arrayFastPathCheck` in `JSLib.h` so that it can be shared
between `Array.cpp` and `hermes.cpp`

This will be used for the `Array.push` API fast path, so that pushing
elements into an Array through JSI will have the same performance as it
does in JS.

Reviewed By: avp

Differential Revision: D83614548

fbshipit-source-id: 052f0114286cdaa504b01118a74eeb370a90608f
Summary:
X-link: facebook/react-native#56410

Missed when we first added the `ISerialization` interface. In JSI APIs,
`Value` is generally passed in as a const reference. This makes it clear
that the actual reference, not the referent, is const.

Fixing the serialization methods to be consistent with the rest of JSI.

Changelog: [Internal]

Reviewed By: lavenzg

Differential Revision: D100222030

fbshipit-source-id: 2297d5c89b90db51269d216e6c3a822d9a4a93ab
Summary:
X-link: facebook/react-native#54923

After reviewing the feasibility of adding new Runtime functionality, we
realized the current state of `Runtime` makes it hard/inconvenient to
add new basic functionality. It requires creating a new interface (e.g.
`IRuntime2`) to declare the new APIs. Then, everywhere it is needed,
both the original `Runtime` and `IRuntime2` needs to passed in to access
both APIs.

After discussion, we decided to introduce `IRuntime`, which will declare
most of the `Runtime` functionalities. All "protected" APIs, which made
sense before interfaces were introduced, will now be public. The
protected static methods of `Runtime` will remain as is for the Friends
to access.

After we decided to cut "stable" (after incoming JSI improvements), new
functionalities will be added in `IRuntime2` interface. `IRuntime2` will
inherit `IRuntime` to make existing functionality easy to access.

Changelog: [Internal]

Reviewed By: lavenzg

Differential Revision: D89093651

fbshipit-source-id: a4cbfc30b79986aec2db4c2dba3045ee59083de2
Summary:
X-link: facebook/react-native#53762

Currently, the size of a jsi `Array` is immutable. Once the `Array` is
created, users can only set the element at an existing index, but not
append to it.

This change adds an `Array::push` API to improve ergonomics.
The default implementation is also provided in `jsi::Runtime`

Changelog: [Internal]

Reviewed By: lavenzg

Differential Revision: D82254334

fbshipit-source-id: 8d963adce3a1d41894949f87c3dbebaeeaeff5bd
@tsaichien tsaichien force-pushed the jsi-improvements branch 2 times, most recently from 56e9c2d to 301725f Compare April 16, 2026 00:03
Summary:
Adds SynthTrace support for the JSI API `Array.push` so its calls can be
recorded and replayed.

Reviewed By: lavenzg

Differential Revision: D82284888

fbshipit-source-id: cdea585e800c3d6d382299891e9f9ce54449b23d
Summary:
X-link: facebook/react-native#56156

X-link: facebook/react-native#55943

Adds `ArrayBuffer::tryGetMutableBuffer` to JSI. This allows the user to
retrieve a `MutableBuffer` from the `ArrayBuffer`. The returned buffer
will point directly into the same buffer as the runtime object, rather than
copying it out.

The data referencedby the `MutableBuffer` will be alive during the entirety
 of the `MutableBuffer` lifespan.

Addresses: facebook#1578

Changelog: [Internal]

Reviewed By: tmikov

Differential Revision: D91264901

fbshipit-source-id: 7edd66adae16551b64222c834d3fc211f7c88622
Summary: Implements `ArrayBuffer::tryGetMutableBuffer` for Hermes.

Reviewed By: tmikov

Differential Revision: D91264902

fbshipit-source-id: 367e74e7155318069c11b6743117f195ab8b1dd4
Summary:
X-link: facebook/react-native#55944

Add a `ArrayBuffer::detached` method that returns true if the
ArrayBuffer is detached, false otherwise.

Default implementation just checks for the `detached` property

Changelog: [Internal]

Reviewed By: lavenzg

Differential Revision: D92993088

fbshipit-source-id: 77d7055ddc35c21e915915daa2415b44017f81bb
Summary: Implement `ArrayBuffer.detached` method for SH.

Reviewed By: lavenzg

Differential Revision: D92994677

fbshipit-source-id: b92678c65a1568828db75fccbdc617262fd0bf2b
Summary:
X-link: facebook/react-native#56158

Add TypedArray and Uint8Array types to JSI with supporting APIs.

New types:
- `TypedArray`: Base class for all typed arrays
- `Uint8Array`: Uint8Array type extending TypedArray

New IRuntime APIs:
- `getBuffer(TypedArray)`: Get underlying ArrayBuffer
- `getByteOffset(TypedArray)`: Get byte offset property
- `getByteLength(TypedArray)`: Get byte length property
- `getLength(TypedArray)`: Get length property
- `createUint8Array(size_t)`: Create Uint8Array with length
- `createUint8Array(ArrayBuffer, offset, length)`: Create from
  ArrayBuffer
- `isUint8Array(Object)`: Check if object is Uint8Array

Changelog: [Internal]

Reviewed By: lavenzg

Differential Revision: D95245175

fbshipit-source-id: 33e7f5d9de42bfcc0b7a57c681fdd73711c2bb13
Summary:
Implement Hermes runtime support for Uint8Array in the JSI API.

- Add HermesRuntimeImpl implementations for createUint8Array(length),
  createUint8Array(buffer, offset, length), buffer(typedArray),
  byteOffset(typedArray), byteLength(typedArray), length(typedArray),
  and isUint8Array(object).
- Add typed-array handle plumbing via typedArrayHandle.
- Ensure Uint8Array creation from an existing ArrayBuffer preserves
  offset/length metadata and backing-buffer identity.

Reviewed By: lavenzg

Differential Revision: D95245177

fbshipit-source-id: e77fe009bbd26cbd513a90a65a01eafcfe638cfc
Summary:
X-link: facebook/react-native#56159

Add Error creation APIs to JSI to allow native code to create JavaScript
Error objects of all standard types.

Users can also call the static methods in `JSError` that creates a
`JSError` instance that holds the intended error type.

Changelog: [Internal]

Reviewed By: lavenzg

Differential Revision: D95854323

fbshipit-source-id: ec473caad527bfd6c92b1ef2562b8bf41942dd5a
Summary:
Implement the JSI Error creation APIs for Hermes runtime.

Add HermesRuntimeImpl implementations for all standard JavaScript error types:
- createError: Creates a generic Error object
- createEvalError: Creates an EvalError object
- createRangeError: Creates a RangeError object
- createReferenceError: Creates a ReferenceError object
- createSyntaxError: Creates a SyntaxError object
- createTypeError: Creates a TypeError object
- createURIError: Creates a URIError object

Each implementation uses vm::JSError::create with the appropriate error
prototype from the runtime, records a stack trace, and sets the message
property.

Reviewed By: lavenzg

Differential Revision: D95860376

fbshipit-source-id: b0c9aeb17b02ad66c536a3a5f0419e423daebd23
Summary:
Add SynthTrace support for the createError APIs to enable tracing and
replay of JavaScript Error object creation.

New types and records:
- JSErrorType enum class: Represents the 7 standard JS error types
  (Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError,
  URIError)
- CreateJSErrorRecord: Records error creation with object ID, error type,
  and message string ID

Implementation:
- TracingRuntime: Override all 7 createError methods to emit
  CreateJSErrorRecord
- SynthTrace: Add toJSONInternal serialization for CreateJSErrorRecord
- SynthTraceParser: Add parsing support for CreateJSError record type
- TraceInterpreter: Add replay support to recreate errors during trace
  replay

Reviewed By: lavenzg

Differential Revision: D95977774

fbshipit-source-id: 308a4777564a8c3ce5a6294d33c11a79bd4f6c6e
Summary:
X-link: facebook/react-native#56160

Add a JSI API to get the length of a JavaScript string in UTF-16 code
units. This is equivalent to the "length" property of a JS string.

New API:
- `IRuntime::length(const String&)`: Returns the number of UTF-16 code
  units in the string.

Default implementation:
The default implementation in `jsi::Runtime` calls `utf16()` then
returns the size. Note that the default `utf16()` implementation first
converts the JS string to UTF-8, then converts that to UTF-16. This
intermediate UTF-8 step does not handle lone surrogates correctly,
causing code units to be "lost" in the conversion. Runtimes should
provide optimized implementations when possible.

The following optimized implementations are provided:

JSC implementation:
Uses the `JSStringGetLength` API for efficient retrieval.

V8 implementation:
Uses the `v8::String::Length()` API for efficient retrieval.

Changelog: [Internal]

Reviewed By: avp

Differential Revision: D96030262

fbshipit-source-id: acb0404a68c5bccbcdab5c5acdcfb65c3d991d82
Summary:
Implement the `String::length` JSI API for Hermes runtime.

The implementation uses `StringPrimitive::getStringLength()` to
directly retrieve the UTF-16 code unit count from the Hermes VM,
providing an efficient alternative to the default JSI implementation.

Reviewed By: avp

Differential Revision: D96164189

fbshipit-source-id: 4e212302056cb9244e8b5cfdecd13987780de0cc
Summary:
X-link: facebook/react-native#56161

Add a `isInteger` method under `jsi::Value` that returns true iff
`Number.isInteger` returns true.

This can be implemented without relying on the Runtime.

Changelog: [Internal]

Reviewed By: lavenzg

Differential Revision: D96175707

fbshipit-source-id: af482ae512ffc53f18c1686dd8a2a95521d0bc59
@tsaichien tsaichien merged commit 67a8f55 into facebook:250829098.0.0-stable Apr 16, 2026
26 checks passed
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