You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
PERRY_JSON_TAPE=0 direct parser loses a ULP on JSON floats — round-trip is not byte-stable (tape path and node are) #7266
Found while verifying #7264 (fixed in #7265). Separate bug, separate path — filing so it isn't lost.
With PERRY_JSON_TAPE=0 (the direct recursive-descent parser, used as a bisection escape hatch and as the perry (mark-sweep, no lazy) row in benchmarks/json_polyglot), a JSON.parse → JSON.stringify round-trip does not preserve the shortest round-trippable double. The default tape path and node both do.
perry (default, tape) len=944711 same=true
perry PERRY_JSON_TAPE=0 len=944728 same=false
node 26.5.1 len=944711 same=true
First divergence:
blob: ..."name":"item_83","value":260.75197,...
re : ..."name":"item_83","value":260.75197000000003,...
So the direct parser produces a double one ULP away from the one the tape parser (and node) produce for the same text 260.75197, and the re-serialization is 17 characters longer per 10k-record blob.
Impact
Anything run with PERRY_JSON_TAPE=0 — bisection runs, the idiomatic perry row of benchmarks/json_polyglot — sees different data than the default path. That makes the escape hatch unsound as a bisection tool for anything numeric: "the bug goes away with the tape off" can be the tape being right.
It shifts bench_field_access's checksum by +850 (17 chars × 50 iterations).
Likely area: the number-token → f64 conversion in crates/perry-runtime/src/json/parser.rs, versus materialize_number in crates/perry-runtime/src/json_tape.rs. One of them is not using a correctly-rounded decimal→binary conversion.
Closed by ee768b095 (PR #7483, merged 2026-08-06) — it predates today's sweep and was simply never triaged.
DirectParser::parse_number in json/parser.rs no longer uses the two-rounding fixed-point path; it takes a Clinger single-rounding fast path. Verified against this issue's own reproducer rather than by title match: the commit message carries the same literal, 260.75197, and the same bit pattern correction (0x40704c0811b1d92c → 0x40704c0811b1d92b).
Activity
proggeramlug commentedon Aug 9, 2026
Closed by
ee768b095(PR #7483, merged 2026-08-06) — it predates today's sweep and was simply never triaged.DirectParser::parse_numberinjson/parser.rsno longer uses the two-rounding fixed-point path; it takes a Clinger single-rounding fast path. Verified against this issue's own reproducer rather than by title match: the commit message carries the same literal,260.75197, and the same bit pattern correction (0x40704c0811b1d92c→0x40704c0811b1d92b).