mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Make JS Representation cache all TurboModule properties (#36625)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/36625 ## Context Previously, jsRepresentation would only cache the **HostFunctions** returned from TurboModule::createHostFunction(). ## Changes This diff replaces TurboModule::createHostFunction() with TurboModule::create(). Now, jsRepresentation will cache **all** the **properties** returned from TurboModule::create(). ## Motivation For interop modules, constants will be exported as properties on the TurboModule HostObject. This diff allows those constants (which are non HostFunctions) to be cached. Changelog: [Internal] Reviewed By: javache Differential Revision: D44253229 fbshipit-source-id: d3dd042f4ccb6c076b83503f3712e4d1609388ce
This commit is contained in:
committed by
Facebook GitHub Bot
parent
70239629e4
commit
51893c4e9f
@@ -15,21 +15,6 @@ TurboModule::TurboModule(
|
||||
std::shared_ptr<CallInvoker> jsInvoker)
|
||||
: name_(std::move(name)), jsInvoker_(std::move(jsInvoker)) {}
|
||||
|
||||
jsi::Value TurboModule::createHostFunction(
|
||||
jsi::Runtime &runtime,
|
||||
const jsi::PropNameID &propName,
|
||||
const MethodMetadata &meta) {
|
||||
return jsi::Function::createFromHostFunction(
|
||||
runtime,
|
||||
propName,
|
||||
static_cast<unsigned int>(meta.argCount),
|
||||
[this, meta](
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &thisVal,
|
||||
const jsi::Value *args,
|
||||
size_t count) { return meta.invoker(rt, *this, args, count); });
|
||||
}
|
||||
|
||||
void TurboModule::emitDeviceEvent(
|
||||
jsi::Runtime &runtime,
|
||||
const std::string &eventName,
|
||||
|
||||
+30
-20
@@ -48,22 +48,15 @@ class JSI_EXPORT TurboModule : public facebook::jsi::HostObject {
|
||||
facebook::jsi::Runtime &runtime,
|
||||
const facebook::jsi::PropNameID &propName) override {
|
||||
{
|
||||
std::string propNameUtf8 = propName.utf8(runtime);
|
||||
auto p = methodMap_.find(propNameUtf8);
|
||||
if (p == methodMap_.end()) {
|
||||
// Method was not found, let JS decide what to do.
|
||||
return facebook::jsi::Value::undefined();
|
||||
} else {
|
||||
auto moduleMethod = createHostFunction(runtime, propName, p->second);
|
||||
// If we have a JS wrapper, cache the result of this lookup
|
||||
// We don't cache misses, to allow for methodMap_ to dynamically be
|
||||
// extended
|
||||
if (jsRepresentation_) {
|
||||
jsRepresentation_->lock(runtime).asObject(runtime).setProperty(
|
||||
runtime, propName, moduleMethod);
|
||||
}
|
||||
return moduleMethod;
|
||||
auto prop = create(runtime, propName);
|
||||
// If we have a JS wrapper, cache the result of this lookup
|
||||
// We don't cache misses, to allow for methodMap_ to dynamically be
|
||||
// extended
|
||||
if (jsRepresentation_ && !prop.isUndefined()) {
|
||||
jsRepresentation_->lock(runtime).asObject(runtime).setProperty(
|
||||
runtime, propName, prop);
|
||||
}
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,15 +104,32 @@ class JSI_EXPORT TurboModule : public facebook::jsi::HostObject {
|
||||
const std::string &eventName,
|
||||
ArgFactory argFactory = nullptr);
|
||||
|
||||
virtual jsi::Value create(
|
||||
jsi::Runtime &runtime,
|
||||
const jsi::PropNameID &propName) {
|
||||
std::string propNameUtf8 = propName.utf8(runtime);
|
||||
auto p = methodMap_.find(propNameUtf8);
|
||||
if (p == methodMap_.end()) {
|
||||
// Method was not found, let JS decide what to do.
|
||||
return facebook::jsi::Value::undefined();
|
||||
} else {
|
||||
const MethodMetadata &meta = p->second;
|
||||
return jsi::Function::createFromHostFunction(
|
||||
runtime,
|
||||
propName,
|
||||
static_cast<unsigned int>(meta.argCount),
|
||||
[this, meta](
|
||||
jsi::Runtime &rt,
|
||||
const jsi::Value &thisVal,
|
||||
const jsi::Value *args,
|
||||
size_t count) { return meta.invoker(rt, *this, args, count); });
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
friend class TurboCxxModule;
|
||||
friend class TurboModuleBinding;
|
||||
std::unique_ptr<jsi::WeakObject> jsRepresentation_;
|
||||
|
||||
facebook::jsi::Value createHostFunction(
|
||||
facebook::jsi::Runtime &runtime,
|
||||
const facebook::jsi::PropNameID &propName,
|
||||
const MethodMetadata &meta);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+20
-5
@@ -138,6 +138,13 @@ jsi::Value TurboModuleBinding::getModule(
|
||||
return jsi::Object::createFromHostObject(runtime, std::move(module));
|
||||
}
|
||||
|
||||
// What is jsRepresentation? A cache for the TurboModule's properties
|
||||
// Henceforth, always return the cache (i.e: jsRepresentation) to JavaScript
|
||||
//
|
||||
// If a jsRepresentation is found on the TurboModule, return it.
|
||||
//
|
||||
// Note: TurboModules are cached by name in TurboModuleManagers. Hence,
|
||||
// jsRepresentation is also cached by by name by the TurboModuleManager
|
||||
auto &weakJsRepresentation = module->jsRepresentation_;
|
||||
if (weakJsRepresentation) {
|
||||
auto jsRepresentation = weakJsRepresentation->lock(runtime);
|
||||
@@ -146,20 +153,28 @@ jsi::Value TurboModuleBinding::getModule(
|
||||
}
|
||||
}
|
||||
|
||||
// No JS representation found, or object has been collected
|
||||
// Status: No jsRepresentation found on TurboModule
|
||||
// Create a brand new jsRepresentation, and attach it to TurboModule
|
||||
jsi::Object jsRepresentation(runtime);
|
||||
weakJsRepresentation =
|
||||
std::make_unique<jsi::WeakObject>(runtime, jsRepresentation);
|
||||
|
||||
if (bindingMode_ == TurboModuleBindingMode::Prototype) {
|
||||
// Option 1: create plain object, with it's prototype mapped back to the
|
||||
// hostobject. Any properties accessed are stored on the plain object
|
||||
// Option 1: Lazily populate the jsRepresentation, on property access.
|
||||
//
|
||||
// How does this work?
|
||||
// 1. Initially jsRepresentation is empty: {}
|
||||
// 2. If property lookup on jsRepresentation fails, the JS runtime will
|
||||
// search jsRepresentation's prototype: jsi::Object(TurboModule).
|
||||
// 3. TurboModule::get(runtime, propKey) executes. This creates the
|
||||
// property, caches it on jsRepresentation, then returns it to
|
||||
// JavaScript.
|
||||
auto hostObject =
|
||||
jsi::Object::createFromHostObject(runtime, std::move(module));
|
||||
jsRepresentation.setProperty(runtime, "__proto__", std::move(hostObject));
|
||||
} else {
|
||||
// Option 2: eagerly install all hostfunctions at this point, avoids
|
||||
// prototype
|
||||
// Option 2: Eagerly populate the jsRepresentation, on create.
|
||||
// Object.assign(jsRepresentation, jsi::Object(TurboModule))
|
||||
for (auto &propName : module->getPropertyNames(runtime)) {
|
||||
module->get(runtime, propName);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user