Skip to content

TypedArray map/filter/reduce/slice/indexOf produce garbage (read raw storage as NaN-boxed) #2447

Description

@proggeramlug

Summary

Several TypedArray.prototype iteration/transformation methods produce garbage or wrong results — they read the typed (raw i32/f64) backing store as if it were NaN-boxed JSValue elements.

const ta = new Int32Array([1,2,3,4]);
ta.map(x => x*2)    // garbage floats (e.g. 1.016e-321,…)   Node: Int32Array [2,4,6,8]
ta.filter(x => x>2) // []                                   Node: Int32Array [3,4]
ta.reduce((a,b)=>a+b, 0) // 1.45e-311 (raw bits as f64)     Node: 10
ta.slice(1,3)       // a number (then .slice/.join throws)  Node: Int32Array [2,3]
ta.indexOf(3)       // -1                                   Node: 2

Working (typed-aware paths exist): index access ta[i], spread [...ta], forEach, TypedArray.from, .length, .byteLength.

Root cause

TypedArrays store raw element bits (i32 / f64 per kind) in their TypedArrayHeader data region — NOT NaN-boxed JSValues. map/filter/reduce/slice/indexOf appear to dispatch to the generic Array.prototype implementations, which read each slot as a NaN-boxed f64 and feed the raw bits to the callback / comparison — hence the denormal-garbage outputs and -1 indexOf. slice returns a scalar instead of a new TypedArray.

Fix direction

Provide TypedArray-aware implementations (or a typed dispatch layer) for map/filter/reduce/reduceRight/slice/subarray/indexOf/lastIndexOf/includes/find/findIndex/some/every/sort that:

  • read each element via lookup_typed_array_kind + the kind's load (matching the existing forEach/format paths),
  • box to a JSValue number before invoking the callback, and unbox/clamp back to the element type on write,
  • return a new TypedArray of the same kind for map/slice/subarray/filter (filter → same kind, length = match count).

Likely related to the typed-array reification follow-up (#2059 family). Found via probe-vs-node (#800). High impact — TypedArray transforms are common in binary/codec code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions