Parent: #496 Related: #473, #480, #493
Problem
Every RegExp literal is correctly compiled during parsing so invalid flags/patterns and zig-regex's security analysis remain early errors. The validation result is then discarded, but today it is allocated in the long-lived parser/Context arena and never deinitialized. Non-Unicode literals also call normalizeAnnexBClassRanges, which builds a complete growth-list copy even when no Annex B rewrite is needed and then returns the original slice.
Regex-heavy source therefore retains parse-only AST/NFA/optimizer/named-capture state until Context teardown and performs an avoidable full-pattern copy on the common unchanged path. Runtime evaluation compiles the literal again because the parser-side object is not an executable artifact.
Scope
- Freeze parser-only 1K/2K/4K RegExp-literal growth rows before changing the implementation, with unchanged non-Unicode patterns plus Unicode and Annex B rewrite controls.
- Make unchanged Annex B normalization allocation-free and changed normalization one exact bounded allocation.
- Compile validation state through the parser's invocation-local scratch allocator and deinitialize every successful validation object before returning.
- Preserve exact pattern/flag source slices in the AST; this issue does not introduce a compiled-artifact cache or move compilation outside the parse boundary.
- Keep the runtime compile and security analyzer authoritative for the executable RegExp object.
No-workaround rules
- No delayed or skipped syntax validation, disabled ReDoS/security analysis, benchmark/source recognition, hash-only cache key, permanent compiled-object leak, reduced pattern/flag coverage, or arena-reset trick that invalidates AST/source slices.
- No change to JavaScript-visible RegExp identity or creation timing.
Acceptance
- Benchmark source, 1K/2K/4K identities, controls, exact checksums, allocation accounting, warmup, and timed boundary land before the implementation.
- Unchanged non-Unicode normalization performs zero allocation; rewritten Annex B input performs one exact allocation and releases it after compile.
- Successful parse validation releases all zig-regex compile state through freeable scratch; every failure path remains leak-free and reports the same parse-phase error.
- Valid/invalid flags, Unicode
u/v, Annex B class ranges, escapes, named captures, lookarounds, backreferences, and security-rejected patterns retain exact semantics. - OOM/fault injection, bounded Context teardown, focused TSan/frontend tests, full units, and exact-parent RegExp/test262 comparisons pass with zero regressions.
- Exact-parent evidence reports wall/instructions/allocation/RSS changes without hiding validation work or runtime compilation.
Security boundary
Pattern bytes and source size are attacker-controlled. Validation must remain eager, bounded by the existing zig-regex security policy, failure-atomic under OOM, and free of proportional retained parse-only state.