diff --git a/RNTester/Podfile.lock b/RNTester/Podfile.lock
index 85013c176d71b7..85de4e30cae5d0 100644
--- a/RNTester/Podfile.lock
+++ b/RNTester/Podfile.lock
@@ -236,6 +236,7 @@ PODS:
- glog
- React-callinvoker (= 1000.0.0)
- React-jsinspector (= 1000.0.0)
+ - React-runtimeexecutor (= 1000.0.0)
- React-jsi (1000.0.0):
- boost-for-react-native (= 1.63.0)
- DoubleConversion
@@ -318,6 +319,8 @@ PODS:
- React-Core/RCTVibrationHeaders (= 1000.0.0)
- React-jsi (= 1000.0.0)
- ReactCommon/turbomodule/core (= 1000.0.0)
+ - React-runtimeexecutor (1000.0.0):
+ - React-jsi (= 1000.0.0)
- ReactCommon/turbomodule/core (1000.0.0):
- DoubleConversion
- Folly (= 2020.01.13.00)
@@ -388,6 +391,7 @@ DEPENDENCIES:
- React-RCTTest (from `./RCTTest`)
- React-RCTText (from `../Libraries/Text`)
- React-RCTVibration (from `../Libraries/Vibration`)
+ - React-runtimeexecutor (from `../ReactCommon/runtimeexecutor`)
- ReactCommon/turbomodule/core (from `../ReactCommon`)
- ReactCommon/turbomodule/samples (from `../ReactCommon`)
- Yoga (from `../ReactCommon/yoga`)
@@ -462,6 +466,8 @@ EXTERNAL SOURCES:
:path: "../Libraries/Text"
React-RCTVibration:
:path: "../Libraries/Vibration"
+ React-runtimeexecutor:
+ :path: "../ReactCommon/runtimeexecutor"
ReactCommon:
:path: "../ReactCommon"
Yoga:
@@ -491,7 +497,7 @@ SPEC CHECKSUMS:
React-callinvoker: 0dada022d38b73e6e15b33e2a96476153f79bbf6
React-Core: 08c69f013e6fd654ea8f9fd84bbd66780a54d886
React-CoreModules: d13d148c851af5780f864be74bc2165140923dc7
- React-cxxreact: 091da030e879ed93d970e95dd74fcbacb2a1d661
+ React-cxxreact: b43a94e679b307660de530a3af872ab4c7d9925d
React-jsi: fe94132da767bfc4801968c2a12abae43e9a833e
React-jsiexecutor: 55eff40b2e0696e7a979016e321793ec8b28a2ac
React-jsinspector: 7fbf9b42b58b02943a0d89b0ba9fff0070f2de98
@@ -506,6 +512,7 @@ SPEC CHECKSUMS:
React-RCTTest: cfe25fcf70b04a747dba4326105db398250caa9a
React-RCTText: 6c01963d3e562109f5548262b09b1b2bc260dd60
React-RCTVibration: d42d73dafd9f63cf758656ee743aa80c566798ff
+ React-runtimeexecutor: 60dd6204a13f68a1aa1118870edcc604a791df2b
ReactCommon: 39e00b754f5e1628804fab28f44146d06280f700
Yoga: f7fa200d8c49f97b54c9421079e781fb900b5cae
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java
index f95b974e30d064..1a5067b7edb358 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java
@@ -99,14 +99,18 @@ public interface CatalystInstance
void setGlobalVariable(String propName, String jsonValue);
/**
- * Get the C pointer (as a long) to the JavaScriptCore context associated with this instance.
+ * Do not use this anymore. Use {@link #getRuntimeExecutor()} instead. Get the C pointer (as a
+ * long) to the JavaScriptCore context associated with this instance.
*
*
Use the following pattern to ensure that the JS context is not cleared while you are using
* it: JavaScriptContextHolder jsContext = reactContext.getJavaScriptContextHolder()
* synchronized(jsContext) { nativeThingNeedingJsContext(jsContext.get()); }
*/
+ @Deprecated
JavaScriptContextHolder getJavaScriptContextHolder();
+ RuntimeExecutor getRuntimeExecutor();
+
void addJSIModules(List jsiModules);
/**
diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java
index 864c85c73601e6..62cdb8a6cda784 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java
@@ -664,6 +664,9 @@ public JavaScriptContextHolder getJavaScriptContextHolder() {
return mJavaScriptContextHolder;
}
+ @Override
+ public native RuntimeExecutor getRuntimeExecutor();
+
@Override
public void addJSIModules(List jsiModules) {
mJSIModuleRegistry.registerModules(jsiModules);
diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp
index 4b279d208b41b1..7d5b1acf483f88 100644
--- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp
+++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp
@@ -131,6 +131,8 @@ void CatalystInstanceImpl::registerNatives() {
makeNativeMethod(
"jniHandleMemoryPressure",
CatalystInstanceImpl::handleMemoryPressure),
+ makeNativeMethod(
+ "getRuntimeExecutor", CatalystInstanceImpl::getRuntimeExecutor),
});
JNativeRunnable::registerNatives();
@@ -326,5 +328,14 @@ CatalystInstanceImpl::getNativeCallInvokerHolder() {
return nativeCallInvokerHolder_;
}
+jni::alias_ref
+CatalystInstanceImpl::getRuntimeExecutor() {
+ if (!runtimeExecutor_) {
+ runtimeExecutor_ = jni::make_global(
+ JRuntimeExecutor::newObjectCxxArgs(instance_->getRuntimeExecutor()));
+ }
+ return runtimeExecutor_;
+}
+
} // namespace react
} // namespace facebook
diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h
index 32a2eef9178399..dd9990ef090a00 100644
--- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h
+++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h
@@ -9,10 +9,12 @@
#include
#include
+#include
#include
#include "CxxModuleWrapper.h"
#include "JMessageQueueThread.h"
+#include "JRuntimeExecutor.h"
#include "JSLoader.h"
#include "JavaModuleWrapper.h"
#include "ModuleRegistryBuilder.h"
@@ -92,6 +94,7 @@ class CatalystInstanceImpl : public jni::HybridClass {
void jniCallJSCallback(jint callbackId, NativeArray *arguments);
jni::alias_ref getJSCallInvokerHolder();
jni::alias_ref getNativeCallInvokerHolder();
+ jni::alias_ref getRuntimeExecutor();
void setGlobalVariable(std::string propName, std::string &&jsonValue);
jlong getJavaScriptContext();
void handleMemoryPressure(int pressureLevel);
@@ -103,6 +106,7 @@ class CatalystInstanceImpl : public jni::HybridClass {
std::shared_ptr moduleMessageQueue_;
jni::global_ref jsCallInvokerHolder_;
jni::global_ref nativeCallInvokerHolder_;
+ jni::global_ref runtimeExecutor_;
};
} // namespace react
diff --git a/ReactCommon/cxxreact/Android.mk b/ReactCommon/cxxreact/Android.mk
index 553e0a93e5ca89..32d7e91cae7b50 100644
--- a/ReactCommon/cxxreact/Android.mk
+++ b/ReactCommon/cxxreact/Android.mk
@@ -19,7 +19,7 @@ LOCAL_CFLAGS := \
LOCAL_CFLAGS += -fexceptions -frtti -Wno-unused-lambda-capture
-LOCAL_STATIC_LIBRARIES := boost jsi callinvoker
+LOCAL_STATIC_LIBRARIES := boost jsi callinvoker runtimeexecutor
LOCAL_SHARED_LIBRARIES := jsinspector libfolly_json glog
include $(BUILD_STATIC_LIBRARY)
diff --git a/ReactCommon/cxxreact/BUCK b/ReactCommon/cxxreact/BUCK
index ef23abe0562aa1..af2604498b77a3 100644
--- a/ReactCommon/cxxreact/BUCK
+++ b/ReactCommon/cxxreact/BUCK
@@ -151,6 +151,7 @@ rn_xplat_cxx_library(
react_native_xplat_target("callinvoker:callinvoker"),
react_native_xplat_target("jsinspector:jsinspector"),
react_native_xplat_target("microprofiler:microprofiler"),
+ react_native_xplat_target("runtimeexecutor:runtimeexecutor"),
"//third-party/glog:glog",
"//xplat/folly:optional",
],
diff --git a/ReactCommon/cxxreact/Instance.cpp b/ReactCommon/cxxreact/Instance.cpp
index 6643b83a617865..d5b4af5e515ad8 100644
--- a/ReactCommon/cxxreact/Instance.cpp
+++ b/ReactCommon/cxxreact/Instance.cpp
@@ -229,6 +229,10 @@ std::shared_ptr Instance::getJSCallInvoker() {
return std::static_pointer_cast(jsCallInvoker_);
}
+RuntimeExecutor Instance::getRuntimeExecutor() {
+ return nativeToJsBridge_->getRuntimeExecutor();
+}
+
std::shared_ptr Instance::getDecoratedNativeCallInvoker(
std::shared_ptr nativeInvoker) {
return nativeToJsBridge_->getDecoratedNativeCallInvoker(nativeInvoker);
diff --git a/ReactCommon/cxxreact/Instance.h b/ReactCommon/cxxreact/Instance.h
index 0d5bacb5360243..f475bf8a7fa72c 100644
--- a/ReactCommon/cxxreact/Instance.h
+++ b/ReactCommon/cxxreact/Instance.h
@@ -12,6 +12,7 @@
#include
#include
+#include
#include
#ifndef RN_EXPORT
@@ -129,6 +130,11 @@ class RN_EXPORT Instance {
std::shared_ptr getDecoratedNativeCallInvoker(
std::shared_ptr nativeInvoker);
+ /**
+ * RuntimeExecutor is used by Fabric to access the jsi::Runtime.
+ */
+ RuntimeExecutor getRuntimeExecutor();
+
private:
void callNativeModules(folly::dynamic &&calls, bool isEndOfBatch);
void loadBundle(
diff --git a/ReactCommon/cxxreact/NativeToJsBridge.cpp b/ReactCommon/cxxreact/NativeToJsBridge.cpp
index 4d31ef058a17ad..2d3c21dacd8d72 100644
--- a/ReactCommon/cxxreact/NativeToJsBridge.cpp
+++ b/ReactCommon/cxxreact/NativeToJsBridge.cpp
@@ -331,5 +331,18 @@ std::shared_ptr NativeToJsBridge::getDecoratedNativeCallInvoker(
return std::make_shared(m_delegate, nativeInvoker);
}
+RuntimeExecutor NativeToJsBridge::getRuntimeExecutor() {
+ auto runtimeExecutor =
+ [this](std::function &&callback) {
+ runOnExecutorQueue(
+ [=, callback = std::move(callback)](JSExecutor *executor) {
+ jsi::Runtime *runtime =
+ (jsi::Runtime *)executor->getJavaScriptContext();
+ callback(*runtime);
+ });
+ };
+ return runtimeExecutor;
+}
+
} // namespace react
} // namespace facebook
diff --git a/ReactCommon/cxxreact/NativeToJsBridge.h b/ReactCommon/cxxreact/NativeToJsBridge.h
index 9cc9176b093bca..f4bb5bcd746c1b 100644
--- a/ReactCommon/cxxreact/NativeToJsBridge.h
+++ b/ReactCommon/cxxreact/NativeToJsBridge.h
@@ -13,6 +13,7 @@
#include
#include
+#include
#include
namespace folly {
@@ -106,6 +107,11 @@ class NativeToJsBridge {
std::shared_ptr getDecoratedNativeCallInvoker(
std::shared_ptr nativeInvoker);
+ /**
+ * RuntimeExecutor is used by Fabric to access the jsi::Runtime
+ */
+ RuntimeExecutor getRuntimeExecutor();
+
private:
// This is used to avoid a race condition where a proxyCallback gets queued
// after ~NativeToJsBridge(), on the same thread. In that case, the callback
diff --git a/ReactCommon/cxxreact/React-cxxreact.podspec b/ReactCommon/cxxreact/React-cxxreact.podspec
index cb6835be464488..452d817812e87b 100644
--- a/ReactCommon/cxxreact/React-cxxreact.podspec
+++ b/ReactCommon/cxxreact/React-cxxreact.podspec
@@ -41,4 +41,5 @@ Pod::Spec.new do |s|
s.dependency "glog"
s.dependency "React-jsinspector", version
s.dependency "React-callinvoker", version
+ s.dependency "React-runtimeexecutor", version
end
diff --git a/ReactCommon/runtimeexecutor/React-runtimeexecutor.podspec b/ReactCommon/runtimeexecutor/React-runtimeexecutor.podspec
new file mode 100644
index 00000000000000..e7fc8d2d2a3319
--- /dev/null
+++ b/ReactCommon/runtimeexecutor/React-runtimeexecutor.podspec
@@ -0,0 +1,36 @@
+# Copyright (c) Facebook, Inc. and its affiliates.
+#
+# This source code is licensed under the MIT license found in the
+# LICENSE file in the root directory of this source tree.
+
+require "json"
+
+package = JSON.parse(File.read(File.join(__dir__, "..", "..", "package.json")))
+version = package['version']
+
+source = { :git => 'https://github.com/facebook/react-native.git' }
+if version == '1000.0.0'
+ # This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in.
+ source[:commit] = `git rev-parse HEAD`.strip
+else
+ source[:tag] = "v#{version}"
+end
+
+folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
+folly_version = '2020.01.13.00'
+boost_compiler_flags = '-Wno-documentation'
+
+Pod::Spec.new do |s|
+ s.name = "React-runtimeexecutor"
+ s.version = version
+ s.summary = "-" # TODO
+ s.homepage = "https://reactnative.dev/"
+ s.license = package["license"]
+ s.author = "Facebook, Inc. and its affiliates"
+ s.platforms = { :ios => "10.0", :tvos => "10.0" }
+ s.source = source
+ s.source_files = "**/*.{cpp,h}"
+ s.header_dir = "ReactCommon"
+
+ s.dependency "React-jsi", version
+end
diff --git a/scripts/react_native_pods.rb b/scripts/react_native_pods.rb
index 86afd7ff5a0653..d54c09f3406846 100644
--- a/scripts/react_native_pods.rb
+++ b/scripts/react_native_pods.rb
@@ -41,6 +41,7 @@ def use_react_native! (options={})
pod 'React-jsiexecutor', :path => "#{prefix}/ReactCommon/jsiexecutor"
pod 'React-jsinspector', :path => "#{prefix}/ReactCommon/jsinspector"
pod 'React-callinvoker', :path => "#{prefix}/ReactCommon/callinvoker"
+ pod 'React-runtimeexecutor', :path => "#{prefix}/ReactCommon/runtimeexecutor"
pod 'ReactCommon/turbomodule/core', :path => "#{prefix}/ReactCommon"
pod 'Yoga', :path => "#{prefix}/ReactCommon/yoga", :modular_headers => true