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
correctness: class reference + number treats the INT32-boxed class ref as a number (should be string concat) #9087
classK{staticm(): number{return1;}}lets: any=K;for(leti=0;i<8;i++)s+=i;// also reproduces without the loop: K + 1console.log(typeofs,String(s).slice(0,20));
node 26.5.1: string class K { static m() — + on a class does ToPrimitive → the function source string → concatenation.
perry (main b2f163c5a0, also with PERRY_PACKED_LOOP_NUMERIC_ACCUMULATOR=0, so unrelated to #9060): number 29 — the class reference participates as a NUMBER.
Analysis
A ClassRef is NaN-boxed with INT32_TAG carrying the registered class id (see the #321 note on value_bits_to_number in array/header.rs, which added is_class_id_registered exactly to keep class refs off numeric paths — for array slots). The dynamic + path (or an upstream numeric-operand classifier) apparently lacks that exclusion, so class + number takes the numeric arm instead of ToPrimitive/concat.
Found while adversarially testing #9060's accumulator admission (which is not implicated — its tag test rejects the whole NaN-box band including INT32); reported by the ECS/ops perf campaign, session https://claude.ai/code/session_019WVcWKmYsUBnnFB7nBgbBJ. Repro file preserved at /private/tmp/acc-int32.ts shape above.
The same missing exclusion may affect other INT32-band consumers (-/* coercions, comparisons); worth auditing is_class_id_registered call sites vs the numeric-classifier entry points.
Consolidation note from #9088 (duplicate, closed): every tag dispatch that treats INT32-band bits as a plain number likely needs the same registered-class-id audit — not only the dynamic + path. Candidates: -/* coercions, relational compares, and any (bits & TAG_MASK) == INT32_TAG arm that skips is_class_id_registered.
Activity
proggeramlug commentedon Aug 29, 2026
Consolidation note from #9088 (duplicate, closed): every tag dispatch that treats INT32-band bits as a plain number likely needs the same registered-class-id audit — not only the dynamic
+path. Candidates:-/*coercions, relational compares, and any(bits & TAG_MASK) == INT32_TAGarm that skipsis_class_id_registered.perf(codegen): unboxed reduce accumulators in packed fast clones
perf(codegen): unboxed reduce accumulators in packed fast clones
perf(codegen): unboxed reduce accumulators in packed fast clones
perf(codegen): unboxed reduce accumulators in packed fast clones (#9091)