Skip to content

Commit

Permalink
Add external ArrayBuffers to JSI (#793)
Browse files Browse the repository at this point in the history
Summary:
X-link: facebook/hermes#793

Add a JSI API for constructing `ArrayBuffer`s from a user provided
`jsi::MutableBuffer`.

Changelog: [General][Added] Added ability to construct ArrayBuffers from existing memory buffers.

Reviewed By: jpporto

Differential Revision: D37744467

fbshipit-source-id: 9d9ece00d1dbde341846c45fa30c935b5fa81e9a
  • Loading branch information
neildhar authored and facebook-github-bot committed Aug 23, 2022
1 parent 49a2354 commit 3bae268
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 0 deletions.
7 changes: 7 additions & 0 deletions ReactCommon/jsi/JSCRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ class JSCRuntime : public jsi::Runtime {
jsi::Value lockWeakObject(jsi::WeakObject &) override;

jsi::Array createArray(size_t length) override;
jsi::ArrayBuffer createArrayBuffer(
std::shared_ptr<jsi::MutableBuffer> buffer) override;
size_t size(const jsi::Array &) override;
size_t size(const jsi::ArrayBuffer &) override;
uint8_t *data(const jsi::ArrayBuffer &) override;
Expand Down Expand Up @@ -1087,6 +1089,11 @@ jsi::Array JSCRuntime::createArray(size_t length) {
return createObject(obj).getArray(*this);
}

jsi::ArrayBuffer JSCRuntime::createArrayBuffer(
std::shared_ptr<jsi::MutableBuffer> buffer) {
throw std::logic_error("Not implemented");
}

size_t JSCRuntime::size(const jsi::Array &arr) {
return static_cast<size_t>(
getProperty(arr, createPropNameID(getLengthString())).getNumber());
Expand Down
8 changes: 8 additions & 0 deletions ReactCommon/jsi/jsi/decorator.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,10 @@ class RuntimeDecorator : public Base, private jsi::Instrumentation {
Array createArray(size_t length) override {
return plain_.createArray(length);
};
ArrayBuffer createArrayBuffer(
std::shared_ptr<MutableBuffer> buffer) override {
return plain_.createArrayBuffer(std::move(buffer));
};
size_t size(const Array& a) override {
return plain_.size(a);
};
Expand Down Expand Up @@ -701,6 +705,10 @@ class WithRuntimeDecorator : public RuntimeDecorator<Plain, Base> {
Around around{with_};
return RD::createArray(length);
};
ArrayBuffer createArrayBuffer(
std::shared_ptr<MutableBuffer> buffer) override {
return RD::createArrayBuffer(std::move(buffer));
};
size_t size(const Array& a) override {
Around around{with_};
return RD::size(a);
Expand Down
2 changes: 2 additions & 0 deletions ReactCommon/jsi/jsi/jsi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ Value callGlobalFunction(Runtime& runtime, const char* name, const Value& arg) {

Buffer::~Buffer() = default;

MutableBuffer::~MutableBuffer() = default;

PreparedJavaScript::~PreparedJavaScript() = default;

Value HostObject::get(Runtime&, const PropNameID&) {
Expand Down
21 changes: 21 additions & 0 deletions ReactCommon/jsi/jsi/jsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ class FBJSRuntime;
namespace facebook {
namespace jsi {

/// Base class for buffers of data or bytecode that need to be passed to the
/// runtime. The buffer is expected to be fully immutable, so the result of
/// size(), data(), and the contents of the pointer returned by data() must not
/// change after construction.
class JSI_EXPORT Buffer {
public:
virtual ~Buffer();
Expand All @@ -52,6 +56,18 @@ class JSI_EXPORT StringBuffer : public Buffer {
std::string s_;
};

/// Base class for buffers of data that need to be passed to the runtime. The
/// result of size() and data() must not change after construction. However, the
/// region pointed to by data() may be modified by the user or the runtime. The
/// user must ensure that access to the contents of the buffer is properly
/// synchronised.
class JSI_EXPORT MutableBuffer {
public:
virtual ~MutableBuffer();
virtual size_t size() const = 0;
virtual uint8_t* data() = 0;
};

/// PreparedJavaScript is a base class representing JavaScript which is in a
/// form optimized for execution, in a runtime-specific way. Construct one via
/// jsi::Runtime::prepareJavaScript().
Expand Down Expand Up @@ -336,6 +352,8 @@ class JSI_EXPORT Runtime {
virtual Value lockWeakObject(WeakObject&) = 0;

virtual Array createArray(size_t length) = 0;
virtual ArrayBuffer createArrayBuffer(
std::shared_ptr<MutableBuffer> buffer) = 0;
virtual size_t size(const Array&) = 0;
virtual size_t size(const ArrayBuffer&) = 0;
virtual uint8_t* data(const ArrayBuffer&) = 0;
Expand Down Expand Up @@ -915,6 +933,9 @@ class JSI_EXPORT ArrayBuffer : public Object {
ArrayBuffer(ArrayBuffer&&) = default;
ArrayBuffer& operator=(ArrayBuffer&&) = default;

ArrayBuffer(Runtime& runtime, std::shared_ptr<MutableBuffer> buffer)
: ArrayBuffer(runtime.createArrayBuffer(std::move(buffer))) {}

/// \return the size of the ArrayBuffer, according to its byteLength property.
/// (C++ naming convention)
size_t size(Runtime& runtime) const {
Expand Down

0 comments on commit 3bae268

Please sign in to comment.