ReviewOS

zig-utils/zig-js

Frontend: size tagged-template substitution arrays exactly

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

Parent: #496 Related: #537, #549, #550

Problem

parseTaggedTemplate stores multi-substitution results in three independent arena-backed ArrayListUnmanaged values for cooked quasis, raw quasis, and expressions. A template with N substitutions has exact cardinalities N+1, N+1, and N, but the parser retains each list's growth capacity and transfer history for the full AST lifetime.

Scope

  • Add parser-only 1K/2K/4K single-tagged-template workloads with N substitutions and independently validate every cooked quasi, raw quasi, expression value, pointer/lifetime invariant, and checksum.
  • Count top-level substitutions with the same escape/nesting rules used by parsing, allocate the three final AST arrays at their exact cardinalities, and fill them directly.
  • Preserve the no-substitution exact fast path and source-backed plain quasis.
  • Preserve nested braces/templates/strings/regex/comments in substitutions, raw/cooked divergence, invalid tagged escapes, inherited yield/await/private/strict/module contexts, source ranges, evaluation order, and OOM propagation.

No-workaround rules

  • No benchmark source splitting, hidden AST side table, worst-case allocation, dropped raw/cooked entry, expression pre-evaluation, reduced nesting grammar, deferred syntax error, or benchmark-specific template shape.

Acceptance

  • Benchmark-first 1K/2K/4K rows freeze exact per-quasi/per-expression validation and allocation growth before parser changes.
  • N substitutions allocate exact final arrays of N+1 cooked entries, N+1 raw entries, and N expression pointers with no list growth/transfer.
  • Direct tests cover zero/one/many substitutions, escaped and invalid quasis, nested braces/templates/regex/comments, inherited parse contexts, exact cardinalities, and deterministic OOM/retry.
  • Parser/lexer/frontend, TSan, full units, forced tree-walker/VM execution, and exact template/tagged-template test262 comparisons pass without regressions.
  • Exact-parent evidence records wall, hardware counters, allocation requests/bytes, RSS, checksums, and 1K/2K/4K growth without moving parsing or AST validation outside the timed boundary.
8 days ago

Implemented, verified, and published on main:

The lexer now records top-level substitution cardinality during its existing brace/string/regex/comment/nested-template scan. The parser uses that exact count to allocate final N+1 cooked, N+1 raw, and N expression arrays and fills them directly, eliminating three retained growth lists without adding a second parser scan. The no-substitution exact path and source-backed quasis remain intact.

Verification:

  • template units: 11/11
  • focused frontend Debug and TSan: 12/12 each
  • full units: 1,621 passed, 1 skipped, 0 failed, 0 leaked
  • exact-parent test262: template literals 57 -> 57; tagged templates 27 -> 27
  • forced tagged-template witness: tree-walker pass and required-bytecode pass

Across seven order-balanced pairs, allocated bytes fall 12.2%, 16.7%, and 18.3% at 1K/2K/4K substitutions. Stable instructions fall 1.3-1.4%; stable 1K/2K wall improves 1.9%/2.2%. Noisy 4K wall/RSS rows remain diagnostic. Every acceptance item is complete.

Sign in to comment on this issue.