Summary: Adds support for dynamic value that are `std::vector<std::vector<RawValue>>`
Reviewed By: shergin, mdvacca
Differential Revision: D16936932
fbshipit-source-id: fc8d087f9705af9da56ccc1bd9a0537b2bfeb50d
Summary: We used this mechanism at the very early stages of Fabric. Now we do component registration differently.
Reviewed By: JoshuaGross, mdvacca
Differential Revision: D17200952
fbshipit-source-id: 16ff9d6569714a24e2a8d58dc6e60ad4d7bc1e16
Summary: This allows to implement `findNodeHandle` in Fabric world (temporary).
Reviewed By: zackargyle, JoshuaGross, mdvacca
Differential Revision: D17175953
fbshipit-source-id: c88bd1c58608450812799d4ecb4a6bf2c027c5f3
Summary: The mehtod implements the core functionality of finding a shadow node by given tag.
Reviewed By: zackargyle, JoshuaGross, mdvacca
Differential Revision: D17175955
fbshipit-source-id: 5cfbb80b2d4e54a33ca9c20a21988df4de54c800
Summary: The new methods provides a way to iterate over all registered shadow trees.
Reviewed By: zackargyle, JoshuaGross, mdvacca
Differential Revision: D17175954
fbshipit-source-id: e4e6ee5a0e0a4e4e36b99d546f8724b99559c8c2
Summary:
Fix Android gradle build error for native debug build.
`NATIVE_BUILD_TYPE=Debug ./gradlew :ReactAndroid:installArchives`
The root cause is `folly::Future<bool>` not declared.
As we don't include true folly::Future implementation in OSS build but to use a forward declaration,
the fix is pretty much like to original declaration as `folly::Future<folly::Unit>`.
## Changelog
[Android] [Fixed] - Fix compile error for native debug build
This change could be ignored from changelog which is only for internal development.
Pull Request resolved: https://github.com/facebook/react-native/pull/26248
Test Plan: Makes sure `NATIVE_BUILD_TYPE=Debug ./gradlew :ReactAndroid:installArchives` build without errors.
Differential Revision: D17169696
Pulled By: mdvacca
fbshipit-source-id: 42e8b84b7ee0d1bd99d913702df98bc030965f63
Summary:
This diff fixes a redbox happens on every single hot-reload practically saying that ImageLoader is misconfigured. The issue happened because after reloading Fabric used the previous obsolete instance of `ImageLoader` created and stored inside old (and already destroyed) instance of Bridge. The fix is simple: We update all dependencies after the Bridge was reloaded.
See https://fb.workplace.com/groups/rn.support/permalink/2677343372314261/ for more details.
Reviewed By: mdvacca
Differential Revision: D17173702
fbshipit-source-id: 5ff0c418feae10ede9b76c184cd24ad06ee008b7
Summary:
We don't need to have those methods virtual anymore.
Nowadays we have a pointer to a `ComponentDescriptor` in `ShadowNode`, it's simpler to get that value from there.
That's also more code-size friendly because we now can remove those methods from a template.
Reviewed By: sammy-SC
Differential Revision: D17142173
fbshipit-source-id: 9f54fbe6c1ebad3ed49843ed75a01ca5ee48c34f
Summary: We merge `events` module into `core` long time ago, so we don't need this anymore.
Reviewed By: mdvacca
Differential Revision: D17142174
fbshipit-source-id: 6e63f7f22dc3d65ed2f9cc3bd4f4776404dfe788
Summary:
This fixes an error when using RN's version of yoga with Flipper.
```
[!] The following Swift pods cannot yet be integrated as static libraries:
The Swift pod `YogaKit` depends upon `Yoga`, which does not define modules. To opt into those targets generating module maps (which is necessary to import them from Swift when building as static libraries), you may set `use_modular_headers!` globally in your Podfile, or specify `:modular_headers => true` for particular dependencies.
```
Taken from https://github.com/facebook/yoga/blob/master/Yoga.podspec#L25
## Changelog
[Internal] [Fixed] - Add `DEFINES_MODULE=YES` to the yoga podspec
Pull Request resolved: https://github.com/facebook/react-native/pull/26276
Reviewed By: priteshrnandgaonkar
Differential Revision: D17149819
Pulled By: axe-fb
fbshipit-source-id: 5060b8e7111ba411f6e26e3479ad4fb55a552b4e
Summary:
The type is wrong in the constructor.
build-break
Differential Revision: D17145039
fbshipit-source-id: f6b80e38c05e60f04d029aa34baa0c55c237a39a
Summary: Support existing, backwards-compatible AndroidTextInput component for minimal support of TextInput on Android.
Reviewed By: shergin, mdvacca
Differential Revision: D17086758
fbshipit-source-id: 25726f22229e0d5dfe96eb36b386a5317601283d
Summary:
The purpose of `EventBeat` is handling an asynchronous callback to itself which is being delivered on some different thread. That brings a challenge of ensuring that the `EventBeat` object stays valid during the timeframe of callback execution. The concept of Owner helps with that.
The owner is a shared pointer that retains (probably indirectly) the `EventBeat` object. To ensure the correctness of the call, `EventBeat` retains the owner (practically creating a retain cycle) during executing the callback. In case if the pointer to the owner already null, `EventBeat` skips executing the callback.
It's impossible to retain itself directly or refer to the shared pointer to itself from a constructor. `OwnerBox` is designed to work around this issue; it allows to store the pointer later, right after the creation of some other object that owns an `EventBeat`.
Reviewed By: JoshuaGross
Differential Revision: D17128549
fbshipit-source-id: 7ed34fd865430975157fd362f51c4a3d64214430
Summary:
Seems it's more logical and safe to store ShadowTreeRegistry in UIManager than in Scheduler. We also probably will move some functionality dealing with the registry to UIManager.
But most importantly we need it to manage the ownership properly. UIManager might overlive Scheduler and still get a call to process a shadow tree. In the current configuration, it causes a crash because the registry owns by Scheduler. Moving that to UIManager solves that.
Reviewed By: JoshuaGross
Differential Revision: D17128550
fbshipit-source-id: e6735acaa11f2ed82ca17f18a45e389d79aa1a08
Summary:
This diff changes the way how `UIManager`, `UIManagerBindging`, `Scheduler` and `EventDisaptcher` refer to each other which should help with stability and reliability.
Here is the node that describes the details:
# Retaining dilemma
# Players
We have many logical of moving pieces but most of them can be abstracted by following high-level components.
* **Scheduler**
`Scheduler` is the main representation of running React Native infrastructure. Creation of it means the creation of all React Native C++ subsystems (excluding RuntimeExecutor) and destruction of that means the destruction of all dependent parts. Both processes must be thread-safe.
* **UIManager**
UIManager is a module that contains the most high-level logic of managing shadow trees. All React Renderer calls are practically implemented there.
* **UIManagerBinding**
UIManagerBinding is a representation (aka `HostObject`) of UIManager in the JavaScript world.
* **EventDispatcher**
EventDispatcher is a class that implements all logic related to dispatching events: from calling event on any thread anywhere to executing a particular JavaScript handler responsible for handling that event.
Instances of those classes have complex relationships in terms of owning each other, order of creation and destruction. The configuration of these relationships is dictated by a set of constraints that those classes need to satisfy to be constructed, accessed, and destructed in a hostile multithreaded environment. Messing with that can cause deadlocks, random crashes, suboptimal performance or memory leaks. Make sure you consider all constraints and requirements before changing that.
# Goal
We need to have a safe and reliable way to construct and destroy those objects (on any thread, in any random moment). Keep in mind that all of those objects are being accessed from random threads and have random states in any particular moment. Switching threads happens all the time, so having some state in one place does not guarantee any state in other places.
# Caveats
Let's discuss all concrete constrains that the moving pieces have to satisfy.
* **UIManagerBinding is a HostObject**
Practically that means:
1. It must be constructed "on JavaScript thread" (with exclusive access to JavaScript VM);
2. It must not be retained by other parts of the system because overliving the VM will cause a crash.
3. It can be destructed on any thread (VM does not give any guarantees here). The particular configuration guarantees that the destruction cannot be run concurrently with any JS execution though (because we never clear the reference to the host object from JavaScript side).
* **UIManager needs to be connected with UIManagerBinding and vice-versa**
Those to modules call each other to perform some UI updates or deliver events.
* **Scheduler can be deallocated on any thread at any time**
Timing and thread are up to the application side. The Scheduler must be resilient to that.
* **EventDispatcher can call UIManager at any time**
Luckily, that happens only on JavaScript thread.
* **Using weak pointers cames at a cost**
`std::weak_ptr` is a concept for managing the non-owning relationships in a safe manner. Dereferencing such pointers cames at a cost (additional object construction and atomic counters bumps). So, we should use that carefully; we cannot use shared and week pointers everywhere and assume that will work magically.
# How does this blow up?
Without describing the current configuration, here are a variety of cases that we currently observe.
1. `Scheduler` was deallocated and destroyed UIManager but VM is still running. The VM calls the UIManagerBinding, UIManagerBinding calls a method on already deallocated UIManager. Boom.
2. VM is being deallocated and deletes all host object as part of this process. Some UI event is sill in flight on some thread. The event retains UIManagerBinding via UIManager. VM cannot destroy UIManagerBinding because it's being retained. Boom.
3. VM was deallocated. `Scheduler` was deallocated. But some native state update is still in flight. It retains EventDispatcher and eventually trying to access some shadow tree that was retained by Scheduler and already dead. Boom.
That's pretty much routine endless nightmare of any low-level framework. Luckily, the good proper decisions (and iterating on that!) can solve that.
# Proposed configuration
The configuration is based on those ideas:
1. Never retain `UIManagerBinging`.
2. Never recreate `UIManagerBinging`. Create once and load lazily from JS environment on demand.
3. Consider UIManager as an object with shared ownership between JS and native. That object must be able to overlive native infra or JS VM.
4. Use EventDispatcher as a single weak representation of the JavaScript world; Never retain it strongly except by the Scheduler.
5. `UIManagerBinging` and `UIManager` can be attached or detached. `UIManagerBinging` retains `UIManager`, `UIManager` does not retain `UIManagerBinging` back. Destroying `UIManagerBinging` nulls the raw pointer to that from `UIManager`.
6. All calls from native to JavaScript can validate the pointer from `UIManager` to `UIManagerBinging` to check that the call is possible. All that calls happen on JavaScript thread.
## Stages
* **Creation process**
Creation Scheduler creates `UIManager` and scheduler asynchronous call to JavaScript to create `UIManagerBinding` and attach them. At the same time `Scheduler` creates `EventDispatcher` and makes it retains `UIManager`.
* **JavaScript-to-native invocation**
`UIManagerBinding` has a shared pointer to `UIManager` and can cheaply and safely verify that the pointer is not nullptr. Any mutation of this pointer happens on the JavaScript thread or effectively on VM destruction (non-concurrently).
* **Native-to-JavaScript invocation**
The invocation starts from retaining `EventDispatcher` (converting a weak pointer to strong one), that retains `UIManager`. Later, on the JavaScript thread, `UIManager` checks the raw pointer to `UIManagerBinding` to verify that the call can be performed safely.
# Easy ways to break the fragile balance
- Never retain `EventDispatcher` as a shared pointer. That causes a leak of UIManager and associated resources.
- Access a shared pointer to `UIManager` by value only. The simple way to break that is to specify `[=]` capture block for a lambda and access an instance variable pointing to a `UIManager` (that does not retain the pointer; make a copy on the stack and copy that to the lambda).
Reviewed By: JoshuaGross
Differential Revision: D17120333
fbshipit-source-id: 83138657683e91ceb2f48f18f30e745199c83e82
Summary: We don't use it anymore. (And that was debug only concept.)
Reviewed By: sammy-SC
Differential Revision: D17115538
fbshipit-source-id: 20aac5457e37666cbf9ca9f62cdfca411026c219
Summary: We don't use it anymore.
Reviewed By: JoshuaGross
Differential Revision: D17115539
fbshipit-source-id: e1fa5cc023cd27e53307aa0ea8eae0bad5413be3
Summary: Storing a strong shared pointer to `ComponentDescriptor` can cause a memory leak. Therefore we enforce all call sides and params to be weak pointers. The only Scheduler preserves a retaining pointer to it (to prevent preliminary deallocation).
Reviewed By: sammy-SC
Differential Revision: D17115540
fbshipit-source-id: fdea7d19f742ff04d5ba5470dd9748a5b226aa7c
Summary: Yoga is currently published in cocoapods. While we don't use the Yoga from Cocoapods in React Native, we should atleast try to follow that version, so that other integrations with Yoga are possible
Reviewed By: shergin
Differential Revision: D17127625
fbshipit-source-id: bca2e1e33ad775e2a0d7a6f1e4177c3b480c023a
Summary:
Needed to capitalize the name, since this is the convention used elsewhere too
## Changelog:
[iOS] [Changed] - Renamed yoga podspec to Yoga
Reviewed By: shergin
Differential Revision: D17127104
fbshipit-source-id: 14047bf452edda000037701f4ba7f4a02a0e717b
Summary: That was always part of design, that's okay to get a newer state from any other state. We will need it in the future diffs.
Reviewed By: sammy-SC
Differential Revision: D17053429
fbshipit-source-id: 2174e7d6e3a1ed231f7f6e238d216d0b09ec8797
Summary:
It's okay in Fabric model to commit some subtrees which are kinda obsolete (that's strange but technically it's not against the model), but it's not okay to commit some states that were already committed before.
This diff prevents that.
Reviewed By: JoshuaGross
Differential Revision: D17053428
fbshipit-source-id: fb3536312163b7b57011647b4ba7b931c2179d89
Summary: This diff adds support from `ScrollView::scrollEventThrottle` property on iOS.
Reviewed By: JoshuaGross
Differential Revision: D17000397
fbshipit-source-id: 93f23919a6a2588000c0eeca869171d1036348b6
Summary:
Certain turbomodules set `requiresMainQueueSetup` to true. This is b/c they use some fancy APIs in setup that need main queue.
TurboModuleManager mostly adhered to this restriction, the only case it didn't is when setting bridge. There is possibility that this happens on JS thread, which would crash the app for these certain TM. This diff fixes that.
Reviewed By: RSNara
Differential Revision: D16921644
fbshipit-source-id: 69b2410550360d3ccb03c0b71fb7dfccb889eda4
Summary: There's an old hack in the C++ code that prevents TextInputs from being rendered by forcing them to render as Views instead. We don't need this anymore.
Reviewed By: shergin
Differential Revision: D16932795
fbshipit-source-id: 347df106f638c2bf936e2312f42bcb9310d72c6d
Summary:
This diff moves RCTImageLoader, RCTImageEditingManager, and RCTImageStoreManager to CoreModules. This is necessary for us to convert all these NativeModules to TurboModules.
**Note:** As a part of this diff, I had to break apart `RCTImageLoader.h`. All the protocols that were in `RCTImageLoader` are now in their own headers. Furthermore, `RCTImageLoader`'s methods are defined in `RCTImageLoaderProtocol`, so that we can call them from classes like `RCTImageViewManager` in `RCTImage`.
Reviewed By: PeteTheHeat
Differential Revision: D16805827
fbshipit-source-id: 89f6728b0766c30b74e25f7af1be8e6b8a7e6397
Summary: Just ran `arc f ReactCommon/turbomodule/core/**/*`.
Reviewed By: ejanzer
Differential Revision: D16691807
fbshipit-source-id: 3f499ffeffaae47bda550c0071c93cd7f48e2a23
Summary:
Use an array for counting measure callbacks due to each reason.
and this is now added as qpl metadata in Layout Calculation qpl event
Reviewed By: davidaurelio
Differential Revision: D16666786
fbshipit-source-id: ff85fba835148f06b9c5d90c4604e552a813777a
Summary: The previous rename from RCT->RN prefix ended up causing some confusions on which prefix to use for which files and under what circumstances. To avoid further confusion before we're done with the re-architecture project, let's keep them as RCT.
Reviewed By: mdvacca
Differential Revision: D16705566
fbshipit-source-id: 395bff771c84e5ded6b2261a84c7549df1e6c5e5
Summary:
No need for a copy here.
Pull Request resolved: https://github.com/facebook/yoga/pull/919
Differential Revision: D16701461
Pulled By: davidaurelio
fbshipit-source-id: 3a90adbb2b5c43d5aefe693a8525aa3a37e53b3d
Summary: Replaces the usage of C++ bitfields with our portable `Bitfield` class.
Reviewed By: SidharthGuglani
Differential Revision: D16656361
fbshipit-source-id: 05f679e2e994e109b2bd1090c879d6850fabdc40
Summary:
@public
Removes the style properties bitmask. We have used this for experimentation, and it's no longer necessary.
This simplifyies the code, and allows us to cut over to `Bitfield.h` more easily.
Reviewed By: astreet
Differential Revision: D16648862
fbshipit-source-id: 17c0899807af976f4ba34db54f8f0f6a3cd92519
Summary:
@public
Our usage of C++ bit fields has lead to quite some problems with different compiler setups. Problems include sign bits, alignment, etc.
Here we introduce a portable implementation as a variadic template, allowing the user to store a number of booleans and enums (defined with `YG_ENUM_SEQ_DECL`) in an unsigned integer type of their choice.
This will replace all usages of bit fields across the Yoga code base.
Differential Revision: D16647801
fbshipit-source-id: 230ffab500885a3ad662ea8f19e35a5e9357a563
Summary:
Fragment was assigned incorrect `tag` and `surfaceID` (`surfaceID` is the important one).
Wrong `surfaceID` means that `navigationCoordinator` is never resolved. As a result of navigationCoordinator not being assigned, tapping a video ad on Marketplace results in showing video ad overlay rather than showing full screen video.
Reviewed By: JoshuaGross
Differential Revision: D16646492
fbshipit-source-id: 0da5c56ecb7c81e9f4a9469a3626ccd430a01558
Summary:
## The Problem
1. `CatalystInstanceImpl` indirectly holds on to the `jsi::Runtime`. When you destroy `CatalystInstanceImpl`, you destroy the `jsi::Runtime`. As a part of reloading React Native, we destroy and re-create `CatalystInstanceImpl`, which destroys and re-creates the `jsi::Runtime`.
2. When JS passes in a callback to a TurboModule method, we take that callback (a `jsi::Function`) and wrap it in a Java `Callback` (implemented by `JCxxCallbackImpl`). This Java `Callback`, when executed, schedules the `jsi::Function` to be invoked on a Java thread at a later point in time. **Note:** The Java NativeModule can hold on to the Java `Callback` (and, by transitivity, the `jsi::Function`) for potentially forever.
3. It is a requirement of `jsi::Runtime` that all objects associated with the Runtime (ex: `jsi::Function`) must be destroyed before the Runtime itself is destroyed. See: https://fburl.com/m3mqk6wt
### jsi.h
```
/// .................................................... In addition, to
/// make shutdown safe, destruction of objects associated with the Runtime
/// must be destroyed before the Runtime is destroyed, or from the
/// destructor of a managed HostObject or HostFunction. Informally, this
/// means that the main source of unsafe behavior is to hold a jsi object
/// in a non-Runtime-managed object, and not clean it up before the Runtime
/// is shut down. If your lifecycle is such that avoiding this is hard,
/// you will probably need to do use your own locks.
class Runtime {
public:
virtual ~Runtime();
```
Therefore, when you delete `CatalystInstanceImpl`, you could end up with a situation where the `jsi::Runtime` is destroyed before all `jsi::Function`s are destroyed. In dev, this leads the program to crash when you reload the app after having used a TurboModule method that uses callbacks.
## The Solution
If the only reference to a `HostObject` or a `HostFunction` is in the JS Heap, then the `HostObject` and `HostFunction` destructors can destroy JSI objects. The TurboModule cache is the only thing, aside from the JS Heap, that holds a reference to all C++ TurboModules. But that cache (and the entire native side of `TurboModuleManager`) is destroyed when we call `mHybridData.resetNative()` in `TurboModuleManager.onCatalystInstanceDestroy()` in D16552730. (I verified this by commenting out `mHybridData.resetNative()` and placing a breakpoint in the destructor of `JavaTurboModule`). So, when we're cleaning up `TurboModuleManager`, the only reference to a Java TurboModule is the JS Heap. Therefore, it's safe and correct for us to destroy all `jsi::Function`s created by the Java TurboModule in `~JavaTurboModule`. So, in this diff, I keep a set of all `CallbackWrappers`, and explicitly call `destroy()` on them in the `JavaTurboModule` destructor. Note that since `~JavaTurboModule` accesses `callbackWrappers_`, it must be executed on the JS Thread, since `createJavaCallbackFromJSIFunction` also accesses `callbackWrappers_` on the JS Thread.
For additional safety, I also eagerly destroyed the `jsi::Function` after it's been invoked once. I'm not yet sure if we only want JS callbacks to only ever be invoked once. So, I've created a Task to document this work: T48128233.
Reviewed By: mdvacca
Differential Revision: D16623340
fbshipit-source-id: 3a4c3efc70b9b3c8d329f19fdf4b4423c489695b
Summary: This diff implements the JSResponderHandler methods in the core of RN (scheduler API and friends)
Reviewed By: ejanzer
Differential Revision: D16543437
fbshipit-source-id: dac03e30c4330d182ecf134f3174ba942dbf7289
Summary: When you create a TurboModule from the JS side, we instantiate its Java class and simply make this `javaobject` a `jni::global_ref` in C++. But the reason why we need to make this a global ref is because `JavaTurboModule` needs it to be a global reference for method calls. Making this a `jni::global_ref` from the perspective to TurboModuleManager doesn't really make any sense. So, this diff refactors that bit of code.
Differential Revision: D16622133
fbshipit-source-id: 6a5c20bb405b945c06378a3423d5e7eb38ef244c
Summary: On iOS, calling the `__turboModuleProxy` function with the same name returns the same instance of the TurboModule. Adding this behaviour to Andorid as well.
Differential Revision: D16622131
fbshipit-source-id: 472011ac3356e7c30497f848be0c888596c449b1