diff --git a/Libraries/LibJS/Runtime/RegExpLegacyStaticProperties.cpp b/Libraries/LibJS/Runtime/RegExpLegacyStaticProperties.cpp index 8788bcc7956..620ceb33d7d 100644 --- a/Libraries/LibJS/Runtime/RegExpLegacyStaticProperties.cpp +++ b/Libraries/LibJS/Runtime/RegExpLegacyStaticProperties.cpp @@ -15,9 +15,12 @@ void RegExpLegacyStaticProperties::invalidate() { m_input = {}; m_last_match = {}; + m_last_match_string = {}; m_last_paren = {}; m_left_context = {}; + m_left_context_string = {}; m_right_context = {}; + m_right_context_string = {}; m_$1 = {}; m_$2 = {}; m_$3 = {}; @@ -92,7 +95,7 @@ void update_legacy_regexp_static_properties(RegExpConstructor& constructor, Utf1 // 8. Set the value of C’s [[RegExpLastMatch]] internal slot to a String whose length is endIndex - startIndex and containing the code units from S with indices startIndex through endIndex - 1, in ascending order. auto last_match = string.view().substring_view(start_index, end_index - start_index); - legacy_static_properties.set_last_match(Utf16String::create(last_match)); + legacy_static_properties.set_last_match(last_match); // 9. If n > 0, set the value of C’s [[RegExpLastParen]] internal slot to the last element of capturedValues. if (group_count > 0) { @@ -106,11 +109,11 @@ void update_legacy_regexp_static_properties(RegExpConstructor& constructor, Utf1 // 11. Set the value of C’s [[RegExpLeftContext]] internal slot to a String whose length is startIndex and containing the code units from S with indices 0 through startIndex - 1, in ascending order. auto left_context = string.view().substring_view(0, start_index); - legacy_static_properties.set_left_context(Utf16String::create(left_context)); + legacy_static_properties.set_left_context(left_context); // 12. Set the value of C’s [[RegExpRightContext]] internal slot to a String whose length is len - endIndex and containing the code units from S with indices endIndex through len - 1, in ascending order. auto right_context = string.view().substring_view(end_index, len - end_index); - legacy_static_properties.set_right_context(Utf16String::create(right_context)); + legacy_static_properties.set_right_context(right_context); // 13. For each integer i such that 1 ≤ i ≤ 9 for (size_t i = 1; i <= 9; i++) { diff --git a/Libraries/LibJS/Runtime/RegExpLegacyStaticProperties.h b/Libraries/LibJS/Runtime/RegExpLegacyStaticProperties.h index bac7ca0a533..f861ad6c879 100644 --- a/Libraries/LibJS/Runtime/RegExpLegacyStaticProperties.h +++ b/Libraries/LibJS/Runtime/RegExpLegacyStaticProperties.h @@ -23,10 +23,25 @@ namespace JS { class RegExpLegacyStaticProperties { public: Optional const& input() const { return m_input; } - Optional const& last_match() const { return m_last_match; } + Optional const& last_match() const + { + if (!m_last_match_string.has_value()) + m_last_match_string = Utf16String::create(m_last_match); + return m_last_match_string; + } Optional const& last_paren() const { return m_last_paren; } - Optional const& left_context() const { return m_left_context; } - Optional const& right_context() const { return m_right_context; } + Optional const& left_context() const + { + if (!m_left_context_string.has_value()) + m_left_context_string = Utf16String::create(m_left_context); + return m_left_context_string; + } + Optional const& right_context() const + { + if (!m_right_context_string.has_value()) + m_right_context_string = Utf16String::create(m_right_context); + return m_right_context_string; + } Optional const& $1() const { return m_$1; } Optional const& $2() const { return m_$2; } Optional const& $3() const { return m_$3; } @@ -38,10 +53,22 @@ public: Optional const& $9() const { return m_$9; } void set_input(Utf16String input) { m_input = move(input); } - void set_last_match(Utf16String last_match) { m_last_match = move(last_match); } + void set_last_match(Utf16View last_match) + { + m_last_match = last_match; + m_last_match_string = {}; + } void set_last_paren(Utf16String last_paren) { m_last_paren = move(last_paren); } - void set_left_context(Utf16String left_context) { m_left_context = move(left_context); } - void set_right_context(Utf16String right_context) { m_right_context = move(right_context); } + void set_left_context(Utf16View left_context) + { + m_left_context = left_context; + m_left_context_string = {}; + } + void set_right_context(Utf16View right_context) + { + m_right_context = right_context; + m_right_context_string = {}; + } void set_$1(Utf16String value) { m_$1 = move(value); } void set_$2(Utf16String value) { m_$2 = move(value); } void set_$3(Utf16String value) { m_$3 = move(value); } @@ -55,10 +82,7 @@ public: private: Optional m_input; - Optional m_last_match; Optional m_last_paren; - Optional m_left_context; - Optional m_right_context; Optional m_$1; Optional m_$2; Optional m_$3; @@ -68,6 +92,14 @@ private: Optional m_$7; Optional m_$8; Optional m_$9; + + // NOTE: These are views into m_input and we only turn them into full strings if/when needed. + Utf16View m_last_match; + Utf16View m_left_context; + Utf16View m_right_context; + mutable Optional m_last_match_string; + mutable Optional m_left_context_string; + mutable Optional m_right_context_string; }; ThrowCompletionOr set_legacy_regexp_static_property(VM& vm, RegExpConstructor& constructor, Value this_value, void (RegExpLegacyStaticProperties::*property_setter)(Utf16String), Value value);