mirror of
https://github.com/tc39/test262.git
synced 2025-07-30 17:34:51 +02:00
Add tests for NaN handling with Typed Arrays (#623)
Ensure that NaN values are canonicalized consistently by all invocations of SetValueInBuffer. Also ensure that `%TypedArray%.prototype.set` and `%TypedArray%.prototype.slice` preserve the bit-level encoding of the source data. Use a set of experimentally-derived expressions known to produce NaN values with distinct bit patterns in various platforms.
This commit is contained in:
parent
4dac3e4ce8
commit
b17ffc0298
9
harness/nans.js
Normal file
9
harness/nans.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* A collection of NaN values produced from expressions that have been observed
|
||||||
|
* to create distinct bit representations on various platforms. These provide a
|
||||||
|
* weak basis for assertions regarding the consistent canonicalization of NaN
|
||||||
|
* values in Array buffers.
|
||||||
|
*/
|
||||||
|
var distinctNaNs = [
|
||||||
|
0/0, Infinity/Infinity, -(0/0), Math.pow(-1, 0.5), -Math.pow(-1, 0.5)
|
||||||
|
];
|
70
test/built-ins/TypedArray/prototype/fill/fill-values-conversion-operations-consistent-nan.js
vendored
Normal file
70
test/built-ins/TypedArray/prototype/fill/fill-values-conversion-operations-consistent-nan.js
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// 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-%typedarray%.prototype.fill
|
||||||
|
es6id: 22.2.3.8
|
||||||
|
description: Consistent canonicalization of NaN values
|
||||||
|
info: >
|
||||||
|
22.2.3.8 %TypedArray%.prototype.fill (value [ , start [ , end ] ] )
|
||||||
|
|
||||||
|
%TypedArray%.prototype.fill is a distinct function that implements the same
|
||||||
|
algorithm as Array.prototype.fill as defined in 22.1.3.6 except that the this
|
||||||
|
object's [[ArrayLength]] internal slot is accessed in place of performing a
|
||||||
|
[[Get]] of "length". The implementation of the algorithm may be optimized with
|
||||||
|
the knowledge that the this value is an object that has a fixed length and
|
||||||
|
whose integer indexed properties are not sparse. However, such optimization
|
||||||
|
must not introduce any observable changes in the specified behaviour of the
|
||||||
|
algorithm.
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
22.1.3.6 Array.prototype.fill (value [ , start [ , end ] ] )
|
||||||
|
|
||||||
|
...
|
||||||
|
7. Repeat, while k < final
|
||||||
|
a. Let Pk be ! ToString(k).
|
||||||
|
b. Perform ? Set(O, Pk, value, true).
|
||||||
|
...
|
||||||
|
|
||||||
|
24.1.1.6 SetValueInBuffer ( arrayBuffer, byteIndex, type, value [ ,
|
||||||
|
isLittleEndian ] )
|
||||||
|
|
||||||
|
...
|
||||||
|
8. If type is "Float32", then
|
||||||
|
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
|
||||||
|
nearest, ties to even” rounding mode. If isLittleEndian is false, the
|
||||||
|
bytes are arranged in big endian order. Otherwise, the bytes are
|
||||||
|
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
|
||||||
|
encoding. An implementation must always choose the same encoding for
|
||||||
|
each implementation distinguishable NaN value.
|
||||||
|
9. Else, if type is "Float64", then
|
||||||
|
a. Set rawBytes to a List containing the 8 bytes that are the IEEE
|
||||||
|
754-2008 binary64 format encoding of value. If isLittleEndian is false,
|
||||||
|
the bytes are arranged in big endian order. Otherwise, the bytes are
|
||||||
|
arranged in little endian order. If value is NaN, rawValue may be set
|
||||||
|
to any implementation chosen IEEE 754-2008 binary32 format Not-a-Number
|
||||||
|
encoding. An implementation must always choose the same encoding for
|
||||||
|
each implementation distinguishable NaN value.
|
||||||
|
...
|
||||||
|
includes: [nans.js, testTypedArray.js, compareArray.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function body(FloatArray) {
|
||||||
|
var sample = new FloatArray(3);
|
||||||
|
var control, idx, someNaN, sampleBytes, controlBytes;
|
||||||
|
|
||||||
|
for (idx = 0; idx < distinctNaNs.length; ++idx) {
|
||||||
|
someNaN = distinctNaNs[idx];
|
||||||
|
control = new FloatArray([someNaN, someNaN, someNaN]);
|
||||||
|
|
||||||
|
sample.fill(someNaN);
|
||||||
|
|
||||||
|
sampleBytes = new Uint8Array(sample.buffer);
|
||||||
|
controlBytes = new Uint8Array(control.buffer);
|
||||||
|
assert(compareArray(sampleBytes, controlBytes), 'NaN value #' + idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testWithTypedArrayConstructors(body, [Float32Array, Float64Array]);
|
@ -0,0 +1,60 @@
|
|||||||
|
// 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-%typedarray%.prototype.map
|
||||||
|
description: Consistent canonicalization of NaN values
|
||||||
|
info: >
|
||||||
|
22.2.3.19 %TypedArray%.prototype.map ( callbackfn [ , thisArg ] )
|
||||||
|
|
||||||
|
...
|
||||||
|
8. Repeat, while k < len
|
||||||
|
...
|
||||||
|
d. Perform ? Set(A, Pk, mappedValue, true).
|
||||||
|
...
|
||||||
|
|
||||||
|
9.4.5.9 IntegerIndexedElementSet ( O, index, value )
|
||||||
|
|
||||||
|
...
|
||||||
|
15. Perform SetValueInBuffer(buffer, indexedPosition, elementType, numValue).
|
||||||
|
...
|
||||||
|
|
||||||
|
24.1.1.6 SetValueInBuffer ( arrayBuffer, byteIndex, type, value [ ,
|
||||||
|
isLittleEndian ] )
|
||||||
|
|
||||||
|
...
|
||||||
|
8. If type is "Float32", then
|
||||||
|
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
|
||||||
|
nearest, ties to even” rounding mode. If isLittleEndian is false, the
|
||||||
|
bytes are arranged in big endian order. Otherwise, the bytes are
|
||||||
|
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
|
||||||
|
encoding. An implementation must always choose the same encoding for
|
||||||
|
each implementation distinguishable NaN value.
|
||||||
|
9. Else, if type is "Float64", then
|
||||||
|
a. Set rawBytes to a List containing the 8 bytes that are the IEEE
|
||||||
|
754-2008 binary64 format encoding of value. If isLittleEndian is false,
|
||||||
|
the bytes are arranged in big endian order. Otherwise, the bytes are
|
||||||
|
arranged in little endian order. If value is NaN, rawValue may be set
|
||||||
|
to any implementation chosen IEEE 754-2008 binary32 format Not-a-Number
|
||||||
|
encoding. An implementation must always choose the same encoding for
|
||||||
|
each implementation distinguishable NaN value.
|
||||||
|
...
|
||||||
|
includes: [nans.js, testTypedArray.js, compareArray.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function body(FloatArray) {
|
||||||
|
var sample = new FloatArray(distinctNaNs);
|
||||||
|
var sampleBytes, resultBytes;
|
||||||
|
|
||||||
|
var result = sample.map(function(value) {
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
|
||||||
|
sampleBytes = new Uint8Array(sample.buffer);
|
||||||
|
resultBytes = new Uint8Array(result.buffer);
|
||||||
|
|
||||||
|
assert(compareArray(sampleBytes, resultBytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
testWithTypedArrayConstructors(body, [Float32Array, Float64Array]);
|
35
test/built-ins/TypedArray/prototype/set/bit-precision.js
vendored
Normal file
35
test/built-ins/TypedArray/prototype/set/bit-precision.js
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// 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-%typedarray%.prototype.set
|
||||||
|
es6id: 22.2.3.22.2
|
||||||
|
description: Preservation of bit-level encoding
|
||||||
|
info: |
|
||||||
|
[...]
|
||||||
|
28. Else,
|
||||||
|
a. NOTE: If srcType and targetType are the same, the transfer must be
|
||||||
|
performed in a manner that preserves the bit-level encoding of the
|
||||||
|
source data.
|
||||||
|
b. Repeat, while targetByteIndex < limit
|
||||||
|
i. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, "Uint8").
|
||||||
|
ii. Perform SetValueInBuffer(targetBuffer, targetByteIndex, "Uint8",
|
||||||
|
value).
|
||||||
|
iii. Set srcByteIndex to srcByteIndex + 1.
|
||||||
|
iv. Set targetByteIndex to targetByteIndex + 1.
|
||||||
|
includes: [nans.js, compareArray.js, testTypedArray.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function body(FloatArray) {
|
||||||
|
var source = new FloatArray(distinctNaNs);
|
||||||
|
var target = new FloatArray(distinctNaNs.length);
|
||||||
|
var sourceBytes, targetBytes;
|
||||||
|
|
||||||
|
target.set(source);
|
||||||
|
|
||||||
|
sourceBytes = new Uint8Array(source.buffer);
|
||||||
|
targetBytes = new Uint8Array(target.buffer);
|
||||||
|
|
||||||
|
assert(compareArray(sourceBytes, targetBytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
testWithTypedArrayConstructors(body, [Float32Array, Float64Array]);
|
39
test/built-ins/TypedArray/prototype/slice/bit-precision.js
vendored
Normal file
39
test/built-ins/TypedArray/prototype/slice/bit-precision.js
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// 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-%typedarray%.prototype.slice
|
||||||
|
es6id: 22.2.3.23
|
||||||
|
description: Preservation of bit-level encoding
|
||||||
|
info: |
|
||||||
|
[...]
|
||||||
|
15. Else if count > 0, then
|
||||||
|
[...]
|
||||||
|
e. NOTE: If srcType and targetType are the same, the transfer must be
|
||||||
|
performed in a manner that preserves the bit-level encoding of the
|
||||||
|
source data.
|
||||||
|
f. Let srcByteOffet be the value of O's [[ByteOffset]] internal slot.
|
||||||
|
g. Let targetByteIndex be A's [[ByteOffset]] internal slot.
|
||||||
|
h. Let srcByteIndex be (k × elementSize) + srcByteOffet.
|
||||||
|
i. Let limit be targetByteIndex + count × elementSize.
|
||||||
|
j. Repeat, while targetByteIndex < limit
|
||||||
|
i. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, "Uint8").
|
||||||
|
ii. Perform SetValueInBuffer(targetBuffer, targetByteIndex, "Uint8",
|
||||||
|
value).
|
||||||
|
iii. Increase srcByteIndex by 1.
|
||||||
|
iv. Increase targetByteIndex by 1.
|
||||||
|
includes: [nans.js, compareArray.js, testTypedArray.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function body(FloatArray) {
|
||||||
|
var subject = new FloatArray(distinctNaNs);
|
||||||
|
var sliced, subjectBytes, slicedBytes;
|
||||||
|
|
||||||
|
sliced = subject.slice();
|
||||||
|
|
||||||
|
subjectBytes = new Uint8Array(subject.buffer);
|
||||||
|
slicedBytes = new Uint8Array(sliced.buffer);
|
||||||
|
|
||||||
|
assert(compareArray(subjectBytes, slicedBytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
testWithTypedArrayConstructors(body, [Float32Array, Float64Array]);
|
@ -0,0 +1,66 @@
|
|||||||
|
// 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-integer-indexed-exotic-objects-defineownproperty-p-desc
|
||||||
|
description: Consistent canonicalization of NaN values
|
||||||
|
info: >
|
||||||
|
9.4.5.3 [[DefineOwnProperty]] ( P, Desc)
|
||||||
|
|
||||||
|
...
|
||||||
|
3. If Type(P) is String, then
|
||||||
|
...
|
||||||
|
b. If numericIndex is not undefined, then
|
||||||
|
...
|
||||||
|
xi. If Desc has a [[Value]] field, then
|
||||||
|
1. Let value be Desc.[[Value]].
|
||||||
|
2. Return ? IntegerIndexedElementSet(O, intIndex, value).
|
||||||
|
...
|
||||||
|
|
||||||
|
9.4.5.9 IntegerIndexedElementSet ( O, index, value )
|
||||||
|
|
||||||
|
...
|
||||||
|
15. Perform SetValueInBuffer(buffer, indexedPosition, elementType, numValue).
|
||||||
|
...
|
||||||
|
|
||||||
|
24.1.1.6 SetValueInBuffer ( arrayBuffer, byteIndex, type, value [ ,
|
||||||
|
isLittleEndian ] )
|
||||||
|
|
||||||
|
...
|
||||||
|
8. If type is "Float32", then
|
||||||
|
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
|
||||||
|
nearest, ties to even” rounding mode. If isLittleEndian is false, the
|
||||||
|
bytes are arranged in big endian order. Otherwise, the bytes are
|
||||||
|
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
|
||||||
|
encoding. An implementation must always choose the same encoding for
|
||||||
|
each implementation distinguishable NaN value.
|
||||||
|
9. Else, if type is "Float64", then
|
||||||
|
a. Set rawBytes to a List containing the 8 bytes that are the IEEE
|
||||||
|
754-2008 binary64 format encoding of value. If isLittleEndian is false,
|
||||||
|
the bytes are arranged in big endian order. Otherwise, the bytes are
|
||||||
|
arranged in little endian order. If value is NaN, rawValue may be set
|
||||||
|
to any implementation chosen IEEE 754-2008 binary32 format Not-a-Number
|
||||||
|
encoding. An implementation must always choose the same encoding for
|
||||||
|
each implementation distinguishable NaN value.
|
||||||
|
...
|
||||||
|
includes: [nans.js, testTypedArray.js, compareArray.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function body(FloatArray) {
|
||||||
|
var sample = new FloatArray(1);
|
||||||
|
var control, idx, someNaN, sampleBytes, controlBytes;
|
||||||
|
|
||||||
|
for (idx = 0; idx < distinctNaNs.length; ++idx) {
|
||||||
|
someNaN = distinctNaNs[idx];
|
||||||
|
control = new FloatArray([someNaN]);
|
||||||
|
|
||||||
|
Object.defineProperty(sample, '0', { value: someNaN });
|
||||||
|
|
||||||
|
sampleBytes = new Uint8Array(sample.buffer);
|
||||||
|
controlBytes = new Uint8Array(control.buffer);
|
||||||
|
assert(compareArray(sampleBytes, controlBytes));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testWithTypedArrayConstructors(body, [Float32Array, Float64Array]);
|
@ -0,0 +1,63 @@
|
|||||||
|
// 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-integer-indexed-exotic-objects-set-p-v-receiver
|
||||||
|
description: Consistent canonicalization of NaN values
|
||||||
|
info: >
|
||||||
|
9.4.5.5 [[Set]] ( P, V, Receiver)
|
||||||
|
|
||||||
|
...
|
||||||
|
2. If Type(P) is String, then
|
||||||
|
...
|
||||||
|
b. If numericIndex is not undefined, then
|
||||||
|
i. Return ? IntegerIndexedElementSet(O, numericIndex, V).
|
||||||
|
...
|
||||||
|
|
||||||
|
9.4.5.9 IntegerIndexedElementSet ( O, index, value )
|
||||||
|
|
||||||
|
...
|
||||||
|
15. Perform SetValueInBuffer(buffer, indexedPosition, elementType, numValue).
|
||||||
|
...
|
||||||
|
|
||||||
|
24.1.1.6 SetValueInBuffer ( arrayBuffer, byteIndex, type, value [ ,
|
||||||
|
isLittleEndian ] )
|
||||||
|
|
||||||
|
...
|
||||||
|
8. If type is "Float32", then
|
||||||
|
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
|
||||||
|
nearest, ties to even” rounding mode. If isLittleEndian is false, the
|
||||||
|
bytes are arranged in big endian order. Otherwise, the bytes are
|
||||||
|
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
|
||||||
|
encoding. An implementation must always choose the same encoding for
|
||||||
|
each implementation distinguishable NaN value.
|
||||||
|
9. Else, if type is "Float64", then
|
||||||
|
a. Set rawBytes to a List containing the 8 bytes that are the IEEE
|
||||||
|
754-2008 binary64 format encoding of value. If isLittleEndian is false,
|
||||||
|
the bytes are arranged in big endian order. Otherwise, the bytes are
|
||||||
|
arranged in little endian order. If value is NaN, rawValue may be set
|
||||||
|
to any implementation chosen IEEE 754-2008 binary32 format Not-a-Number
|
||||||
|
encoding. An implementation must always choose the same encoding for
|
||||||
|
each implementation distinguishable NaN value.
|
||||||
|
...
|
||||||
|
includes: [nans.js, testTypedArray.js, compareArray.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function body(FloatArray) {
|
||||||
|
var sample = new FloatArray(1);
|
||||||
|
var control, idx, someNaN, sampleBytes, controlBytes;
|
||||||
|
|
||||||
|
for (idx = 0; idx < distinctNaNs.length; ++idx) {
|
||||||
|
someNaN = distinctNaNs[idx];
|
||||||
|
control = new FloatArray([someNaN]);
|
||||||
|
|
||||||
|
sample[0] = someNaN;
|
||||||
|
|
||||||
|
sampleBytes = new Uint8Array(sample.buffer);
|
||||||
|
controlBytes = new Uint8Array(control.buffer);
|
||||||
|
assert(compareArray(sampleBytes, controlBytes), 'NaN value #' + idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testWithTypedArrayConstructors(body, [Float32Array, Float64Array]);
|
@ -0,0 +1,60 @@
|
|||||||
|
// 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-typedarray-object
|
||||||
|
description: Consistent canonicalization of NaN values
|
||||||
|
info: >
|
||||||
|
22.2.4.4 TypedArray ( object )
|
||||||
|
|
||||||
|
This description applies only if the TypedArray function is called with at
|
||||||
|
least one argument and the Type of the first argument is Object and that
|
||||||
|
object does not have either a [[TypedArrayName]] or an [[ArrayBufferData]]
|
||||||
|
internal slot.
|
||||||
|
|
||||||
|
...
|
||||||
|
9. Repeat, while k < len
|
||||||
|
...
|
||||||
|
c. Perform ? Set(O, Pk, kValue, true).
|
||||||
|
...
|
||||||
|
|
||||||
|
9.4.5.9 IntegerIndexedElementSet ( O, index, value )
|
||||||
|
|
||||||
|
...
|
||||||
|
15. Perform SetValueInBuffer(buffer, indexedPosition, elementType, numValue).
|
||||||
|
...
|
||||||
|
|
||||||
|
24.1.1.6 SetValueInBuffer ( arrayBuffer, byteIndex, type, value [ ,
|
||||||
|
isLittleEndian ] )
|
||||||
|
|
||||||
|
...
|
||||||
|
8. If type is "Float32", then
|
||||||
|
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
|
||||||
|
nearest, ties to even” rounding mode. If isLittleEndian is false, the
|
||||||
|
bytes are arranged in big endian order. Otherwise, the bytes are
|
||||||
|
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
|
||||||
|
encoding. An implementation must always choose the same encoding for
|
||||||
|
each implementation distinguishable NaN value.
|
||||||
|
9. Else, if type is "Float64", then
|
||||||
|
a. Set rawBytes to a List containing the 8 bytes that are the IEEE
|
||||||
|
754-2008 binary64 format encoding of value. If isLittleEndian is false,
|
||||||
|
the bytes are arranged in big endian order. Otherwise, the bytes are
|
||||||
|
arranged in little endian order. If value is NaN, rawValue may be set
|
||||||
|
to any implementation chosen IEEE 754-2008 binary32 format Not-a-Number
|
||||||
|
encoding. An implementation must always choose the same encoding for
|
||||||
|
each implementation distinguishable NaN value.
|
||||||
|
...
|
||||||
|
includes: [nans.js, testTypedArray.js, compareArray.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function body(FloatArray) {
|
||||||
|
var first = new FloatArray(distinctNaNs);
|
||||||
|
var second = new FloatArray(distinctNaNs);
|
||||||
|
var firstBytes = new Uint8Array(first.buffer);
|
||||||
|
var secondBytes = new Uint8Array(second.buffer);
|
||||||
|
|
||||||
|
assert(compareArray(firstBytes, secondBytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
testWithTypedArrayConstructors(body, [Float32Array, Float64Array]);
|
Loading…
x
Reference in New Issue
Block a user