diff --git a/packages/react-native/Libraries/Image/RCTImageLoader.mm b/packages/react-native/Libraries/Image/RCTImageLoader.mm index 75362da2dd43..e7e1260240da 100644 --- a/packages/react-native/Libraries/Image/RCTImageLoader.mm +++ b/packages/react-native/Libraries/Image/RCTImageLoader.mm @@ -32,7 +32,7 @@ static NSInteger RCTImageBytesForImage(UIImage *image) return image.images ? image.images.count * singleImageBytes : singleImageBytes; } -static auto currentRequestCount = std::atomic(0); +static constinit auto currentRequestCount = std::atomic(0); static NSError *addResponseHeadersToError(NSError *originalError, NSHTTPURLResponse *response) { diff --git a/packages/react-native/Libraries/Network/RCTNetworkTask.mm b/packages/react-native/Libraries/Network/RCTNetworkTask.mm index e397936d31ba..99c9e237a989 100644 --- a/packages/react-native/Libraries/Network/RCTNetworkTask.mm +++ b/packages/react-native/Libraries/Network/RCTNetworkTask.mm @@ -21,7 +21,7 @@ @implementation RCTNetworkTask { RCTNetworkTask *_selfReference; } -static auto currentRequestId = std::atomic(0); +static constinit auto currentRequestId = std::atomic(0); - (instancetype)initWithRequest:(NSURLRequest *)request handler:(id)handler diff --git a/packages/react-native/React/Base/RCTUtils.mm b/packages/react-native/React/Base/RCTUtils.mm index 21ddfb6ff1f2..57949ad56f88 100644 --- a/packages/react-native/React/Base/RCTUtils.mm +++ b/packages/react-native/React/Base/RCTUtils.mm @@ -386,7 +386,7 @@ UIDeviceOrientation RCTDeviceOrientation(void) CGSize RCTScreenSize(void) { - static std::atomic cachedSize; + static constinit std::atomic cachedSize; __block CGSize size = cachedSize.load(std::memory_order_relaxed); if (CGSizeEqualToSize(size, CGSizeZero)) { diff --git a/packages/react-native/React/CoreModules/RCTDevSettings.mm b/packages/react-native/React/CoreModules/RCTDevSettings.mm index 89a7b0c793e6..0c8eb0cc091c 100644 --- a/packages/react-native/React/CoreModules/RCTDevSettings.mm +++ b/packages/react-native/React/CoreModules/RCTDevSettings.mm @@ -127,7 +127,7 @@ - (void)_reloadWithDefaults:(NSDictionary *)defaultValues #if RCT_DEV_SETTINGS_ENABLE_PACKAGER_CONNECTION static RCTHandlerToken reloadToken; static RCTHandlerToken devMenuToken; -static std::atomic numInitializedModules{0}; +static constinit std::atomic numInitializedModules{0}; #endif @interface RCTDevSettings () { diff --git a/packages/react-native/ReactAndroid/src/main/jni/first-party/fbgloginit/glog_init.cpp b/packages/react-native/ReactAndroid/src/main/jni/first-party/fbgloginit/glog_init.cpp index c7174b832275..34df76e08dc9 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/first-party/fbgloginit/glog_init.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/first-party/fbgloginit/glog_init.cpp @@ -112,7 +112,7 @@ lastResort(const char* tag, const char* msg, const char* arg = nullptr) { namespace facebook::gloginit { void initialize(const char* tag) { - static std::once_flag flag{}; + static constinit std::once_flag flag{}; static auto failed = false; std::call_once(flag, [tag] { diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AnimatedPropBufferEncoder.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AnimatedPropBufferEncoder.cpp index 6331bfe710f1..d8b930215289 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AnimatedPropBufferEncoder.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AnimatedPropBufferEncoder.cpp @@ -9,10 +9,13 @@ #include #include +#include #include #include +#include #include #include +#include namespace facebook::react { @@ -87,74 +90,110 @@ constexpr int CMD_TRANSFORM_PERSPECTIVE = 112; constexpr int CMD_UNIT_PX = 202; constexpr int CMD_UNIT_PERCENT = 203; +using CommandEntry = std::pair; + +// Group by name length so lookup only scans a small set of candidates. +template +constexpr auto indexCommandLengths(std::span entries) { + std::array, MaxLength + 1> index{}; + size_t start = 0; + for (size_t length = 0; length < index.size(); ++length) { + auto end = start; + while (end < entries.size() && entries[end].first.size() == length) { + ++end; + } + index[length] = entries.subspan(start, end - start); + start = end; + } + return index; +} + +std::optional findCommand( + std::string_view name, + std::span> index) { + if (name.size() >= index.size()) { + return std::nullopt; + } + for (const auto& [key, command] : index[name.size()]) { + if (key == name) { + return command; + } + } + return std::nullopt; +} + std::optional propNameToCommand(const std::string& name) { - static const std::unordered_map kMap = { + static constexpr std::array kMap{{ + {"color", CMD_COLOR}, + {"zIndex", CMD_Z_INDEX}, {"opacity", CMD_OPACITY}, {"elevation", CMD_ELEVATION}, - {"zIndex", CMD_Z_INDEX}, - {"shadowOpacity", CMD_SHADOW_OPACITY}, - {"shadowRadius", CMD_SHADOW_RADIUS}, - {"backgroundColor", CMD_BACKGROUND_COLOR}, - {"color", CMD_COLOR}, {"tintColor", CMD_TINT_COLOR}, - {"placeholderTextColor", CMD_PLACEHOLDER_TEXT_COLOR}, + {"transform", CMD_START_OF_TRANSFORM}, + {"borderColor", CMD_BORDER_COLOR}, {"shadowColor", CMD_SHADOW_COLOR}, {"borderRadius", CMD_BORDER_RADIUS}, + {"outlineColor", CMD_OUTLINE_COLOR}, + {"outlineWidth", CMD_OUTLINE_WIDTH}, + {"shadowRadius", CMD_SHADOW_RADIUS}, + {"outlineOffset", CMD_OUTLINE_OFFSET}, + {"shadowOpacity", CMD_SHADOW_OPACITY}, + {"borderEndColor", CMD_BORDER_END_COLOR}, + {"borderTopColor", CMD_BORDER_TOP_COLOR}, + {"backgroundColor", CMD_BACKGROUND_COLOR}, + {"borderLeftColor", CMD_BORDER_LEFT_COLOR}, + {"borderBlockColor", CMD_BORDER_BLOCK_COLOR}, + {"borderRightColor", CMD_BORDER_RIGHT_COLOR}, + {"borderStartColor", CMD_BORDER_START_COLOR}, + {"borderBottomColor", CMD_BORDER_BOTTOM_COLOR}, + {"borderEndEndRadius", CMD_BORDER_END_END_RADIUS}, + {"borderTopEndRadius", CMD_BORDER_TOP_END_RADIUS}, + {"borderBlockEndColor", CMD_BORDER_BLOCK_END_COLOR}, {"borderTopLeftRadius", CMD_BORDER_TOP_LEFT_RADIUS}, + {"borderEndStartRadius", CMD_BORDER_END_START_RADIUS}, + {"borderStartEndRadius", CMD_BORDER_START_END_RADIUS}, {"borderTopRightRadius", CMD_BORDER_TOP_RIGHT_RADIUS}, {"borderTopStartRadius", CMD_BORDER_TOP_START_RADIUS}, - {"borderTopEndRadius", CMD_BORDER_TOP_END_RADIUS}, + {"placeholderTextColor", CMD_PLACEHOLDER_TEXT_COLOR}, + {"borderBlockStartColor", CMD_BORDER_BLOCK_START_COLOR}, + {"borderBottomEndRadius", CMD_BORDER_BOTTOM_END_RADIUS}, {"borderBottomLeftRadius", CMD_BORDER_BOTTOM_LEFT_RADIUS}, + {"borderStartStartRadius", CMD_BORDER_START_START_RADIUS}, {"borderBottomRightRadius", CMD_BORDER_BOTTOM_RIGHT_RADIUS}, {"borderBottomStartRadius", CMD_BORDER_BOTTOM_START_RADIUS}, - {"borderBottomEndRadius", CMD_BORDER_BOTTOM_END_RADIUS}, - {"borderStartStartRadius", CMD_BORDER_START_START_RADIUS}, - {"borderStartEndRadius", CMD_BORDER_START_END_RADIUS}, - {"borderEndStartRadius", CMD_BORDER_END_START_RADIUS}, - {"borderEndEndRadius", CMD_BORDER_END_END_RADIUS}, - {"borderColor", CMD_BORDER_COLOR}, - {"borderTopColor", CMD_BORDER_TOP_COLOR}, - {"borderBottomColor", CMD_BORDER_BOTTOM_COLOR}, - {"borderLeftColor", CMD_BORDER_LEFT_COLOR}, - {"borderRightColor", CMD_BORDER_RIGHT_COLOR}, - {"borderStartColor", CMD_BORDER_START_COLOR}, - {"borderEndColor", CMD_BORDER_END_COLOR}, - {"borderBlockColor", CMD_BORDER_BLOCK_COLOR}, - {"borderBlockStartColor", CMD_BORDER_BLOCK_START_COLOR}, - {"borderBlockEndColor", CMD_BORDER_BLOCK_END_COLOR}, - {"outlineColor", CMD_OUTLINE_COLOR}, - {"outlineOffset", CMD_OUTLINE_OFFSET}, - {"outlineWidth", CMD_OUTLINE_WIDTH}, - {"transform", CMD_START_OF_TRANSFORM}, - }; - auto it = kMap.find(name); - if (it == kMap.end()) { - return std::nullopt; - } - return it->second; + }}; + static constexpr auto kIndex = + indexCommandLengths(kMap); + static_assert( + kIndex.back().data() == + std::span{kMap}.last(kIndex.back().size()).data(), + "Command entries must be sorted by name length"); + return findCommand(name, kIndex); } std::optional transformNameToCommand(const std::string& name) { - static const std::unordered_map kMap = { - {"translateX", CMD_TRANSFORM_TRANSLATE_X}, - {"translateY", CMD_TRANSFORM_TRANSLATE_Y}, + static constexpr std::array kMap{{ {"scale", CMD_TRANSFORM_SCALE}, + {"skewX", CMD_TRANSFORM_SKEW_X}, + {"skewY", CMD_TRANSFORM_SKEW_Y}, + {"matrix", CMD_TRANSFORM_MATRIX}, + {"rotate", CMD_TRANSFORM_ROTATE}, {"scaleX", CMD_TRANSFORM_SCALE_X}, {"scaleY", CMD_TRANSFORM_SCALE_Y}, - {"rotate", CMD_TRANSFORM_ROTATE}, {"rotateX", CMD_TRANSFORM_ROTATE_X}, {"rotateY", CMD_TRANSFORM_ROTATE_Y}, {"rotateZ", CMD_TRANSFORM_ROTATE_Z}, - {"skewX", CMD_TRANSFORM_SKEW_X}, - {"skewY", CMD_TRANSFORM_SKEW_Y}, - {"matrix", CMD_TRANSFORM_MATRIX}, + {"translateX", CMD_TRANSFORM_TRANSLATE_X}, + {"translateY", CMD_TRANSFORM_TRANSLATE_Y}, {"perspective", CMD_TRANSFORM_PERSPECTIVE}, - }; - auto it = kMap.find(name); - if (it == kMap.end()) { - return std::nullopt; - } - return it->second; + }}; + static constexpr auto kIndex = + indexCommandLengths(kMap); + static_assert( + kIndex.back().data() == + std::span{kMap}.last(kIndex.back().size()).data(), + "Command entries must be sorted by name length"); + return findCommand(name, kIndex); } bool packLength( diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp index 8d37b2ba8b01..b5f1eb569b2e 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp @@ -28,8 +28,10 @@ #include #include +#include #include #include +#include #include namespace facebook::react { @@ -81,7 +83,7 @@ namespace { // List of layout-only props extracted from ViewProps.kt used to filter out // component props from Props 1.5 to validate the Props 2.0 output inline bool isLayoutOnlyProp(const std::string& propName) { - static const std::vector layoutOnlyProps = { + static constexpr std::array layoutOnlyProps = { // Flexbox Alignment "alignItems", "alignSelf", @@ -146,8 +148,10 @@ inline bool isLayoutOnlyProp(const std::string& propName) { // Other "collapsable", }; - return std::find(layoutOnlyProps.begin(), layoutOnlyProps.end(), propName) != - layoutOnlyProps.end(); + return std::find( + layoutOnlyProps.begin(), + layoutOnlyProps.end(), + std::string_view{propName}) != layoutOnlyProps.end(); } #endif diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/test/AnimatedPropBufferEncoderTest.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/test/AnimatedPropBufferEncoderTest.cpp index 66b2af196ad1..0e9987bf6d18 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/test/AnimatedPropBufferEncoderTest.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/test/AnimatedPropBufferEncoderTest.cpp @@ -9,9 +9,14 @@ #include #include #include +#include +#include #include #include #include +#include +#include +#include namespace facebook::react { @@ -29,6 +34,8 @@ enum Command : int { CMD_PLACEHOLDER_TEXT_COLOR = 18, CMD_SHADOW_COLOR = 19, CMD_BORDER_RADIUS = 20, + CMD_BORDER_END_END_RADIUS = 32, + CMD_BORDER_COLOR = 40, CMD_BORDER_BLOCK_COLOR = 47, CMD_BORDER_BLOCK_START_COLOR = 48, CMD_BORDER_BLOCK_END_COLOR = 49, @@ -36,12 +43,85 @@ enum Command : int { CMD_OUTLINE_OFFSET = 51, CMD_OUTLINE_WIDTH = 52, CMD_TRANSFORM_TRANSLATE_X = 100, + CMD_TRANSFORM_TRANSLATE_Y = 101, CMD_TRANSFORM_ROTATE = 105, CMD_TRANSFORM_SKEW_Y = 110, + CMD_TRANSFORM_MATRIX = 111, CMD_UNIT_PX = 202, CMD_UNIT_PERCENT = 203, }; +constexpr std::array, 37> kPropCommands{{ + {"opacity", 10}, + {"elevation", 11}, + {"zIndex", 12}, + {"shadowOpacity", 13}, + {"shadowRadius", 14}, + {"backgroundColor", 15}, + {"color", 16}, + {"tintColor", 17}, + {"placeholderTextColor", 18}, + {"shadowColor", 19}, + {"borderRadius", 20}, + {"borderTopLeftRadius", 21}, + {"borderTopRightRadius", 22}, + {"borderTopStartRadius", 23}, + {"borderTopEndRadius", 24}, + {"borderBottomLeftRadius", 25}, + {"borderBottomRightRadius", 26}, + {"borderBottomStartRadius", 27}, + {"borderBottomEndRadius", 28}, + {"borderStartStartRadius", 29}, + {"borderStartEndRadius", 30}, + {"borderEndStartRadius", 31}, + {"borderEndEndRadius", 32}, + {"borderColor", 40}, + {"borderTopColor", 41}, + {"borderBottomColor", 42}, + {"borderLeftColor", 43}, + {"borderRightColor", 44}, + {"borderStartColor", 45}, + {"borderEndColor", 46}, + {"borderBlockColor", 47}, + {"borderBlockStartColor", 48}, + {"borderBlockEndColor", 49}, + {"outlineColor", 50}, + {"outlineOffset", 51}, + {"outlineWidth", 52}, + {"transform", 2}, +}}; + +constexpr std::array, 13> kTransformCommands{{ + {"translateX", 100}, + {"translateY", 101}, + {"scale", 102}, + {"scaleX", 103}, + {"scaleY", 104}, + {"rotate", 105}, + {"rotateX", 106}, + {"rotateY", 107}, + {"rotateZ", 108}, + {"skewX", 109}, + {"skewY", 110}, + {"matrix", 111}, + {"perspective", 112}, +}}; + +std::array lookupBoundaryNames(std::string_view name) { + auto differentCase = std::string{name}; + differentCase[0] = static_cast(differentCase[0] - 'a' + 'A'); + return { + "", + std::string{name.substr(0, name.size() - 1)}, + std::string{name} + "Suffix", + differentCase, + std::string{name} + '\0', + std::string(1, '\0') + std::string{name}, + std::string{name.substr(0, name.size() / 2)} + '\0' + + std::string{name.substr(name.size() / 2)}, + }; +} + } // namespace TEST( @@ -137,6 +217,115 @@ AnimatedPropsBuffer encodeRawProps(const folly::dynamic& props) { } } // namespace +TEST(AnimatedPropBufferEncoderTest, encodesEveryPropertyCommand) { + for (const auto& [name, command] : kPropCommands) { + SCOPED_TRACE(name); + folly::dynamic value = 1.25; + std::vector expectedInts{CMD_START_OF_VIEW, 10, command}; + std::vector expectedDoubles; + if (command == CMD_START_OF_TRANSFORM) { + value = folly::dynamic::array; + expectedInts.push_back(CMD_END_OF_TRANSFORM); + } else if ( + (command >= CMD_BACKGROUND_COLOR && command <= CMD_SHADOW_COLOR) || + (command >= CMD_BORDER_COLOR && command <= CMD_OUTLINE_COLOR)) { + value = int64_t{0xff112233}; + expectedInts.push_back(static_cast(0xff112233)); + } else { + if (command >= CMD_BORDER_RADIUS && + command <= CMD_BORDER_END_END_RADIUS) { + expectedInts.push_back(CMD_UNIT_PX); + } + expectedDoubles.push_back(1.25); + } + expectedInts.push_back(CMD_END_OF_VIEW); + auto buffer = encodeRawProps(folly::dynamic::object(name, value)); + EXPECT_EQ(buffer.ints, expectedInts); + EXPECT_EQ(buffer.doubles, expectedDoubles); + EXPECT_TRUE(buffer.rawProps.empty()); + } +} + +TEST(AnimatedPropBufferEncoderTest, encodesEveryTransformCommand) { + for (const auto& [name, command] : kTransformCommands) { + SCOPED_TRACE(name); + folly::dynamic value = 1.25; + std::vector expectedDoubles{1.25}; + if (command == CMD_TRANSFORM_MATRIX) { + value = folly::dynamic::array; + for (int i = 0; i < 16; ++i) { + value.push_back(1.25); + } + expectedDoubles.assign(16, 1.25); + } + std::vector expectedInts{ + CMD_START_OF_VIEW, 10, CMD_START_OF_TRANSFORM, command}; + if (command == CMD_TRANSFORM_TRANSLATE_X || + command == CMD_TRANSFORM_TRANSLATE_Y) { + expectedInts.push_back(CMD_UNIT_PX); + } + expectedInts.push_back(CMD_END_OF_TRANSFORM); + expectedInts.push_back(CMD_END_OF_VIEW); + auto buffer = encodeRawProps( + folly::dynamic::object( + "transform", + folly::dynamic::array(folly::dynamic::object(name, value)))); + EXPECT_EQ(buffer.ints, expectedInts); + EXPECT_EQ(buffer.doubles, expectedDoubles); + EXPECT_TRUE(buffer.rawProps.empty()); + } +} + +TEST(AnimatedPropBufferEncoderTest, preservesPropertyLookupBoundaryFallbacks) { + for (const auto& mapping : kPropCommands) { + for (const auto& name : lookupBoundaryNames(mapping.first)) { + if (std::any_of( + kPropCommands.begin(), + kPropCommands.end(), + [&](const auto& entry) { return name == entry.first; })) { + continue; + } + SCOPED_TRACE(name); + folly::dynamic props = folly::dynamic::object("opacity", 0.5)(name, 1); + auto buffer = encodeRawProps(props); + EXPECT_EQ( + buffer.ints, + (std::vector{ + CMD_START_OF_VIEW, 10, CMD_RAW_PROPS, CMD_END_OF_VIEW})); + EXPECT_TRUE(buffer.doubles.empty()); + ASSERT_EQ(buffer.rawProps.size(), 1); + EXPECT_EQ(buffer.rawProps[0], props); + } + } +} + +TEST(AnimatedPropBufferEncoderTest, preservesTransformLookupBoundaryFallbacks) { + for (const auto& mapping : kTransformCommands) { + for (const auto& name : lookupBoundaryNames(mapping.first)) { + if (std::any_of( + kTransformCommands.begin(), + kTransformCommands.end(), + [&](const auto& entry) { return name == entry.first; })) { + continue; + } + SCOPED_TRACE(name); + folly::dynamic props = folly::dynamic::object("opacity", 0.5)( + "transform", + folly::dynamic::array( + folly::dynamic::object("scale", 2), + folly::dynamic::object(name, 1))); + auto buffer = encodeRawProps(props); + EXPECT_EQ( + buffer.ints, + (std::vector{ + CMD_START_OF_VIEW, 10, CMD_RAW_PROPS, CMD_END_OF_VIEW})); + EXPECT_TRUE(buffer.doubles.empty()); + ASSERT_EQ(buffer.rawProps.size(), 1); + EXPECT_EQ(buffer.rawProps[0], props); + } + } +} + TEST(AnimatedPropBufferEncoderTest, encodesIntegerRadiusAndTranslation) { auto radius = encodeRawProps(folly::dynamic::object("borderRadius", 4)); EXPECT_EQ( diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/hermes/reactexecutor/OnLoad.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/hermes/reactexecutor/OnLoad.cpp index 53d76082651d..fb890992dd87 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/hermes/reactexecutor/OnLoad.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/hermes/reactexecutor/OnLoad.cpp @@ -25,7 +25,7 @@ static void hermesFatalHandler(const std::string& reason) { __android_log_assert(nullptr, "Hermes", "%s", reason.c_str()); } -static std::once_flag flag; +static constinit std::once_flag flag; static ::hermes::vm::RuntimeConfig makeRuntimeConfig(jlong heapSizeMB) { namespace vm = ::hermes::vm; diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/jni/JReactMarker.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/jni/JReactMarker.cpp index 0b3e7442a04f..ee710f0d0c8c 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/jni/JReactMarker.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/jni/JReactMarker.cpp @@ -18,7 +18,7 @@ const int kInstanceKey = 1; } void JReactMarker::setLogPerfMarkerIfNeeded() { - static std::once_flag flag{}; + static constinit std::once_flag flag{}; std::call_once(flag, []() { ReactMarker::logTaggedMarkerImpl = JReactMarker::logPerfMarker; }); diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/jni/SafeReleaseJniRef.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/jni/SafeReleaseJniRef.cpp index 7eb5f504d77c..f8f571570e23 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/jni/SafeReleaseJniRef.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/jni/SafeReleaseJniRef.cpp @@ -20,7 +20,7 @@ void ensureThreadDurationJNIEnvAttached() { // > exits, and call DetachCurrentThread() from there. // https://github.com/facebookincubator/fbjni/blob/7b7efda0d49b956acf1d3307510e3c73fc55b404/cxx/fbjni/detail/Environment.h#L101 // https://developer.android.com/training/articles/perf-jni#threads - static thread_local std::optional threadScope; + static constinit thread_local std::optional threadScope; if (jni::detail::currentOrNull() == nullptr) { threadScope.emplace(); diff --git a/packages/react-native/ReactCommon/cxxreact/TraceSection.h b/packages/react-native/ReactCommon/cxxreact/TraceSection.h index 2c9ff9ddb5f4..7f956ac699c2 100644 --- a/packages/react-native/ReactCommon/cxxreact/TraceSection.h +++ b/packages/react-native/ReactCommon/cxxreact/TraceSection.h @@ -168,7 +168,7 @@ inline os_log_t instrumentsLogHandle = nullptr; static inline os_log_t getOrCreateInstrumentsLogHandle() { - static std::once_flag flag{}; + static constinit std::once_flag flag{}; std::call_once(flag, []() { if (!instrumentsLogHandle) { instrumentsLogHandle = os_log_create("dev.reactnative.instruments", OS_LOG_CATEGORY_DYNAMIC_TRACING); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 4b24a9161d64..ac8ddb96a112 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<56e127471f63e47798ec619e6fa56738>> */ /** @@ -23,7 +23,7 @@ namespace facebook::react { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wglobal-constructors" -std::unique_ptr accessor_; +constinit std::unique_ptr accessor_; #pragma GCC diagnostic pop bool ReactNativeFeatureFlags::commonTestFlag() { diff --git a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm index 83cfe2308b63..7006bf65e226 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm +++ b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm @@ -42,7 +42,7 @@ namespace { int32_t getUniqueId() { - static std::atomic counter{0}; + static constinit std::atomic counter{0}; return counter++; } diff --git a/packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.cpp b/packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.cpp index b21524aed354..5c4d70b1ef5f 100644 --- a/packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.cpp +++ b/packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.cpp @@ -39,7 +39,7 @@ namespace facebook::react { // Global function pointer for getting current time. Current time // can be injected for testing purposes. -static TimePointFunction g_now = &std::chrono::steady_clock::now; +static constinit TimePointFunction g_now = &std::chrono::steady_clock::now; void g_setNativeAnimatedNowTimestampFunction(TimePointFunction nowFunction) { g_now = nowFunction; } @@ -91,7 +91,8 @@ void mergeObjects(folly::dynamic& out, const folly::dynamic& objectToMerge) { } // namespace -thread_local bool NativeAnimatedNodesManager::isOnRenderThread_{false}; +constinit thread_local bool NativeAnimatedNodesManager::isOnRenderThread_{ + false}; NativeAnimatedNodesManager::NativeAnimatedNodesManager( DirectManipulationCallback&& directManipulationCallback, diff --git a/packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.h b/packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.h index fc42b1c11a3f..ff630b31209f 100644 --- a/packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.h +++ b/packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.h @@ -236,7 +236,7 @@ class NativeAnimatedNodesManager : public std::enable_shared_from_this animatedNode(Tag tag, const folly::dynamic &config) noexcept; - static thread_local bool isOnRenderThread_; + static constinit thread_local bool isOnRenderThread_; std::mutex animatedNodesCreatedAsyncMutex_; std::unordered_map> animatedNodesCreatedAsync_; diff --git a/packages/react-native/ReactCommon/react/renderer/components/text/BaseParagraphProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/text/BaseParagraphProps.cpp index 6175bf755ea5..a3f401079f59 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/text/BaseParagraphProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/text/BaseParagraphProps.cpp @@ -64,7 +64,7 @@ void BaseParagraphProps::setProp( // of these fields together, and because there are some collisions between // propnames parsed here and outside of ParagraphAttributes. // This code is also duplicated in AndroidTextInput. - static auto paDefaults = ParagraphAttributes{}; + static constinit auto paDefaults = ParagraphAttributes{}; switch (hash) { REBUILD_FIELD_SWITCH_CASE( paDefaults, diff --git a/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.cpp index 5ce5172499bd..c85f11971acc 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.cpp @@ -151,7 +151,7 @@ void BaseTextInputProps::setProp( // propnames parsed here and outside of ParagraphAttributes. For example, // textBreakStrategy is duplicated. // This code is also duplicated in ParagraphProps. - static auto paDefaults = ParagraphAttributes{}; + static constinit auto paDefaults = ParagraphAttributes{}; switch (hash) { REBUILD_FIELD_SWITCH_CASE( paDefaults, diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp index 8c12efc94e72..2e934259232e 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp @@ -62,7 +62,7 @@ static int FabricDefaultYogaLog( return size_s; } -thread_local LayoutContext threadLocalLayoutContext; +constinit thread_local LayoutContext threadLocalLayoutContext; YogaLayoutableShadowNode::YogaLayoutableShadowNode( const ShadowNodeFragment& fragment, diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp index 73a20cedd883..2047c5b303b4 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp @@ -118,7 +118,7 @@ void YogaStylableProps::setProp( RawPropsPropNameHash hash, const char* propName, const RawValue& value) { - static const auto ygDefaults = yoga::Style{}; + static constinit const auto ygDefaults = yoga::Style{}; static const auto defaults = YogaStylableProps{}; Props::setProp(context, hash, propName, value); diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.cpp b/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.cpp index ee4f386d614d..a65de91bf0c0 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/EventEmitter.cpp @@ -44,9 +44,7 @@ std::mutex& EventEmitter::DispatchMutex() { } ValueFactory EventEmitter::defaultPayloadFactory() { - static auto payloadFactory = - ValueFactory{[](jsi::Runtime& runtime) { return jsi::Object(runtime); }}; - return payloadFactory; + return [](jsi::Runtime& runtime) { return jsi::Object(runtime); }; } EventEmitter::EventEmitter( diff --git a/packages/react-native/ReactCommon/react/renderer/core/ReactRootViewTagGenerator.cpp b/packages/react-native/ReactCommon/react/renderer/core/ReactRootViewTagGenerator.cpp index 8ae8d1e3d7ad..90b7e3f804dc 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/ReactRootViewTagGenerator.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/ReactRootViewTagGenerator.cpp @@ -15,7 +15,7 @@ constexpr SurfaceId ROOT_VIEW_TAG_INCREMENT = 10; SurfaceId getNextRootViewTag() noexcept { // Numbering of these tags goes from 11, 21, 31, ..., 100501, ... - static std::atomic nextRootViewTag = 1; + static constinit std::atomic nextRootViewTag = 1; return nextRootViewTag += ROOT_VIEW_TAG_INCREMENT; } diff --git a/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp index 5ed77b7b1e81..4ff280cf23ee 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp @@ -25,7 +25,8 @@ namespace facebook::react { * tree simultaneously. This thread_local flag allows enabling the updates for * chosen threads. */ -thread_local bool useRuntimeShadowNodeReferenceUpdateOnThread{false}; // NOLINT +constinit thread_local bool useRuntimeShadowNodeReferenceUpdateOnThread{ + false}; // NOLINT /* static */ void ShadowNode::setUseRuntimeShadowNodeReferenceUpdateOnThread( bool isEnabled) { diff --git a/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeFragment.cpp b/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeFragment.cpp index 186de7a87b90..1534c4971b8e 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeFragment.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/ShadowNodeFragment.cpp @@ -16,20 +16,20 @@ namespace facebook::react { #endif const Props::Shared& ShadowNodeFragment::propsPlaceholder() { - NO_DESTROY static Props::Shared instance; + NO_DESTROY static constinit Props::Shared instance; return instance; } const std::shared_ptr>>& ShadowNodeFragment::childrenPlaceholder() { - NO_DESTROY static std::shared_ptr< + NO_DESTROY static constinit std::shared_ptr< const std::vector>> instance; return instance; } const State::Shared& ShadowNodeFragment::statePlaceholder() { - NO_DESTROY static State::Shared instance; + NO_DESTROY static constinit State::Shared instance; return instance; } diff --git a/packages/react-native/ReactCommon/react/renderer/core/tests/EventEmitterTest.cpp b/packages/react-native/ReactCommon/react/renderer/core/tests/EventEmitterTest.cpp new file mode 100644 index 000000000000..5202b37f19c3 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/core/tests/EventEmitterTest.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include + +namespace facebook::react { + +TEST(EventEmitterTest, defaultPayloadFactoryCreatesFreshEmptyObjects) { + auto runtime = hermes::makeHermesRuntime(); + auto factory = EventEmitter::defaultPayloadFactory(); + + auto first = factory(*runtime).getObject(*runtime); + EXPECT_EQ(first.getPropertyNames(*runtime).size(*runtime), 0u); + first.setProperty(*runtime, "mutation", 42); + EXPECT_EQ(first.getProperty(*runtime, "mutation").getNumber(), 42); + + auto second = factory(*runtime).getObject(*runtime); + EXPECT_EQ(second.getPropertyNames(*runtime).size(*runtime), 0u); + EXPECT_FALSE(second.hasProperty(*runtime, "mutation")); +} + +TEST(EventEmitterTest, defaultPayloadFactoryUsesSuppliedRuntime) { + auto firstRuntime = hermes::makeHermesRuntime(); + auto secondRuntime = hermes::makeHermesRuntime(); + auto factory = EventEmitter::defaultPayloadFactory(); + + auto first = factory(*firstRuntime).getObject(*firstRuntime); + first.setProperty(*firstRuntime, "mutation", 42); + + auto second = factory(*secondRuntime).getObject(*secondRuntime); + EXPECT_EQ(second.getPropertyNames(*secondRuntime).size(*secondRuntime), 0u); + EXPECT_FALSE(second.hasProperty(*secondRuntime, "mutation")); + EXPECT_EQ(first.getProperty(*firstRuntime, "mutation").getNumber(), 42); +} + +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.cpp b/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.cpp index 5e82135e65b1..68f962ff320f 100644 --- a/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.cpp +++ b/packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.cpp @@ -69,12 +69,12 @@ SharedColor parsePlatformColor( if (!resourcePaths.empty()) { // Cache the (costly) JNI results. A cached nullopt is an explicit miss, // distinct from a path that resolves to transparent (ARGB 0). - static std::mutex getColorCacheMutex; + static constinit std::mutex getColorCacheMutex; static folly::EvictingCacheMap> getColorCache(64); // Listen for appearance changes, which should invalidate the cache - static std::once_flag setupCacheInvalidation; + static constinit std::once_flag setupCacheInvalidation; std::call_once( setupCacheInvalidation, configurePlatformColorCacheInvalidationHook, diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Legacy.cpp b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Legacy.cpp index 90057c69124b..552ab8104ed3 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Legacy.cpp +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Legacy.cpp @@ -133,7 +133,7 @@ void RuntimeScheduler_Legacy::executeNowOnTheSameThread( RawCallback&& callback) { TraceSection s("RuntimeScheduler::executeNowOnTheSameThread"); - static thread_local jsi::Runtime* runtimePtr = nullptr; + static constinit thread_local jsi::Runtime* runtimePtr = nullptr; if (runtimePtr == nullptr) { runtimeAccessRequests_ += 1; diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.cpp b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.cpp index 791a4f3a8d0b..2e57e23b0ce2 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.cpp +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.cpp @@ -153,7 +153,7 @@ void RuntimeScheduler_Modern::executeNowOnTheSameThread( RawCallback&& callback) { TraceSection s("RuntimeScheduler::executeNowOnTheSameThread"); - static thread_local jsi::Runtime* runtimePtr = nullptr; + static constinit thread_local jsi::Runtime* runtimePtr = nullptr; auto currentTime = now_(); auto priority = SchedulerPriority::ImmediatePriority; diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/Task.cpp b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/Task.cpp index fa44d3d6f812..fced88bb4079 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/Task.cpp +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/Task.cpp @@ -13,7 +13,7 @@ namespace facebook::react { namespace { inline uint64_t getNextId() noexcept { - static std::atomic nextId = 1; + static constinit std::atomic nextId = 1; return nextId++; } diff --git a/packages/react-native/ReactCommon/react/renderer/telemetry/TransactionTelemetry.cpp b/packages/react-native/ReactCommon/react/renderer/telemetry/TransactionTelemetry.cpp index a5506321e04f..e30402c6f047 100644 --- a/packages/react-native/ReactCommon/react/renderer/telemetry/TransactionTelemetry.cpp +++ b/packages/react-native/ReactCommon/react/renderer/telemetry/TransactionTelemetry.cpp @@ -13,7 +13,8 @@ namespace facebook::react { -thread_local TransactionTelemetry* threadLocalTransactionTelemetry = nullptr; +constinit thread_local TransactionTelemetry* threadLocalTransactionTelemetry = + nullptr; TransactionTelemetry::TransactionTelemetry() : TransactionTelemetry(telemetryTimePointNow) {} diff --git a/packages/react-native/ReactCommon/reactperflogger/reactperflogger/ReactPerfetto.cpp b/packages/react-native/ReactCommon/reactperflogger/reactperflogger/ReactPerfetto.cpp index 77ebb2845ada..86f7b3375406 100644 --- a/packages/react-native/ReactCommon/reactperflogger/reactperflogger/ReactPerfetto.cpp +++ b/packages/react-native/ReactCommon/reactperflogger/reactperflogger/ReactPerfetto.cpp @@ -22,7 +22,7 @@ namespace facebook::react { -std::once_flag perfettoInit; +constinit std::once_flag perfettoInit; void initializePerfetto() { std::call_once(perfettoInit, []() { perfetto::TracingInitArgs args; diff --git a/packages/react-native/ReactCommon/runtimeexecutor/platform/ios/ReactCommon/RuntimeExecutorSyncUIThreadUtils.mm b/packages/react-native/ReactCommon/runtimeexecutor/platform/ios/ReactCommon/RuntimeExecutorSyncUIThreadUtils.mm index 77273fdf9475..3119ee46bd40 100644 --- a/packages/react-native/ReactCommon/runtimeexecutor/platform/ios/ReactCommon/RuntimeExecutorSyncUIThreadUtils.mm +++ b/packages/react-native/ReactCommon/runtimeexecutor/platform/ios/ReactCommon/RuntimeExecutorSyncUIThreadUtils.mm @@ -53,7 +53,7 @@ OnScopeExit onScopeExit(^{ // Protects access to g_uiTask std::mutex &g_mutex() { - static std::mutex mutex; + static constinit std::mutex mutex; return mutex; } @@ -65,13 +65,13 @@ OnScopeExit onScopeExit(^{ std::mutex &g_ticket() { - static std::mutex ticket; + static constinit std::mutex ticket; return ticket; } std::optional &g_uiTask() { - static std::optional uiTaskQueue; + static constinit std::optional uiTaskQueue; return uiTaskQueue; } diff --git a/packages/react-native/ReactCommon/yoga/test/BaselineTest.cpp b/packages/react-native/ReactCommon/yoga/test/BaselineTest.cpp index 5e5c96ae892f..505ceda62b0f 100644 --- a/packages/react-native/ReactCommon/yoga/test/BaselineTest.cpp +++ b/packages/react-native/ReactCommon/yoga/test/BaselineTest.cpp @@ -19,6 +19,20 @@ namespace facebook::yoga { namespace { +TEST(ConfigTest, defaultConfigIsConstexpr) { +#if defined(_WIN32) + const auto& config = Config::getDefault(); + const auto copy = config; +#else + constexpr const auto& config = Config::getDefault(); + constexpr auto copy = config; + static_assert(&config == &Config::getDefault()); +#endif + + EXPECT_EQ(&config, YGConfigGetDefault()); + EXPECT_EQ(copy.getPointScaleFactor(), config.getPointScaleFactor()); +} + void setMeasuredSize(Node& node, float width, float height) { node.setLayoutMeasuredDimension(width, Dimension::Width); node.setLayoutMeasuredDimension(height, Dimension::Height); diff --git a/packages/react-native/ReactCommon/yoga/yoga/config/Config.cpp b/packages/react-native/ReactCommon/yoga/yoga/config/Config.cpp index 0f5fb019cb18..c589a9c4e2aa 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/config/Config.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/config/Config.cpp @@ -106,7 +106,8 @@ void Config::log( LogLevel logLevel, const char* format, va_list args) const { - logger_(this, node, unscopedEnum(logLevel), format, args); + const auto logger = logger_ != nullptr ? logger_ : getDefaultLogger(); + logger(this, node, unscopedEnum(logLevel), format, args); } void Config::setCloneNodeCallback(YGCloneNodeFunc cloneNode) { @@ -127,9 +128,11 @@ YGNodeRef Config::cloneNode( return clone; } +#if defined(_WIN32) /*static*/ const Config& Config::getDefault() { - static Config config{getDefaultLogger()}; + static constexpr Config config{nullptr}; return config; } +#endif } // namespace facebook::yoga diff --git a/packages/react-native/ReactCommon/yoga/yoga/config/Config.h b/packages/react-native/ReactCommon/yoga/yoga/config/Config.h index 90bb578e65a0..95f63e87a483 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/config/Config.h +++ b/packages/react-native/ReactCommon/yoga/yoga/config/Config.h @@ -32,7 +32,7 @@ bool configUpdateInvalidatesLayout( class YG_EXPORT Config : public ::YGConfig { public: - explicit Config(YGLogger logger) : logger_{logger} {} + explicit constexpr Config(YGLogger logger) : logger_{logger} {} void setUseWebDefaults(bool useWebDefaults); bool useWebDefaults() const; @@ -66,9 +66,20 @@ class YG_EXPORT Config : public ::YGConfig { YGNodeRef cloneNode(YGNodeConstRef node, YGNodeConstRef owner, size_t childIndex) const; +#if defined(_WIN32) static const Config& getDefault(); +#else + static constexpr const Config& getDefault() { + return defaultConfig_; + } +#endif private: +#if !defined(_WIN32) + // NOLINTNEXTLINE(facebook-hte-NonPodStaticDeclaration) + static constinit const Config defaultConfig_; +#endif + YGCloneNodeFunc cloneNodeCallback_{nullptr}; YGLogger logger_{}; @@ -82,6 +93,10 @@ class YG_EXPORT Config : public ::YGConfig { void* context_ = nullptr; }; +#if !defined(_WIN32) +inline constexpr Config Config::defaultConfig_{nullptr}; +#endif + inline Config* resolveRef(const YGConfigRef ref) { return static_cast(ref); } diff --git a/packages/react-native/ReactCxxPlatform/react/profiling/perfetto.cpp b/packages/react-native/ReactCxxPlatform/react/profiling/perfetto.cpp index c15a1179ae77..cc448e654ae8 100644 --- a/packages/react-native/ReactCxxPlatform/react/profiling/perfetto.cpp +++ b/packages/react-native/ReactCxxPlatform/react/profiling/perfetto.cpp @@ -11,7 +11,7 @@ #include void initializePerfetto() { - static std::once_flag s_PerfettoIsInitialized; + static constinit std::once_flag s_PerfettoIsInitialized; std::call_once(s_PerfettoIsInitialized, []() { perfetto::TracingInitArgs args; diff --git a/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlags.cpp-template.js b/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlags.cpp-template.js index 32d4e1788582..6c51a17a5817 100644 --- a/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlags.cpp-template.js +++ b/packages/react-native/scripts/featureflags/templates/common-cxx/ReactNativeFeatureFlags.cpp-template.js @@ -31,7 +31,7 @@ namespace facebook::react { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wglobal-constructors" -std::unique_ptr accessor_; +constinit std::unique_ptr accessor_; #pragma GCC diagnostic pop ${Object.entries(definitions.common) diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api index 6d9ac1caa787..0b8d391a4639 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api @@ -6560,13 +6560,13 @@ constexpr bool facebook::yoga::operator>=(facebook::yoga::FloatOptional lhs, fac constexpr facebook::yoga::FloatOptional facebook::yoga::operator+(facebook::yoga::FloatOptional lhs, facebook::yoga::FloatOptional rhs); class facebook::yoga::Config : public YGConfig { - public Config(YGLogger logger); public YGNodeRef cloneNode(YGNodeConstRef node, YGNodeConstRef owner, size_t childIndex) const; public bool hasErrata(facebook::yoga::Errata errata) const; public bool useWebDefaults() const; + public constexpr Config(YGLogger logger); public facebook::yoga::Errata getErrata() const; public float getPointScaleFactor() const; - public static const facebook::yoga::Config& getDefault(); + public static constexpr const facebook::yoga::Config& getDefault(); public uint32_t getVersion() const noexcept; public void addErrata(facebook::yoga::Errata errata); public void log(const facebook::yoga::Node* node, facebook::yoga::LogLevel logLevel, const char* format, va_list args) const; diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api index d2b41ea569c8..063d23740fac 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api @@ -11010,13 +11010,13 @@ constexpr bool facebook::yoga::operator>=(facebook::yoga::FloatOptional lhs, fac constexpr facebook::yoga::FloatOptional facebook::yoga::operator+(facebook::yoga::FloatOptional lhs, facebook::yoga::FloatOptional rhs); class facebook::yoga::Config : public YGConfig { - public Config(YGLogger logger); public YGNodeRef cloneNode(YGNodeConstRef node, YGNodeConstRef owner, size_t childIndex) const; public bool hasErrata(facebook::yoga::Errata errata) const; public bool useWebDefaults() const; + public constexpr Config(YGLogger logger); public facebook::yoga::Errata getErrata() const; public float getPointScaleFactor() const; - public static const facebook::yoga::Config& getDefault(); + public static constexpr const facebook::yoga::Config& getDefault(); public uint32_t getVersion() const noexcept; public void addErrata(facebook::yoga::Errata errata); public void log(const facebook::yoga::Node* node, facebook::yoga::LogLevel logLevel, const char* format, va_list args) const; diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api index 57f7bc098311..636dea874c76 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api @@ -6409,13 +6409,13 @@ constexpr bool facebook::yoga::operator>=(facebook::yoga::FloatOptional lhs, fac constexpr facebook::yoga::FloatOptional facebook::yoga::operator+(facebook::yoga::FloatOptional lhs, facebook::yoga::FloatOptional rhs); class facebook::yoga::Config : public YGConfig { - public Config(YGLogger logger); public YGNodeRef cloneNode(YGNodeConstRef node, YGNodeConstRef owner, size_t childIndex) const; public bool hasErrata(facebook::yoga::Errata errata) const; public bool useWebDefaults() const; + public constexpr Config(YGLogger logger); public facebook::yoga::Errata getErrata() const; public float getPointScaleFactor() const; - public static const facebook::yoga::Config& getDefault(); + public static constexpr const facebook::yoga::Config& getDefault(); public uint32_t getVersion() const noexcept; public void addErrata(facebook::yoga::Errata errata); public void log(const facebook::yoga::Node* node, facebook::yoga::LogLevel logLevel, const char* format, va_list args) const; diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api index 57f7bc098311..636dea874c76 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api @@ -6409,13 +6409,13 @@ constexpr bool facebook::yoga::operator>=(facebook::yoga::FloatOptional lhs, fac constexpr facebook::yoga::FloatOptional facebook::yoga::operator+(facebook::yoga::FloatOptional lhs, facebook::yoga::FloatOptional rhs); class facebook::yoga::Config : public YGConfig { - public Config(YGLogger logger); public YGNodeRef cloneNode(YGNodeConstRef node, YGNodeConstRef owner, size_t childIndex) const; public bool hasErrata(facebook::yoga::Errata errata) const; public bool useWebDefaults() const; + public constexpr Config(YGLogger logger); public facebook::yoga::Errata getErrata() const; public float getPointScaleFactor() const; - public static const facebook::yoga::Config& getDefault(); + public static constexpr const facebook::yoga::Config& getDefault(); public uint32_t getVersion() const noexcept; public void addErrata(facebook::yoga::Errata errata); public void log(const facebook::yoga::Node* node, facebook::yoga::LogLevel logLevel, const char* format, va_list args) const; diff --git a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api index 9815b007ef82..1ca098e4b6f9 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api @@ -8313,13 +8313,13 @@ constexpr bool facebook::yoga::operator>=(facebook::yoga::FloatOptional lhs, fac constexpr facebook::yoga::FloatOptional facebook::yoga::operator+(facebook::yoga::FloatOptional lhs, facebook::yoga::FloatOptional rhs); class facebook::yoga::Config : public YGConfig { - public Config(YGLogger logger); public YGNodeRef cloneNode(YGNodeConstRef node, YGNodeConstRef owner, size_t childIndex) const; public bool hasErrata(facebook::yoga::Errata errata) const; public bool useWebDefaults() const; + public constexpr Config(YGLogger logger); public facebook::yoga::Errata getErrata() const; public float getPointScaleFactor() const; - public static const facebook::yoga::Config& getDefault(); + public static constexpr const facebook::yoga::Config& getDefault(); public uint32_t getVersion() const noexcept; public void addErrata(facebook::yoga::Errata errata); public void log(const facebook::yoga::Node* node, facebook::yoga::LogLevel logLevel, const char* format, va_list args) const; diff --git a/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api index 7d95a55afddb..4d74084f2445 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleFrameworksCxx.api @@ -12796,13 +12796,13 @@ constexpr bool facebook::yoga::operator>=(facebook::yoga::FloatOptional lhs, fac constexpr facebook::yoga::FloatOptional facebook::yoga::operator+(facebook::yoga::FloatOptional lhs, facebook::yoga::FloatOptional rhs); class facebook::yoga::Config : public YGConfig { - public Config(YGLogger logger); public YGNodeRef cloneNode(YGNodeConstRef node, YGNodeConstRef owner, size_t childIndex) const; public bool hasErrata(facebook::yoga::Errata errata) const; public bool useWebDefaults() const; + public constexpr Config(YGLogger logger); public facebook::yoga::Errata getErrata() const; public float getPointScaleFactor() const; - public static const facebook::yoga::Config& getDefault(); + public static constexpr const facebook::yoga::Config& getDefault(); public uint32_t getVersion() const noexcept; public void addErrata(facebook::yoga::Errata errata); public void log(const facebook::yoga::Node* node, facebook::yoga::LogLevel logLevel, const char* format, va_list args) const; diff --git a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api index e74431082e29..df4b2417b5af 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleNewarchCxx.api @@ -8164,13 +8164,13 @@ constexpr bool facebook::yoga::operator>=(facebook::yoga::FloatOptional lhs, fac constexpr facebook::yoga::FloatOptional facebook::yoga::operator+(facebook::yoga::FloatOptional lhs, facebook::yoga::FloatOptional rhs); class facebook::yoga::Config : public YGConfig { - public Config(YGLogger logger); public YGNodeRef cloneNode(YGNodeConstRef node, YGNodeConstRef owner, size_t childIndex) const; public bool hasErrata(facebook::yoga::Errata errata) const; public bool useWebDefaults() const; + public constexpr Config(YGLogger logger); public facebook::yoga::Errata getErrata() const; public float getPointScaleFactor() const; - public static const facebook::yoga::Config& getDefault(); + public static constexpr const facebook::yoga::Config& getDefault(); public uint32_t getVersion() const noexcept; public void addErrata(facebook::yoga::Errata errata); public void log(const facebook::yoga::Node* node, facebook::yoga::LogLevel logLevel, const char* format, va_list args) const; diff --git a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api index 08697b483f6e..1c4998b3d189 100644 --- a/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api @@ -8172,13 +8172,13 @@ constexpr bool facebook::yoga::operator>=(facebook::yoga::FloatOptional lhs, fac constexpr facebook::yoga::FloatOptional facebook::yoga::operator+(facebook::yoga::FloatOptional lhs, facebook::yoga::FloatOptional rhs); class facebook::yoga::Config : public YGConfig { - public Config(YGLogger logger); public YGNodeRef cloneNode(YGNodeConstRef node, YGNodeConstRef owner, size_t childIndex) const; public bool hasErrata(facebook::yoga::Errata errata) const; public bool useWebDefaults() const; + public constexpr Config(YGLogger logger); public facebook::yoga::Errata getErrata() const; public float getPointScaleFactor() const; - public static const facebook::yoga::Config& getDefault(); + public static constexpr const facebook::yoga::Config& getDefault(); public uint32_t getVersion() const noexcept; public void addErrata(facebook::yoga::Errata errata); public void log(const facebook::yoga::Node* node, facebook::yoga::LogLevel logLevel, const char* format, va_list args) const; diff --git a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api index cd608ca12bc3..dfbc4d44eccf 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api @@ -3795,13 +3795,13 @@ constexpr bool facebook::yoga::operator>=(facebook::yoga::FloatOptional lhs, fac constexpr facebook::yoga::FloatOptional facebook::yoga::operator+(facebook::yoga::FloatOptional lhs, facebook::yoga::FloatOptional rhs); class facebook::yoga::Config : public YGConfig { - public Config(YGLogger logger); public YGNodeRef cloneNode(YGNodeConstRef node, YGNodeConstRef owner, size_t childIndex) const; public bool hasErrata(facebook::yoga::Errata errata) const; public bool useWebDefaults() const; + public constexpr Config(YGLogger logger); public facebook::yoga::Errata getErrata() const; public float getPointScaleFactor() const; - public static const facebook::yoga::Config& getDefault(); + public static constexpr const facebook::yoga::Config& getDefault(); public uint32_t getVersion() const noexcept; public void addErrata(facebook::yoga::Errata errata); public void log(const facebook::yoga::Node* node, facebook::yoga::LogLevel logLevel, const char* format, va_list args) const; diff --git a/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api index c06d3fc44d2a..40d47068ebce 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonFrameworksCxx.api @@ -8143,13 +8143,13 @@ constexpr bool facebook::yoga::operator>=(facebook::yoga::FloatOptional lhs, fac constexpr facebook::yoga::FloatOptional facebook::yoga::operator+(facebook::yoga::FloatOptional lhs, facebook::yoga::FloatOptional rhs); class facebook::yoga::Config : public YGConfig { - public Config(YGLogger logger); public YGNodeRef cloneNode(YGNodeConstRef node, YGNodeConstRef owner, size_t childIndex) const; public bool hasErrata(facebook::yoga::Errata errata) const; public bool useWebDefaults() const; + public constexpr Config(YGLogger logger); public facebook::yoga::Errata getErrata() const; public float getPointScaleFactor() const; - public static const facebook::yoga::Config& getDefault(); + public static constexpr const facebook::yoga::Config& getDefault(); public uint32_t getVersion() const noexcept; public void addErrata(facebook::yoga::Errata errata); public void log(const facebook::yoga::Node* node, facebook::yoga::LogLevel logLevel, const char* format, va_list args) const; diff --git a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api index 1da6bfffd246..845fb97ab917 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonNewarchCxx.api @@ -3788,13 +3788,13 @@ constexpr bool facebook::yoga::operator>=(facebook::yoga::FloatOptional lhs, fac constexpr facebook::yoga::FloatOptional facebook::yoga::operator+(facebook::yoga::FloatOptional lhs, facebook::yoga::FloatOptional rhs); class facebook::yoga::Config : public YGConfig { - public Config(YGLogger logger); public YGNodeRef cloneNode(YGNodeConstRef node, YGNodeConstRef owner, size_t childIndex) const; public bool hasErrata(facebook::yoga::Errata errata) const; public bool useWebDefaults() const; + public constexpr Config(YGLogger logger); public facebook::yoga::Errata getErrata() const; public float getPointScaleFactor() const; - public static const facebook::yoga::Config& getDefault(); + public static constexpr const facebook::yoga::Config& getDefault(); public uint32_t getVersion() const noexcept; public void addErrata(facebook::yoga::Errata errata); public void log(const facebook::yoga::Node* node, facebook::yoga::LogLevel logLevel, const char* format, va_list args) const; diff --git a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api index 1da6bfffd246..845fb97ab917 100644 --- a/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api @@ -3788,13 +3788,13 @@ constexpr bool facebook::yoga::operator>=(facebook::yoga::FloatOptional lhs, fac constexpr facebook::yoga::FloatOptional facebook::yoga::operator+(facebook::yoga::FloatOptional lhs, facebook::yoga::FloatOptional rhs); class facebook::yoga::Config : public YGConfig { - public Config(YGLogger logger); public YGNodeRef cloneNode(YGNodeConstRef node, YGNodeConstRef owner, size_t childIndex) const; public bool hasErrata(facebook::yoga::Errata errata) const; public bool useWebDefaults() const; + public constexpr Config(YGLogger logger); public facebook::yoga::Errata getErrata() const; public float getPointScaleFactor() const; - public static const facebook::yoga::Config& getDefault(); + public static constexpr const facebook::yoga::Config& getDefault(); public uint32_t getVersion() const noexcept; public void addErrata(facebook::yoga::Errata errata); public void log(const facebook::yoga::Node* node, facebook::yoga::LogLevel logLevel, const char* format, va_list args) const;