ReviewOS

zig-utils/zig-js

Frontend: allocate escaped template quasis exactly once

#549
Closed chris opened this 8 days ago ·
8 days ago

Parent: #496 Related: #537, #548

Problem

Plain cooked template quasis borrow source after #537, but any escape still switches parseTemplate / parseTaggedTemplate to arena-backed ArrayListUnmanaged growth. Allocation requests and retained capacity therefore depend on escape and quasi layout. Tagged templates also perform allocation work before discovering that an invalid escape makes the cooked quasi undefined.

Scope

  • Add 1K/2K/4K escaped untagged-template target rows and keep plain/tagged controls with exact cooked/raw validation.
  • Reuse the lexer fixed escape decoder to size and fill valid cooked quasis with one exact allocation.
  • Preserve substitution boundaries and contexts, TRV line normalization, line continuations, UTF-16/WTF-8 behavior, raw quasis, tagged invalid-escape undefined, and untagged early errors.
  • Make invalid and OOM paths failure-atomic; do not allocate cooked bytes for a tagged invalid quasi.

No-workaround rules

  • No worst-case over-allocation, hidden scratch copy, source transformation, delayed syntax error, dropped raw bytes, benchmark-only path, or special casing one template shape.

Acceptance

  • Each valid escaped cooked quasi uses one exact decoded-byte allocation with no growth/transfer; plain quasis remain source-backed.
  • Tagged invalid quasis allocate no cooked byte buffer and retain exact raw text plus undefined cooked value.
  • Unit tests cover every escape family, multiple quasis/substitutions, raw/cooked divergence, invalid tagged/untagged escapes, line normalization/continuation, WTF-8, and deterministic OOM.
  • Focused frontend, parser/lexer, TSan, full units, and exact template test262 comparisons pass.
  • Exact-parent evidence records wall, hardware counters, allocation requests/bytes, RSS, checksums, and 1K/2K/4K growth without moving parsing/decoding outside the timed boundary.
8 days ago

Implemented and verified on main:

The parser now validates and sizes every escaped cooked quasi before one exact allocation, fills it through the lexer's shared escape decoder, preserves source borrowing for plain quasis, and returns undefined for invalid tagged cooked quasis without allocating their cooked byte buffer. Untagged invalid escapes remain early errors. The implementation is failure-atomic under deterministic OOM and preserves raw text, substitution boundaries, line normalization and continuations, WTF-8, and surrogate-pair behavior.

Verification:

  • parser/lexer integration: 125/125
  • focused frontend Debug: 12/12
  • focused frontend TSan: 12/12
  • full unit suite: 1,617 passed, 1 skipped, 0 failed, 0 leaked
  • exact-parent test262: template literals 57 -> 57; tagged templates 27 -> 27

Exact-parent evidence across seven order-balanced pairs shows allocation bytes down 10.9%, 14.4%, and 12.1% for 1K/2K/4K escaped-template rows while retaining exactly one cooked allocation per quasi. Instructions fell 2.8%, 2.7%, and 2.3%; stable wall-time rows improved 8.4%, 12.3%, and 3.6%. Plain and tagged controls retained exact semantic checks; noisy wall rows remain explicitly diagnostic in the report.

This completes every acceptance item in #549 and advances parent #496.

Sign in to comment on this issue.