Browse documentation

Purpose-built RegExp VM

Date: 2026-05-08 Area: engine

Replace TRegExpr with a purpose-built backtracking bytecode VM regex engine. TRegExpr used native call recursion for backtracking, causing SIGSEGV on inputs ~42K+ chars when combined with the evaluator's stack depth (#515). Three preprocessing passes papered over feature gaps: (?s) modifier scope leak, no named groups (two-pass rewrite), and inadequate Unicode (\p{...} expanded to ASCII approximations). New architecture: Goccia.RegExp.Compiler.pas (recursive-descent parser + bytecode emitter) and Goccia.RegExp.VM.pas (iterative dispatch loop with heap-allocated backtrack stack and always-on failure memoization). The compiler parses ES2026 regex grammar directly, handling named groups, Unicode property escapes, inline modifier groups, and backreferences natively — no preprocessing passes. The memoization cache records (PC, InputPos) failure states to prune exponential backtracking (e.g., (a+)+b). Configurable step limit (default 10M) throws Error instead of crashing. Removes the FPC regexpr package from the cross-compilation toolchain. Reuses TextSemantics.pas UTF-8 functions (TryReadUTF8CodePoint, AdvanceUTF8StringIndex, CodePointToUTF8, etc.) rather than reimplementing. Public API (ExecuteRegExp signature, TGocciaRegExpMatchResult record) unchanged; Goccia.RegExp.Runtime.pas and Goccia.Builtins.GlobalRegExp.pas unmodified.