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