Преглед на файлове

LibRegex: Avoid generating ForkJumps when jumping to the next alt block

Fixes #2398.
Ali Mohammad Pur преди 8 месеца
родител
ревизия
5a4d657a4e
променени са 2 файла, в които са добавени 11 реда и са изтрити 3 реда
  1. 2 0
      Libraries/LibRegex/RegexOptimizer.cpp
  2. 9 3
      Tests/LibRegex/Regex.cpp

+ 2 - 0
Libraries/LibRegex/RegexOptimizer.cpp

@@ -1197,6 +1197,8 @@ void Optimizer::append_alternation(ByteCode& target, Span<ByteCode> alternatives
             for (auto& patch : patch_locations) {
             for (auto& patch : patch_locations) {
                 if (!patch.done && node_is(node, patch.source_ip)) {
                 if (!patch.done && node_is(node, patch.source_ip)) {
                     auto value = static_cast<ByteCodeValueType>(target.size() - patch.target_ip - 1);
                     auto value = static_cast<ByteCodeValueType>(target.size() - patch.target_ip - 1);
+                    if (value == 0)
+                        target[patch.target_ip - 1] = static_cast<ByteCodeValueType>(OpCodeId::Jump);
                     target[patch.target_ip] = value;
                     target[patch.target_ip] = value;
                     patch.done = true;
                     patch.done = true;
                 }
                 }

+ 9 - 3
Tests/LibRegex/Regex.cpp

@@ -1074,7 +1074,7 @@ TEST_CASE(optimizer_char_class_lut)
 TEST_CASE(optimizer_alternation)
 TEST_CASE(optimizer_alternation)
 {
 {
     Array tests {
     Array tests {
-        // Pattern, Subject, Expected length
+        // Pattern, Subject, Expected length [0 == fail]
         Tuple { "a|"sv, "a"sv, 1u },
         Tuple { "a|"sv, "a"sv, 1u },
         Tuple { "a|a|a|a|a|a|a|a|a|b"sv, "a"sv, 1u },
         Tuple { "a|a|a|a|a|a|a|a|a|b"sv, "a"sv, 1u },
         Tuple { "ab|ac|ad|bc"sv, "bc"sv, 2u },
         Tuple { "ab|ac|ad|bc"sv, "bc"sv, 2u },
@@ -1084,13 +1084,19 @@ TEST_CASE(optimizer_alternation)
         Tuple { "^(\\d+|x)"sv, "42"sv, 2u },
         Tuple { "^(\\d+|x)"sv, "42"sv, 2u },
         // `Repeat' does not add its insn size to the jump target.
         // `Repeat' does not add its insn size to the jump target.
         Tuple { "[0-9]{2}|[0-9]"sv, "92"sv, 2u },
         Tuple { "[0-9]{2}|[0-9]"sv, "92"sv, 2u },
+        // Don't ForkJump to the next instruction, rerunning it would produce the same result. see ladybird#2398.
+        Tuple { "(xxxxxxxxxxxxxxxxxxxxxxx|xxxxxxxxxxxxxxxxxxxxxxx)?b"sv, "xxxxxxxxxxxxxxxxxxxxxxx"sv, 0u },
     };
     };
 
 
     for (auto& test : tests) {
     for (auto& test : tests) {
         Regex<ECMA262> re(test.get<0>());
         Regex<ECMA262> re(test.get<0>());
         auto result = re.match(test.get<1>());
         auto result = re.match(test.get<1>());
-        EXPECT(result.success);
-        EXPECT_EQ(result.matches.first().view.length(), test.get<2>());
+        if (test.get<2>() != 0) {
+            EXPECT(result.success);
+            EXPECT_EQ(result.matches.first().view.length(), test.get<2>());
+        } else {
+            EXPECT(!result.success);
+        }
     }
     }
 }
 }