From bfe8f312f3674d83f25191ee8acbb71af222697a Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Fri, 21 Jan 2022 12:33:49 +0330 Subject: [PATCH] LibRegex: Correct jump offset to the start of the loop block Previously we were jumping to the new end of the previous block (created by the newly inserted ForkStay), correct the offset to jump to the correct block as shown in the comments. Fixes #12033. --- Tests/LibRegex/Regex.cpp | 2 ++ Userland/Libraries/LibRegex/RegexOptimizer.cpp | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Tests/LibRegex/Regex.cpp b/Tests/LibRegex/Regex.cpp index 8b705eb978e..3123472bc87 100644 --- a/Tests/LibRegex/Regex.cpp +++ b/Tests/LibRegex/Regex.cpp @@ -914,6 +914,8 @@ TEST_CASE(optimizer_atomic_groups) Tuple { "(1+)\\1"sv, "11"sv, true }, Tuple { "(1+)1"sv, "11"sv, true }, Tuple { "(1+)0"sv, "10"sv, true }, + // Rewrite should not skip over first required iteration of +. + Tuple { "a+"sv, ""sv, false }, }; for (auto& test : tests) { diff --git a/Userland/Libraries/LibRegex/RegexOptimizer.cpp b/Userland/Libraries/LibRegex/RegexOptimizer.cpp index ea2288ded9b..2dbd96eb1ca 100644 --- a/Userland/Libraries/LibRegex/RegexOptimizer.cpp +++ b/Userland/Libraries/LibRegex/RegexOptimizer.cpp @@ -376,7 +376,7 @@ void Regex::attempt_rewrite_loops_as_atomic_groups(BasicBlockList const& if (candidate.new_target_block.has_value()) { // Insert a fork-stay targeted at the second block. bytecode.insert(candidate.forking_block.start, (ByteCodeValueType)OpCodeId::ForkStay); - bytecode.insert(candidate.forking_block.start + 1, candidate.new_target_block->start - candidate.forking_block.start); + bytecode.insert(candidate.forking_block.start + 1, candidate.new_target_block->start - candidate.forking_block.start + 2); needed_patches.insert(candidate.forking_block.start, 2u); } } @@ -427,9 +427,9 @@ void Regex::attempt_rewrite_loops_as_atomic_groups(BasicBlockList const& if (patch_it.key() == ip) return; - if (patch_point.value < 0 && target_offset < patch_it.key() && ip > patch_it.key()) + if (patch_point.value < 0 && target_offset <= patch_it.key() && ip > patch_it.key()) bytecode[patch_point.offset] += (patch_point.should_negate ? 1 : -1) * (*patch_it); - else if (patch_point.value > 0 && target_offset > patch_it.key() && ip < patch_it.key()) + else if (patch_point.value > 0 && target_offset >= patch_it.key() && ip < patch_it.key()) bytecode[patch_point.offset] += (patch_point.should_negate ? -1 : 1) * (*patch_it); };