Skip to content

Commit 257f036

Browse files
tsaichienmeta-codesync[bot]
authored andcommitted
Add ISerialization interface (#52624)
Summary: Pull Request resolved: #52624 Add a new optional interface `ISerialization` to JSI. This interface contains four APIs to clone objects from one runtime to another runtime. Four methods are introduced in this interface: * `serialize`: Takes in a JS value (represented by `jsi::Value`) and serialize the value into an opaque `Serialized` object. * `deserialize`: Takes in the `Serialized` object created by `serialize` and deserialize it into the runtime, returning the created JS value. * `serializeWithTransfer`: Takes in a JS value (represented by `jsi::Value`) and a `transferList` (a `jsi::Array` of `jsi::Value`s). This will serialize the `value` into an opaque `Serialize` object and transfer the ownership of everything in `transferList` into the `Serialized` object. If any non-transferable values is passed into the transferList, this will throw. This `Serialized` object must only be deserialized once. * `deserializeWithTransfer`: Takes in the `Serialized` object created by `serializeWithTransfer`. It will deserialize the object into the runtime and any value owned by the `Serialized` object will now be owned by the current runtime. It will return an `jsi::Array` where the first value is the deserialized value passed into `serializeWithTransfer`, followed by all transferred values. The lifetime of the `Serialized` object created from the APIs is independent of the original object and runtime. Note that objects can only be copied into another runtime instance of the same type. For example, a serialized object produced by the Hermes runtime can only be deserialized by another Hermes runtime. Changelog: [Internal] Reviewed By: dannysu, fbmal7 Differential Revision: D76547681 fbshipit-source-id: 0c774f3f469c26d3894cac179f4ce5e32cf5ad7f
1 parent 064a385 commit 257f036

2 files changed

Lines changed: 70 additions & 0 deletions

File tree

packages/react-native/ReactCommon/jsi/jsi/jsi.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,10 @@ HostObject::~HostObject() {}
284284

285285
NativeState::~NativeState() {}
286286

287+
#ifdef JSI_UNSTABLE
288+
Serialized::~Serialized() {}
289+
#endif
290+
287291
Runtime::~Runtime() {}
288292

289293
ICast* Runtime::castInterface(const UUID& /*interfaceUUID*/) {

packages/react-native/ReactCommon/jsi/jsi/jsi.h

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,72 @@ class JSI_EXPORT NativeState {
257257
// the future. Until released, these features may be subject to change. After
258258
// release, these features will be moved out of JSI_UNSTABLE and become frozen.
259259
#ifdef JSI_UNSTABLE
260+
/// Opaque class that is used to store serialized object from a runtime. The
261+
/// lifetime of this object is orthogonal to the original runtime object, and
262+
/// may outlive the original object.
263+
class JSI_EXPORT Serialized {
264+
public:
265+
/// Uses \p secretAddr to validate if the Serialized data is supported. If so,
266+
/// return the pointer to the underlying serialized data. Otherwise, return a
267+
/// nullptr. This should be used by the runtime to deserialize the data.
268+
virtual void* getPrivate(const void* secretAddr) = 0;
269+
virtual ~Serialized();
270+
};
271+
272+
/// Provides a set of APIs that allows copying objects between different
273+
/// runtime instances. The runtimes instances must be of the same type. As an
274+
/// example, a serialized object from Hermes runtime may only be deserialized by
275+
/// another Hermes runtime.
276+
class JSI_EXPORT ISerialization : public ICast {
277+
public:
278+
static constexpr jsi::UUID uuid{
279+
0xd40fe0ec,
280+
0xa47c,
281+
0x42c9,
282+
0x8c09,
283+
0x661aeab832d8};
284+
285+
/// Serializes the given Value \p value using the structured clone algorithm.
286+
/// It returns a shared pointer of an opaque Serialized object that can be
287+
/// deserialized multiple times. The lifetime of the Serialized object is not
288+
/// tied to the lifetime of the original object.
289+
virtual std::shared_ptr<Serialized> serialize(Value& value) = 0;
290+
291+
/// Given a Serialized object provided by \p serialized, deserialize it using
292+
/// the structured clone algorithm into a JS value in the current runtime.
293+
/// Returns the deserialized JS value.
294+
virtual Value deserialize(const std::shared_ptr<Serialized>& serialized) = 0;
295+
296+
/// Serializes the given jsi::Value \p value using the structured clone
297+
/// algorithm. \p transferList must be a JS Array. Given the length property
298+
/// of \p transferList, this API will transfer everything at index [0, length
299+
/// - 1] to the serialized object. The transferred values will no longer be
300+
/// usable in the original runtime. It returns a unique pointer of an opaque
301+
/// Serialized object that can be deserialized once only by
302+
/// deserializeWithTransfer. The lifetime of the Serialized object is not tied
303+
/// to the lifetime of the original object.
304+
virtual std::unique_ptr<Serialized> serializeWithTransfer(
305+
Value& value,
306+
const Array& transferList) = 0;
307+
308+
/// Using the structure clone algorithm, deserialize the object provided by \p
309+
/// serialized into a JS value in the current runtime. \p serialized must be
310+
/// created by serializeWithTransfer. If the current runtime does not support
311+
/// the serialization scheme in \p serialized, then this method will throw and
312+
/// \p serialized will remain unmodified. Otherwise, this will consume the
313+
/// serialized data entirely and make the serialized objects in the current
314+
/// runtime. Any transferred values in the serialized object will be owned by
315+
/// the current runtime.
316+
// This method returns an Array containing the deserialized values, where the
317+
// first element is the value passed into serializeWithTransfer,
318+
/// followed by all transferred values.
319+
virtual Array deserializeWithTransfer(
320+
std::unique_ptr<Serialized>& serialized) = 0;
321+
322+
protected:
323+
~ISerialization() = default;
324+
};
325+
260326
#endif // JSI_UNSTABLE
261327

262328
/// Represents a JS runtime. Movable, but not copyable. Note that

0 commit comments

Comments
 (0)