From 9c5febe8009ed905828b583adbdfd8fc67789015 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Sun, 10 Jul 2022 11:42:31 +0430 Subject: [PATCH] LibRegex: Flush compare tables before entering a permanent inverse state --- Userland/Libraries/LibRegex/RegexByteCode.cpp | 2 +- .../Libraries/LibRegex/RegexOptimizer.cpp | 82 ++++++++++--------- 2 files changed, 46 insertions(+), 38 deletions(-) diff --git a/Userland/Libraries/LibRegex/RegexByteCode.cpp b/Userland/Libraries/LibRegex/RegexByteCode.cpp index cccdb93982..8b9dcea0c2 100644 --- a/Userland/Libraries/LibRegex/RegexByteCode.cpp +++ b/Userland/Libraries/LibRegex/RegexByteCode.cpp @@ -459,7 +459,7 @@ ALWAYS_INLINE ExecutionResult OpCode_Compare::execute(MatchInput const& input, M auto compare_type = (CharacterCompareType)m_bytecode->at(offset++); if (compare_type == CharacterCompareType::Inverse) { - inverse = true; + inverse = !inverse; continue; } else if (compare_type == CharacterCompareType::TemporaryInverse) { diff --git a/Userland/Libraries/LibRegex/RegexOptimizer.cpp b/Userland/Libraries/LibRegex/RegexOptimizer.cpp index 78f7017f58..fdb806f954 100644 --- a/Userland/Libraries/LibRegex/RegexOptimizer.cpp +++ b/Userland/Libraries/LibRegex/RegexOptimizer.cpp @@ -840,6 +840,47 @@ void Optimizer::append_character_class(ByteCode& target, Vector active_range; + size_t range_count = 0; + for (auto& range : table) { + if (!active_range.has_value()) { + active_range = range; + continue; + } + + if (range.from <= active_range->to + 1 && range.to + 1 >= active_range->from) { + active_range = CharRange { min(range.from, active_range->from), max(range.to, active_range->to) }; + } else { + ++range_count; + arguments.append(active_range.release_value()); + active_range = range; + } + } + if (active_range.has_value()) { + ++range_count; + arguments.append(active_range.release_value()); + } + arguments[size_index] = range_count; + }; + + auto contains_regular_table = !table.is_empty(); + auto contains_inverted_table = !inverted_table.is_empty(); + if (contains_regular_table) + append_table(table); + + if (contains_inverted_table) { + ++argument_count; + arguments.append(to_underlying(CharacterCompareType::TemporaryInverse)); + append_table(inverted_table); + } + }; + for (auto& value : pairs) { auto should_invert_after_this_iteration = invert_for_next_iteration; invert_for_next_iteration = false; @@ -861,8 +902,9 @@ void Optimizer::append_character_class(ByteCode& target, Vector active_range; - size_t range_count = 0; - for (auto& range : table) { - if (!active_range.has_value()) { - active_range = range; - continue; - } - if (range.from <= active_range->to + 1 && range.to + 1 >= active_range->from) { - active_range = CharRange { min(range.from, active_range->from), max(range.to, active_range->to) }; - } else { - ++range_count; - arguments.append(active_range.release_value()); - active_range = range; - } - } - if (active_range.has_value()) { - ++range_count; - arguments.append(active_range.release_value()); - } - arguments[size_index] = range_count; - }; - - if (!table.is_empty()) - append_table(table); - - if (!inverted_table.is_empty()) { - ++argument_count; - arguments.append(to_underlying(CharacterCompareType::TemporaryInverse)); - append_table(inverted_table); - } + flush_tables(); } target.empend(static_cast(OpCodeId::Compare));