ReviewOS

zig-utils/zig-js

Strings: reuse receiver cells across protocol dispatch

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

Parents: #473, #480 Related: #666, #777, #779

Problem

Interpreter.stringMethod constructed a fresh StringCell before checking whether the requested method had a well-known Symbol protocol. Plain methods such as charCodeAt therefore duplicated an immutable receiver cell on every call.

The protocol and coercion values must remain distinct. ECMA-262 passes the original RequireObjectCoercible result O to custom @@split, @@match, @@search, and @@replace methods before ToString; a boxed String must stay boxed and an overriding conversion method must not run. When execution falls through to the ordinary String algorithm, the later ToString result may itself be an existing StringData cell and should be retained.

Flat Latin-1 receivers also paid an eager whole-string WTF-8 transcode before code-unit-only methods even though their bounded StringCell index reads physical code units directly.

Scope

  • Determine whether a method has protocol dispatch before materializing any coerced receiver.
  • Pass the original O unchanged to custom Symbol protocol methods.
  • Retain the exact StringData Value produced by the later ToString operation.
  • Let charAt, charCodeAt, at, and codePointAt consume the StringCell directly without an eager canonical snapshot.
  • Preserve replaceAll IsRegExp/global-flag/GetMethod ordering and every observable coercion boundary.
  • Add fail-first allocation, boxed-receiver identity, overridden-coercion, flat Latin-1, and moving/TSan coverage.

No-workaround rules

  • No disabled protocol dispatch, forced storage representation, cached mutable receiver, skipped coercion, special input result, or weakened observable ordering.
  • No stacks, queues, jobs, Promise, Worker, or Map/Set iterator changes.

Acceptance

  • Plain String methods do not allocate a duplicate protocol receiver.
  • Protocol methods receive the original O, including boxed String identity.
  • Ordinary methods retain the actual post-ToString StringData cell.
  • Code-unit-only methods avoid eager flat Latin-1 transcoding.
  • Focused normal/TSan units, relevant exact-parent Test262 accounting, threadfuzz, and the full unit gate pass without regressions.
9 days ago

Implementation landed on main in 0c464096.

  • Plain String methods now test the spec protocol set before materializing any receiver Value.
  • Primitive and boxed protocol paths retain their existing StringData cell; generic coerced receivers allocate only when a real protocol call needs a String Value.
  • The fail-first witness proves plain charCodeAt performs zero receiver allocations and a physical flat Latin-1 protocol receiver preserves raw cell identity.
  • Exact-parent Test262 test/built-ins/String at a0e184e9: 1,223 -> 1,223 pass, 0 fail, 0 flips.
  • Focused witness: 1/1 normal and 1/1 TSan, with zero leaks or sanitizer reports.
  • Threadfuzz default: 400 programs from seed 1, zero failures.

The issue remains open pending the shared clean-host full unit gate for #778, #779, and #780; unrelated Home/Bun Zig jobs are still active.

9 days ago

Spec-correct follow-up landed in a85154ed.

The protocol receiver and coercion result are now explicitly separate:

  • custom @@match/search/split/replace receives the original O, so boxed String identity is preserved and ToString does not run before an overriding protocol returns;
  • ordinary fallback retains the exact later ToString Value and derives the StringCell from that result;
  • charAt, charCodeAt, at, and codePointAt read physical StringCell code units without an eager flat Latin-1 -> WTF-8 snapshot.

Evidence on the final source: 4/4 focused normal, 4/4 focused TSan, zero leaks/sanitizer reports; exact-parent built-ins/String 1,223 -> 1,223 with zero flips; threadfuzz 400/0. The only remaining acceptance item is the clean-host full unit gate.

9 days ago

Acceptance is complete. Clean main CI run 33071676798 passed all four ordinary unit shards at 872dbbb5; the issue-specific focused normal/TSan/OOM, exact-parent Test262, allocation, and deterministic fuzz evidence is recorded above. Closing with no semantic regressions.

Sign in to comment on this issue.