Re: Observability of NaN distinctions — is this a concern?

Kenneth Russell kbr at
Mon Mar 25 11:48:55 PDT 2013

On Fri, Mar 22, 2013 at 10:34 PM, David Herman <dherman at> wrote:
> On Mar 22, 2013, at 7:47 PM, Brendan Eich <brendan at> wrote:
>> Kenneth Russell wrote:
>>> I hope that the ES6 integration of typed arrays will not require
>>> normalization of NaNs on write, even if other specification changes
>>> need to be made to avoid requiring it.
>> What other specification changes?
> Ken means that we should change the part of the specification that states the invariant about multiple representations of NaN being unobservable, because he wants typed arrays to be allowed to break that invariant.

To be clear, my intent is to eliminate possible performance
bottlenecks that would prevent ES6 from efficiently implementing
numerical algorithms.

This was a design goal of the typed array specification from day one,
and one of the reasons the specification has achieved a measure of
success. It would be short-sighted to discard this property without
careful consideration while integrating typed arrays into the ES6

> I disagree with Ken.
>> JITs use nan-boxing ( If a typed array user could forge a nan-boxed value, they could pwn the JITting VM.
>> For interop, JS requires cross-browser (VM) NaN canonicalization to avoid observably different results on different browsers.
> IMO this latter point is the most important: regardless of NaN-boxing, allowing different engines to non-deterministically produce one of several different bit patterns when writing a NaN into a typed array is under-specification and asking for portability bugs.

Realistically, no developer is going to store a NaN into a
Float32Array or Float64Array and expect that a certain set of bytes
were produced, verifiable using another view like Uint8Array. This
concern was raised by hixie in the context of WebSockets some time
ago, and I deliberately resisted making changes to the typed array
specification in order to avoid adding a mandatory test-and-branch, or
conditional move, in the setter of Float32Array and Float64Array. In
the interim time, this issue has never been raised as a portability
concern by real world developers.

> Not only that, but I believe any time a web API designer wants to break a long-standing invariant of JS, particularly one that is stated *explicitly* in ECMAScript, the onus is on them to argue that they have a right to break that invariant.

This issue shouldn't be decided by someone arguing over the "right" to
break an ES6 invariant. It should be decided by creating a benchmark
of storing large amounts of data into a Float32Array or Float64Array,
and running the benchmark on two versions of the same JIT, one with
NaN canonicalization on write, and one without. If the performance
loss from NaN canonicalization on write is large, then in my opinion,
the ES6 spec should be changed to not require it.


>> Ergo, ES6 must specify normative handling of NaNs
> Agreed.
> Dave

More information about the es-discuss mailing list