<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; " class=""><br class=""><div><div class="">On Mar 26, 2013, at 1:29 AM, Oliver Hunt wrote:</div><br class=""><blockquote type="cite"><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; " class=""><div class=""><div class=""><br class=""></div><div class="">Ok, I'll try to go over this again, because for whatever reason it doesn't appear to stick:</div><div class=""><br class=""></div><div class="">If you have a double-typed array, and access a member:</div><div class="">typedArray[0]</div><div class=""><br class=""></div><div class="">Then in ES it is a double that can be one of these values: +Infinitity, -Infinity, NaN, or a discrete value representable in IEEE double spec.  There are no signaling NaNs, nor is there any exposure of what the underlying bit pattern of the NaN is.</div><div class=""><br class=""></div><div class="">So the runtime loads this double, and then stores it somewhere, anywhere, it doesn't matter where, eg.</div><div class="">var tmp = typedArray[0];</div><div class=""><br class=""></div><div class="">Now you store it:</div><div class="">typedArray[whatever] = tmp;</div><div class=""><br class=""></div><div class="">The specification must allow a bitwise comparison of typedArray[whatever] to typedArray[0] to return false, as it is not possible for any NaN-boxing engine to maintain the bit equality that you would otherwise desire, as that would be trivially exploitable.  When I say security and correctness i mean it in the "can't be remotely pwned" sense.</div><div class=""><br class=""></div><div class="">Given that we can't guarantee that the bit pattern will remain unchanged the spec should mandate normalizing to the non-signalling NaN.</div><div class=""><br class=""></div><div class="">--Oliver</div></div></div></blockquote><br class=""></div><div>Oliver,</div><div><br class=""></div><div>Let's look at actual ES6 spec. language and see if there is actually anything you would like to see changed.  The encoding of NaNs is only discussed in three places:</div><div><br class=""></div><div>Section 8.1.5, first paragraph says:  </div><br class=""><div class=""><p style="margin: 0.0px 0.0px 12.0px 0.0px; text-align: justify; line-height: 11.5px; font: 10.0px Arial" class="">The Number type has exactly <span style="font: 10.0px 'Times New Roman'" class="">18437736874454810627</span> (that is, <span style="font: 10.0px 'Times New Roman'" class="">2<sup class="">64</sup>2<sup class="">53</sup>+3</span>) values, representing the double-precision 64-bit format IEEE 754 values as specified in the IEEE Standard for Binary Floating-Point Arithmetic, except that the <span style="font: 10.0px 'Times New Roman'" class="">9007199254740990</span> (that is, <span style="font: 10.0px 'Times New Roman'" class="">2<sup class="">53</sup>2</span>) distinct “Not-a-Number” values of the IEEE Standard are represented in ECMAScript as a single special <b class="">NaN</b> value. (Note that the <b class="">NaN</b> value is produced by the program expression <span style="font: 10.0px 'Courier New'" class=""><b class="">NaN</b></span>.) In some implementations, external code might be able to detect a difference between various Not-a-Number values, but such behaviour is implementation-dependent; to ECMAScript code, all NaN values are indistinguishable from each other.</p></div><div class="">This is very old text, most of which dates to ES1. It is defining the ES Number type, which is an abstraction, not an actual bit-level encoding. To me it say these things:</div><div class="">   1) Unlike the the IEEE 64-bit floating point type.  The ES Number type has only a single NaN value. </div><div class="">   2) An implementations are free to internally encode the Number type any why it desires (as long is it observably conforms to all the requirements of section 8.1.5).</div><div class="">   3) In particular, an implementation  might have multiple internal bit patterns all of which correspond to the single NaN element of the Number type.  </div><div class="">   4) A corollary of 3) is that implementation are not required to internally canonicalize NaNs, that is an implementation level design decision.</div><div class="">   5) Implementations are not required to canonicalize NaNs when they are passed or otherwise made visible to non-ES code.  Hence such code may be able to observe details of the NaN encoding, including whether or not a canonical NaN value is used internally by the ES implementation.</div><div class=""><br class=""></div><div class="">Is there anything you think should change in the above specification text?</div><div class=""><br class=""></div><div class="">Section 15.13.5.1.3 defines the GetValueFromBuffer abstraction operation which is currently the only place in the ES6 spec. where a ES Number value is retrieved from an ArrayBuffer. Step 8 of the specification algorithm is:</div><div class=""><ul class=""><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal 'Times New Roman'; "><span class="" style="letter-spacing: 0.3px; ">8<span class="Apple-tab-span" style="white-space: pre; "> </span>If <i class="">type</i> is “Float64” , then</span></li><ol class="" style="list-style-type: lower-alpha; "><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal 'Times New Roman'; "><span class="" style="letter-spacing: 0.3px; "><i class=""><span class="Apple-tab-span" style="white-space: pre; ">  </span>rawValue</i> is interpreted, taking into accont the value of <i class="">isBigEndian</i>,  as a bit string encoding of an IEEE 754-208 binary64 value.</span></li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal 'Times New Roman'; "><span class="" style="letter-spacing: 0.3px; "><span class="Apple-tab-span" style="white-space: pre; "> </span>If <i class="">rawValue</i> is any an IEEE 754-208 binary64 NaN value, return the <b class="">NaN</b> Number value.</span></li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal 'Times New Roman'; "><span class="" style="letter-spacing: 0.3px; "><span class="Apple-tab-span" style="white-space: pre; ">    </span>Return the Number value that is encoded by <i class="">rawValue</i>.</span></li></ol></ul><div>Step 7 is similar but deals with Float32 values.</div></div><div class=""><br></div><div class="">To me it say these things:</div><div class="">   1) In all cases, an ES Number value (as defined in 8.1.5) is returned.</div><div class="">   2) All IEEE NaN values are logically canonicalized as the single ES NaN value.</div><div class="">   3) No additional requirements for ES Numbers, beyond those in 8.1.5 are introduced.  Actual representation remains up to implementation.</div><div class=""><br></div><div class="">Should anything change? If 8.1.5 continues to not mandate any particular or single encoding representation of a NaN, I don't see why this should either.</div><div class=""><br></div><div class=""><div class="">Section 15.13.5.1.4 defines the SetValueInBuffer abstraction operation which is currently the only place in the ES6 spec. where a ES Number value is stored into a ArrayBuffer. Step 8 of the specification algorithm is:</div><div class=""><br></div><div class=""><ul class="">
<li style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px 'Times New Roman'"><span style="letter-spacing: 0.3px">8.<span class="Apple-tab-span" style="white-space:pre">       </span>Else, if <i>type</i> is “Float64” , then</span></li>
<ol style="list-style-type: lower-alpha">
<li style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px 'Times New Roman'"><span style="letter-spacing: 0.3px"><span class="Apple-tab-span" style="white-space:pre"> </span>Set <i>rawValue</i> to the 8 bytes that are the IEEE-868-2005 binary64 format encoding of <i>value</i>. If <i>isBigEndian</i> is <b>true</b>, the bytes are arranged in big endian order.  Otherwise, the bytes are arranged in little endian order.  If <i>value</i> is <b>NaN</b>, <i>rawValue</i> is may be set to any implementation choosen non-signaling NaN encoding.</span></li>
</ol>
</ul></div><div class=""><div class=""><div>Step 7 is similar but deals with Float32 values.</div></div><div class=""><br></div><div class="">To me it say these things:</div><div class="">   1) When storing into an ArrayBuffer, canonicalization of ES NaN to some particular IEEE NaN is permitted but not required.</div><div class="">   2) The actual ArrayBuffer bit-level representation of NaN values is completely implementation dependent.  It need not even be consistent across multiple stores. .</div><div class="">   3) External observers of such a stored value may be able to detect NaN encoding differences by observing Numbers stored into ArrayBuffers.  This is allowed by 8.1.5</div><div class="">   4) The actual encoding of a NaN value in an ArrayBuffer is observable by ES code by overly a non-float typed Array on an ArrayBuffer where a Number has been stored using the above steps.</div><div class=""><br></div><div class="">Point 4 seems to be in conflict with the 8.1.5 requirement "to ECMAScript code, all NaN values are indistinguishable from each other.".  However, consider that what is being observed is not directly an ES Number NaN value but instead a bit pattern that according to15.13.5.1.4 above may not be a direct reflection of the Number NaN that was stored. So maybe it slips by.</div><div class=""><br></div><div class="">So, again any change requests?</div><div class=""><br></div><div class="">From a spec. perspective we could require canonicalization to some specific IEEE NaN (how do we pick one?) in 15.13.5.4.  If we are going to do that, we presumably also should require canonicalization of endian-ness which is also observable and arguably a bigger interop hazard than NaNs.  However, I think the performance arguments for not canonicalizing endian-ness in typed array are stronger.  If we are going to continue to  let endian-ness be implementation determined then I don't think there is much point in worrying about changing the the handling of NaNs in 15.13.5.1.4. But, I'm flexible.</div><div class=""><br></div><div class="">Allen</div></div><div class=""><br></div><div class=""><br></div><div class=""><div><br></div></div><div><br></div></div><div class=""><br></div><div class=""><br></div><div class=""><br></div><div class=""><ul class=""><ol style="list-style-type: lower-alpha" class="">
</ol>
</ul></div></body></html>