diff --git a/ReactCommon/fabric/core/primitives/RawProps.h b/ReactCommon/fabric/core/primitives/RawProps.h index 6a87f688b1d..29ac85bcbda 100644 --- a/ReactCommon/fabric/core/primitives/RawProps.h +++ b/ReactCommon/fabric/core/primitives/RawProps.h @@ -116,6 +116,12 @@ class RawProps final { // Case 2: Source data is represented as `folly::dynamic`. folly::dynamic dynamic_; + /* + * The index of a prop value that was evaluated on the previous iterations of + * calling `at()`. + */ + mutable int keyIndexCursor_{0}; + /* * Parsed artefacts: * To be used by `RawPropParser`. diff --git a/ReactCommon/fabric/core/primitives/RawPropsParser.cpp b/ReactCommon/fabric/core/primitives/RawPropsParser.cpp index c829ad0f44e..0da2edf6202 100644 --- a/ReactCommon/fabric/core/primitives/RawPropsParser.cpp +++ b/ReactCommon/fabric/core/primitives/RawPropsParser.cpp @@ -17,6 +17,8 @@ RawValue const *RawPropsParser::at( RawProps const &rawProps, RawPropsKey const &key) const { if (UNLIKELY(!ready_)) { + // This is not thread-safe part; this happens only during initialization of + // a `ComponentDescriptor` where it is actually safe. keys_.push_back(key); nameToIndex_.insert(key, size_); size_++; @@ -24,14 +26,14 @@ RawValue const *RawPropsParser::at( } do { - keyIndex_++; + rawProps.keyIndexCursor_++; - if (UNLIKELY(keyIndex_ >= size_)) { - keyIndex_ = 0; + if (UNLIKELY(rawProps.keyIndexCursor_ >= size_)) { + rawProps.keyIndexCursor_ = 0; } - } while (UNLIKELY(key != keys_[keyIndex_])); + } while (UNLIKELY(key != keys_[rawProps.keyIndexCursor_])); - auto valueIndex = rawProps.keyIndexToValueIndex_[keyIndex_]; + auto valueIndex = rawProps.keyIndexToValueIndex_[rawProps.keyIndexCursor_]; return valueIndex == kRawPropsValueIndexEmpty ? nullptr : &rawProps.values_[valueIndex]; } @@ -39,13 +41,14 @@ RawValue const *RawPropsParser::at( void RawPropsParser::postPrepare() { ready_ = true; nameToIndex_.reindex(); - // Next increment will give `0`. - keyIndex_ = size_ - 1; } void RawPropsParser::preparse(RawProps const &rawProps) const { rawProps.keyIndexToValueIndex_.resize(size_, kRawPropsValueIndexEmpty); + // Resetting the cursor, the next increment will give `0`. + rawProps.keyIndexCursor_ = size_ - 1; + switch (rawProps.mode_) { case RawProps::Mode::Empty: return; diff --git a/ReactCommon/fabric/core/primitives/RawPropsParser.h b/ReactCommon/fabric/core/primitives/RawPropsParser.h index 8a0f8b6e138..e9b142fdd51 100644 --- a/ReactCommon/fabric/core/primitives/RawPropsParser.h +++ b/ReactCommon/fabric/core/primitives/RawPropsParser.h @@ -69,8 +69,6 @@ class RawPropsParser final { mutable better::small_vector keys_{}; mutable RawPropsKeyMap nameToIndex_{}; - - mutable int keyIndex_{0}; mutable int size_{0}; mutable bool ready_{false}; };