mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-03 00:42:54 +00: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
Notes:
sideshowbarker
2024-07-17 07:14:09 +09:00
Author: https://github.com/alimpfard
Commit: fb262de7cb
Pull-request: https://github.com/SerenityOS/serenity/pull/19390
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)
|
for (auto& entry : alternatives)
|
||||||
basic_blocks.append(Regex<PosixBasicParser>::split_basic_blocks(entry));
|
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();
|
size_t shared_block_count = basic_blocks.first().size();
|
||||||
for (auto& entry : basic_blocks)
|
for (auto& entry : basic_blocks)
|
||||||
shared_block_count = min(shared_block_count, entry.size());
|
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();
|
state.instruction_position += opcode.size();
|
||||||
skip = state.instruction_position;
|
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());
|
dbgln_if(REGEX_DEBUG, "Skipping {}/{} bytecode entries from {}", left_skip, 0, alternatives[0].size());
|
||||||
|
|
||||||
if (left_skip > 0) {
|
if (left_skip.has_value() && *left_skip > 0) {
|
||||||
target.extend(alternatives[0].release_slice(basic_blocks.first().first().start, left_skip));
|
target.extend(alternatives[0].release_slice(basic_blocks.first().first().start, *left_skip));
|
||||||
auto first = true;
|
auto first = true;
|
||||||
for (auto& entry : alternatives) {
|
for (auto& entry : alternatives) {
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
entry = entry.release_slice(left_skip);
|
entry = entry.release_slice(*left_skip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue