mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-24 02:12:09 -05:00
LibRegex: Make append_alternation() actually skip the common blocks
Previously we started with 'left_skip' set to zero, which made it so that no blocks were selected to be skipped.
This commit is contained in:
parent
b1ca2e5e39
commit
fb262de7cb
1 changed files with 32 additions and 5 deletions
|
@ -701,7 +701,7 @@ void Optimizer::append_alternation(ByteCode& target, Span<ByteCode> alternatives
|
|||
for (auto& entry : alternatives)
|
||||
basic_blocks.append(Regex<PosixBasicParser>::split_basic_blocks(entry));
|
||||
|
||||
size_t left_skip = 0;
|
||||
Optional<size_t> left_skip;
|
||||
size_t shared_block_count = basic_blocks.first().size();
|
||||
for (auto& entry : basic_blocks)
|
||||
shared_block_count = min(shared_block_count, entry.size());
|
||||
|
@ -741,21 +741,48 @@ void Optimizer::append_alternation(ByteCode& target, Span<ByteCode> alternatives
|
|||
state.instruction_position += opcode.size();
|
||||
skip = state.instruction_position;
|
||||
}
|
||||
left_skip = min(skip, left_skip);
|
||||
|
||||
if (left_skip.has_value())
|
||||
left_skip = min(skip, *left_skip);
|
||||
else
|
||||
left_skip = skip;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove forward jumps as they no longer make sense.
|
||||
state.instruction_position = 0;
|
||||
for (size_t i = 0; i < left_skip.value_or(0);) {
|
||||
auto& opcode = alternatives[0].get_opcode(state);
|
||||
switch (opcode.opcode_id()) {
|
||||
case OpCodeId::Jump:
|
||||
case OpCodeId::ForkJump:
|
||||
case OpCodeId::JumpNonEmpty:
|
||||
case OpCodeId::ForkStay:
|
||||
case OpCodeId::ForkReplaceJump:
|
||||
case OpCodeId::ForkReplaceStay:
|
||||
if (opcode.argument(0) + opcode.size() > left_skip.value_or(0)) {
|
||||
left_skip = i;
|
||||
goto break_out;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
i += opcode.size();
|
||||
}
|
||||
break_out:;
|
||||
|
||||
dbgln_if(REGEX_DEBUG, "Skipping {}/{} bytecode entries from {}", left_skip, 0, alternatives[0].size());
|
||||
|
||||
if (left_skip > 0) {
|
||||
target.extend(alternatives[0].release_slice(basic_blocks.first().first().start, left_skip));
|
||||
if (left_skip.has_value() && *left_skip > 0) {
|
||||
target.extend(alternatives[0].release_slice(basic_blocks.first().first().start, *left_skip));
|
||||
auto first = true;
|
||||
for (auto& entry : alternatives) {
|
||||
if (first) {
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
entry = entry.release_slice(left_skip);
|
||||
entry = entry.release_slice(*left_skip);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue