From cb7f3f4499232797ce8e60b00270f30641923ddc Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Fri, 6 Nov 2020 13:08:51 -0800 Subject: [PATCH] Setup TurboModule JS Codegen experiment Summary: ## Android API ``` // Before we initialize TurboModuleManager ReactFeatureFlags.useTurboModuleJSCodegen = true ``` ## iOS API ``` // Before we initialize RCTBridge RCTEnableTurboModuleJSCodegen(true); ``` ## How is the JS Codegen actually enabled? The above native flags are translated to the following global variable in JavaScript: ``` global.RN$JSTurboModuleCodegenEnabled = true; ``` Then, all our NativeModule specs are transpiled to contain this logic: ``` interface Foo extends TurboModule { // ... } function __getModuleSchema() { if (!global.RN$JSTurboModuleCodegenEnabled) { return undefined; } // Return the schema of this spec. return {...}; } export default TurboModuleRegistry.get('foo', __getModuleSchema()); ``` Then, in our C++ JavaTurboModule, and ObjCTurboModule classes, we use the TurboModule JS codegen when the jsi::Object schema is provided from JavaScript in the TurboModuleRegistry.get call. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D24636307 fbshipit-source-id: 80dcd604cc1121b8a69df875bbfc87e9bb8e4814 --- React/Base/RCTBridge.h | 4 ++++ React/Base/RCTBridge.m | 11 +++++++++++ .../facebook/react/config/ReactFeatureFlags.java | 3 +++ .../turbomodule/core/TurboModuleManager.java | 6 ++++-- .../core/jni/ReactCommon/TurboModuleManager.cpp | 15 ++++++++++----- .../core/jni/ReactCommon/TurboModuleManager.h | 7 +++++-- .../core/ReactCommon/TurboModuleBinding.cpp | 8 +++++++- .../core/ReactCommon/TurboModuleBinding.h | 3 ++- .../core/platform/ios/RCTTurboModuleManager.mm | 2 +- 9 files changed, 47 insertions(+), 12 deletions(-) diff --git a/React/Base/RCTBridge.h b/React/Base/RCTBridge.h index 1331f5009cb..5ce3ebe35a3 100644 --- a/React/Base/RCTBridge.h +++ b/React/Base/RCTBridge.h @@ -164,6 +164,10 @@ RCT_EXTERN void RCTEnableTurboModuleSharedMutexInit(BOOL enabled); RCT_EXTERN BOOL RCTTurboModuleBlockCopyEnabled(void); RCT_EXTERN void RCTEnableTurboModuleBlockCopy(BOOL enabled); +// Turn on TurboModule JS Codegen +RCT_EXTERN BOOL RCTTurboModuleJSCodegenEnabled(void); +RCT_EXTERN void RCTEnableTurboModuleJSCodegen(BOOL enabled); + /** * Async batched bridge used to communicate with the JavaScript application. */ diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m index 2429d58f86b..1adc463bf06 100644 --- a/React/Base/RCTBridge.m +++ b/React/Base/RCTBridge.m @@ -146,6 +146,17 @@ void RCTEnableTurboModuleBlockCopy(BOOL enabled) turboModuleBlockCopyEnabled = enabled; } +static BOOL turboModuleJSCodegenEnabled = NO; +BOOL RCTTurboModuleJSCodegenEnabled(void) +{ + return turboModuleJSCodegenEnabled; +} + +void RCTEnableTurboModuleJSCodegen(BOOL enabled) +{ + turboModuleJSCodegenEnabled = enabled; +} + @interface RCTBridge () @end diff --git a/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java b/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java index 9d8f1c4859a..a304728a3b2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +++ b/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java @@ -26,6 +26,9 @@ public class ReactFeatureFlags { /** Should we dispatch TurboModule methods with promise returns to the NativeModules thread? */ public static volatile boolean enableTurboModulePromiseAsyncDispatch = false; + /** Enable TurboModule JS Codegen. */ + public static volatile boolean useTurboModuleJSCodegen = false; + /* * This feature flag enables logs for Fabric */ diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java index 8303d153f61..8cd4c670370 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java @@ -61,7 +61,8 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry { (CallInvokerHolderImpl) jsCallInvokerHolder, (CallInvokerHolderImpl) nativeCallInvokerHolder, delegate, - ReactFeatureFlags.enableTurboModulePromiseAsyncDispatch); + ReactFeatureFlags.enableTurboModulePromiseAsyncDispatch, + ReactFeatureFlags.useTurboModuleJSCodegen); installJSIBindings(); mEagerInitModuleNames = @@ -294,7 +295,8 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry { CallInvokerHolderImpl jsCallInvokerHolder, CallInvokerHolderImpl nativeCallInvokerHolder, TurboModuleManagerDelegate tmmDelegate, - boolean enablePromiseAsyncDispatch); + boolean enablePromiseAsyncDispatch, + boolean enableTurboModuleJSCodegen); private native void installJSIBindings(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp index 131b41b075e..52d9861de96 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp @@ -26,13 +26,15 @@ TurboModuleManager::TurboModuleManager( jsi::Runtime *rt, std::shared_ptr jsCallInvoker, std::shared_ptr nativeCallInvoker, - jni::alias_ref delegate) + jni::alias_ref delegate, + bool enableJSCodegen) : javaPart_(jni::make_global(jThis)), runtime_(rt), jsCallInvoker_(jsCallInvoker), nativeCallInvoker_(nativeCallInvoker), delegate_(jni::make_global(delegate)), - turboModuleCache_(std::make_shared()) {} + turboModuleCache_(std::make_shared()), + enableJSCodegen_(enableJSCodegen) {} jni::local_ref TurboModuleManager::initHybrid( jni::alias_ref jThis, @@ -40,7 +42,8 @@ jni::local_ref TurboModuleManager::initHybrid( jni::alias_ref jsCallInvokerHolder, jni::alias_ref nativeCallInvokerHolder, jni::alias_ref delegate, - bool enablePromiseAsyncDispatch) { + bool enablePromiseAsyncDispatch, + bool enableJSCodegen) { auto jsCallInvoker = jsCallInvokerHolder->cthis()->getCallInvoker(); auto nativeCallInvoker = nativeCallInvokerHolder->cthis()->getCallInvoker(); @@ -51,7 +54,8 @@ jni::local_ref TurboModuleManager::initHybrid( (jsi::Runtime *)jsContext, jsCallInvoker, nativeCallInvoker, - delegate); + delegate, + enableJSCodegen); } void TurboModuleManager::registerNatives() { @@ -146,7 +150,8 @@ void TurboModuleManager::installJSIBindings() { jsCallInvoker_->invokeAsync( [this, turboModuleProvider = std::move(turboModuleProvider)]() -> void { - TurboModuleBinding::install(*runtime_, std::move(turboModuleProvider)); + TurboModuleBinding::install( + *runtime_, std::move(turboModuleProvider), enableJSCodegen_); }); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.h b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.h index 899d2a1d1cf..2a6a95aed2d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.h +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.h @@ -31,7 +31,8 @@ class TurboModuleManager : public jni::HybridClass { jni::alias_ref jsCallInvokerHolder, jni::alias_ref nativeCallInvokerHolder, jni::alias_ref delegate, - bool enablePromiseAsyncDispatch); + bool enablePromiseAsyncDispatch, + bool enableJSCodegen); static void registerNatives(); private: @@ -52,6 +53,7 @@ class TurboModuleManager : public jni::HybridClass { * they want to be long-lived or short-lived. */ std::shared_ptr turboModuleCache_; + bool enableJSCodegen_; void installJSIBindings(); explicit TurboModuleManager( @@ -59,7 +61,8 @@ class TurboModuleManager : public jni::HybridClass { jsi::Runtime *rt, std::shared_ptr jsCallInvoker, std::shared_ptr nativeCallInvoker, - jni::alias_ref delegate); + jni::alias_ref delegate, + bool enableJSCodegen); }; } // namespace react diff --git a/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleBinding.cpp b/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleBinding.cpp index 0b04ac69b10..d35ad88dfd7 100644 --- a/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleBinding.cpp +++ b/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleBinding.cpp @@ -27,7 +27,13 @@ TurboModuleBinding::TurboModuleBinding( void TurboModuleBinding::install( jsi::Runtime &runtime, - const TurboModuleProviderFunctionType &&moduleProvider) { + const TurboModuleProviderFunctionType &&moduleProvider, + bool enableJSTurboModuleCodegen) { + runtime.global().setProperty( + runtime, + "RN$JSTurboModuleCodegenEnabled", + jsi::Value(enableJSTurboModuleCodegen)); + runtime.global().setProperty( runtime, "__turboModuleProxy", diff --git a/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleBinding.h b/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleBinding.h index 2546730959f..d1c9abcdec0 100644 --- a/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleBinding.h +++ b/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleBinding.h @@ -28,7 +28,8 @@ class TurboModuleBinding { */ static void install( jsi::Runtime &runtime, - const TurboModuleProviderFunctionType &&moduleProvider); + const TurboModuleProviderFunctionType &&moduleProvider, + bool enableJSTurboModuleCodegen); TurboModuleBinding(const TurboModuleProviderFunctionType &&moduleProvider); virtual ~TurboModuleBinding(); diff --git a/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.mm b/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.mm index 223522eb684..cd7ba02c510 100644 --- a/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.mm +++ b/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModuleManager.mm @@ -718,7 +718,7 @@ static Class getFallbackClassFromName(const char *name) }; runtimeExecutor([turboModuleProvider = std::move(turboModuleProvider)](jsi::Runtime &runtime) { - react::TurboModuleBinding::install(runtime, std::move(turboModuleProvider)); + react::TurboModuleBinding::install(runtime, std::move(turboModuleProvider), RCTTurboModuleJSCodegenEnabled()); }); }