ReviewOS

zig-utils/zig-js

Zig API: canonicalize Error Value.toString fields

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

Parents: #495, #473 Regression follow-up to: #693 Related: #682, #686, #692

Problem

The public Zig js.Value.toString(allocator) boundary canonicalizes a primitive String Value, but its non-observable Error-object renderer still reads own name/message fields through Value.asStr() before concatenating them. With flat Latin-1 storage active, an Error carrying caféÿ fields returns physical one-byte storage instead of canonical WTF-8 to the embedder. JavaScript Error.prototype.toString and Error.stack already use representation-aware paths; this is specifically the direct Zig Value rendering API.

Every Promise, stack implementation, queue, job, Worker, and shared Map/Set iterator surface is explicitly excluded and remains user-owned. Error.stack behavior is also out of scope.

Scope

  • Canonicalize String-valued Error name/message fields in the Zig-level Value.toString renderer.
  • Preserve the renderer’s intentionally side-effect-free own-property behavior, fallback error class name, empty-field formatting, array recursion, existing allocation ownership, and OOM propagation.
  • Keep canonical/ASCII fields borrowed; only physical flat Latin-1 performs bounded conversion.
  • Add a direct Context-to-public-Value witness that fails with the exact old reads under forced flat storage.

No-workaround rules

  • No flat-storage disablement, JavaScript hook invocation, replacement characters, eager global canonicalization, Error.stack change, alternate renderer, hidden retry, or input-specific special case.
  • No Promise, stack implementation, queue, job, Worker, or shared Map/Set iterator changes.

Acceptance

  • Direct js.Value.toString returns exact canonical WTF-8 for non-ASCII Error name and message fields under canonical and forced-flat storage.
  • Empty-name/message and fallback-name rendering remain exact with no observable JavaScript getters invoked.
  • Focused Debug, forced-flat Debug, ReleaseSafe, TSan, and full units pass.
  • Relevant Test262 accounting is reported without claiming direct Zig API coverage.
9 days ago

Landed in fix(zig-api): canonicalize Error rendering fields (#701).

Validation:

  • Exact old reads under forced-flat storage return raw e9/ff bytes instead of canonical c3 a9/c3 bf.
  • Repaired direct Zig API witness passes Debug, forced-flat Debug, ReleaseSafe, and TSan.
  • Witness covers non-ASCII name/message composition, empty name, empty message, fallback Error name, and the renderer’s existing side-effect-free formatting.
  • Full units: 1,795 passed, 1 skipped, 0 failed, 0 leaked.
  • The Test262 text matches are unrelated JavaScript variable names; 0 cases exercise js.Value.toString, so flips 0 cases.

No JavaScript Error.prototype.toString, Error.stack, ABI layout, or user-owned stack/queue/job surface changed.

Sign in to comment on this issue.