Problem
Intl.Locale currently exposes its specification-internal [[Locale]] state as a forgeable \0locale ordinary own property. The constructor, CanonicalizeLocaleList, every prototype accessor, and every prototype method recover the brand through generic named-property lookup; most consumers then rescan the same canonical BCP 47 tag on every call.
This is both a security boundary defect (a forged NUL-named property passes the brand check and bypasses ordinary conversion) and unnecessary steady-state work (property synchronization plus repeated subtag/Unicode-extension parsing).
Parent work: #475, #460. Related internal-state migrations: #528, #589. Worst-case/bounded-latency context: #493.
Scope
- Freeze a representative Locale reflection workload with construction outside the timed boundary and checksum parity with JavaScriptCore.
- Publish
Intl.Localeonly after all constructor coercions and option observations complete, preserving the required order:language,script,region,variants,calendar,collation,hourCycle,caseFirst,numeric,numberingSystem,firstDayOfWeek. - Replace the forgeable ordinary property with object-owned immutable native state containing the one canonical GC-managed locale string plus precomputed byte ranges/closed values for the base-name components and supported Unicode extension keys.
- Add explicit strong tracing and moving-GC relocation for the retained string; finalize the native record exactly once through object backing ownership.
- Route construction from an existing Locale,
CanonicalizeLocaleList, all accessors,toString, maximize/minimize, and Locale info methods through the unforgeable native brand. - Preserve Locale subclass behavior: internal-slot consumers must recognize branded subclass instances without observing an overridden
toString.
Acceptance
- A plain object with a forged
\0localeproperty is rejected by Locale prototype accessors/methods and is treated as an ordinary object by locale-list/constructor conversion. Intl.Localeinstances publish no NUL-prefixed own property.- Repeated reflection performs no generic own-property lookup and does not reparse the canonical tag.
- Constructor failure/OOM publishes no partial native state; installed state survives moving GC and shared/no-GIL access without races or leaks.
- The frozen workload has the exact same checksum on zig-js and JavaScriptCore.
test/intl402/Localeremains at least 152/152, the full Intl402 subtree has no regressions, focused normal/TSan tests pass, and the full sharded unit suite remains green.- Exact-parent timing and allocation/locking telemetry are reported without a throughput claim unless the sample window is stable.