mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Lazily instantiate native modules
Summary: Instead of sending a list of modules over to JS on startup (and actually blocking script execution) instead provide a proxy object that constructs each of these lazily. Reviewed By: lexs Differential Revision: D3936979 fbshipit-source-id: 71bde822f01eb17a29f56c5e60e95e98e207d74d
This commit is contained in:
committed by
Facebook Github Bot
parent
606fc11487
commit
9ed9bca0bf
@@ -20,6 +20,7 @@
|
||||
#include "Platform.h"
|
||||
#include "SystraceSection.h"
|
||||
#include "Value.h"
|
||||
#include "JSCNativeModules.h"
|
||||
#include "JSCSamplingProfiler.h"
|
||||
#include "JSModulesUnbundle.h"
|
||||
#include "ModuleRegistry.h"
|
||||
@@ -79,6 +80,28 @@ inline JSObjectCallAsFunctionCallback exceptionWrapMethod() {
|
||||
return &funcWrapper::call;
|
||||
}
|
||||
|
||||
template<JSValueRef (JSCExecutor::*method)(JSObjectRef object, JSStringRef propertyName)>
|
||||
inline JSObjectGetPropertyCallback exceptionWrapMethod() {
|
||||
struct funcWrapper {
|
||||
static JSValueRef call(
|
||||
JSContextRef ctx,
|
||||
JSObjectRef object,
|
||||
JSStringRef propertyName,
|
||||
JSValueRef *exception) {
|
||||
try {
|
||||
auto globalObj = JSContextGetGlobalObject(ctx);
|
||||
auto executor = static_cast<JSCExecutor*>(JSObjectGetPrivate(globalObj));
|
||||
return (executor->*method)(object, propertyName);
|
||||
} catch (...) {
|
||||
*exception = translatePendingCppExceptionToJSError(ctx, object);
|
||||
return JSValueMakeUndefined(ctx);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return &funcWrapper::call;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
@@ -109,28 +132,15 @@ JSCExecutor::JSCExecutor(std::shared_ptr<ExecutorDelegate> delegate,
|
||||
m_delegate(delegate),
|
||||
m_deviceCacheDir(cacheDir),
|
||||
m_messageQueueThread(messageQueueThread),
|
||||
m_nativeModules(delegate->getModuleRegistry()),
|
||||
m_jscConfig(jscConfig) {
|
||||
initOnJSVMThread();
|
||||
|
||||
SystraceSection s("setBatchedBridgeConfig");
|
||||
|
||||
folly::dynamic nativeModuleConfig = folly::dynamic::array();
|
||||
|
||||
{
|
||||
SystraceSection s("collectNativeModuleNames");
|
||||
for (auto& name : delegate->getModuleRegistry()->moduleNames()) {
|
||||
nativeModuleConfig.push_back(folly::dynamic::array(std::move(name)));
|
||||
}
|
||||
SystraceSection s("nativeModuleProxy object");
|
||||
installGlobalProxy(m_context, "nativeModuleProxy",
|
||||
exceptionWrapMethod<&JSCExecutor::getNativeModule>());
|
||||
}
|
||||
|
||||
folly::dynamic config =
|
||||
folly::dynamic::object
|
||||
("remoteModuleConfig", std::move(nativeModuleConfig));
|
||||
|
||||
SystraceSection t("setGlobalVariable");
|
||||
setGlobalVariable(
|
||||
"__fbBatchedBridgeConfig",
|
||||
folly::make_unique<JSBigStdString>(folly::toJson(config)));
|
||||
}
|
||||
|
||||
JSCExecutor::JSCExecutor(
|
||||
@@ -146,6 +156,7 @@ JSCExecutor::JSCExecutor(
|
||||
m_owner(owner),
|
||||
m_deviceCacheDir(owner->m_deviceCacheDir),
|
||||
m_messageQueueThread(messageQueueThread),
|
||||
m_nativeModules(delegate->getModuleRegistry()),
|
||||
m_jscConfig(jscConfig) {
|
||||
// We post initOnJSVMThread here so that the owner doesn't have to wait for
|
||||
// initialization on its own thread
|
||||
@@ -211,7 +222,6 @@ void JSCExecutor::initOnJSVMThread() throw(JSException) {
|
||||
// Add a pointer to ourselves so we can retrieve it later in our hooks
|
||||
JSObjectSetPrivate(JSContextGetGlobalObject(m_context), this);
|
||||
|
||||
installNativeHook<&JSCExecutor::nativeRequireModuleConfig>("nativeRequireModuleConfig");
|
||||
installNativeHook<&JSCExecutor::nativeFlushQueueImmediate>("nativeFlushQueueImmediate");
|
||||
installNativeHook<&JSCExecutor::nativeCallSyncHook>("nativeCallSyncHook");
|
||||
|
||||
@@ -264,6 +274,8 @@ void JSCExecutor::terminateOnJSVMThread() {
|
||||
terminateOwnedWebWorker(workerId);
|
||||
}
|
||||
|
||||
m_nativeModules.reset();
|
||||
|
||||
JSGlobalContextRelease(m_context);
|
||||
m_context = nullptr;
|
||||
}
|
||||
@@ -647,6 +659,14 @@ void JSCExecutor::installNativeHook(const char* name) {
|
||||
installGlobalFunction(m_context, name, exceptionWrapMethod<method>());
|
||||
}
|
||||
|
||||
JSValueRef JSCExecutor::getNativeModule(JSObjectRef object, JSStringRef propertyName) {
|
||||
if (JSStringIsEqualToUTF8CString(propertyName, "name")) {
|
||||
return Value(m_context, String("NativeModules"));
|
||||
}
|
||||
|
||||
return m_nativeModules.getModule(m_context, propertyName);
|
||||
}
|
||||
|
||||
JSValueRef JSCExecutor::nativePostMessage(
|
||||
size_t argumentCount,
|
||||
const JSValueRef arguments[]) {
|
||||
@@ -680,18 +700,6 @@ JSValueRef JSCExecutor::nativeRequire(
|
||||
return JSValueMakeUndefined(m_context);
|
||||
}
|
||||
|
||||
JSValueRef JSCExecutor::nativeRequireModuleConfig(
|
||||
size_t argumentCount,
|
||||
const JSValueRef arguments[]) {
|
||||
if (argumentCount != 1) {
|
||||
throw std::invalid_argument("Got wrong number of args");
|
||||
}
|
||||
|
||||
std::string moduleName = Value(m_context, arguments[0]).toString().str();
|
||||
folly::dynamic config = m_delegate->getModuleRegistry()->getConfig(moduleName);
|
||||
return Value::fromDynamic(m_context, config);
|
||||
}
|
||||
|
||||
JSValueRef JSCExecutor::nativeFlushQueueImmediate(
|
||||
size_t argumentCount,
|
||||
const JSValueRef arguments[]) {
|
||||
|
||||
Reference in New Issue
Block a user