Skip to content

Commit 1dedc83

Browse files
javachefacebook-github-bot
authored andcommitted
Do not create RuntimeExecutor on non-JSI executors (facebook#38125)
Summary: Pull Request resolved: facebook#38125 On Android, when using the remote debugging feature (using legacy websockets), it's not safe to assume we can get a `jsi::Runtime` from `JSExecutor`. Changelog: [General][Fixed] Android does't crash when using remote debugger Reviewed By: NickGerleman Differential Revision: D47124234 fbshipit-source-id: 45ccc2544f104223efde1bec44e11b9cdfc1de52
1 parent 835f62c commit 1dedc83

File tree

4 files changed

+47
-33
lines changed

4 files changed

+47
-33
lines changed

packages/react-native/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -398,8 +398,11 @@ CatalystInstanceImpl::getNativeMethodCallInvokerHolder() {
398398
jni::alias_ref<JRuntimeExecutor::javaobject>
399399
CatalystInstanceImpl::getRuntimeExecutor() {
400400
if (!runtimeExecutor_) {
401-
runtimeExecutor_ = jni::make_global(
402-
JRuntimeExecutor::newObjectCxxArgs(instance_->getRuntimeExecutor()));
401+
auto executor = instance_->getRuntimeExecutor();
402+
if (executor) {
403+
runtimeExecutor_ =
404+
jni::make_global(JRuntimeExecutor::newObjectCxxArgs(executor));
405+
}
403406
}
404407
return runtimeExecutor_;
405408
}
@@ -408,15 +411,16 @@ jni::alias_ref<JRuntimeScheduler::javaobject>
408411
CatalystInstanceImpl::getRuntimeScheduler() {
409412
if (!runtimeScheduler_) {
410413
auto runtimeExecutor = instance_->getRuntimeExecutor();
411-
auto runtimeScheduler = std::make_shared<RuntimeScheduler>(runtimeExecutor);
412-
413-
runtimeScheduler_ =
414-
jni::make_global(JRuntimeScheduler::newObjectCxxArgs(runtimeScheduler));
415-
416-
runtimeExecutor([runtimeScheduler](jsi::Runtime &runtime) {
417-
RuntimeSchedulerBinding::createAndInstallIfNeeded(
418-
runtime, runtimeScheduler);
419-
});
414+
if (runtimeExecutor) {
415+
auto runtimeScheduler =
416+
std::make_shared<RuntimeScheduler>(runtimeExecutor);
417+
runtimeScheduler_ = jni::make_global(
418+
JRuntimeScheduler::newObjectCxxArgs(runtimeScheduler));
419+
runtimeExecutor([scheduler =
420+
std::move(runtimeScheduler)](jsi::Runtime &runtime) {
421+
RuntimeSchedulerBinding::createAndInstallIfNeeded(runtime, scheduler);
422+
});
423+
}
420424
}
421425

422426
return runtimeScheduler_;

packages/react-native/ReactCommon/cxxreact/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ target_link_libraries(reactnative
2727
jsinspector
2828
logger
2929
reactperflogger
30-
runtimeexecutor)
30+
runtimeexecutor
31+
react_debug)

packages/react-native/ReactCommon/cxxreact/Instance.cpp

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <cxxreact/JSIndexedRAMBundle.h>
2222
#include <folly/MoveWrapper.h>
2323
#include <folly/json.h>
24+
#include <react/debug/react_native_assert.h>
2425

2526
#include <glog/logging.h>
2627

@@ -211,26 +212,31 @@ std::shared_ptr<CallInvoker> Instance::getJSCallInvoker() {
211212
}
212213

213214
RuntimeExecutor Instance::getRuntimeExecutor() {
214-
std::weak_ptr<NativeToJsBridge> weakNativeToJsBridge = nativeToJsBridge_;
215+
// HACK: RuntimeExecutor is not compatible with non-JSIExecutor, we return
216+
// a null callback, which the caller should handle.
217+
if (!getJavaScriptContext()) {
218+
return nullptr;
219+
}
215220

216-
auto runtimeExecutor =
217-
[weakNativeToJsBridge](
218-
std::function<void(jsi::Runtime & runtime)> &&callback) {
219-
if (auto strongNativeToJsBridge = weakNativeToJsBridge.lock()) {
220-
strongNativeToJsBridge->runOnExecutorQueue(
221-
[callback = std::move(callback)](JSExecutor *executor) {
222-
jsi::Runtime *runtime =
223-
(jsi::Runtime *)executor->getJavaScriptContext();
224-
try {
225-
callback(*runtime);
226-
executor->flush();
227-
} catch (jsi::JSError &originalError) {
228-
handleJSError(*runtime, originalError, true);
229-
}
230-
});
231-
}
232-
};
233-
return runtimeExecutor;
221+
std::weak_ptr<NativeToJsBridge> weakNativeToJsBridge = nativeToJsBridge_;
222+
return [weakNativeToJsBridge](
223+
std::function<void(jsi::Runtime & runtime)> &&callback) {
224+
if (auto strongNativeToJsBridge = weakNativeToJsBridge.lock()) {
225+
strongNativeToJsBridge->runOnExecutorQueue(
226+
[callback = std::move(callback)](JSExecutor *executor) {
227+
// Assumes the underlying executor is a JSIExecutor
228+
jsi::Runtime *runtime =
229+
(jsi::Runtime *)executor->getJavaScriptContext();
230+
try {
231+
react_native_assert(runtime != nullptr);
232+
callback(*runtime);
233+
executor->flush();
234+
} catch (jsi::JSError &originalError) {
235+
handleJSError(*runtime, originalError, true);
236+
}
237+
});
238+
}
239+
};
234240
}
235241

236242
std::shared_ptr<NativeMethodCallInvoker>

packages/react-native/ReactCommon/cxxreact/React-cxxreact.podspec

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ Pod::Spec.new do |s|
3333
s.source_files = "*.{cpp,h}"
3434
s.exclude_files = "SampleCxxModule.*"
3535
s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags
36-
s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\"",
37-
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17" }
36+
s.pod_target_xcconfig = {
37+
"HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_CONFIGURATION_BUILD_DIR)/React-debug/React_debug.framework/Headers\"",
38+
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
39+
}
3840
s.header_dir = "cxxreact"
3941

4042
s.dependency "boost", "1.76.0"
@@ -47,6 +49,7 @@ Pod::Spec.new do |s|
4749
s.dependency "React-perflogger", version
4850
s.dependency "React-jsi", version
4951
s.dependency "React-logger", version
52+
s.dependency "React-debug", version
5053

5154
if ENV['USE_HERMES'] == nil || ENV['USE_HERMES'] == "1"
5255
s.dependency 'hermes-engine'

0 commit comments

Comments
 (0)