New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

24.1.1.6, 24.1.1.7, non-canonical NaNs #546

Closed
pipcet opened this Issue Apr 18, 2016 · 2 comments

Comments

Projects
None yet
3 participants
@pipcet

pipcet commented Apr 18, 2016

I am wondering whether the current SpiderMonkey asm.js implementation is compliant when it comes to non-canonical NaNs; the current implementation normalizes an NaN stored at address 0 in the Float64Array HEAPF64 when HEAPF64[0] = HEAPF64[0] is executed in normal code, but leaves the NaN non-canonicalized when the same code is compiled as asm.js.

There appears to be an inconsistency in the spec: 24.1.1.6 speaks of the (singular) NaN value while 24.1.1.7 mentions the possibility of there being several "implementation distinguishable NaN values".

My understanding of the specification's intent is that there is a way of implementing a ==== operator on NaNs (i.e. all values with x !== x) such that:
(1) x ==== x
(2) if x ==== y and y ==== z, then x ==== z
(3) x ==== y iff y ==== x
(4) two identical array buffers remain identical if x====y and x and y, respectively, are written to the same address of either buffer.
but not necessarily
(5) if two identical array buffers remain identical after x and y have been written to the same address of either buffer, then x ==== y

We could then refer to two NaNs as implementation-indistinguishable iff x ==== y.

I would suggest the best course of action is to remove the stipulation that "An implementation must always choose the same encoding for each implementation distinguishable NaN value." That would obviate the need to define what implementation distinguishable NaN values are and render the current implementation compliant in this regard.

https://bugzilla.mozilla.org/show_bug.cgi?id=1259280

@allenwb

This comment has been minimized.

Show comment
Hide comment
@allenwb

allenwb Apr 19, 2016

Member

For the motivation of that language in the 24.1.1.5 language see https://bugs.ecmascript.org/show_bug.cgi?id=3508#3 and also https://bugs.ecmascript.org/show_bug.cgi?id=4382

What the language is trying to say is that a consistent policy must be applied to storing NaN values into ArrayBuffers. Canonicalization of all NaNs to some single NaN bit-pattern is not required but each distinct NaN value (if multiiple NaN encodings can exist in an implementation as Number values) must be handled in a consistent manner.

Here are two illustrative examples:

let f64a = new Float64Array(1);
let bytes = new Uint8Array(f64a.buffer, 0, 8);
// use some Uint8 level accesses to insert your favorite NaN bit encoding into bytes
let nun = f64a[0];
let f64target = new Float64Array(2);
f64target[0] = num;
f64target[1] = num;
let uintTarget = new Uint8Array(f64.target.buffer, 0, 16);
//assert uintTarget.slice(0,7) and uintTarget.slice(8,15) are the same byte sequences.
//they may or may not be the same as the byte sequence as bytes.slice(0,7)

//example 2
let n1 = NaN+NaN;
let n2 = NaN*NaN; 
let f64target1 = new Float64Array(2);
f64target1[0]=n1;
f64target1[1]=n2;
let f64target2 = new Float64Array(2);
f64target2[0]=n1;
f64target2[1]=n2;
let uintTarget1 = new Uint8Array(f64.target1.buffer, 0, 16);
let uintTarget2 = new Uint8Array(f64.target2.buffer, 0, 16);
//assert uintTarget1.slice(0,7) and uintTarget2.slice(0,7) are the same byte sequences.
//assert uintTarget1.slice(8,18) and  uintTarget2.slice(8,15) are the same byte sequences.
//It is up to the implementation whether or not uintTarget1.slice(0,7) and uintTarget1.slice(8,15)  are the same byte sequences
Member

allenwb commented Apr 19, 2016

For the motivation of that language in the 24.1.1.5 language see https://bugs.ecmascript.org/show_bug.cgi?id=3508#3 and also https://bugs.ecmascript.org/show_bug.cgi?id=4382

What the language is trying to say is that a consistent policy must be applied to storing NaN values into ArrayBuffers. Canonicalization of all NaNs to some single NaN bit-pattern is not required but each distinct NaN value (if multiiple NaN encodings can exist in an implementation as Number values) must be handled in a consistent manner.

Here are two illustrative examples:

let f64a = new Float64Array(1);
let bytes = new Uint8Array(f64a.buffer, 0, 8);
// use some Uint8 level accesses to insert your favorite NaN bit encoding into bytes
let nun = f64a[0];
let f64target = new Float64Array(2);
f64target[0] = num;
f64target[1] = num;
let uintTarget = new Uint8Array(f64.target.buffer, 0, 16);
//assert uintTarget.slice(0,7) and uintTarget.slice(8,15) are the same byte sequences.
//they may or may not be the same as the byte sequence as bytes.slice(0,7)

//example 2
let n1 = NaN+NaN;
let n2 = NaN*NaN; 
let f64target1 = new Float64Array(2);
f64target1[0]=n1;
f64target1[1]=n2;
let f64target2 = new Float64Array(2);
f64target2[0]=n1;
f64target2[1]=n2;
let uintTarget1 = new Uint8Array(f64.target1.buffer, 0, 16);
let uintTarget2 = new Uint8Array(f64.target2.buffer, 0, 16);
//assert uintTarget1.slice(0,7) and uintTarget2.slice(0,7) are the same byte sequences.
//assert uintTarget1.slice(8,18) and  uintTarget2.slice(8,15) are the same byte sequences.
//It is up to the implementation whether or not uintTarget1.slice(0,7) and uintTarget1.slice(8,15)  are the same byte sequences
@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Apr 20, 2016

Member

Seems answered.

Member

bterlson commented Apr 20, 2016

Seems answered.

@bterlson bterlson closed this Apr 20, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment