diff options
| author | Maxime Coste <mawww@kakoune.org> | 2017-10-02 16:24:38 +0800 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2017-11-01 14:05:14 +0800 |
| commit | 5b0c2cbdc2c15d3845dd9cd3799ea0282b65ba94 (patch) | |
| tree | dcf17d1e70eb19d0fc45a7b745893ec0afef31ea /src | |
| parent | b4f923b7fc53a83d0f6243d5b524cc7d4fc58c8f (diff) | |
Regex: Ensure we dont have a thread explosion in ThreadedRegexVM
Always remove threads with lower priority that end up on the same
instruction as a higher priority thread (as we know they will behave
the same from now on)
Diffstat (limited to 'src')
| -rw-r--r-- | src/regex_impl.hh | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/src/regex_impl.hh b/src/regex_impl.hh index 322b60a4..be61698e 100644 --- a/src/regex_impl.hh +++ b/src/regex_impl.hh @@ -167,7 +167,6 @@ struct ThreadedRegexVM break; } case CompiledRegex::Match: - thread.inst = nullptr; return StepResult::Matched; } } @@ -186,13 +185,16 @@ struct ThreadedRegexVM for (m_pos = Utf8It{m_begin, m_begin, m_end}; m_pos != m_end; ++m_pos) { - for (int i = 0; i < m_threads.size(); ++i) + for (int i = 0; i < m_threads.size(); ) { const auto res = step(i); if (res == StepResult::Matched) { if (match) + { + m_threads.erase(m_threads.begin() + i); continue; // We are not at end, this is not a full match + } m_captures = std::move(m_threads[i].saves); found_match = true; @@ -201,10 +203,19 @@ struct ThreadedRegexVM return true; } else if (res == StepResult::Failed) - m_threads[i].inst = nullptr; + m_threads.erase(m_threads.begin() + i); + else + { + auto it = m_threads.begin() + i; + if (std::find_if(m_threads.begin(), it, [inst = it->inst](auto& t) + { return t.inst == inst; }) != it) + m_threads.erase(it); + else + ++i; + } } - m_threads.erase(std::remove_if(m_threads.begin(), m_threads.end(), - [](const Thread& t) { return t.inst == nullptr; }), m_threads.end()); + // we should never have more than one thread on the same instruction + kak_assert(m_threads.size() <= m_program.bytecode.size()); if (m_threads.empty()) return found_match; } @@ -230,6 +241,7 @@ struct ThreadedRegexVM if (std::find_if(m_threads.begin(), m_threads.end(), [inst](const Thread& t) { return t.inst == inst; }) == m_threads.end()) m_threads.insert(m_threads.begin() + index, {inst, std::move(saves)}); + kak_assert(m_threads.size() < m_program.bytecode.size()); } bool is_line_start() const |
