ReviewOS

zig-utils/zig-js

Runtime: canonicalize ToString byte egress

#693
Closed chris opened this 9 days ago ·
9 days ago

Parents: #473, #465 Related: #668, #672, #674, #692

Problem

Value.toString is the byte-returning ECMAScript ToString boundary used by Interpreter.toStringV. Its string branch currently returns Value.asStr(), which is the StringCell physical image. Under flat Latin-1 storage, direct strings and object-to-primitive results can therefore reach parsers, formatters, Web APIs, and embedding helpers as raw one-byte code units instead of canonical WTF-8.

Scope

  • Make the byte-returning ToString boundary return canonical WTF-8 for existing string values.
  • Preserve Symbol rejection, ToPrimitive hint/order, abrupt completion, primitive formatting, and current canonical-storage zero-copy behavior.
  • Propagate flat-storage conversion OOM through the existing EvalError/allocator channels.
  • Keep toStringValue as the representation-aware value-retaining path for consumers that operate directly on UTF-16 code units.
  • Add direct-string and object-to-primitive flat-storage witnesses plus fail-first allocation coverage.

No-workaround rules

  • No global eager canonicalization, disabled flat storage, forced UTF-16 representation, lossy repair, retry, alternate coercion path, or swallowed OOM.
  • No stacks, queues, jobs, Promise, microtask, Worker-lifecycle, or Map/Set iterator changes.

Acceptance

  • Value.toString and Interpreter.toStringV return canonical WTF-8 for all StringData representations.
  • Direct and object-produced strings preserve exact ToString ordering/results under canonical and flat Latin-1 storage.
  • Flat conversion OOM is explicit and the disabled representation remains allocation-free.
  • Focused Debug/forced-flat/ReleaseSafe/TSan and full units pass with exact Test262 accounting.
9 days ago

Implementation landed on main in b962e23d.

Value.toString now returns canonical WTF-8 for existing StringData. Canonical/ASCII cells retain the borrowed zero-allocation path; physical flat-Latin-1 cells use the existing bounded conversion and propagate OOM. The representation-aware toStringValue path remains unchanged. Direct and object-produced witnesses cover canonical bytes, fail-first allocation, and ToPrimitive string-hint ordering.

Evidence:

  • focused Debug: 13/13
  • forced physical flat storage: 13/13, including explicit OOM
  • focused ReleaseSafe: 13/13
  • focused TSan: 13/13, zero warnings
  • full Debug: 1791 passed, 1 skipped, 0 failed, 0 leaked
  • exact parent -> candidate Test262 computed-property-names: 0 fail / 48 pass -> 0 / 48, byte-identical transcript
  • full TSan test accounting: 1790 passed, 2 skipped, 0 failed, 0 leaked

The full TSan process correctly exited nonzero for one independent Environment reuse race in an existing C-API parallel-GC witness. That root cause is tracked as #694 with no suppression or sanitizer relaxation. #693 remains open until the current-head full TSan gate is warning-free.

9 days ago

The current-head repository-wide TSan gate is now clean after the independently tracked #694 fix in d5d63780: 1790 passed, 2 skipped, 0 failed/leaked, zero sanitizer warnings.

Together with the #693 implementation b962e23d, focused Debug/forced-flat/ReleaseSafe/TSan, full Debug 1791/1, and exact Test262 48 -> 48 with byte-identical transcripts, every acceptance item is complete. Closing.

9 days ago

Follow-up #701 closed the Error-object branch outside this issue’s primitive/direct ToString scope. 40febcea canonicalizes the public Zig Value.toString renderer’s own name/message fields; the exact old branch returns physical e9/ff under forced-flat storage, while the repaired path passes Debug/ReleaseSafe/TSan and full units.

Sign in to comment on this issue.