mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
57dd48b246
Summary: Exceptions in C++ work quite differently from exceptions in other languages. To make exceptions actually work **correctly** all the code needs to be written with "exceptions in mind" (e.g., see https://www.stroustrup.com/except.pdf). In short, if the code is not "exceptions ready", throwing an exception causes memory leaks, dangling pointers, and invariant violations all over the place, which will probably cause another crashes down the road (which will be especially hard to investigate and attribute to the original issue). Fabric Core (Layout, Props parsing, ShadowNodes management, and so on) does not use exceptions because in most (all?) the cases the exception is now recoverable. So, if a program detects some internal state invariant violation or missing some resource, *logically* it's fatal. We also don't want to pay code-size and performance tax for exception support, so that's why we don't use them. It's just not the right fit for Fabric Core. This does not mean that exceptions don't happen though. C++ standard library can throw them... sometimes. And if our library is compiled with exceptions enabled (still the case, unfortunately), an exception can bubble to JavaScript code and losing all context down the road. And it's hard to investigate such crashes. To isolate those occasional exceptions inside C++ core we are marking all C++/JS boundaries with `noexcept` that stops the bubbling. I hope that will give us much more informative crash reports. Changelog: [Internal] Fabric-specific internal change. Reviewed By: sammy-SC Differential Revision: D23787492 fbshipit-source-id: 0822dbf36fc680c15b02b5cd0f2d87328296b642
79 lines
2.2 KiB
C++
79 lines
2.2 KiB
C++
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
|
|
#include <jsi/jsi.h>
|
|
|
|
namespace facebook {
|
|
namespace react {
|
|
|
|
/*
|
|
* `EventTarget` represents storage of a weak instance handle object with some
|
|
* information about the possibility of retaining that strongly on demand.
|
|
* Note: Retaining an `EventTarget` does *not* guarantee that actual event
|
|
* target (a JavaScript object) is retaining and/or valid in JavaScript realm.
|
|
* The `EventTarget` retains an `instanceHandle` value in `unsafe-unretained`
|
|
* manner.
|
|
* All `EventTarget` instances must be deallocated before
|
|
* stopping JavaScript machine.
|
|
*/
|
|
class EventTarget {
|
|
public:
|
|
/*
|
|
* We have to repeat `Tag` type definition here because `events` module does
|
|
* not depend on `core` module (and should not).
|
|
*/
|
|
using Tag = int32_t;
|
|
|
|
/*
|
|
* Constructs an EventTarget from a weak instance handler and a tag.
|
|
*/
|
|
EventTarget(jsi::Runtime &runtime, jsi::Value const &instanceHandle, Tag tag);
|
|
|
|
/*
|
|
* Sets the `enabled` flag that allows creating a strong instance handle from
|
|
* a weak one.
|
|
*/
|
|
void setEnabled(bool enabled) const;
|
|
|
|
/*
|
|
* Retains an instance handler by creating a strong reference to it.
|
|
* If the EventTarget is disabled, does nothing.
|
|
*/
|
|
void retain(jsi::Runtime &runtime) const;
|
|
|
|
/*
|
|
* Releases the instance handler by nulling a strong reference to it.
|
|
*/
|
|
void release(jsi::Runtime &runtime) const;
|
|
|
|
/*
|
|
* Creates and returns the `instanceHandle`.
|
|
* Returns `null` if the `instanceHandle` is not retained at this moment.
|
|
*/
|
|
jsi::Value getInstanceHandle(jsi::Runtime &runtime) const;
|
|
|
|
/*
|
|
* Deprecated. Do not use.
|
|
*/
|
|
Tag getTag() const;
|
|
|
|
private:
|
|
mutable bool enabled_{false}; // Protected by `EventEmitter::DispatchMutex()`.
|
|
mutable jsi::WeakObject weakInstanceHandle_; // Protected by `jsi::Runtime &`.
|
|
mutable jsi::Value strongInstanceHandle_; // Protected by `jsi::Runtime &`.
|
|
Tag tag_;
|
|
};
|
|
|
|
using SharedEventTarget = std::shared_ptr<const EventTarget>;
|
|
|
|
} // namespace react
|
|
} // namespace facebook
|