summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2022-01-21 12:33:49 +0330
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2022-01-21 18:14:08 +0330
commitbfe8f312f3674d83f25191ee8acbb71af222697a (patch)
tree1c00c5ac131c9799b8fd2dabb764221c7df1acaa
parent3de51a4b997a73854cc9626a6176093062f70cb0 (diff)
downloadserenity-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.cpp2
-rw-r--r--Userland/Libraries/LibRegex/RegexOptimizer.cpp6
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);
};