Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/48851
Changelog: [internal]
Remove the feature flag to disable the event loop on bridgeless, as we no longer have a use case for it. From now on, we can be 100% certain that Bridgeless == Event Loop!
Reviewed By: sammy-SC
Differential Revision: D68270102
fbshipit-source-id: c661bf11f51d4044f9f485b971c43f03197e2983
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/48383
## Changelog:
[Internal] -
This changes the name of `SystraceSection` class to `TraceSection`, the purpose being to make it Systrace/FBSystrace agnostic (and that it can be mapped to e.g. Perfetto instead).
It changes all the internal callsites to the RN code code, and also adds a shim include, `<cxxreact/SystraceSection.h`, for backward compatibility with the external callers for now (which will be addressed separately).
Reviewed By: javache
Differential Revision: D67621914
fbshipit-source-id: 337c63c45a7b075c6e00cfca67ecc06c298c94c0
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47915
## Purpose of this noop-ing
If an fatal js error happens during js runtime init, the js thread continues executing and raises **yet another** fatal error.
This noop-ing was an **attempt** to prevent that second inactionable fatal from happening: That fatal is usually inactionable.
## Problems with this noop-ing
I don't think this is the right approach: There could be legitimate reasons to continue executing native -> js calls post first js fatal.
I don't think it does *much*: it doesn't noop native -> js calls executed on the runtime scheduler, which should be most of them.
## Changes
Instead of trying to prevent that fatal, just let it happen. Then, don't report the second fatal: D66193194 and D66392706.
## Safetly
The production impact is negligible: This codepath is executed only after early js errors. There shouldn't be any in production right now.
We've spent a lot of time making our javascript error handling pipeline's coverage compresive. So, after an early js fatal error happens, subsequent js fatals should get handled properly.
Changelog: [Internal]
Reviewed By: javache
Differential Revision: D66394278
fbshipit-source-id: ef342fc2eba9ae9f27b15a0f412fb69bd92aed43
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47783
After the first javascript fatal, the runtime starts tearing down. And it becomes invalid. So, subsequent js fatals will most likely be just noise. Let's filter them out.
This impacts bridgeless mode: both the javascript and c++ pipeline.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D66193194
fbshipit-source-id: 61a731850f7ac4f00bfac24e3260673bf94ba8ed
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47637
Changelog: [Internal]
RSNRS does not support off JS thread layout due to current fiber tree corruption when syncing happens on more than one shadow tree at the same time. This diff guarantees that RSNRS will only be enabled on the JS thread, avoiding any state corruption.
Reviewed By: sammy-SC
Differential Revision: D64500893
fbshipit-source-id: aa20f54a0fcfa47534ae099e95307a692bd9fd0f
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47529
RuntimeExecutor, RuntimeScheduler, etc. can execute arbitrary c++ on the javascript thread.
If that c++ throws a non-jsi::JSError, it will bypass the js error handler (and start tearing down the react instance 😱).
Let's have the js error handler manage all exceptions raised while native is calling into js. This is more sane.
Changelog: [Internal]
Reviewed By: sammy-SC
Differential Revision: D64626610
fbshipit-source-id: 40132f24b4e2737ae3f055fbd09153111404e5bf
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47466
Now, when the useAlwaysAvailableJSErrorHandling feature flag is true, React Native will use the earlyjs c++ error reporting pipeline for handling all javascript errors!
Changelog: [Internal]
Reviewed By: javache
Differential Revision: D64715159
fbshipit-source-id: 597a5278eb792f87dca10e06fa9816b3a8c47b84
Summary:
## Changes
If the c++ pipeline is active:
If someone calls console.error:
- The c++ pipeline will report it as a soft error
If someone reports an error:
- The c++ pipeline will log it via console.error
Changelog: [Internal]
Reviewed By: javache
Differential Revision: D64506069
fbshipit-source-id: 293cd1774f19ee03d7eb61572b7b1f03a47a4756
Summary:
Now, handleError can be called with a JSError that wraps a non-error object!
Changelog: [Internal]
Reviewed By: javache
Differential Revision: D64706198
fbshipit-source-id: 562ed7d4e2a13eaef48acfdf3499296462e54166
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47119
# Changelog:
[General] [Fixed] - Microtasks are now correctly executed after the code evaluation in Console panel of DevTools.
Fixes https://github.com/facebook/react-native/issues/46966.
`runtimeExecutor` which is propagated here, is actually being used by Hermes:
https://www.internalfb.com/code/fbsource/[cba75f2b515a]/xplat/js/react-native-github/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp?lines=112-113
The issue was that any expression that should be evaluated as part of `Runtime.evaluate` was not going through `RuntimeScheduler`, because specified `runtimeExecutor` was not going through it as well, and it was defined prior to `RuntimeScheduler`. Because of this, `RuntimeScheduler` was not draining out the microtasks queue and basically any scheduled Microtasks were not executed, see T200616136.
With this fix, we create an executor that goes through `RuntimeScheduler`, which is using another executor that makes sure that all scheduled callbacks are only executed after `Inspector` was setup.
It is extremely messy and in the future we should untangle these circular dependencies and try to simplify the approach.
Reviewed By: rubennorte
Differential Revision: D64552372
fbshipit-source-id: 467d37c71a2eb7c940297ce90ca8d68268b1ff33
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/47084
Changelog: [internal]
This unifies all the feature flags that control the new event loop on RN. Before, we'd have granular flags for different aspects of it. With this diff, we enable the event loop by default with bridgeless, and we introduce a new flag to explicitly disable it in that case if necessary.
When we're ready to clean up this opt-out, we just need to remove the `&& !ReactNativeFeatureFlags::disableEventLoopOnBridgeless()` conditions.
Reviewed By: fkgozali
Differential Revision: D64464902
fbshipit-source-id: d1a0ba38dd4c189c2da905b49de23a821223ac3a
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/46953
Changelog: [internal]
This unifies all the feature flags that control the new event loop on RN. Before, we'd have granular flags for different aspects of it. With this diff, we enable the event loop by default with bridgeless, and we introduce a new flag to explicitly disable it in that case if necessary.
When we're ready to clean up this opt-out, we just need to remove the `&& !ReactNativeFeatureFlags::disableEventLoopOnBridgeless()` conditions.
Reviewed By: javache
Differential Revision: D64175216
fbshipit-source-id: b879447def8ab47c6ab772812ff1031177494069
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/46935
Now, whenever the earlyjs c++ pipeline handles an error, it'll invoke callbacks registered via javascript.
## The API
```
if (global.RN$registerExceptionListener != null) {
global.RN$registerExceptionListener(
(error: ExtendedExceptionData & {preventDefault: () => mixed}) => {
error.preventDefault();
// show logbox
},
);
}
```
## The Future API
We want something more aligned with the HTML spec:
```
addEventListener('error', (event) => {
event.preventDefault();
// show logbox
});
```
## Fatals vs soft errors
The earlyjs pipeline covers just main bundle execution for now.
So, it displays logbox only if there was a soft error. If there was a fatal error, it'll just continue to display redbox as usual.
Changelog: [Internal]
Reviewed By: javache
Differential Revision: D63769385
fbshipit-source-id: 9c01e1cfe0ec80842af2e5bcfbf0adfb040dbcf3
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/46735
We had some crash on Android where we call [`callFunctionOnModule`](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp#L258) when the `bufferedRuntimeExecutor_` might not be initialized. This can happen when navigating away from RN surface and quickly navigate to another one or across refreshes.
There could be a scheduled JS function from the previous surface/instance that might try to call a native module while the new instance is being created.
This change prevent the crash and replace it with a soft crash, that should show a RedBox on the screen.
## Changelog
[Internal] - Throw JS exception when calling a method if buffereRuntimeExecutor is not initialized
## Facebook
Have a look at T201983945 that generated the crash report
Reviewed By: cortinico
Differential Revision: D63638633
fbshipit-source-id: ba331f5173963265232d0810c2d12895cea3d528
Summary:
A crash we are getting in the wild suggests that destruction on weak ref count going away may be delaying RuntimeExecutor task destruction to a point where jsi::Function is invalid. Let's try backing D62748768 out and seeing if the crash goes away.
Changelog:
[General][Fixed] - Attempt to fix crash from delayed RuntimeExecutor task destruction
#bypass-github-export-checks
Reviewed By: mdvacca
Differential Revision: D63568504
fbshipit-source-id: 6152e7293902d0eb67a14c5840bea56561c35b08
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/46542
If `bufferedRuntimeExecutor_` is referenced beyond the lifetime of the ReactInstance, it may point to invalid memory. RuntimeScheduler already holds weak references to the actual runtime, so it's safe to retain that instead.
Changelog: [Internal]
Reviewed By: rshest
Differential Revision: D62748768
fbshipit-source-id: 1cd8fcb050dd561e7d54a11d91c89eda3a5ddaaa
Summary:
If a fatal error is caught in js, and the js pipeline isn't ready, route it through the c++ pipeline.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D60138414
fbshipit-source-id: 333e38e2b904d6434a88469816e39bf1b9d0bc3f
Summary:
If any fatal js error is caught in c++, just route it through js error handler.
Then, make js error handler call into the right pipeline:
1. After the js pipeline is ready: Route the errors through the js pipeline
2. Otherwise: Route errors through the c++ pipeline.
Changelog: [Internal]
Reviewed By: javache
Differential Revision: D60138417
fbshipit-source-id: 24c466ffadbd14a9e9a5571548f3d34d2f406a8d
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45473
This is a basic implementation of the Long Tasks API (https://w3c.github.io/longtasks/).
It detects and reports long tasks when using the Event Loop (in the modern RuntimeScheduler) when a new feature flag for this purpose is enabled.
This doesn't include attribution information at the moment.
Changelog: [internal]
Reviewed By: sammy-SC
Differential Revision: D55491870
fbshipit-source-id: e1ccad9cc6a35073b31230a8cf3a4660ab9a043d
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45331
Let's add the a new JSRuntime API to register the thread. This allows Hermes sampling to correctly work in Bridgeless/Activity.
## Changelog:
[General][Added] - Add experimental api to JSRuntimeFactory to initialize runtime on js thread
Reviewed By: RSNara
Differential Revision: D58787655
fbshipit-source-id: 2202271b9ad88cf8ba2145fb4e9e7bfd6e0c09fa
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44576
Store callable modules as either a factory function or an object, so we can skip invoking the factory function for frequently accessed objects.
Changelog: [Internal]
Reviewed By: sammy-SC
Differential Revision: D57338528
fbshipit-source-id: cd39ccbe7168c6f093a0e62d5880cbbcd5209c8e
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43985
This is just personal preference.
The name "OnJsError" makes the intent of the abstraction clear: an instance of OnJsError is a function that gets called when a js error is caught.
The name "JsErrorHandlingFunc" is not as good.
Changelog: [General][Breaking] - JsErrorHandler: Rename JsErrorHandlingFunc to OnJsError
Reviewed By: christophpurrer
Differential Revision: D55563580
fbshipit-source-id: 4d20bc984e6633aeac6193b9276a88d76961df2c
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43957
Right now, JsErrorHandler is only used to handle fatal exceptions.
So, let's just scope handleJsError down to handleFatalError.
Changelog: [General][Breaking] - JsErrorHandler: Rename handleJsError to handleFatalError
Reviewed By: cortinico
Differential Revision: D55547901
fbshipit-source-id: 261e0c8fea2852bc95e53c688d90d012d4abea34
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43956
I think we should try to centralize all things js error handling related inside JsErrorHandler. So, I moved this bool into JsErrorHandler.
This makes ReactInstance easier to understand: it removes one member variable from ReactInstance.
Changelog: [Internal]
Reviewed By: cipolleschi
Differential Revision: D55547897
fbshipit-source-id: 73d1e0eedf3896c42cda4ce1013863960585da2c
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43955
Just makes it easier to pass around JsErrorHandler.
We'll need this in D55547897, when we start storing the "has fataled" boolean inside the JsErrorHandler.
Changelog: [internal]
Reviewed By: cipolleschi
Differential Revision: D55547898
fbshipit-source-id: 162faaeff43bada0301de29111b2c17f7ef878c6
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43952
getRuntimeScheduler() allows things to schedule work on the js thread by bypassing main bundle buffering.
This is unsafe: almost everything should be using the buffered runtime executor, unless it sets up bindings used in the main bundle.
I filed a task for the investigation to see if there's any problems. And added it to the code in this diff.
Changelog: [Internal]
Reviewed By: cipolleschi
Differential Revision: D55547899
fbshipit-source-id: 7785b9777e93f36ea0278993332662ed45a20cf2
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43951
## Context
The **early js** error reporting pipeline catches javascript exceptions.
After errors are caught, the pipeline parses the exception, and puts the data into into a map buffer. 🤨
## Problems
We don't need to use a mapbuffer here: The structure of this exception data is known and never changes. (A map buffer is a type-unsafe bag of key/value pairs).
Instead, we could just use lower-level type-safe language primitives: regular C++ struct, and java class w/ fbjni.
## Changes
Migrate the **early js** error handling infra to C++ structs/fbjni.
## Impact
Now, there is no mapbuffer usage on iOS. We could re-introduce it when there is a need.
Changelog: [Internal]
Reviewed By: fkgozali
Differential Revision: D55265170
fbshipit-source-id: cda97633d4c6ccaad541e5d416067390fe6f61b2
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43346
Changelog: [Internal]
(Continuing the theme of reducing integration boilerplate from D54537844.)
This diff changes both `JSExecutor` (Bridge) and `JSRuntime` (Bridgeless) to no longer implement `RuntimeTargetDelegate`. Instead, each of them exposes a `getRuntimeTargetDelegate()` method that returns a stable reference to a target delegate that it *owns*.
To facilitate this, we create a new `FallbackRuntimeTargetDelegate` for use in non-Hermes cases. This replaces *almost* all direct uses of `FallbackRuntimeAgentDelegate` outside of `jsinspector`. I'll follow up in a separate diff to deal with the last case and make the fallback agent delegate fully private.
As a result, changing the `RuntimeTargetDelegate` interface (which we'll need to do for console support) becomes much easier: we only have unit test mocks + two concrete `RuntimeTargetDelegate` implementations (one fallback, one Hermes) to update for each API change.
Reviewed By: huntie
Differential Revision: D54585658
fbshipit-source-id: 08b61c74008ddc36c2b134a40755ef8e43ab21ed
Summary:
Changelog: [internal]
This fixes a crashes during logout on Android and iOS caused by trying to unregister the inspector from instances that were not previously registered. This is because I removed a check in D51459050 that was necessary when the inspector was disabled via the flag (and we call the `unregisterFromInspector` method unconditionally).
This also gates the registration/unregistration on Android properly.
Reviewed By: huntie
Differential Revision: D54357554
fbshipit-source-id: 945288acdabdface324884bee1e832870ec8806f
Summary:
Changelog: [Internal]
This implements the integration of `ReactInstance` with the modern CDP backend.
This is the last missing piece to complete the integration of bridgeless with the modern CDP backend, and now we can test it end to end.
Reviewed By: huntie
Differential Revision: D51459050
fbshipit-source-id: 54e8972ee199cbcc8e5e73d7215a34f008feeaa3
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43113
Changelog: [Internal]
Renames the "Page" concept in the modern CDP backend to "Host". Now all the Target types we have are named consistently after React Native concepts (ReactHost, ReactInstance, JSI Runtime) rather than CDP/browser concepts (Page).
Reviewed By: robhogan
Differential Revision: D53945333
fbshipit-source-id: 90e8b914ba8b4927806cbdd072ca36c78fd2093f
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/43013
Changelog: [Android][Added]
This is a pre-deprecated API to give access to the jsi::Runtime in Android in bridgeless. In bridge, this value is exposed via the ReactContext, but is not implemented in the BridgelessReactContext. We do that here.
This should work out of the box in bridgeless if you are already retrieveing the pointer via ReactContext. However, we recommend users to eventually migrate towards C++ TurboModule or the RuntimeExecutor if possible. This will be removed in the future.
Reviewed By: RSNara
Differential Revision: D53645247
fbshipit-source-id: b98657560c43a625bdf947d19d186952c9b44364
Summary:
Changelog: [Internal]
I'm refactoring the way the Runtime concept works in the modern CDP backend to bring it in line with the Page/Instance concepts.
Overall, this will let us:
* Integrate with engines that require us to instantiate a shared Target-like object (e.g. Hermes AsyncDebuggingAPI) in addition to an per-session Agent-like object.
* Access JSI in a CDP context (both at target setup/teardown time and during a CDP session) to implement our own engine-agnostic functionality (`console` interception, `Runtime.addBinding`, etc).
* Manage CDP execution contexts natively in RN, and (down the line) enable first-class debugging support for multiple Runtimes in an Instance.
The core diffs in this stack will:
* ~~Introduce a `RuntimeTarget` class similar to `{Page,Instance}Target`. ~~
* ~~Make runtime registration explicit (`InstanceTarget::registerRuntime` similar to `PageTarget::registerInstance`). ~~
* ~~Rename the existing `RuntimeAgent` interface to `RuntimeAgentDelegate`.~~
* ~~Create a new concrete `RuntimeAgent` class similar to `{Page,Instance}Agent`.~~
* Provide `RuntimeTarget` and `RuntimeAgent` with primitives for safe JSI access, namely a `RuntimeExecutor` for scheduling work on the JS thread. *← This diff*
* We'll likely develop a similar mechanism for scheduling work on the "main" thread from the JS thread, for when we need to do more than just send a CDP message (which we can already do with the thread-safe `FrontendChannel`) in response to a JS event.
## Architecture diagrams
Before this stack:
https://pxl.cl/4h7m0
After this stack:
https://pxl.cl/4h7m7
Reviewed By: hoxyq
Differential Revision: D53266710
fbshipit-source-id: df3a181fcc8e033c37a7f4f430f23a29b326b56a
Summary:
Changelog: [Internal]
I'm refactoring the way the Runtime concept works in the modern CDP backend to bring it in line with the Page/Instance concepts.
Overall, this will let us:
* Integrate with engines that require us to instantiate a shared Target-like object (e.g. Hermes AsyncDebuggingAPI) in addition to an per-session Agent-like object.
* Access JSI in a CDP context (both at target setup/teardown time and during a CDP session) to implement our own engine-agnostic functionality (`console` interception, `Runtime.addBinding`, etc).
* Manage CDP execution contexts natively in RN, and (down the line) enable first-class debugging support for multiple Runtimes in an Instance.
The core diffs in this stack will:
* Introduce a `RuntimeTarget` class similar to `{Page,Instance}Target`. *← This diff*
* Make runtime registration explicit (`InstanceTarget::registerRuntime` similar to `PageTarget::registerInstance`). *← Also in this diff*
* Rename the existing `RuntimeAgent` interface to `RuntimeAgentDelegate`.
* Create a new concrete `RuntimeAgent` class similar to `{Page,Instance}Agent`.
* Provide `RuntimeTarget` and `RuntimeAgent` with primitives for safe JSI access, namely a `RuntimeExecutor` for scheduling work on the JS thread.
* We'll likely develop a similar mechanism for scheduling work on the "main" thread from the JS thread, for when we need to do more than just send a CDP message (which we can already do with the thread-safe `FrontendChannel`) in response to a JS event.
## Architecture diagrams
Before this stack:
https://pxl.cl/4h7m0
After this stack:
https://pxl.cl/4h7m7
Reviewed By: hoxyq
Differential Revision: D53233914
fbshipit-source-id: 166ae3e25059bd9c9c051a0a3312a3ba78a3935a
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/42746
Changelog: [Internal]
Formally introduces the concept of "session state" to the modern CDP backend, with the simplest possible implementation:
* `PageTargetSession` has a mutable `SessionState` member.
* All agents receive the same `SessionState&` in their constructor (with `SessionState`'s lifetime being the caller's responsibility).
* It's only legal to read/write to `SessionState` on the thread where requests are handled and Agents are created (the "main" thread).
* Agents are expected to play nice and not clobber each other's state in `SessionState`; this is *not* protected with visibility or `const`ness, however.
* We'll probably want to come up with some API-level mechanism to control this as the complexity of our agents grows.
## Current use case: `<Domain>.enable`
The first use case for session state is to let `PageAgent` manage the `Log.enable` and `Runtime.enable` state for the session. This will allow agents created later in the session (or recreated as part of a reload) to emit Log and Runtime notifications without waiting for additional `enable` messages (that the client is not required to send).
We'll likely want to generalise this design to arbitrary domains in some way (e.g. add a top-level domain router that agents register with explicitly?) but I went with the simplest implementation for our current needs.
NOTE: The CDP spec doesn't state this explicitly, but it's clear from Chrome's behaviour that a `<Domain>.enable` command is intended to be session-scoped and survive reloads.
## Future use case: Instance/Runtime state persistence
The `<Domain>.enable` use case could have been solved with passing *immutable* state to Agents (`const SessionState&`). We make the state mutable in anticipation of `HermesRuntimeAgent` needing to store its own state in the session down the line, which we know is going to be needed in order for breakpoints to survive reloads.
Agents that never need to mutate state SHOULD only store this as a const reference.
Reviewed By: huntie
Differential Revision: D53006916
fbshipit-source-id: a0443c507294faa94efdf25b2f1670129774dc78
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/42635
Changelog: [Internal]
Adds a RuntimeAgent interface to the modern CDP backend, plus an `InstanceTargetDelegate::createRuntimeAgent()` method. This allows the RN integration to provide an engine-specific CDP implementation.
This diff includes all the plumbing in Bridge and Bridgeless to route `createRuntimeAgent()` calls to the right place - ending up at `JSExecutor::createRuntimeAgent()` and `JSIRuntimeHolder::createInspectorAgent` respectively - at which point we currently return `nullptr` to signify that JS debugging isn't supported.
## Next steps
In upcoming diffs we'll add concrete implementations of `RuntimeAgent`, and teach both Bridge and Bridgeless to create them as appropriate:
* `HermesRuntimeAgent` for Hermes
* `FallbackRuntimeAgent` for all other JS engines (JSI or not)
We'll also (likely) add assertions to ensure that any JSI runtime that reports itself as "inspectable" (a flag used to control some of the in-app debugging UI) comes with a non-default `createRuntimeAgent()` implementation. We avoid this for now to prevent crashing the modern backend on Hermes.
NOTE: Like the rest of the modern CDP backend, the `RuntimeAgent` API is 100% experimental and subject to change without notice. A *future* version of this API will allow out-of-tree JSI engines to integrate with the modern CDP backend. Either way, it is intended strictly for the use case of integrating with a JS engine, not for adding any other framework-level CDP functionality.
Reviewed By: huntie
Differential Revision: D51231326
fbshipit-source-id: 81e87c5134df73cc4aac0f9d5793a5236b5720d6
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/42636
Changelog: [Internal]
Models the Native instance lifecycle in the modern CDP backend, by:
1. Registering the instance, once created, with `PageTarget`.
2. While an instance is registered, delegating messages from `PageAgent` to an internal `InstanceAgent`.
3. Unregistering the instance once it is invalidated and about to be destroyed.
We use this infrastructure to implement two simple behaviours that will be superseded in future diffs (mainly by delegating work to the JSVM), but that are useful as stubs for testing:
* Sending [`Runtime.executionContextDestroyed`](https://cdpstatus.reactnative.dev/devtools-protocol/tot/Runtime#event-executionContextDestroyed), [`Runtime.executionContextsCleared`](https://cdpstatus.reactnative.dev/devtools-protocol/tot/Runtime#event-executionContextsCleared), and [`Runtime.executionContextCreated`](https://cdpstatus.reactnative.dev/devtools-protocol/tot/Runtime#event-executionContextCreated) events to the frontend when reloading the instance.
* Implementing a toy version of [`Runtime.getHeapUsage`](https://cdpstatus.reactnative.dev/devtools-protocol/tot/Runtime#method-getHeapUsage) (that always reports zero memory usage) to exercise the Page→Instance message dispatching logic.
iOS Bridge/Bridgeless and `PageTargetTest` are the only integrations that exist as of this diff, and are all updated here; Android will follow later.
## Object lifetimes
* PageTarget owns an InstanceTarget that it creates (in `registerInstance`) and destroys (in `unregisterInstance`).
* `registerInstance` returns a raw `InstanceTarget&` reference, which becomes invalid upon calling `unregisterInstance`. It's the caller's responsibility to stop using the reference at the point of calling `unregisterInstance`.
* InstanceTarget holds a raw `InstanceTargetDelegate&` reference. It's the caller's responsibility to keep this reference valid at least until `unregisterInstance` returns.
## Thread safety
* As with PageTarget's constructor and destructor, It's the caller's responsibility to invoke `registerInstance` and `unregisterInstance` on the main thread (or using appropriate synchronisation).
* `InstanceAgent` handles messages on the same thread as `PageAgent` (typically the platform-specific main thread) and receives a copy of the same thread-safe `FrontendChannel` for sending messages back.
Reviewed By: huntie
Differential Revision: D51214056
fbshipit-source-id: 2dc2ff30d2dda6887871831a818aa117ca3e6e91
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/42434
Changelog: [internal]
The flags for the event loop were set up using different mechanisms due to the limitations of the previous feature flags systems. Now we can centralize on the new system and use them consistently on Android and iOS.
Reviewed By: RSNara
Differential Revision: D52819137
fbshipit-source-id: e30a6f2e12b4a027a906502b80a70dd48bb657b6
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/41549
Changelog: [Internal]
Introduces the `JSRuntime` interface as a straightforward wrapper around `jsi::Runtime`, and refactors `ReactInstance` to hold a `JSRuntime` instead of a `jsi::Runtime`. In an upcoming diff we'll add debugging-related methods to `JSRuntime` and specialise their implementations for Hermes.
NOTE: `JSRuntime` is somewhat analogous to `JSExecutor` in the Bridge architecture.
Reviewed By: huntie
Differential Revision: D51447934
fbshipit-source-id: cfcab9ae0dd3d2a34c064abaac6cb676f435e216