diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2022-01-21 12:33:49 +0330 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2022-01-21 18:14:08 +0330 |
commit | bfe8f312f3674d83f25191ee8acbb71af222697a (patch) | |
tree | 1c00c5ac131c9799b8fd2dabb764221c7df1acaa | |
parent | 3de51a4b997a73854cc9626a6176093062f70cb0 (diff) | |
download | serenity-bfe8f312f3674d83f25191ee8acbb71af222697a.zip |
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.
-rw-r--r-- | Tests/LibRegex/Regex.cpp | 2 | ||||
-rw-r--r-- | 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 8b705eb978..3123472bc8 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 <x>+. + Tuple { "a+"sv, ""sv, false }, }; for (auto& test : tests) { diff --git a/Userland/Libraries/LibRegex/RegexOptimizer.cpp b/Userland/Libraries/LibRegex/RegexOptimizer.cpp index ea2288ded9..2dbd96eb1c 100644 --- a/Userland/Libraries/LibRegex/RegexOptimizer.cpp +++ b/Userland/Libraries/LibRegex/RegexOptimizer.cpp @@ -376,7 +376,7 @@ void Regex<Parser>::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<Parser>::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); }; |