mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Clear all held jsi::Functions when jsi::Runtime is deleted
Summary: ## Description You're not supposed to hold on to JSI objects (ex: `jsi::Function`) past the point where their `jsi::Runtime` is deleted. Otherwise, we get a dangling pointer crash, like this: T60262810! Historically, this cleanup problem has always been really tricky to get right. With this diff, I hope to fix that problem once and for all by deleting all `jsi::Function`s when we delete the global `__turboModuleProxy` function. ## Current Setup - The TurboModules infra uses weak references to `CallbackWrapper`s to hold on to the `jsi::Function`s passed from JS to ObjC. - The LongLivedObjectCollection holds on to strong references to `CallbackWrapper`s. This ensures that the `jsi::Function`s aren't deleted prematurely. This also means that we can use `LongLivedObjectCollection` to delete all `CallbackWrappers`. - `TurboModuleBinding` is the abstraction we use to install the global `__turboModuleProxy` function. It is owned by `TurboModuleManager`, and `TurboModuleManager` uses it to clear all references to `jsi::Function`s, when we delete all NativeModules. ## Solution 1. Transfer ownership of `TurboModuleBinding` from `TurboModuleManager` to the `__turboModuleProxy` function. 2. Clear the `LongLivedObjectCollection` when `TurboModuleBinding` is deleted. Changelog: [iOS][Fixed] - Clear all held jsi::Functions when jsi::Runtime is deleted Reviewed By: JoshuaGross Differential Revision: D19565499 fbshipit-source-id: e3510ea04e72f6bda363a8fc3ee2be60303b70a6
This commit is contained in:
committed by
Facebook Github Bot
parent
7001dc3fe0
commit
9ae95582e7
+48
-51
@@ -65,65 +65,62 @@ void TurboModuleManager::installJSIBindings() {
|
||||
|
||||
TurboModuleBinding::install(
|
||||
*runtime_,
|
||||
std::make_shared<TurboModuleBinding>(
|
||||
[turboModuleCache_ =
|
||||
std::weak_ptr<TurboModuleCache>(turboModuleCache_),
|
||||
jsCallInvoker_ = std::weak_ptr<CallInvoker>(jsCallInvoker_),
|
||||
nativeCallInvoker_ = std::weak_ptr<CallInvoker>(nativeCallInvoker_),
|
||||
delegate_ = jni::make_weak(delegate_),
|
||||
javaPart_ = jni::make_weak(javaPart_)](
|
||||
const std::string &name) -> std::shared_ptr<TurboModule> {
|
||||
auto turboModuleCache = turboModuleCache_.lock();
|
||||
auto jsCallInvoker = jsCallInvoker_.lock();
|
||||
auto nativeCallInvoker = nativeCallInvoker_.lock();
|
||||
auto delegate = delegate_.lockLocal();
|
||||
auto javaPart = javaPart_.lockLocal();
|
||||
[turboModuleCache_ = std::weak_ptr<TurboModuleCache>(turboModuleCache_),
|
||||
jsCallInvoker_ = std::weak_ptr<CallInvoker>(jsCallInvoker_),
|
||||
nativeCallInvoker_ = std::weak_ptr<CallInvoker>(nativeCallInvoker_),
|
||||
delegate_ = jni::make_weak(delegate_),
|
||||
javaPart_ = jni::make_weak(javaPart_)](
|
||||
const std::string &name) -> std::shared_ptr<TurboModule> {
|
||||
auto turboModuleCache = turboModuleCache_.lock();
|
||||
auto jsCallInvoker = jsCallInvoker_.lock();
|
||||
auto nativeCallInvoker = nativeCallInvoker_.lock();
|
||||
auto delegate = delegate_.lockLocal();
|
||||
auto javaPart = javaPart_.lockLocal();
|
||||
|
||||
if (!turboModuleCache || !jsCallInvoker || !nativeCallInvoker ||
|
||||
!delegate || !javaPart) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!turboModuleCache || !jsCallInvoker || !nativeCallInvoker ||
|
||||
!delegate || !javaPart) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto turboModuleLookup = turboModuleCache->find(name);
|
||||
if (turboModuleLookup != turboModuleCache->end()) {
|
||||
return turboModuleLookup->second;
|
||||
}
|
||||
auto turboModuleLookup = turboModuleCache->find(name);
|
||||
if (turboModuleLookup != turboModuleCache->end()) {
|
||||
return turboModuleLookup->second;
|
||||
}
|
||||
|
||||
auto cxxModule =
|
||||
delegate->cthis()->getTurboModule(name, jsCallInvoker);
|
||||
if (cxxModule) {
|
||||
turboModuleCache->insert({name, cxxModule});
|
||||
return cxxModule;
|
||||
}
|
||||
auto cxxModule = delegate->cthis()->getTurboModule(name, jsCallInvoker);
|
||||
if (cxxModule) {
|
||||
turboModuleCache->insert({name, cxxModule});
|
||||
return cxxModule;
|
||||
}
|
||||
|
||||
static auto getLegacyCxxModule =
|
||||
delegate->getClass()
|
||||
->getMethod<jni::alias_ref<CxxModuleWrapper::javaobject>(
|
||||
const std::string &)>("getLegacyCxxModule");
|
||||
auto legacyCxxModule = getLegacyCxxModule(delegate.get(), name);
|
||||
static auto getLegacyCxxModule =
|
||||
delegate->getClass()
|
||||
->getMethod<jni::alias_ref<CxxModuleWrapper::javaobject>(
|
||||
const std::string &)>("getLegacyCxxModule");
|
||||
auto legacyCxxModule = getLegacyCxxModule(delegate.get(), name);
|
||||
|
||||
if (legacyCxxModule) {
|
||||
auto turboModule = std::make_shared<react::TurboCxxModule>(
|
||||
legacyCxxModule->cthis()->getModule(), jsCallInvoker);
|
||||
turboModuleCache->insert({name, turboModule});
|
||||
return turboModule;
|
||||
}
|
||||
if (legacyCxxModule) {
|
||||
auto turboModule = std::make_shared<react::TurboCxxModule>(
|
||||
legacyCxxModule->cthis()->getModule(), jsCallInvoker);
|
||||
turboModuleCache->insert({name, turboModule});
|
||||
return turboModule;
|
||||
}
|
||||
|
||||
static auto getJavaModule =
|
||||
javaPart->getClass()
|
||||
->getMethod<jni::alias_ref<JTurboModule>(
|
||||
const std::string &)>("getJavaModule");
|
||||
auto moduleInstance = getJavaModule(javaPart.get(), name);
|
||||
static auto getJavaModule =
|
||||
javaPart->getClass()
|
||||
->getMethod<jni::alias_ref<JTurboModule>(const std::string &)>(
|
||||
"getJavaModule");
|
||||
auto moduleInstance = getJavaModule(javaPart.get(), name);
|
||||
|
||||
if (moduleInstance) {
|
||||
auto turboModule = delegate->cthis()->getTurboModule(
|
||||
name, moduleInstance, jsCallInvoker, nativeCallInvoker);
|
||||
turboModuleCache->insert({name, turboModule});
|
||||
return turboModule;
|
||||
}
|
||||
if (moduleInstance) {
|
||||
auto turboModule = delegate->cthis()->getTurboModule(
|
||||
name, moduleInstance, jsCallInvoker, nativeCallInvoker);
|
||||
turboModuleCache->insert({name, turboModule});
|
||||
return turboModule;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}));
|
||||
return nullptr;
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
|
||||
Reference in New Issue
Block a user