From 54edf29f1b0731f582ffec7fa5c806d7da72f063 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 13 Apr 2025 18:24:31 +0200 Subject: [PATCH] LibRegex: Make Match::capture_group_name an index into the string table This removes another Match member that required destruction. The "API" for accessing the strings is definitely a bit awkward. We'll think of something nicer eventually. --- Libraries/LibJS/Runtime/RegExpPrototype.cpp | 2 +- Libraries/LibRegex/RegexByteCode.cpp | 2 +- Libraries/LibRegex/RegexByteCode.h | 3 ++- Libraries/LibRegex/RegexMatch.h | 6 +++--- Tests/LibRegex/Regex.cpp | 8 ++++---- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Libraries/LibJS/Runtime/RegExpPrototype.cpp b/Libraries/LibJS/Runtime/RegExpPrototype.cpp index 491747c7804..966dbb3495c 100644 --- a/Libraries/LibJS/Runtime/RegExpPrototype.cpp +++ b/Libraries/LibJS/Runtime/RegExpPrototype.cpp @@ -330,7 +330,7 @@ static ThrowCompletionOr regexp_builtin_exec(VM& vm, RegExpObject& regexp // e. If the ith capture of R was defined with a GroupName, then if (capture.capture_group_name.has_value()) { // i. Let s be the CapturingGroupName of the corresponding RegExpIdentifierName. - auto group_name = capture.capture_group_name.release_value(); + auto group_name = regex.parser_result.bytecode.get_string(capture.capture_group_name.release_value()); // ii. Perform ! CreateDataPropertyOrThrow(groups, s, capturedValue). MUST(groups_object->create_data_property_or_throw(group_name, captured_value)); diff --git a/Libraries/LibRegex/RegexByteCode.cpp b/Libraries/LibRegex/RegexByteCode.cpp index d95cb1be283..9005ac05848 100644 --- a/Libraries/LibRegex/RegexByteCode.cpp +++ b/Libraries/LibRegex/RegexByteCode.cpp @@ -409,7 +409,7 @@ ALWAYS_INLINE ExecutionResult OpCode_SaveRightNamedCaptureGroup::execute(MatchIn auto view = input.view.substring_view(start_position, length); - match = { view, name(), input.line, start_position, input.global_offset + start_position }; + match = { view, name_string_table_index(), input.line, start_position, input.global_offset + start_position }; return ExecutionResult::Continue; } diff --git a/Libraries/LibRegex/RegexByteCode.h b/Libraries/LibRegex/RegexByteCode.h index 4be198117a6..1c0767159d0 100644 --- a/Libraries/LibRegex/RegexByteCode.h +++ b/Libraries/LibRegex/RegexByteCode.h @@ -839,7 +839,8 @@ public: ExecutionResult execute(MatchInput const& input, MatchState& state) const override; ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::SaveRightNamedCaptureGroup; } ALWAYS_INLINE size_t size() const override { return 3; } - ALWAYS_INLINE FlyString name() const { return m_bytecode->get_string(argument(0)); } + ALWAYS_INLINE FlyString name() const { return m_bytecode->get_string(name_string_table_index()); } + ALWAYS_INLINE size_t name_string_table_index() const { return argument(0); } ALWAYS_INLINE size_t length() const { return name().bytes_as_string_view().length(); } ALWAYS_INLINE size_t id() const { return argument(1); } ByteString arguments_string() const override diff --git a/Libraries/LibRegex/RegexMatch.h b/Libraries/LibRegex/RegexMatch.h index 73a90e77e5b..84fa5e5ba69 100644 --- a/Libraries/LibRegex/RegexMatch.h +++ b/Libraries/LibRegex/RegexMatch.h @@ -489,9 +489,9 @@ public: { } - Match(RegexStringView const view_, StringView capture_group_name_, size_t const line_, size_t const column_, size_t const global_offset_) + Match(RegexStringView const view_, size_t capture_group_name_, size_t const line_, size_t const column_, size_t const global_offset_) : view(view_) - , capture_group_name(MUST(FlyString::from_utf8(capture_group_name_))) + , capture_group_name(capture_group_name_) , line(line_) , column(column_) , global_offset(global_offset_) @@ -510,7 +510,7 @@ public: } RegexStringView view {}; - Optional capture_group_name {}; + Optional capture_group_name {}; // This is a string table index. size_t line { 0 }; size_t column { 0 }; size_t global_offset { 0 }; diff --git a/Tests/LibRegex/Regex.cpp b/Tests/LibRegex/Regex.cpp index eb4c8ba1a55..6804406185a 100644 --- a/Tests/LibRegex/Regex.cpp +++ b/Tests/LibRegex/Regex.cpp @@ -426,10 +426,10 @@ TEST_CASE(named_capture_group) EXPECT_EQ(result.count, 2u); EXPECT_EQ(result.matches.at(0).view, "Opacity=255"); EXPECT_EQ(result.capture_group_matches.at(0).at(0).view, "255"); - EXPECT_EQ(result.capture_group_matches.at(0).at(0).capture_group_name, "Test"); + EXPECT_EQ(re.parser_result.bytecode.get_string(result.capture_group_matches.at(0).at(0).capture_group_name.value()), "Test"); EXPECT_EQ(result.matches.at(1).view, "AudibleBeep=0"); EXPECT_EQ(result.capture_group_matches.at(1).at(0).view, "0"); - EXPECT_EQ(result.capture_group_matches.at(1).at(0).capture_group_name, "Test"); + EXPECT_EQ(re.parser_result.bytecode.get_string(result.capture_group_matches.at(1).at(0).capture_group_name.value()), "Test"); } TEST_CASE(ecma262_named_capture_group_with_dollar_sign) @@ -449,10 +449,10 @@ TEST_CASE(ecma262_named_capture_group_with_dollar_sign) EXPECT_EQ(result.count, 2u); EXPECT_EQ(result.matches.at(0).view, "Opacity=255"); EXPECT_EQ(result.capture_group_matches.at(0).at(0).view, "255"); - EXPECT_EQ(result.capture_group_matches.at(0).at(0).capture_group_name, "$Test$"); + EXPECT_EQ(re.parser_result.bytecode.get_string(result.capture_group_matches.at(0).at(0).capture_group_name.value()), "$Test$"); EXPECT_EQ(result.matches.at(1).view, "AudibleBeep=0"); EXPECT_EQ(result.capture_group_matches.at(1).at(0).view, "0"); - EXPECT_EQ(result.capture_group_matches.at(1).at(0).capture_group_name, "$Test$"); + EXPECT_EQ(re.parser_result.bytecode.get_string(result.capture_group_matches.at(1).at(0).capture_group_name.value()), "$Test$"); } TEST_CASE(a_star)