Skip to content

Commit

Permalink
Add API for setting/getting native state
Browse files Browse the repository at this point in the history
Summary:
Add API for setting/getting native state.

When present, the internal NativeState property of an object always stores a NativeState with a pointer to a heap-allocated shared_ptr + a finalizer that simply `delete`s it.

Changelog:
[Internal][Added] - JSI API for setting/getting native state on a JS object

Reviewed By: jpporto

Differential Revision: D36499239

fbshipit-source-id: a1ff1905811db1aac99ece3f928b81d0abfb342b
  • Loading branch information
kodafb authored and facebook-github-bot committed Jul 18, 2022
1 parent 639daf8 commit 6179233
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 0 deletions.
21 changes: 21 additions & 0 deletions ReactCommon/jsi/JSCRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ class JSCRuntime : public jsi::Runtime {
const jsi::Object &) override;
jsi::HostFunctionType &getHostFunction(const jsi::Function &) override;

bool hasNativeState(const jsi::Object &) override;
std::shared_ptr<jsi::NativeState> getNativeState(
const jsi::Object &) override;
void setNativeState(const jsi::Object &, std::shared_ptr<jsi::NativeState>)
override;

jsi::Value getProperty(const jsi::Object &, const jsi::String &name) override;
jsi::Value getProperty(const jsi::Object &, const jsi::PropNameID &name)
override;
Expand Down Expand Up @@ -862,6 +868,21 @@ std::shared_ptr<jsi::HostObject> JSCRuntime::getHostObject(
return metadata->hostObject;
}

bool JSCRuntime::hasNativeState(const jsi::Object &) {
throw std::logic_error("Not implemented");
}

std::shared_ptr<jsi::NativeState> JSCRuntime::getNativeState(
const jsi::Object &) {
throw std::logic_error("Not implemented");
}

void JSCRuntime::setNativeState(
const jsi::Object &,
std::shared_ptr<jsi::NativeState>) {
throw std::logic_error("Not implemented");
}

jsi::Value JSCRuntime::getProperty(
const jsi::Object &obj,
const jsi::String &name) {
Expand Down
11 changes: 11 additions & 0 deletions ReactCommon/jsi/jsi/decorator.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,17 @@ class RuntimeDecorator : public Base, private jsi::Instrumentation {
return dhf.target<DecoratedHostFunction>()->plainHF_;
};

bool hasNativeState(const Object& o) override {
return plain_.hasNativeState(o);
}
std::shared_ptr<NativeState> getNativeState(const Object& o) override {
return plain_.getNativeState(o);
}
void setNativeState(const Object& o, std::shared_ptr<NativeState> state)
override {
plain_.setNativeState(o, state);
}

Value getProperty(const Object& o, const PropNameID& name) override {
return plain_.getProperty(o, name);
};
Expand Down
18 changes: 18 additions & 0 deletions ReactCommon/jsi/jsi/jsi-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,24 @@ inline std::shared_ptr<HostObject> Object::getHostObject<HostObject>(
return runtime.getHostObject(*this);
}

template <typename T>
inline bool Object::hasNativeState(Runtime& runtime) const {
return runtime.hasNativeState(*this) &&
std::dynamic_pointer_cast<T>(runtime.getNativeState(*this));
}

template <typename T>
inline std::shared_ptr<T> Object::getNativeState(Runtime& runtime) const {
assert(hasNativeState<T>(runtime));
return std::static_pointer_cast<T>(runtime.getNativeState(*this));
}

inline void Object::setNativeState(
Runtime& runtime,
std::shared_ptr<NativeState> state) const {
runtime.setNativeState(*this, state);
}

inline Array Object::getPropertyNames(Runtime& runtime) const {
return runtime.getPropertyNames(*this);
}
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 @@ -81,6 +81,8 @@ void HostObject::set(Runtime& rt, const PropNameID& name, const Value&) {

HostObject::~HostObject() {}

NativeState::~NativeState() {}

Runtime::~Runtime() {}

Instrumentation& Runtime::instrumentation() {
Expand Down
32 changes: 32 additions & 0 deletions ReactCommon/jsi/jsi/jsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,13 @@ class JSI_EXPORT HostObject {
virtual std::vector<PropNameID> getPropertyNames(Runtime& rt);
};

/// Native state (and destructor) that can be attached to any JS object
/// using setNativeState.
class JSI_EXPORT NativeState {
public:
virtual ~NativeState();
};

/// Represents a JS runtime. Movable, but not copyable. Note that
/// this object may not be thread-aware, but cannot be used safely from
/// multiple threads at once. The application is responsible for
Expand Down Expand Up @@ -296,6 +303,12 @@ class JSI_EXPORT Runtime {
virtual std::shared_ptr<HostObject> getHostObject(const jsi::Object&) = 0;
virtual HostFunctionType& getHostFunction(const jsi::Function&) = 0;

virtual bool hasNativeState(const jsi::Object&) = 0;
virtual std::shared_ptr<NativeState> getNativeState(const jsi::Object&) = 0;
virtual void setNativeState(
const jsi::Object&,
std::shared_ptr<NativeState> state) = 0;

virtual Value getProperty(const Object&, const PropNameID& name) = 0;
virtual Value getProperty(const Object&, const String& name) = 0;
virtual bool hasProperty(const Object&, const PropNameID& name) = 0;
Expand Down Expand Up @@ -711,6 +724,25 @@ class JSI_EXPORT Object : public Pointer {
template <typename T = HostObject>
std::shared_ptr<T> asHostObject(Runtime& runtime) const;

/// \return whether this object has native state of type T previously set by
/// \c setNativeState.
template <typename T = NativeState>
bool hasNativeState(Runtime& runtime) const;

/// \return a shared_ptr to the state previously set by \c setNativeState.
/// If \c hasNativeState<T> is false, this will assert. Note that this does a
/// type check and will assert if the native state isn't of type \c T
template <typename T = NativeState>
std::shared_ptr<T> getNativeState(Runtime& runtime) const;

/// Set the internal native state property of this object, overwriting any old
/// value. Creates a new shared_ptr to the object managed by \p state, which
/// will live until the value at this property becomes unreachable.
///
/// Throws a type error if this object is a proxy or host object.
void setNativeState(Runtime& runtime, std::shared_ptr<NativeState> state)
const;

/// \return same as \c getProperty(name).asObject(), except with
/// a better exception message.
Object getPropertyAsObject(Runtime& runtime, const char* name) const;
Expand Down

0 comments on commit 6179233

Please sign in to comment.