mirror of https://github.com/tc39/test262.git
Weaken tests about NaN canonicalization.
Fixes gh-1476 Closes gh-1484
This commit is contained in:
parent
7b200cb9e7
commit
2975694f86
|
@ -7,6 +7,15 @@ description: |
|
||||||
weak basis for assertions regarding the consistent canonicalization of NaN
|
weak basis for assertions regarding the consistent canonicalization of NaN
|
||||||
values in Array buffers.
|
values in Array buffers.
|
||||||
---*/
|
---*/
|
||||||
var distinctNaNs = [
|
|
||||||
0/0, Infinity/Infinity, -(0/0), Math.pow(-1, 0.5), -Math.pow(-1, 0.5)
|
var NaNs = [
|
||||||
|
() => NaN,
|
||||||
|
() => Number.NaN,
|
||||||
|
() => NaN * 0,
|
||||||
|
() => 0/0,
|
||||||
|
() => Infinity/Infinity,
|
||||||
|
() => -(0/0),
|
||||||
|
() => Math.pow(-1, 0.5),
|
||||||
|
() => -Math.pow(-1, 0.5),
|
||||||
|
() => Number("Not-a-Number"),
|
||||||
];
|
];
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
esid: sec-ordinary-object-internal-methods-and-internal-slots-defineownproperty-p-desc
|
||||||
|
description: >
|
||||||
|
Replaces value field even if they pass in the SameValue algorithm, including
|
||||||
|
distinct NaN values
|
||||||
|
info: |
|
||||||
|
This test does not compare the actual byte values, instead it simply checks that
|
||||||
|
the value is some valid NaN encoding.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Previously, this test compared the "value" field using the SameValue
|
||||||
|
algorithm (thereby ignoring distinct NaN values)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
[[DefineOwnProperty]] (P, Desc)
|
||||||
|
|
||||||
|
Return ? OrdinaryDefineOwnProperty(O, P, Desc).
|
||||||
|
|
||||||
|
#sec-ordinarydefineownproperty
|
||||||
|
OrdinaryDefineOwnProperty ( O, P, Desc )
|
||||||
|
|
||||||
|
1. Let current be ? O.[[GetOwnProperty]](P).
|
||||||
|
2. Let extensible be O.[[Extensible]].
|
||||||
|
3. Return ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc,
|
||||||
|
current).
|
||||||
|
|
||||||
|
#sec-validateandapplypropertydescriptor
|
||||||
|
ValidateAndApplyPropertyDescriptor ( O, P, extensible, Desc, current )
|
||||||
|
|
||||||
|
...
|
||||||
|
7. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both true,
|
||||||
|
then
|
||||||
|
a. If current.[[Configurable]] is false and current.[[Writable]] is false,
|
||||||
|
then
|
||||||
|
...
|
||||||
|
...
|
||||||
|
9. If O is not undefined, then
|
||||||
|
a. For each field of Desc that is present, set the corresponding attribute
|
||||||
|
of the property named P of object O to the value of the field.
|
||||||
|
10. Return true.
|
||||||
|
|
||||||
|
#sec-isnan-number
|
||||||
|
|
||||||
|
NOTE: A reliable way for ECMAScript code to test if a value X is a NaN is
|
||||||
|
an expression of the form X !== X. The result will be true if and only
|
||||||
|
if X is a NaN.
|
||||||
|
includes: [nans.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var len = NaNs.length;
|
||||||
|
|
||||||
|
for (var idx = 0; idx < len; ++idx) {
|
||||||
|
for (var jdx = 0; jdx < len; ++jdx) {
|
||||||
|
var a = {};
|
||||||
|
|
||||||
|
a.prop = NaNs[idx]();
|
||||||
|
a.prop = NaNs[jdx]();
|
||||||
|
|
||||||
|
assert(
|
||||||
|
a.prop !== a.prop,
|
||||||
|
`Object property value reassigned to NaN produced by (${NaNs[idx].toString()}) results in a valid NaN`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
esid: sec-ordinary-object-internal-methods-and-internal-slots-defineownproperty-p-desc
|
||||||
|
description: >
|
||||||
|
Replaces value field even if they pass in the SameValue algorithm, including
|
||||||
|
distinct NaN values
|
||||||
|
info: |
|
||||||
|
This test does not compare the actual byte values, instead it simply checks that
|
||||||
|
the value is some valid NaN encoding.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Previously, this method compared the "value" field using the SameValue
|
||||||
|
algorithm (thereby ignoring distinct NaN values)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
[[DefineOwnProperty]] (P, Desc)
|
||||||
|
|
||||||
|
Return ? OrdinaryDefineOwnProperty(O, P, Desc).
|
||||||
|
|
||||||
|
#sec-ordinarydefineownproperty
|
||||||
|
OrdinaryDefineOwnProperty ( O, P, Desc )
|
||||||
|
|
||||||
|
1. Let current be ? O.[[GetOwnProperty]](P).
|
||||||
|
2. Let extensible be O.[[Extensible]].
|
||||||
|
3. Return ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc,
|
||||||
|
current).
|
||||||
|
|
||||||
|
#sec-validateandapplypropertydescriptor
|
||||||
|
ValidateAndApplyPropertyDescriptor ( O, P, extensible, Desc, current )
|
||||||
|
|
||||||
|
...
|
||||||
|
7. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both true,
|
||||||
|
then
|
||||||
|
a. If current.[[Configurable]] is false and current.[[Writable]] is false,
|
||||||
|
then
|
||||||
|
...
|
||||||
|
...
|
||||||
|
9. If O is not undefined, then
|
||||||
|
a. For each field of Desc that is present, set the corresponding attribute
|
||||||
|
of the property named P of object O to the value of the field.
|
||||||
|
10. Return true.
|
||||||
|
|
||||||
|
#sec-isnan-number
|
||||||
|
|
||||||
|
NOTE: A reliable way for ECMAScript code to test if a value X is a NaN is
|
||||||
|
an expression of the form X !== X. The result will be true if and only
|
||||||
|
if X is a NaN.
|
||||||
|
includes: [nans.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
var len = NaNs.length;
|
||||||
|
|
||||||
|
for (var idx = 0; idx < len; ++idx) {
|
||||||
|
for (var jdx = 0; jdx < len; ++jdx) {
|
||||||
|
var a = {};
|
||||||
|
var b = {};
|
||||||
|
|
||||||
|
Object.defineProperty(a, "prop", {
|
||||||
|
value: NaNs[idx](),
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(a, "prop", {
|
||||||
|
value: NaNs[jdx](),
|
||||||
|
});
|
||||||
|
|
||||||
|
assert(
|
||||||
|
a.prop !== a.prop,
|
||||||
|
`Object property value reconfigured to NaN produced by (${NaNs[idx].toString()}) results in a valid NaN`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,87 +0,0 @@
|
||||||
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
|
||||||
/*---
|
|
||||||
esid: sec-ordinary-object-internal-methods-and-internal-slots-defineownproperty-p-desc
|
|
||||||
es6id: 9.1.6
|
|
||||||
description: >
|
|
||||||
Replaces value field even if they pass in the SameValue algorithm, including
|
|
||||||
distinct NaN values
|
|
||||||
info: |
|
|
||||||
Previously, this method compared the "value" field using the SameValue
|
|
||||||
algorithm (thereby ignoring distinct NaN values)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
[[DefineOwnProperty]] (P, Desc)
|
|
||||||
|
|
||||||
1. Return ? OrdinaryDefineOwnProperty(O, P, Desc).
|
|
||||||
|
|
||||||
9.1.6.1 OrdinaryDefineOwnProperty
|
|
||||||
|
|
||||||
1. Let current be ? O.[[GetOwnProperty]](P).
|
|
||||||
2. Let extensible be O.[[Extensible]].
|
|
||||||
3. Return ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc,
|
|
||||||
current).
|
|
||||||
|
|
||||||
9.1.6.3 ValidateAndApplyPropertyDescriptor
|
|
||||||
|
|
||||||
[...]
|
|
||||||
7. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both true,
|
|
||||||
then
|
|
||||||
a. If current.[[Configurable]] is false and current.[[Writable]] is false,
|
|
||||||
then
|
|
||||||
[...]
|
|
||||||
[...]
|
|
||||||
9. If O is not undefined, then
|
|
||||||
a. For each field of Desc that is present, set the corresponding attribute
|
|
||||||
of the property named P of object O to the value of the field.
|
|
||||||
10. Return true.
|
|
||||||
features: [Float64Array, Uint8Array, Uint16Array]
|
|
||||||
includes: [nans.js]
|
|
||||||
---*/
|
|
||||||
|
|
||||||
var isLittleEndian = new Uint8Array(new Uint16Array([1]).buffer)[0] !== 0;
|
|
||||||
|
|
||||||
var float = new Float64Array(1);
|
|
||||||
var ints = new Uint8Array(float.buffer);
|
|
||||||
var len = distinctNaNs.length;
|
|
||||||
|
|
||||||
function byteValue(value) {
|
|
||||||
float[0] = value;
|
|
||||||
|
|
||||||
var hex = "0123456789ABCDEF";
|
|
||||||
var s = "";
|
|
||||||
for (var i = 0; i < 8; ++i) {
|
|
||||||
var v = ints[isLittleEndian ? 7 - i : i];
|
|
||||||
s += hex[(v >> 4) & 0xf] + hex[v & 0xf];
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterate over each pair of distinct NaN values (with replacement). If two or
|
|
||||||
* more suitable NaN values cannot be identified, the semantics under test
|
|
||||||
* cannot be verified and this test is expected to pass without evaluating any
|
|
||||||
* assertions.
|
|
||||||
*/
|
|
||||||
for (var idx = 0; idx < len; ++idx) {
|
|
||||||
for (var jdx = 0; jdx < len; ++jdx) {
|
|
||||||
// NB: Don't store the distinct NaN values as global variables, because
|
|
||||||
// global variables are properties of the global object. And in this test
|
|
||||||
// we want to ensure NaN-valued properties in objects are properly handled,
|
|
||||||
// so storing NaN values in the (global) object defeats the purpose.
|
|
||||||
if (byteValue(distinctNaNs[idx]) === byteValue(distinctNaNs[jdx])) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var subject = {};
|
|
||||||
subject.prop = distinctNaNs[idx];
|
|
||||||
subject.prop = distinctNaNs[jdx];
|
|
||||||
|
|
||||||
assert.sameValue(
|
|
||||||
byteValue(subject.prop),
|
|
||||||
byteValue(distinctNaNs[jdx]),
|
|
||||||
'Property value was re-set'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,14 +17,14 @@ features: [TypedArray]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function body(FloatArray) {
|
function body(FloatArray) {
|
||||||
var subject = new FloatArray(distinctNaNs.length * 2);
|
var subject = new FloatArray(NaNs.length * 2);
|
||||||
|
|
||||||
distinctNaNs.forEach(function(v, i) {
|
NaNs.forEach(function(v, i) {
|
||||||
subject[i] = v;
|
subject[i] = v();
|
||||||
});
|
});
|
||||||
|
|
||||||
var originalBytes, copiedBytes;
|
var originalBytes, copiedBytes;
|
||||||
var length = distinctNaNs.length * FloatArray.BYTES_PER_ELEMENT;
|
var length = NaNs.length * FloatArray.BYTES_PER_ELEMENT;
|
||||||
|
|
||||||
originalBytes = new Uint8Array(
|
originalBytes = new Uint8Array(
|
||||||
subject.buffer,
|
subject.buffer,
|
||||||
|
@ -32,7 +32,7 @@ function body(FloatArray) {
|
||||||
length
|
length
|
||||||
);
|
);
|
||||||
|
|
||||||
subject.copyWithin(distinctNaNs.length, 0);
|
subject.copyWithin(NaNs.length, 0);
|
||||||
copiedBytes = new Uint8Array(
|
copiedBytes = new Uint8Array(
|
||||||
subject.buffer,
|
subject.buffer,
|
||||||
length
|
length
|
||||||
|
|
|
@ -2,8 +2,14 @@
|
||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
/*---
|
/*---
|
||||||
esid: sec-%typedarray%.prototype.fill
|
esid: sec-%typedarray%.prototype.fill
|
||||||
description: Consistent canonicalization of NaN values
|
description: >
|
||||||
|
An implementation must always choose either the same encoding for each implementation distinguishable *NaN* value, or an implementation-defined canonical value.
|
||||||
info: |
|
info: |
|
||||||
|
This test does not compare the actual byte values, instead it simply checks that
|
||||||
|
the value is some valid NaN encoding.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
22.2.3.8 %TypedArray%.prototype.fill (value [ , start [ , end ] ] )
|
22.2.3.8 %TypedArray%.prototype.fill (value [ , start [ , end ] ] )
|
||||||
|
|
||||||
%TypedArray%.prototype.fill is a distinct function that implements the same
|
%TypedArray%.prototype.fill is a distinct function that implements the same
|
||||||
|
@ -17,7 +23,8 @@ info: |
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
22.1.3.6 Array.prototype.fill (value [ , start [ , end ] ] )
|
#sec-array.prototype.fill
|
||||||
|
Array.prototype.fill (value [ , start [ , end ] ] )
|
||||||
|
|
||||||
...
|
...
|
||||||
7. Repeat, while k < final
|
7. Repeat, while k < final
|
||||||
|
@ -25,46 +32,70 @@ info: |
|
||||||
b. Perform ? Set(O, Pk, value, true).
|
b. Perform ? Set(O, Pk, value, true).
|
||||||
...
|
...
|
||||||
|
|
||||||
24.1.1.6 SetValueInBuffer ( arrayBuffer, byteIndex, type, value [ ,
|
#sec-setvalueinbuffer
|
||||||
|
SetValueInBuffer ( arrayBuffer, byteIndex, type, value [ ,
|
||||||
isLittleEndian ] )
|
isLittleEndian ] )
|
||||||
|
|
||||||
...
|
8. Let rawBytes be NumberToRawBytes(type, value, isLittleEndian).
|
||||||
8. If type is "Float32", then
|
|
||||||
|
#sec-numbertorawbytes
|
||||||
|
NumberToRawBytes( type, value, isLittleEndian )
|
||||||
|
|
||||||
|
1. If type is "Float32", then
|
||||||
a. Set rawBytes to a List containing the 4 bytes that are the result
|
a. Set rawBytes to a List containing the 4 bytes that are the result
|
||||||
of converting value to IEEE 754-2008 binary32 format using “Round to
|
of converting value to IEEE 754-2008 binary32 format using “Round to
|
||||||
nearest, ties to even” rounding mode. If isLittleEndian is false, the
|
nearest, ties to even” rounding mode. If isLittleEndian is false, the
|
||||||
bytes are arranged in big endian order. Otherwise, the bytes are
|
bytes are arranged in big endian order. Otherwise, the bytes are
|
||||||
arranged in little endian order. If value is NaN, rawValue may be set
|
arranged in little endian order. If value is NaN, rawValue may be set
|
||||||
to any implementation chosen IEEE 754-2008 binary64 format Not-a-Number
|
to any implementation chosen IEEE 754-2008 binary64 format Not-a-Number
|
||||||
encoding. An implementation must always choose the same encoding for
|
encoding. An implementation must always choose either the same encoding
|
||||||
each implementation distinguishable NaN value.
|
for each implementation distinguishable *NaN* value, or an
|
||||||
9. Else, if type is "Float64", then
|
implementation-defined canonical value.
|
||||||
a. Set rawBytes to a List containing the 8 bytes that are the IEEE
|
2. Else, if type is "Float64", then
|
||||||
754-2008 binary64 format encoding of value. If isLittleEndian is false,
|
a. Set _rawBytes_ to a List containing the 8 bytes that are the IEEE
|
||||||
the bytes are arranged in big endian order. Otherwise, the bytes are
|
754-2008 binary64 format encoding of _value_. If _isLittleEndian_ is
|
||||||
arranged in little endian order. If value is NaN, rawValue may be set
|
*false*, the bytes are arranged in big endian order. Otherwise,
|
||||||
to any implementation chosen IEEE 754-2008 binary32 format Not-a-Number
|
the bytes are arranged in little endian order. If _value_ is *NaN*,
|
||||||
encoding. An implementation must always choose the same encoding for
|
_rawValue_ may be set to any implementation chosen IEEE 754-2008
|
||||||
each implementation distinguishable NaN value.
|
binary64 format Not-a-Number encoding. An implementation must
|
||||||
|
always choose either the same encoding for each implementation
|
||||||
|
distinguishable *NaN* value, or an implementation-defined
|
||||||
|
canonical value.
|
||||||
...
|
...
|
||||||
includes: [nans.js, testTypedArray.js, compareArray.js]
|
|
||||||
|
#sec-isnan-number
|
||||||
|
|
||||||
|
NOTE: A reliable way for ECMAScript code to test if a value X is a NaN is
|
||||||
|
an expression of the form X !== X. The result will be true if and only
|
||||||
|
if X is a NaN.
|
||||||
|
includes: [nans.js, testTypedArray.js]
|
||||||
features: [TypedArray]
|
features: [TypedArray]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function body(FloatArray) {
|
testWithTypedArrayConstructors(function(FA) {
|
||||||
var sample = new FloatArray(3);
|
var precision = FA === Float32Array ? "single" : "double";
|
||||||
var control, idx, someNaN, sampleBytes, controlBytes;
|
var samples = new FA(3);
|
||||||
|
var controls, idx, aNaN;
|
||||||
|
|
||||||
for (idx = 0; idx < distinctNaNs.length; ++idx) {
|
for (idx = 0; idx < NaNs.length; ++idx) {
|
||||||
someNaN = distinctNaNs[idx];
|
aNaN = NaNs[idx]();
|
||||||
control = new FloatArray([someNaN, someNaN, someNaN]);
|
controls = new Float32Array([aNaN, aNaN, aNaN]);
|
||||||
|
|
||||||
sample.fill(someNaN);
|
samples.fill(aNaN);
|
||||||
|
|
||||||
sampleBytes = new Uint8Array(sample.buffer);
|
for (var i = 0; i < samples.length; i++) {
|
||||||
controlBytes = new Uint8Array(control.buffer);
|
var sample = samples[i];
|
||||||
assert(compareArray(sampleBytes, controlBytes), 'NaN value #' + idx);
|
var control = controls[i];
|
||||||
|
|
||||||
|
assert(
|
||||||
|
samples[i] !== samples[i],
|
||||||
|
`samples (${NaNs[idx].toString()}) produces a valid NaN (${precision} precision)`
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
controls[i] !== controls[i],
|
||||||
|
`controls (${NaNs[idx].toString()}) produces a valid NaN (${precision} precision)`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, [Float32Array, Float64Array]);
|
||||||
testWithTypedArrayConstructors(body, [Float32Array, Float64Array]);
|
|
||||||
|
|
|
@ -45,12 +45,12 @@ features: [TypedArray]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function body(FloatArray) {
|
function body(FloatArray) {
|
||||||
var sample = new FloatArray(distinctNaNs);
|
var sample = new FloatArray(NaNs.map(n => n()));
|
||||||
var sampleBytes, resultBytes;
|
var sampleBytes, resultBytes;
|
||||||
var i = 0;
|
var i = 0;
|
||||||
|
|
||||||
var result = sample.map(function() {
|
var result = sample.map(function() {
|
||||||
return distinctNaNs[i++];
|
return NaNs[i++];
|
||||||
});
|
});
|
||||||
|
|
||||||
sampleBytes = new Uint8Array(sample.buffer);
|
sampleBytes = new Uint8Array(sample.buffer);
|
||||||
|
|
|
@ -19,9 +19,9 @@ includes: [nans.js, compareArray.js, testTypedArray.js]
|
||||||
features: [TypedArray]
|
features: [TypedArray]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function body(FloatArray) {
|
function body(FA) {
|
||||||
var source = new FloatArray(distinctNaNs);
|
var source = new FA(NaNs.map(n => n()));
|
||||||
var target = new FloatArray(distinctNaNs.length);
|
var target = new FA(NaNs.length);
|
||||||
var sourceBytes, targetBytes;
|
var sourceBytes, targetBytes;
|
||||||
|
|
||||||
target.set(source);
|
target.set(source);
|
||||||
|
|
|
@ -25,7 +25,7 @@ features: [TypedArray]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function body(FloatArray) {
|
function body(FloatArray) {
|
||||||
var subject = new FloatArray(distinctNaNs);
|
var subject = new FloatArray(NaNs.map(n => n()));
|
||||||
var sliced, subjectBytes, slicedBytes;
|
var sliced, subjectBytes, slicedBytes;
|
||||||
|
|
||||||
sliced = subject.slice();
|
sliced = subject.slice();
|
||||||
|
|
|
@ -50,8 +50,8 @@ features: [TypedArray]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function body(FloatArray) {
|
function body(FloatArray) {
|
||||||
var first = new FloatArray(distinctNaNs);
|
var first = new FloatArray(NaNs.map(n => n()));
|
||||||
var second = new FloatArray(distinctNaNs);
|
var second = new FloatArray(NaNs.map(n => n()));
|
||||||
var firstBytes = new Uint8Array(first.buffer);
|
var firstBytes = new Uint8Array(first.buffer);
|
||||||
var secondBytes = new Uint8Array(second.buffer);
|
var secondBytes = new Uint8Array(second.buffer);
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,12 @@
|
||||||
esid: sec-integer-indexed-exotic-objects-defineownproperty-p-desc
|
esid: sec-integer-indexed-exotic-objects-defineownproperty-p-desc
|
||||||
description: Consistent canonicalization of NaN values
|
description: Consistent canonicalization of NaN values
|
||||||
info: |
|
info: |
|
||||||
9.4.5.3 [[DefineOwnProperty]] ( P, Desc)
|
This test does not compare the actual byte values, instead it simply checks that
|
||||||
|
the value is some valid NaN encoding.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
[[DefineOwnProperty]] ( P, Desc)
|
||||||
|
|
||||||
...
|
...
|
||||||
3. If Type(P) is String, then
|
3. If Type(P) is String, then
|
||||||
|
@ -16,52 +21,78 @@ info: |
|
||||||
2. Return ? IntegerIndexedElementSet(O, intIndex, value).
|
2. Return ? IntegerIndexedElementSet(O, intIndex, value).
|
||||||
...
|
...
|
||||||
|
|
||||||
9.4.5.9 IntegerIndexedElementSet ( O, index, value )
|
#sec-integerindexedelementset
|
||||||
|
IntegerIndexedElementSet ( O, index, value )
|
||||||
|
|
||||||
...
|
...
|
||||||
15. Perform SetValueInBuffer(buffer, indexedPosition, elementType, numValue).
|
15. Perform SetValueInBuffer(buffer, indexedPosition, elementType, numValue).
|
||||||
...
|
...
|
||||||
|
|
||||||
24.1.1.6 SetValueInBuffer ( arrayBuffer, byteIndex, type, value [ ,
|
#sec-setvalueinbuffer
|
||||||
|
SetValueInBuffer ( arrayBuffer, byteIndex, type, value [ ,
|
||||||
isLittleEndian ] )
|
isLittleEndian ] )
|
||||||
|
|
||||||
...
|
8. Let rawBytes be NumberToRawBytes(type, value, isLittleEndian).
|
||||||
8. If type is "Float32", then
|
|
||||||
|
#sec-numbertorawbytes
|
||||||
|
NumberToRawBytes( type, value, isLittleEndian )
|
||||||
|
|
||||||
|
1. If type is "Float32", then
|
||||||
a. Set rawBytes to a List containing the 4 bytes that are the result
|
a. Set rawBytes to a List containing the 4 bytes that are the result
|
||||||
of converting value to IEEE 754-2008 binary32 format using “Round to
|
of converting value to IEEE 754-2008 binary32 format using “Round to
|
||||||
nearest, ties to even” rounding mode. If isLittleEndian is false, the
|
nearest, ties to even” rounding mode. If isLittleEndian is false, the
|
||||||
bytes are arranged in big endian order. Otherwise, the bytes are
|
bytes are arranged in big endian order. Otherwise, the bytes are
|
||||||
arranged in little endian order. If value is NaN, rawValue may be set
|
arranged in little endian order. If value is NaN, rawValue may be set
|
||||||
to any implementation chosen IEEE 754-2008 binary64 format Not-a-Number
|
to any implementation chosen IEEE 754-2008 binary64 format Not-a-Number
|
||||||
encoding. An implementation must always choose the same encoding for
|
encoding. An implementation must always choose either the same encoding
|
||||||
each implementation distinguishable NaN value.
|
for each implementation distinguishable *NaN* value, or an
|
||||||
9. Else, if type is "Float64", then
|
implementation-defined canonical value.
|
||||||
a. Set rawBytes to a List containing the 8 bytes that are the IEEE
|
2. Else, if type is "Float64", then
|
||||||
754-2008 binary64 format encoding of value. If isLittleEndian is false,
|
a. Set _rawBytes_ to a List containing the 8 bytes that are the IEEE
|
||||||
the bytes are arranged in big endian order. Otherwise, the bytes are
|
754-2008 binary64 format encoding of _value_. If _isLittleEndian_ is
|
||||||
arranged in little endian order. If value is NaN, rawValue may be set
|
*false*, the bytes are arranged in big endian order. Otherwise,
|
||||||
to any implementation chosen IEEE 754-2008 binary32 format Not-a-Number
|
the bytes are arranged in little endian order. If _value_ is *NaN*,
|
||||||
encoding. An implementation must always choose the same encoding for
|
_rawValue_ may be set to any implementation chosen IEEE 754-2008
|
||||||
each implementation distinguishable NaN value.
|
binary64 format Not-a-Number encoding. An implementation must
|
||||||
|
always choose either the same encoding for each implementation
|
||||||
|
distinguishable *NaN* value, or an implementation-defined
|
||||||
|
canonical value.
|
||||||
...
|
...
|
||||||
includes: [nans.js, testTypedArray.js, compareArray.js]
|
|
||||||
|
#sec-isnan-number
|
||||||
|
|
||||||
|
NOTE: A reliable way for ECMAScript code to test if a value X is a NaN is
|
||||||
|
an expression of the form X !== X. The result will be true if and only
|
||||||
|
if X is a NaN.
|
||||||
|
includes: [nans.js, testTypedArray.js]
|
||||||
features: [TypedArray]
|
features: [TypedArray]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function body(FloatArray) {
|
testWithTypedArrayConstructors(function(FA) {
|
||||||
var sample = new FloatArray(1);
|
var precision = FA === Float32Array ? "single" : "double";
|
||||||
var control, idx, someNaN, sampleBytes, controlBytes;
|
var samples = new FA(1);
|
||||||
|
var controls, idx, aNaN;
|
||||||
|
|
||||||
for (idx = 0; idx < distinctNaNs.length; ++idx) {
|
for (idx = 0; idx < NaNs.length; ++idx) {
|
||||||
someNaN = distinctNaNs[idx];
|
aNaN = NaNs[idx]();
|
||||||
control = new FloatArray([someNaN]);
|
controls = new FA([aNaN, aNaN, aNaN]);
|
||||||
|
|
||||||
Object.defineProperty(sample, '0', { value: someNaN });
|
Object.defineProperty(samples, "0", { value: aNaN });
|
||||||
|
|
||||||
sampleBytes = new Uint8Array(sample.buffer);
|
for (var i = 0; i < samples.length; i++) {
|
||||||
controlBytes = new Uint8Array(control.buffer);
|
var sample = samples[i];
|
||||||
assert(compareArray(sampleBytes, controlBytes));
|
var control = controls[i];
|
||||||
|
|
||||||
|
assert(
|
||||||
|
samples[i] !== samples[i],
|
||||||
|
`samples (${NaNs[idx].toString()}) produces a valid NaN (${precision} precision)`
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
controls[i] !== controls[i],
|
||||||
|
`controls (${NaNs[idx].toString()}) produces a valid NaN (${precision} precision)`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, [Float32Array, Float64Array]);
|
||||||
|
|
||||||
testWithTypedArrayConstructors(body, [Float32Array, Float64Array]);
|
|
||||||
|
|
|
@ -4,7 +4,12 @@
|
||||||
esid: sec-integer-indexed-exotic-objects-set-p-v-receiver
|
esid: sec-integer-indexed-exotic-objects-set-p-v-receiver
|
||||||
description: Consistent canonicalization of NaN values
|
description: Consistent canonicalization of NaN values
|
||||||
info: |
|
info: |
|
||||||
9.4.5.5 [[Set]] ( P, V, Receiver)
|
This test does not compare the actual byte values, instead it simply checks that
|
||||||
|
the value is some valid NaN encoding.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
[[Set]] ( P, V, Receiver)
|
||||||
|
|
||||||
...
|
...
|
||||||
2. If Type(P) is String, then
|
2. If Type(P) is String, then
|
||||||
|
@ -13,52 +18,79 @@ info: |
|
||||||
i. Return ? IntegerIndexedElementSet(O, numericIndex, V).
|
i. Return ? IntegerIndexedElementSet(O, numericIndex, V).
|
||||||
...
|
...
|
||||||
|
|
||||||
9.4.5.9 IntegerIndexedElementSet ( O, index, value )
|
#sec-integerindexedelementset
|
||||||
|
IntegerIndexedElementSet ( O, index, value )
|
||||||
|
|
||||||
...
|
...
|
||||||
15. Perform SetValueInBuffer(buffer, indexedPosition, elementType, numValue).
|
15. Perform SetValueInBuffer(buffer, indexedPosition, elementType, numValue).
|
||||||
...
|
...
|
||||||
|
|
||||||
24.1.1.6 SetValueInBuffer ( arrayBuffer, byteIndex, type, value [ ,
|
#sec-setvalueinbuffer
|
||||||
|
SetValueInBuffer ( arrayBuffer, byteIndex, type, value [ ,
|
||||||
isLittleEndian ] )
|
isLittleEndian ] )
|
||||||
|
|
||||||
...
|
8. Let rawBytes be NumberToRawBytes(type, value, isLittleEndian).
|
||||||
8. If type is "Float32", then
|
|
||||||
|
#sec-numbertorawbytes
|
||||||
|
|
||||||
|
NumberToRawBytes( type, value, isLittleEndian )
|
||||||
|
|
||||||
|
1. If type is "Float32", then
|
||||||
a. Set rawBytes to a List containing the 4 bytes that are the result
|
a. Set rawBytes to a List containing the 4 bytes that are the result
|
||||||
of converting value to IEEE 754-2008 binary32 format using “Round to
|
of converting value to IEEE 754-2008 binary32 format using “Round to
|
||||||
nearest, ties to even” rounding mode. If isLittleEndian is false, the
|
nearest, ties to even” rounding mode. If isLittleEndian is false, the
|
||||||
bytes are arranged in big endian order. Otherwise, the bytes are
|
bytes are arranged in big endian order. Otherwise, the bytes are
|
||||||
arranged in little endian order. If value is NaN, rawValue may be set
|
arranged in little endian order. If value is NaN, rawValue may be set
|
||||||
to any implementation chosen IEEE 754-2008 binary64 format Not-a-Number
|
to any implementation chosen IEEE 754-2008 binary64 format Not-a-Number
|
||||||
encoding. An implementation must always choose the same encoding for
|
encoding. An implementation must always choose either the same encoding
|
||||||
each implementation distinguishable NaN value.
|
for each implementation distinguishable *NaN* value, or an
|
||||||
9. Else, if type is "Float64", then
|
implementation-defined canonical value.
|
||||||
a. Set rawBytes to a List containing the 8 bytes that are the IEEE
|
2. Else, if type is "Float64", then
|
||||||
754-2008 binary64 format encoding of value. If isLittleEndian is false,
|
a. Set _rawBytes_ to a List containing the 8 bytes that are the IEEE
|
||||||
the bytes are arranged in big endian order. Otherwise, the bytes are
|
754-2008 binary64 format encoding of _value_. If _isLittleEndian_ is
|
||||||
arranged in little endian order. If value is NaN, rawValue may be set
|
*false*, the bytes are arranged in big endian order. Otherwise,
|
||||||
to any implementation chosen IEEE 754-2008 binary32 format Not-a-Number
|
the bytes are arranged in little endian order. If _value_ is *NaN*,
|
||||||
encoding. An implementation must always choose the same encoding for
|
_rawValue_ may be set to any implementation chosen IEEE 754-2008
|
||||||
each implementation distinguishable NaN value.
|
binary64 format Not-a-Number encoding. An implementation must
|
||||||
|
always choose either the same encoding for each implementation
|
||||||
|
distinguishable *NaN* value, or an implementation-defined
|
||||||
|
canonical value.
|
||||||
...
|
...
|
||||||
includes: [nans.js, testTypedArray.js, compareArray.js]
|
|
||||||
|
#sec-isnan-number
|
||||||
|
|
||||||
|
NOTE: A reliable way for ECMAScript code to test if a value X is a NaN is
|
||||||
|
an expression of the form X !== X. The result will be true if and only
|
||||||
|
if X is a NaN.
|
||||||
|
includes: [nans.js, testTypedArray.js]
|
||||||
features: [TypedArray]
|
features: [TypedArray]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function body(FloatArray) {
|
testWithTypedArrayConstructors(function(FA) {
|
||||||
var sample = new FloatArray(1);
|
var precision = FA === Float32Array ? "single" : "double";
|
||||||
var control, idx, someNaN, sampleBytes, controlBytes;
|
var samples = new FA(1);
|
||||||
|
var controls, idx, aNaN;
|
||||||
|
|
||||||
for (idx = 0; idx < distinctNaNs.length; ++idx) {
|
for (idx = 0; idx < NaNs.length; ++idx) {
|
||||||
someNaN = distinctNaNs[idx];
|
aNaN = NaNs[idx]();
|
||||||
control = new FloatArray([someNaN]);
|
controls = new FA([aNaN, aNaN, aNaN]);
|
||||||
|
|
||||||
sample[0] = someNaN;
|
samples[0] = aNaN;
|
||||||
|
|
||||||
sampleBytes = new Uint8Array(sample.buffer);
|
for (var i = 0; i < samples.length; i++) {
|
||||||
controlBytes = new Uint8Array(control.buffer);
|
var sample = samples[i];
|
||||||
assert(compareArray(sampleBytes, controlBytes), 'NaN value #' + idx);
|
var control = controls[i];
|
||||||
|
|
||||||
|
assert(
|
||||||
|
samples[i] !== samples[i],
|
||||||
|
`samples (${NaNs[idx].toString()}) produces a valid NaN (${precision} precision)`
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
controls[i] !== controls[i],
|
||||||
|
`controls (${NaNs[idx].toString()}) produces a valid NaN (${precision} precision)`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, [Float32Array, Float64Array]);
|
||||||
|
|
||||||
testWithTypedArrayConstructors(body, [Float32Array, Float64Array]);
|
|
||||||
|
|
|
@ -14,6 +14,6 @@ info: |
|
||||||
includes: [nans.js]
|
includes: [nans.js]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
distinctNaNs.forEach(function(v, i) {
|
NaNs.forEach(function(v, i) {
|
||||||
assert.sameValue(isNaN(v), true, "value on position: " + i);
|
assert.sameValue(isNaN(v()), true, "value on position: " + i);
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,15 +4,21 @@
|
||||||
description: >
|
description: >
|
||||||
Including nans.js will expose:
|
Including nans.js will expose:
|
||||||
|
|
||||||
var distinctNaNs = [
|
var NaNs = [
|
||||||
0/0, Infinity/Infinity, -(0/0), Math.pow(-1, 0.5), -Math.pow(-1, 0.5)
|
() => NaN,
|
||||||
|
() => Number.NaN,
|
||||||
|
() => NaN * 0,
|
||||||
|
() => 0/0,
|
||||||
|
() => Infinity/Infinity,
|
||||||
|
() => -(0/0),
|
||||||
|
() => Math.pow(-1, 0.5),
|
||||||
|
() => -Math.pow(-1, 0.5),
|
||||||
|
() => Number("Not-a-Number"),
|
||||||
];
|
];
|
||||||
|
|
||||||
includes: [nans.js]
|
includes: [nans.js]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
assert.sameValue(Number.isNaN(distinctNaNs[0]), true);
|
for (var i = 0; i < NaNs.length; i++) {
|
||||||
assert.sameValue(Number.isNaN(distinctNaNs[1]), true);
|
assert.sameValue(Number.isNaN(NaNs[i]()), true, NaNs[i].toString());
|
||||||
assert.sameValue(Number.isNaN(distinctNaNs[2]), true);
|
}
|
||||||
assert.sameValue(Number.isNaN(distinctNaNs[3]), true);
|
|
||||||
assert.sameValue(Number.isNaN(distinctNaNs[4]), true);
|
|
||||||
|
|
Loading…
Reference in New Issue