feat(parser): WASM VT500 scanner with ScanResult SOA dispatch
- Add C WASM scanner emitting structure-of-arrays ops (kinds, starts, lengths, aux, params) - Integrate scan+dispatch in EscapeSequenceParser with async handler resume - Fix CSI fast-path final byte index, ERROR state reporting, and precedingJoinState for REP - Add build pipeline (build_parser_wasm.sh, transition table generator, wasm embed) Co-authored-by: Daniel Imms <Tyriar@users.noreply.github.com>
This commit is contained in:
co-authored by
Daniel Imms
parent
936442c813
commit
3eca55a80d
Executable
+45
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2026 The xterm.js authors. All rights reserved.
|
||||
# @license MIT
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
if [[ ! -f src/common/parser/wasm/transition_table.h ]]; then
|
||||
npm run build
|
||||
node bin/gen_parser_transition_table.mjs
|
||||
fi
|
||||
|
||||
WASM_DIR=src/common/parser/wasm
|
||||
OUT="$WASM_DIR/parser.wasm"
|
||||
|
||||
clang --target=wasm32-unknown-unknown -O2 -nostdlib -fuse-ld=lld \
|
||||
-Wl,--no-entry \
|
||||
-Wl,--export-memory \
|
||||
-Wl,--export=reset \
|
||||
-Wl,--export=scan \
|
||||
-Wl,--export=probe_action \
|
||||
-Wl,--export=set_state \
|
||||
-Wl,--export=sync_params_from \
|
||||
-Wl,--export=export_params_to \
|
||||
-Wl,--export=get_params_len \
|
||||
-Wl,--export=get_subparams_len \
|
||||
-Wl,--export=get_subparams_ptr \
|
||||
-Wl,--export=get_subparams_idx_ptr \
|
||||
-Wl,--export=get_input_ptr \
|
||||
-Wl,--export=get_kinds_ptr \
|
||||
-Wl,--export=get_starts_ptr \
|
||||
-Wl,--export=get_lengths_ptr \
|
||||
-Wl,--export=get_aux_ptr \
|
||||
-Wl,--export=get_param_starts_ptr \
|
||||
-Wl,--export=get_param_counts_ptr \
|
||||
-Wl,--export=get_params_ptr \
|
||||
-Wl,--export=get_state_ptr \
|
||||
-Wl,--export=get_header_ptr \
|
||||
-Wl,--initial-memory=67108864 \
|
||||
-Wl,--max-memory=67108864 \
|
||||
"$WASM_DIR/parser.c" -o "$OUT"
|
||||
|
||||
node bin/embed_parser_wasm.mjs
|
||||
|
||||
echo "Built $OUT"
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) 2026 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { readFileSync, writeFileSync } from 'fs';
|
||||
import { join, dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const root = join(__dirname, '..');
|
||||
const wasm = readFileSync(join(root, 'src/common/parser/wasm/parser.wasm'));
|
||||
const b64 = wasm.toString('base64');
|
||||
|
||||
const out = `/**
|
||||
* Copyright (c) 2026 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
/** Base64-encoded parser.wasm (generated by bin/build_parser_wasm.sh) */
|
||||
export const PARSER_WASM_BASE64 = '${b64}';\n`;
|
||||
|
||||
writeFileSync(join(root, 'src/common/parser/wasm/parser.wasm.embed.ts'), out);
|
||||
console.info(`Embedded parser.wasm (${wasm.length} bytes)`);
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) 2026 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
// @ts-check
|
||||
import { writeFileSync } from 'fs';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { dirname, join } from 'path';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const root = join(__dirname, '..');
|
||||
|
||||
// Import compiled transition table
|
||||
const { VT500_TRANSITION_TABLE } = await import(join(root, 'out/common/parser/EscapeSequenceParser.js'));
|
||||
|
||||
const table = VT500_TRANSITION_TABLE.table;
|
||||
let out = '/* Auto-generated by bin/gen_parser_transition_table.mjs - do not edit */\n';
|
||||
out += `#ifndef PARSER_TRANSITION_TABLE_H\n#define PARSER_TRANSITION_TABLE_H\n\n`;
|
||||
out += `#include <stdint.h>\n\n`;
|
||||
out += `#define PARSER_TABLE_SIZE ${table.length}\n\n`;
|
||||
out += `static const uint16_t PARSER_TRANSITION_TABLE[PARSER_TABLE_SIZE] = {\n`;
|
||||
for (let i = 0; i < table.length; i++) {
|
||||
if (i % 16 === 0) out += ' ';
|
||||
out += `0x${table[i].toString(16)}`;
|
||||
out += i < table.length - 1 ? ', ' : '';
|
||||
if (i % 16 === 15) out += '\n';
|
||||
}
|
||||
if (table.length % 16 !== 0) out += '\n';
|
||||
out += `};\n\n#endif\n`;
|
||||
|
||||
const headerPath = join(root, 'src/common/parser/wasm/transition_table.h');
|
||||
writeFileSync(headerPath, out);
|
||||
console.info(`Wrote ${headerPath} (${table.length} entries)`);
|
||||
Reference in New Issue
Block a user