ReviewOS

zig-utils/zig-js

Intl.NumberFormat: resolve locale default numbering systems from owned data

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

Parent: #475 Discovered while validating: #569

Problem

new Intl.NumberFormat("ar-EG").format(3) uses ASCII digits in zig-js, while JavaScriptCore resolves the locale default Arabic numbering system and emits Arabic digits. An explicit -u-nu-arab extension works, so digit translation exists; locale default resolution currently falls back to latn unless an option or Unicode extension is present.

This affects NumberFormat text, parts, ranges, resolvedOptions, currencies, units, percent, scientific, and compact notation independently of currency display-name lookup.

Requirements

  • Generate the default numbering system and any CLDR numbering-system fallback metadata for every supported locale from the repository-pinned CLDR input.
  • Resolve precedence exactly: numberingSystem option, supported -u-nu- extension, locale default, then the specified fallback.
  • Keep generated data immutable and shared safely by realms/threads.
  • Preserve exact digit translation and part boundaries for Number and BigInt across text, parts, and ranges.

Acceptance

  • Differential controls cover Arabic, Persian, Thai, Indic, and Latin-default locale families, including explicit option/extension overrides.
  • resolvedOptions().numberingSystem and all NumberFormat sinks agree.
  • Relevant Intl402, OOM, bounded heap, moving GC, no-GIL, TSan, and full units pass.

Non-goals

  • No locale switch, system ICU/JSC dependency, copied output fixture as implementation data, or mutable process-global cache.
9 days ago

The #569 benchmark was explicitly deconfounded in b4b6ade0: its Arabic currency-name row now uses ar-EG-u-nu-arab, which exercises the already-correct explicit numbering-system path. #569 then landed independently in b82dfbfb.

This issue remains specifically about resolving the locale default (for example bare ar-EG) and resolvedOptions().numberingSystem; currency display-name data is no longer a confounder.

9 days ago

Baseline control landed in a389d24e (bench(intl): isolate numbering-system resolution (#571)).

The control covers locale defaults, -u-nu- extensions, explicit numberingSystem precedence, locale/system symbol pairing, Number and BigInt inputs, text, parts, ranges, and resolvedOptions(). At 4 jobs with five stable samples per engine, every sink currently differs from JSC:

  • text: 670224 vs 800528
  • parts: 1790048 vs 2063424
  • range: 673664 vs 804096
  • resolved options: 57328 vs 56928

The implementation will resolve defaults and symbols from generated immutable CLDR data rather than a locale switch or runtime cache.

9 days ago

Implemented and verified in 42cb6a23 (fix(intl): generate numbering-system defaults (#571)).

The generator now emits byte-sorted immutable data for 766 locale defaults and 910 locale/system symbol pairs, derives portable Arabic punctuation from repeated pinned CLDR witnesses, preserves locale-parent word aliases, and splits bidi affixes into correct literal parts. Runtime precedence is option > supported -u-nu- > locale default across NumberFormat and shared Intl consumers.

Verification:

  • 17-case JSC oracle: pass normally and under TSan
  • NumberFormat: 249/249
  • Intl402: 3341/3341
  • full sharded units: 1651 pass, 1 skip, 0 fail, 0 leak
  • generator: byte-for-byte deterministic
  • benchmark checksums at 4 jobs / 5 stable samples: text 800528, parts 2063424, resolved 56928, all exact vs JSC
  • range: 803968 vs 804096; the remaining interval-pattern delta is linked to #570

No test262 regressions (0 flips).

Sign in to comment on this issue.