summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2017-10-02 16:24:38 +0800
committerMaxime Coste <mawww@kakoune.org>2017-11-01 14:05:14 +0800
commit5b0c2cbdc2c15d3845dd9cd3799ea0282b65ba94 (patch)
treedcf17d1e70eb19d0fc45a7b745893ec0afef31ea /src
parentb4f923b7fc53a83d0f6243d5b524cc7d4fc58c8f (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.hh22
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