diff options
author | Christian Duerr <contact@christianduerr.com> | 2025-01-09 06:27:15 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-09 06:27:15 +0000 |
commit | 7321a442a6fc0fc5b6d6ed7af364477d25e706fd (patch) | |
tree | 11ff2608e63a160b8b204b6f78ec3977f019d081 /src/table.rs | |
parent | 89c12df969145ffb5084d1122627d7292c2c638f (diff) | |
download | r-alacritty-vte-7321a442a6fc0fc5b6d6ed7af364477d25e706fd.tar.gz r-alacritty-vte-7321a442a6fc0fc5b6d6ed7af364477d25e706fd.tar.bz2 r-alacritty-vte-7321a442a6fc0fc5b6d6ed7af364477d25e706fd.zip |
Switch parser to multi-byte processing
This patch overhauls the `Parser::advance` API to operate on byte slices
instead of individual bytes, which allows for additional performance
optimizations.
VTE does not support C1 escapes and C0 escapes always start with an
escape character. This makes it possible to simplify processing if a
byte stream is determined to not contain any escapes. The `memchr` crate
provides a battle-tested implementation for SIMD-accelerated byte
searches, which is why this implementation makes use of it.
VTE also only supports UTF8 characters in the ground state, which means
that the new non-escape parsing path is able to rely completely on STD's
`str::from_utf8` since `memchr` gives us the full length of the plain
text character buffer. This allows us to completely remove `utf8parse`
and all related code.
We also make use of `memchr` in the synchronized escape handling in
`ansi.rs`, since it relies heavily on scanning large amounts of text for
the extension/termination escape sequences.
Diffstat (limited to 'src/table.rs')
-rw-r--r-- | src/table.rs | 135 |
1 files changed, 76 insertions, 59 deletions
diff --git a/src/table.rs b/src/table.rs index f2c0105..ac288e7 100644 --- a/src/table.rs +++ b/src/table.rs @@ -1,39 +1,20 @@ -/// This is the state change table. It's indexed first by current state and then by the next -/// character in the pty stream. -use crate::definitions::{pack, Action, State}; - use vte_generate_state_changes::generate_state_changes; +/// This is the state change table. It's indexed first by current state and then +/// by the next character in the pty stream. +use crate::definitions::{pack, Action, State}; + // Generate state changes at compile-time -pub static STATE_CHANGES: [[u8; 256]; 16] = state_changes(); +pub const STATE_CHANGES: [[u8; 256]; 13] = state_changes(); generate_state_changes!(state_changes, { - Anywhere { - 0x18 => (Ground, Execute), - 0x1a => (Ground, Execute), - 0x1b => (Escape, None), - }, - - Ground { - 0x00..=0x17 => (Anywhere, Execute), - 0x19 => (Anywhere, Execute), - 0x1c..=0x1f => (Anywhere, Execute), - 0x20..=0x7f => (Anywhere, Print), - 0x80..=0x8f => (Anywhere, Execute), - 0x91..=0x9a => (Anywhere, Execute), - 0x9c => (Anywhere, Execute), - // Beginning of UTF-8 2 byte sequence - 0xc2..=0xdf => (Utf8, BeginUtf8), - // Beginning of UTF-8 3 byte sequence - 0xe0..=0xef => (Utf8, BeginUtf8), - // Beginning of UTF-8 4 byte sequence - 0xf0..=0xf4 => (Utf8, BeginUtf8), - }, - Escape { 0x00..=0x17 => (Anywhere, Execute), + 0x18 => (Ground, Execute), 0x19 => (Anywhere, Execute), + 0x1a => (Ground, Execute), + 0x1b => (Escape, None), 0x1c..=0x1f => (Anywhere, Execute), - 0x7f => (Anywhere, Ignore), + 0x7f => (Anywhere, None), 0x20..=0x2f => (EscapeIntermediate, Collect), 0x30..=0x4f => (Ground, EscDispatch), 0x51..=0x57 => (Ground, EscDispatch), @@ -51,18 +32,24 @@ generate_state_changes!(state_changes, { EscapeIntermediate { 0x00..=0x17 => (Anywhere, Execute), + 0x18 => (Ground, Execute), 0x19 => (Anywhere, Execute), + 0x1a => (Ground, Execute), + 0x1b => (Escape, None), 0x1c..=0x1f => (Anywhere, Execute), 0x20..=0x2f => (Anywhere, Collect), - 0x7f => (Anywhere, Ignore), + 0x7f => (Anywhere, None), 0x30..=0x7e => (Ground, EscDispatch), }, CsiEntry { 0x00..=0x17 => (Anywhere, Execute), + 0x18 => (Ground, Execute), 0x19 => (Anywhere, Execute), + 0x1a => (Ground, Execute), + 0x1b => (Escape, None), 0x1c..=0x1f => (Anywhere, Execute), - 0x7f => (Anywhere, Ignore), + 0x7f => (Anywhere, None), 0x20..=0x2f => (CsiIntermediate, Collect), 0x30..=0x39 => (CsiParam, Param), 0x3a..=0x3b => (CsiParam, Param), @@ -72,20 +59,26 @@ generate_state_changes!(state_changes, { CsiIgnore { 0x00..=0x17 => (Anywhere, Execute), + 0x18 => (Ground, Execute), 0x19 => (Anywhere, Execute), + 0x1a => (Ground, Execute), + 0x1b => (Escape, None), 0x1c..=0x1f => (Anywhere, Execute), - 0x20..=0x3f => (Anywhere, Ignore), - 0x7f => (Anywhere, Ignore), + 0x20..=0x3f => (Anywhere, None), + 0x7f => (Anywhere, None), 0x40..=0x7e => (Ground, None), }, CsiParam { 0x00..=0x17 => (Anywhere, Execute), + 0x18 => (Ground, Execute), 0x19 => (Anywhere, Execute), + 0x1a => (Ground, Execute), + 0x1b => (Escape, None), 0x1c..=0x1f => (Anywhere, Execute), 0x30..=0x39 => (Anywhere, Param), 0x3a..=0x3b => (Anywhere, Param), - 0x7f => (Anywhere, Ignore), + 0x7f => (Anywhere, None), 0x3c..=0x3f => (CsiIgnore, None), 0x20..=0x2f => (CsiIntermediate, Collect), 0x40..=0x7e => (Ground, CsiDispatch), @@ -93,19 +86,25 @@ generate_state_changes!(state_changes, { CsiIntermediate { 0x00..=0x17 => (Anywhere, Execute), + 0x18 => (Ground, Execute), 0x19 => (Anywhere, Execute), + 0x1a => (Ground, Execute), + 0x1b => (Escape, None), 0x1c..=0x1f => (Anywhere, Execute), 0x20..=0x2f => (Anywhere, Collect), - 0x7f => (Anywhere, Ignore), + 0x7f => (Anywhere, None), 0x30..=0x3f => (CsiIgnore, None), 0x40..=0x7e => (Ground, CsiDispatch), }, DcsEntry { - 0x00..=0x17 => (Anywhere, Ignore), - 0x19 => (Anywhere, Ignore), - 0x1c..=0x1f => (Anywhere, Ignore), - 0x7f => (Anywhere, Ignore), + 0x00..=0x17 => (Anywhere, None), + 0x18 => (Ground, Execute), + 0x19 => (Anywhere, None), + 0x1a => (Ground, Execute), + 0x1b => (Escape, None), + 0x1c..=0x1f => (Anywhere, None), + 0x7f => (Anywhere, None), 0x20..=0x2f => (DcsIntermediate, Collect), 0x30..=0x39 => (DcsParam, Param), 0x3a..=0x3b => (DcsParam, Param), @@ -114,30 +113,39 @@ generate_state_changes!(state_changes, { }, DcsIntermediate { - 0x00..=0x17 => (Anywhere, Ignore), - 0x19 => (Anywhere, Ignore), - 0x1c..=0x1f => (Anywhere, Ignore), + 0x00..=0x17 => (Anywhere, None), + 0x18 => (Ground, Execute), + 0x19 => (Anywhere, None), + 0x1a => (Ground, Execute), + 0x1b => (Escape, None), + 0x1c..=0x1f => (Anywhere, None), 0x20..=0x2f => (Anywhere, Collect), - 0x7f => (Anywhere, Ignore), + 0x7f => (Anywhere, None), 0x30..=0x3f => (DcsIgnore, None), 0x40..=0x7e => (DcsPassthrough, None), }, DcsIgnore { - 0x00..=0x17 => (Anywhere, Ignore), - 0x19 => (Anywhere, Ignore), - 0x1c..=0x1f => (Anywhere, Ignore), - 0x20..=0x7f => (Anywhere, Ignore), + 0x00..=0x17 => (Anywhere, None), + 0x18 => (Ground, Execute), + 0x19 => (Anywhere, None), + 0x1a => (Ground, Execute), + 0x1b => (Escape, None), + 0x1c..=0x1f => (Anywhere, None), + 0x20..=0x7f => (Anywhere, None), 0x9c => (Ground, None), }, DcsParam { - 0x00..=0x17 => (Anywhere, Ignore), - 0x19 => (Anywhere, Ignore), - 0x1c..=0x1f => (Anywhere, Ignore), + 0x00..=0x17 => (Anywhere, None), + 0x18 => (Ground, Execute), + 0x19 => (Anywhere, None), + 0x1a => (Ground, Execute), + 0x1b => (Escape, None), + 0x1c..=0x1f => (Anywhere, None), 0x30..=0x39 => (Anywhere, Param), 0x3a..=0x3b => (Anywhere, Param), - 0x7f => (Anywhere, Ignore), + 0x7f => (Anywhere, None), 0x3c..=0x3f => (DcsIgnore, None), 0x20..=0x2f => (DcsIntermediate, Collect), 0x40..=0x7e => (DcsPassthrough, None), @@ -145,27 +153,36 @@ generate_state_changes!(state_changes, { DcsPassthrough { 0x00..=0x17 => (Anywhere, Put), + 0x18 => (Ground, Execute), 0x19 => (Anywhere, Put), + 0x1a => (Ground, Execute), + 0x1b => (Escape, None), 0x1c..=0x1f => (Anywhere, Put), 0x20..=0x7e => (Anywhere, Put), - 0x7f => (Anywhere, Ignore), + 0x7f => (Anywhere, None), 0x9c => (Ground, None), }, SosPmApcString { - 0x00..=0x17 => (Anywhere, Ignore), - 0x19 => (Anywhere, Ignore), - 0x1c..=0x1f => (Anywhere, Ignore), - 0x20..=0x7f => (Anywhere, Ignore), + 0x00..=0x17 => (Anywhere, None), + 0x18 => (Ground, Execute), + 0x19 => (Anywhere, None), + 0x1a => (Ground, Execute), + 0x1b => (Escape, None), + 0x1c..=0x1f => (Anywhere, None), + 0x20..=0x7f => (Anywhere, None), 0x9c => (Ground, None), }, OscString { - 0x00..=0x06 => (Anywhere, Ignore), + 0x00..=0x06 => (Anywhere, None), 0x07 => (Ground, None), - 0x08..=0x17 => (Anywhere, Ignore), - 0x19 => (Anywhere, Ignore), - 0x1c..=0x1f => (Anywhere, Ignore), + 0x08..=0x17 => (Anywhere, None), + 0x18 => (Ground, Execute), + 0x19 => (Anywhere, None), + 0x1a => (Ground, Execute), + 0x1b => (Escape, None), + 0x1c..=0x1f => (Anywhere, None), 0x20..=0xff => (Anywhere, OscPut), } }); |