Skip to content

Commit

Permalink
Expose RuntimeExecutor on CatalystInstance (#28851)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #28851

This diff creates a RuntimeExecutor that uses the bridge and exposes it on CatalystInstanceImpl.

Changelog: [Internal]

Reviewed By: mdvacca, RSNara

Differential Revision: D21051949

fbshipit-source-id: b3977fc14fa19089f33e297d29cedba0d067526d
  • Loading branch information
Emily Janzer authored and facebook-github-bot committed May 8, 2020
1 parent 13ee5c4 commit a4a47b9
Show file tree
Hide file tree
Showing 14 changed files with 105 additions and 3 deletions.
9 changes: 8 additions & 1 deletion RNTester/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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`)
Expand Down Expand Up @@ -462,6 +466,8 @@ EXTERNAL SOURCES:
:path: "../Libraries/Text"
React-RCTVibration:
:path: "../Libraries/Vibration"
React-runtimeexecutor:
:path: "../ReactCommon/runtimeexecutor"
ReactCommon:
:path: "../ReactCommon"
Yoga:
Expand Down Expand Up @@ -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
Expand All @@ -506,6 +512,7 @@ SPEC CHECKSUMS:
React-RCTTest: cfe25fcf70b04a747dba4326105db398250caa9a
React-RCTText: 6c01963d3e562109f5548262b09b1b2bc260dd60
React-RCTVibration: d42d73dafd9f63cf758656ee743aa80c566798ff
React-runtimeexecutor: 60dd6204a13f68a1aa1118870edcc604a791df2b
ReactCommon: 39e00b754f5e1628804fab28f44146d06280f700
Yoga: f7fa200d8c49f97b54c9421079e781fb900b5cae
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
* <p>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<JSIModuleSpec> jsiModules);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,9 @@ public JavaScriptContextHolder getJavaScriptContextHolder() {
return mJavaScriptContextHolder;
}

@Override
public native RuntimeExecutor getRuntimeExecutor();

@Override
public void addJSIModules(List<JSIModuleSpec> jsiModules) {
mJSIModuleRegistry.registerModules(jsiModules);
Expand Down
11 changes: 11 additions & 0 deletions ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ void CatalystInstanceImpl::registerNatives() {
makeNativeMethod(
"jniHandleMemoryPressure",
CatalystInstanceImpl::handleMemoryPressure),
makeNativeMethod(
"getRuntimeExecutor", CatalystInstanceImpl::getRuntimeExecutor),
});

JNativeRunnable::registerNatives();
Expand Down Expand Up @@ -326,5 +328,14 @@ CatalystInstanceImpl::getNativeCallInvokerHolder() {
return nativeCallInvokerHolder_;
}

jni::alias_ref<JRuntimeExecutor::javaobject>
CatalystInstanceImpl::getRuntimeExecutor() {
if (!runtimeExecutor_) {
runtimeExecutor_ = jni::make_global(
JRuntimeExecutor::newObjectCxxArgs(instance_->getRuntimeExecutor()));
}
return runtimeExecutor_;
}

} // namespace react
} // namespace facebook
4 changes: 4 additions & 0 deletions ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
#include <string>

#include <ReactCommon/CallInvokerHolder.h>
#include <ReactCommon/RuntimeExecutor.h>
#include <fbjni/fbjni.h>

#include "CxxModuleWrapper.h"
#include "JMessageQueueThread.h"
#include "JRuntimeExecutor.h"
#include "JSLoader.h"
#include "JavaModuleWrapper.h"
#include "ModuleRegistryBuilder.h"
Expand Down Expand Up @@ -92,6 +94,7 @@ class CatalystInstanceImpl : public jni::HybridClass<CatalystInstanceImpl> {
void jniCallJSCallback(jint callbackId, NativeArray *arguments);
jni::alias_ref<CallInvokerHolder::javaobject> getJSCallInvokerHolder();
jni::alias_ref<CallInvokerHolder::javaobject> getNativeCallInvokerHolder();
jni::alias_ref<JRuntimeExecutor::javaobject> getRuntimeExecutor();
void setGlobalVariable(std::string propName, std::string &&jsonValue);
jlong getJavaScriptContext();
void handleMemoryPressure(int pressureLevel);
Expand All @@ -103,6 +106,7 @@ class CatalystInstanceImpl : public jni::HybridClass<CatalystInstanceImpl> {
std::shared_ptr<JMessageQueueThread> moduleMessageQueue_;
jni::global_ref<CallInvokerHolder::javaobject> jsCallInvokerHolder_;
jni::global_ref<CallInvokerHolder::javaobject> nativeCallInvokerHolder_;
jni::global_ref<JRuntimeExecutor::javaobject> runtimeExecutor_;
};

} // namespace react
Expand Down
2 changes: 1 addition & 1 deletion ReactCommon/cxxreact/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions ReactCommon/cxxreact/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,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",
],
Expand Down
4 changes: 4 additions & 0 deletions ReactCommon/cxxreact/Instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,10 @@ std::shared_ptr<CallInvoker> Instance::getJSCallInvoker() {
return std::static_pointer_cast<CallInvoker>(jsCallInvoker_);
}

RuntimeExecutor Instance::getRuntimeExecutor() {
return nativeToJsBridge_->getRuntimeExecutor();
}

std::shared_ptr<CallInvoker> Instance::getDecoratedNativeCallInvoker(
std::shared_ptr<CallInvoker> nativeInvoker) {
return nativeToJsBridge_->getDecoratedNativeCallInvoker(nativeInvoker);
Expand Down
6 changes: 6 additions & 0 deletions ReactCommon/cxxreact/Instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <memory>
#include <mutex>

#include <ReactCommon/RuntimeExecutor.h>
#include <cxxreact/NativeToJsBridge.h>

#ifndef RN_EXPORT
Expand Down Expand Up @@ -129,6 +130,11 @@ class RN_EXPORT Instance {
std::shared_ptr<CallInvoker> getDecoratedNativeCallInvoker(
std::shared_ptr<CallInvoker> nativeInvoker);

/**
* RuntimeExecutor is used by Fabric to access the jsi::Runtime.
*/
RuntimeExecutor getRuntimeExecutor();

private:
void callNativeModules(folly::dynamic &&calls, bool isEndOfBatch);
void loadBundle(
Expand Down
17 changes: 17 additions & 0 deletions ReactCommon/cxxreact/NativeToJsBridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,5 +331,22 @@ std::shared_ptr<CallInvoker> NativeToJsBridge::getDecoratedNativeCallInvoker(
return std::make_shared<NativeCallInvoker>(m_delegate, nativeInvoker);
}

RuntimeExecutor NativeToJsBridge::getRuntimeExecutor() {
auto runtimeExecutor =
[this, isDestroyed = m_destroyed](
std::function<void(jsi::Runtime & runtime)> &&callback) {
if (*isDestroyed) {
return;
}
runOnExecutorQueue(
[callback = std::move(callback)](JSExecutor *executor) {
jsi::Runtime *runtime =
(jsi::Runtime *)executor->getJavaScriptContext();
callback(*runtime);
});
};
return runtimeExecutor;
}

} // namespace react
} // namespace facebook
7 changes: 7 additions & 0 deletions ReactCommon/cxxreact/NativeToJsBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <vector>

#include <ReactCommon/CallInvoker.h>
#include <ReactCommon/RuntimeExecutor.h>
#include <cxxreact/JSExecutor.h>

namespace folly {
Expand Down Expand Up @@ -106,6 +107,12 @@ class NativeToJsBridge {
std::shared_ptr<CallInvoker> getDecoratedNativeCallInvoker(
std::shared_ptr<CallInvoker> nativeInvoker);

/**
* RuntimeExecutor is used on Android to access the jsi::Runtime from Fabric
* and TurboModules
*/
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
Expand Down
1 change: 1 addition & 0 deletions ReactCommon/cxxreact/React-cxxreact.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -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
36 changes: 36 additions & 0 deletions ReactCommon/runtimeexecutor/React-runtimeexecutor.podspec
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions scripts/react_native_pods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit a4a47b9

Please sign in to comment.