Summary:
After D28435078, NativeModules can conform to the RCTInitializing protocol, and implement the `-(void)initialize` method. This diff makes the NativeModule system execute the module's initialize method after the infra is done setting it up.
Changelog: [Internal]
Reviewed By: fkgozali
Differential Revision: D28435430
fbshipit-source-id: 1ce00c3fb3c63b024d7e24895ff96c541a6fa654
Summary:
This diff has the bridge attach RCTCallableJSModules to our NativeModules.
Changelog: [Internal]
Differential Revision: D28395447
fbshipit-source-id: 01ca62442013826d28ba0f710e28a5963f5efb65
Summary:
After this diff, every NativeModule that has `synthesize bundleManager = _bundleManager`, will get access to an RCTBundleManager, that it can use to read from/write to the bridge's bundle URL.
Changelog: [iOS][Added] - Attach RCTBundleManager to NativeModules
Reviewed By: PeteTheHeat
Differential Revision: D28086319
fbshipit-source-id: 6e4cd815d300e9036957ec8c743e947d2cb3f365
Summary:
After this diff, NativeModules can synthesize the RCTModuleRegistry, and use that to query for UIViews of components, given their reactTags.
Changelog: [Internal]
Reviewed By: shergin
Differential Revision: D25645052
fbshipit-source-id: bb17606cc4862d07b739ef2c31a5e57f59201364
Summary:
The bridge now creates the RCTModuleRegistry, and assigns it to all NativeModules it creates.
Changelog: [Internal]
Reviewed By: PeteTheHeat
Differential Revision: D25414108
fbshipit-source-id: 81c6a05bde0e52cff8ed60297f27d8aa3ff15a87
Summary:
`RCTModuleData gatherConstants` is [used by `RCTModuleData exportedConstants` to compute and return the constants exported to JS](https://fburl.com/diffusion/ssg4jbeu). However, `RCTModuleData gatherConstants` is also [used by `RCTCxxBridge` to pre-compute NativeModule constants during bridge startup](https://fburl.com/diffusion/nfmjc1ke). Therefore, since `RCTModuleData gatherConstants` can be used outside the context of a JS require, we cannot start the JSRequireEnding marker inside `RCTModuleData gatherConstants` directly.
This diff moves the body of `RCTModuleData gatherConstants` into `gatherConstantsAndSignalJSRequireEnding:(BOOL)startMarkers`:
- `RCTModuleData gatherConstants` calls `RCTModuleData gatherConstantsAndSignalJSRequireEnding:NO`
- `RCTModuleData exportedConstants` calls `RCTModuleData gatherConstantsAndSignalJSRequireEnding:YES`. **Note:** This is okay, because `RCTModuleData exportedConstants` is only called inside `RCTNativeModule::getConstants()`.
This should make sure that we don't start the JSRequireEnding marker outside of a JS require.
Reviewed By: PeteTheHeat
Differential Revision: D22371889
fbshipit-source-id: de17b857259572fb0f840a22072a16b5e465cabd
Summary:
## Context
- If a NativeModule requires main queue setup, its `constantsToExport` method is executed on the main queue.
- In the TurboModule system, `constantsToExport` or `getConstants` is treated like a regular synchronous NativeModule method. Therefore, it's always executed on the JS thread.
This difference in behaviour is dangerous when we're A/B testing the TurboModule infra: One could write a NativeModule that requires main queue setup, and have it expose constants that access objects/state only accessible on the UI thread. This NativeModule would work fine in the legacy infra, which could be the case if the NativeModule author is testing locally. But once it ships to prod, it may run with the TurboModule system, and crash the application. To mitigate this risk, I'm removing this special main queue execution of `constantsToExport` from the legacy infrastructure.
## Consequences
- If a NativeModule's `constantsToExport` method accesses objects/state only accessible on the UI thread, it must do so by explicitly scheduling work on the main thread. I wrote up a codemod to fix this for our OSS modules: D21797048.
- Eagerly initialized NativeModules that required main queue setup had their constants calculated eagerly. After the changes in this diff, those NativeModules will have their constants calculated lazily. I don't think this is a big deal because only a handful of NativeModules are eagerly initialized, and eagerly initialized NativeModules are going away anyway.
Changelog:
[iOS][Removed] - Main queue execution of constantsToExport in NativeModules requiring main queue setup
Reviewed By: fkgozali
Differential Revision: D21829091
fbshipit-source-id: df21fd5fd2ef45a291c07400f360bba801ae290f
Summary:
## Motivation
We got this crash T67304907, which shows a `EXC_BAD_ACCESS / KERN_INVALID_ADDRESS` when calling this line:
```
NativeModulePerfLogger::getInstance().asyncMethodCallBatchPreprocessStart();
```
There are no arguments in that call, so I figured the only error could be when we try to invoke `getInstance()` or `asyncMethodCallBatchPreprocessStart()`.
This diff:
1. Removes the `NativeModulePerfLogger::getInstance()` bit. Now NativeModulePerfLogger is used via regular static C functions. So, there's no way that simply invoking one of the logging functions crashes the application: there's no vtable lookup.
2. Inside each logging function, when perf-logging is disabled, the global perflogger should be `nullptr`. This diff makes it so that in that case, we won't execute any code in the control group of the perf-logging experiment.
## Changes
**How do we enable NativeModule perf-logging?**
- Previously:
- `NativeModulePerfLogger::setInstance(std::make_shared<FBReactNativeModulePerfLogger>(...))`
- `TurboModulePerfLogger::setInstance(std::make_shared<FBReactNativeModulePerfLogger>(...))`.
- Now:
- `BridgeNativeModulePerfLogger::enableLogging(std::make_unique<FBReactNativeModulePerfLogger>(...))`
- `TurboModulePerfLogger::enableLogging(std::make_unique<FBReactNativeModulePerfLogger>(...))`
**How do we do NativeModule perf-logging now?**
- Previously:
- `NativeModulePerfLogger::getInstance().command(...args)`
- `TurboModulePerfLogger::getInstance().command(...args)`.
- Now:
- `BridgeNativeModulePerfLogger::command(...args)`
- `TurboModulePerfLogger::command(...args)`.
The benefit of this approach is that each method in `BridgeNativeModulePerfLogger` is guarded with an if check. Example:
```
void moduleCreateConstructStart(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleCreateConstructStart(moduleName, id);
}
}
```
Therefore, we don't actually execute any code when perf-logging is disabled.
Changelog:
[Internal]
Reviewed By: fkgozali
Differential Revision: D21669888
fbshipit-source-id: 80c73754c430ce787404b563878bad146295e01f
Summary:
## Motivation
This rename will fix the following CircleCI build failures:
- [test_ios_unit_frameworks](https://circleci.com/gh/facebook/react-native/150473?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link)
- [test_ios_detox_frameworks](https://circleci.com/gh/facebook/react-native/150474?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link)
## Investigation
We have 4 podspec targets that map to the same header namespace (i.e: `header_dir`) `ReactCommon`:
- **New:** `React-perflogger`: Directory is `ReactCommon/preflogger`, and contains `NativeModulePerfLogger.{h,cpp}`.
- `React-runtimeexecutor`: Directory is `ReactCommon/runtimeexecutor`, and contains only `RuntimeExecutor.h`
- `React-callinvoker`: Directory is `ReactCommon/callinvoker`, and contains only `CallInvoker.h`
- `ReactCommon/turbomodule/core`: Directory is `ReactCommon/turbomodule`, and contains C++ files, as well has header files.
**The problem:**
We couldn't import headers from `React-perflogger` in `ReactCommon/turbomodule/core` files.
**The cause:**
I'm not entirely sure why, but I was able to discern the following two rules by playing around with the podspecs:
1. If your podspec target has a cpp file, it'll generate a framework when `USE_FRAMEWORKS=1`.
2. Two different frameworks cannot map to the same `module_name` or `header_dir`. (Why? No clue. But something breaks silently when this is the case).
So, this is what happened when I landed `React-perflogger` (D21443610):
1. The TurboModules code generates the `ReactCommon` framework that uses the `ReactCommon` header namespace.
2. `React-runtimeexecutor` and `React-callinvoker` also used the `ReactCommon` header namespace. However, neither generate a framework because of Rule 1.
3. When I comitted `React-perflogger`, I introduced a second framework that competed with the `ReactCommon` framework (i.e: TurboModules code) for the `ReactCommon` header namespace. Rule 2 violation.
## Thoughts on renaming
- `<perflogger/NativeModulePerfLogger.h>` is too generic, and the `perflogger` namepsace is used internally within FB.
- `<react/perflogger/NativeModulePerfLogger.h>` matches our fabric header format, but I'm pretty sure that slashes aren't allowed in `header_dir`: I tested this and it didn't work. IIRC, only alphanumeric and underscore are valid characters for `header_dir` or `module_name`. So, I opted to just use `reactperflogger`.
Changelog: [Internal]
Reviewed By: fkgozali
Differential Revision: D21598852
fbshipit-source-id: 60da5d0f7758eaf13907a080b7d8756688f40723
Summary:
## Motivation
This rename will fix the following CircleCI build failures:
- [test_ios_unit_frameworks](https://circleci.com/gh/facebook/react-native/150473?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link)
- [test_ios_detox_frameworks](https://circleci.com/gh/facebook/react-native/150474?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link)
## Investigation
We have 4 podspec targets that map to the same header namespace (i.e: `header_dir`) `ReactCommon`:
- **New:** `React-perflogger`: Directory is `ReactCommon/preflogger`, and contains `NativeModulePerfLogger.{h,cpp}`.
- `React-runtimeexecutor`: Directory is `ReactCommon/runtimeexecutor`, and contains only `RuntimeExecutor.h`
- `React-callinvoker`: Directory is `ReactCommon/callinvoker`, and contains only `CallInvoker.h`
- `ReactCommon/turbomodule/core`: Directory is `ReactCommon/turbomodule`, and contains C++ files, as well has header files.
**The problem:**
We couldn't import headers from `React-perflogger` in `ReactCommon/turbomodule/core` files.
**The cause:**
I'm not entirely sure why, but I was able to discern the following two rules by playing around with the podspecs:
1. If your podspec target has a cpp file, it'll generate a framework when `USE_FRAMEWORKS=1`.
2. Two different frameworks cannot map to the same `module_name` or `header_dir`. (Why? No clue. But something breaks silently when this is the case).
So, this is what happened when I landed `React-perflogger` (D21443610):
1. The TurboModules code generates the `ReactCommon` framework that uses the `ReactCommon` header namespace.
2. `React-runtimeexecutor` and `React-callinvoker` also used the `ReactCommon` header namespace. However, neither generate a framework because of Rule 1.
3. When I comitted `React-perflogger`, I introduced a second framework that competed with the `ReactCommon` framework (i.e: TurboModules code) for the `ReactCommon` header namespace. Rule 2 violation.
## Thoughts on renaming
- `<perflogger/NativeModulePerfLogger.h>` is too generic, and the `perflogger` namepsace is used internally within FB.
- `<react/perflogger/NativeModulePerfLogger.h>` matches our fabric header format, but I'm pretty sure that slashes aren't allowed in `header_dir`: I tested this and it didn't work. IIRC, only alphanumeric and underscore are valid characters for `header_dir` or `module_name`. So, I opted to just use `reactperflogger`.
Changelog: [Internal]
Reviewed By: fkgozali
Differential Revision: D21585006
fbshipit-source-id: e3339273af5dfd65a1454d87213d1221de6a4651
Summary:
This diff instruments two markers:
- JSRequireBeginning: From the start of the JS require to when we start creating the platform NativeModule
- JSRequireEnding: From the end of platform NativeModule create to the end of the JS require
In order to accomplish this, I had modify `ModuleRegistry::ModuleRegistry()` to accept a `std::shared_ptr<NativeModulePerfLogger>`. I also had to implement the public method `ModuleRegistry::getNativeModulePerfLogger()` so that `JSINativeModules` could start logging the JS require beginning and ending.
Changelog: [Internal]
Reviewed By: PeteTheHeat
Differential Revision: D21418803
fbshipit-source-id: 53828817ae41f23f3f04a95b1d3ac0012735da48
Summary:
`RCTModuleData instance` is the entry-point for creating and initializing NativeModules on iOS. This diff instruments module-create for the legacy NativeModule system.
Changelog: [Internal]
Reviewed By: PeteTheHeat
Differential Revision: D21415435
fbshipit-source-id: 8554e41cba9105ef528a9a63c49042b99ebf8751
Summary:
Right now JS triggers a view manager command with the following code:
```
UIManager.dispatchViewManagerCommand(
nullthrows(this.scrollResponderGetScrollableNode()),
UIManager.getViewManagerConfig('RCTScrollView').Commands.scrollTo,
[x || 0, y || 0, animated !== false],
);
```
As we want to get rid of calls to UIManager, we need to stop looking for the integer defined in native from JavaScript. We will be changing methods like this to be:
```
UIManager.dispatchViewManagerCommand(
nullthrows(this.scrollResponderGetScrollableNode()),
'scrollTo',
[x || 0, y || 0, animated !== false],
);
```
We need to support ints and Strings to be backwards compatible, but ints will be deprecated.
This is the same change as made for Android here: https://github.com/facebook/react-native/commit/3cae6fa950eed54bccccf61a28c0e85d5a004c6c
Reviewed By: PeteTheHeat
Differential Revision: D15983041
fbshipit-source-id: 6cb0f3001553d1f9d26e7e8fb5481e16fbca6847
Summary:
Between invalidating a bridge and suspending its JS thread, native modules may have their methods called.
Only warn when a native module has been invalidated, which happens right before its JS thread is suspended.
Avoid initializing a native module's instance if its bridge is invalidated.
/cc fkgozali https://github.com/facebook/react-native/commit/f94521244798f859648d1769f397102c06d763f0#commitcomment-32467567
[iOS] [Fixed] - Properly validate JS->native method calls
Pull Request resolved: https://github.com/facebook/react-native/pull/23658
Differential Revision: D14287594
Pulled By: fkgozali
fbshipit-source-id: 89dd1906a0c55f3f48ba4ff220aac0cddf2eb822
Summary: This change drops the year from the copyright headers and the LICENSE file.
Reviewed By: yungsters
Differential Revision: D9727774
fbshipit-source-id: df4fc1e4390733fe774b1a160dd41b4a3d83302a
Summary:
Includes React Native and its dependencies Fresco, Metro, and Yoga. Excludes samples/examples/docs.
find: ^(?:( *)|( *(?:[\*~#]|::))( )? *)?Copyright (?:\(c\) )?(\d{4})\b.+Facebook[\s\S]+?BSD[\s\S]+?(?:this source tree|the same directory)\.$
replace: $1$2$3Copyright (c) $4-present, Facebook, Inc.\n$2\n$1$2$3This source code is licensed under the MIT license found in the\n$1$2$3LICENSE file in the root directory of this source tree.
Reviewed By: TheSavior, yungsters
Differential Revision: D7007050
fbshipit-source-id: 37dd6bf0ffec0923bfc99c260bb330683f35553e
Summary:
I've talked to several major community users, and they're all ok with deleting this
code. There's several doc fixes which will make it easier for third
party developers which should land about the same time this will.
Also buried along with it is RCTJSCExecutor.
Reviewed By: javache
Differential Revision: D6880781
fbshipit-source-id: b4cb1143def6fd23a96290e478fa728adbedacd3
Summary:
We've simplified a lot of the conditions for eager of the module init so now we can introduce a final switch to allow modules to opt-out (and in the future opt-in if they still require the behaviour).
We now require you to be explicit about the intended behaviour and implement the `+ (BOOL)requiresMainQueueSetup` method on your module. When you return YES from this method, it tells the bridge the module needs to be created on the main thread (and to avoid deadlocks, we do so eagerly during bridge startup). When you return NO, the native module will be initialised when it's first accessed from JS.
The current behaviour is maintained but a warning is emitted until the new API is adopted.
Reviewed By: fkgozali
Differential Revision: D5527788
fbshipit-source-id: 56d38f81e58cf950547b9780e89bfac4667eeaaa
Summary:
Thanks for submitting a PR! Please read these instructions carefully:
- [ ] Explain the **motivation** for making this change.
- [ ] Provide a **test plan** demonstrating that the code is solid.
- [ ] Match the **code formatting** of the rest of the codebase.
- [ ] Target the `master` branch, NOT a "stable" branch.
What existing problem does the pull request solve?
XCode [Thread Sanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html) find race condition while read/write `_instance` variable in RCTModuleData class. A bridge can check `hasInstance` method while instance writes.
All tests passed on my device.
These changes remove data race, you can turn it in scheme configuration 
Closes https://github.com/facebook/react-native/pull/13757
Differential Revision: D4994041
Pulled By: javache
fbshipit-source-id: 631cd59bbcbde193937d8baf8358ff6868717a2e
Summary:
**Motivation**
This finishes the job of #11817, removing the previously deprecated method. See https://github.com/facebook/react-native/issues/11736 for more context.
**Test plan**
There were no tests for this method, and I searched the whole project to make sure we weren't relying on it anywhere.
Closes https://github.com/facebook/react-native/pull/11854
Differential Revision: D4421671
Pulled By: javache
fbshipit-source-id: 67e0db8d3c594ad3ccd6ccdae08f8ce49ddb8a34