Skip to content

Commit

Permalink
Add Hermes implementation for Object.getPrototypeOf and Object.setPro…
Browse files Browse the repository at this point in the history
…totypeOf

Summary:
Adds the implementation of the JSI methods `getPrototypeOf` and
`setPrototypeOf` for Hermes runtime.

Grafted from 9ff82875b3f0e1fba452358d52a83936d81404e9 (D66729169)
- Grafted path xplat/static_h to xplat/hermes

Reviewed By: tmikov

Differential Revision: D67412931

fbshipit-source-id: a29d60fe3c7ee12ecf9326f748707d34fc548916
  • Loading branch information
tsaichien authored and facebook-github-bot committed Jan 9, 2025
1 parent c995d19 commit 9f0b77f
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
30 changes: 30 additions & 0 deletions API/hermes/hermes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,10 @@ class HermesRuntimeImpl final : public HermesRuntime,
bool isHostFunction(const jsi::Function &) const override;
jsi::Array getPropertyNames(const jsi::Object &) override;

void setPrototypeOf(const jsi::Object &object, const jsi::Value &prototype)
override;
jsi::Value getPrototypeOf(const jsi::Object &object) override;

jsi::WeakObject createWeakObject(const jsi::Object &) override;
jsi::Value lockWeakObject(const jsi::WeakObject &) override;

Expand Down Expand Up @@ -2018,6 +2022,32 @@ void HermesRuntimeImpl::setExternalMemoryPressure(
ns->setContext(reinterpret_cast<void *>(amt));
}

void HermesRuntimeImpl::setPrototypeOf(
const jsi::Object &object,
const jsi::Value &prototype) {
if (!prototype.isObject() && !prototype.isNull()) {
throw jsi::JSError(
*this, "Object prototype argument must be an Object or null");
}

auto cr = vm::JSObject::setParent(
vm::vmcast<vm::JSObject>(phv(object)),
runtime_,
vm::dyn_vmcast<vm::JSObject>(hvFromValue(prototype)),
vm::PropOpFlags().plusThrowOnError());
checkStatus(cr.getStatus());
}

jsi::Value HermesRuntimeImpl::getPrototypeOf(const jsi::Object &object) {
vm::CallResult<vm::PseudoHandle<vm::JSObject>> cr =
vm::JSObject::getPrototypeOf(handle(object), runtime_);
checkStatus(cr.getStatus());
if (!*cr) {
return jsi::Value::null();
}
return valueFromHermesValue(cr->getHermesValue());
}

jsi::Value HermesRuntimeImpl::getProperty(
const jsi::Object &obj,
const jsi::String &name) {
Expand Down
20 changes: 20 additions & 0 deletions unittests/API/APITest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,26 @@ TEST_P(HermesRuntimeTest, GetPropNameIdDataTest) {
buf.clear();
}

TEST_P(HermesRuntimeTest, SetPrototypeOf) {
Object prototypeObj(*rt);
prototypeObj.setProperty(*rt, "someProperty", 123);
Value prototype(*rt, prototypeObj);

Object child(*rt);
child.setPrototype(*rt, prototype);
EXPECT_EQ(child.getProperty(*rt, "someProperty").getNumber(), 123);

auto getPrototypeRes = child.getPrototype(*rt).asObject(*rt);
EXPECT_EQ(getPrototypeRes.getProperty(*rt, "someProperty").getNumber(), 123);

// Tests null value as prototype
child.setPrototype(*rt, Value::null());
EXPECT_TRUE(child.getPrototype(*rt).isNull());

// Throw when prototype is neither an Object nor null
EXPECT_THROW(child.setPrototype(*rt, Value(1)), JSError);
}

INSTANTIATE_TEST_CASE_P(
Runtimes,
HermesRuntimeTest,
Expand Down

0 comments on commit 9f0b77f

Please sign in to comment.