From 99c370959aa03688689960ef88098f8301091d52 Mon Sep 17 00:00:00 2001 From: Marc Horowitz Date: Tue, 4 Dec 2018 11:42:24 -0800 Subject: [PATCH] Don't create the JSCRuntime until createJSExecutor() is called. Summary: This avoids an intermittent reentrancy bug in JSC on iOS 11 (https://bugs.webkit.org/show_bug.cgi?id=186827). It also makes the code more consistent with android. Reviewed By: amnn Differential Revision: D13313265 fbshipit-source-id: f42476b2f660e127ecfc9c72584554817eea1010 --- React/CxxBridge/RCTCxxBridge.mm | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index 6ecfe14ac..2e0c6ff40 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -56,7 +56,6 @@ static NSString *const RCTJSThreadName = @"com.facebook.react.JavaScript"; typedef void (^RCTPendingCall)(); -using namespace facebook::jsc; using namespace facebook::jsi; using namespace facebook::react; @@ -92,6 +91,24 @@ private: std::shared_ptr factory_; }; +class JSCExecutorFactory : public JSExecutorFactory { +public: + std::unique_ptr createJSExecutor( + std::shared_ptr delegate, + std::shared_ptr jsQueue) override { + return folly::make_unique( + facebook::jsc::makeJSCRuntime(), + delegate, + [](const std::string &message, unsigned int logLevel) { + _RCTLogJavaScriptInternal( + static_cast(logLevel), + [NSString stringWithUTF8String:message.c_str()]); + }, + JSIExecutor::defaultTimeoutInvoker, + nullptr); + } +}; + } static bool isRAMBundle(NSData *script) { @@ -320,13 +337,7 @@ struct RCTInstanceCallback : public InstanceCallback { executorFactory = [cxxDelegate jsExecutorFactoryForBridge:self]; } if (!executorFactory) { - executorFactory = std::make_shared( - makeJSCRuntime(), - [](const std::string &message, unsigned int logLevel) { - _RCTLogJavaScriptInternal( - static_cast(logLevel), - [NSString stringWithUTF8String:message.c_str()]); - }, nullptr); + executorFactory = std::make_shared(); } } else { id objcExecutor = [self moduleForClass:self.executorClass];