a3c13435aa
Reason for revert: WebGL tests have been updated and rolled (at https://codereview.chromium.org/2227023002), so this should no longer fail outdated tests. Original issue's description: > Revert of Amend DataView, ArrayBuffer, and TypedArray methods to use ToIndex. (patchset #8 id:140001 of https://codereview.chromium.org/2090353003/ ) > > Reason for revert: > Speculative revert to unblock roll: https://codereview.chromium.org/2107223003/ > > Original issue's description: > > Amend DataView, ArrayBuffer, and TypedArray methods to use ToIndex. > > > > The spec was modified to relax some requirements which implementors had not been > > enforcing. Part of this process involved introducing a new abstract operation > > ToIndex, which had partial overlap with our existing semantics as well as some > > differences (most notably treating undefined as 0). Test262 tests were introduced to > > check for the new semantics, some of which we were failing. This patch amends the > > parts of our implementation corresponding to specification algorithms which use > > ToIndex to follow its semantics precisely. > > > > BUG=v8:4784,v8:5120 > > > > Committed: https://crrev.com/09720349ea058d178521ec58d0a5676443a5a132 > > Cr-Commit-Position: refs/heads/master@{#37406} > > TBR=littledan@chromium.org,adamk@chromium.org,bakkot@google.com > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=v8:4784,v8:5120 > > Committed: https://crrev.com/b1f7f1f4e41a723d5f997738a07e35a031713b8f > Cr-Commit-Position: refs/heads/master@{#37417} TBR=littledan@chromium.org,adamk@chromium.org,hablich@chromium.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=v8:4784,v8:5120 Review-Url: https://codereview.chromium.org/2247073004 Cr-Commit-Position: refs/heads/master@{#38689}
452 lines
15 KiB
JavaScript
452 lines
15 KiB
JavaScript
// Copyright 2013 the V8 project authors. All rights reserved.
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions are
|
|
// met:
|
|
//
|
|
// * Redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer.
|
|
// * Redistributions in binary form must reproduce the above
|
|
// copyright notice, this list of conditions and the following
|
|
// disclaimer in the documentation and/or other materials provided
|
|
// with the distribution.
|
|
// * Neither the name of Google Inc. nor the names of its
|
|
// contributors may be used to endorse or promote products derived
|
|
// from this software without specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
// These tests are adapted from Khronos DataView tests
|
|
|
|
var intArray1 =
|
|
[0, 1, 2, 3, 100, 101, 102, 103, 128, 129, 130, 131, 252, 253, 254, 255];
|
|
var intArray2 =
|
|
[31, 32, 33, 0, 1, 2, 3, 100, 101, 102, 103, 128, 129, 130, 131, 252,
|
|
253, 254, 255];
|
|
var initialArray =
|
|
[204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
|
|
204, 204, 204];
|
|
|
|
var arayBuffer = null;
|
|
var view = null;
|
|
var viewStart = 0;
|
|
var viewLength = 0;
|
|
|
|
function getElementSize(func) {
|
|
switch (func) {
|
|
case "Int8":
|
|
case "Uint8":
|
|
return 1;
|
|
case "Int16":
|
|
case "Uint16":
|
|
return 2;
|
|
case "Int32":
|
|
case "Uint32":
|
|
case "Float32":
|
|
return 4;
|
|
case "Float64":
|
|
return 8;
|
|
default:
|
|
assertUnreachable(func);
|
|
}
|
|
}
|
|
|
|
function checkGet(func, index, expected, littleEndian) {
|
|
function doGet() {
|
|
if (littleEndian != undefined)
|
|
return view["get" + func](index, littleEndian);
|
|
else
|
|
return view["get" + func](index);
|
|
}
|
|
if (index >=0 && index + getElementSize(func) - 1 < view.byteLength)
|
|
assertSame(expected, doGet());
|
|
else
|
|
assertThrows(doGet, RangeError);
|
|
}
|
|
|
|
function checkSet(func, index, value, littleEndian) {
|
|
function doSet() {
|
|
if (littleEndian != undefined)
|
|
view["set" + func](index, value, littleEndian);
|
|
else
|
|
view["set" + func](index, value);
|
|
}
|
|
if (index >= 0 &&
|
|
index + getElementSize(func) - 1 < view.byteLength) {
|
|
assertSame(undefined, doSet());
|
|
checkGet(func, index, value, littleEndian);
|
|
} else {
|
|
assertThrows(doSet, RangeError);
|
|
}
|
|
}
|
|
|
|
function test(isTestingGet, func, index, value, littleEndian) {
|
|
if (isTestingGet)
|
|
checkGet(func, index, value, littleEndian);
|
|
else
|
|
checkSet(func, index, value, littleEndian);
|
|
}
|
|
|
|
function createDataView(
|
|
array, frontPaddingNum, littleEndian, start, length) {
|
|
if (!littleEndian)
|
|
array.reverse();
|
|
var paddingArray = new Array(frontPaddingNum);
|
|
arrayBuffer = (new Uint8Array(paddingArray.concat(array))).buffer;
|
|
view = new DataView(arrayBuffer, viewStart, viewLength);
|
|
if (!littleEndian)
|
|
array.reverse(); // restore the array.
|
|
}
|
|
|
|
function runIntegerTestCases(isTestingGet, array, start, length) {
|
|
createDataView(array, 0, true, start, length);
|
|
|
|
test(isTestingGet, "Int8", 0, 0);
|
|
test(isTestingGet, "Int8", undefined, 0);
|
|
test(isTestingGet, "Int8", 8, -128);
|
|
test(isTestingGet, "Int8", 15, -1);
|
|
test(isTestingGet, "Int8", 1e12, undefined);
|
|
|
|
test(isTestingGet, "Uint8", 0, 0);
|
|
test(isTestingGet, "Uint8", undefined, 0);
|
|
test(isTestingGet, "Uint8", 8, 128);
|
|
test(isTestingGet, "Uint8", 15, 255);
|
|
test(isTestingGet, "Uint8", 1e12, undefined);
|
|
|
|
// Little endian.
|
|
test(isTestingGet, "Int16", 0, 256, true);
|
|
test(isTestingGet, "Int16", undefined, 256, true);
|
|
test(isTestingGet, "Int16", 5, 26213, true);
|
|
test(isTestingGet, "Int16", 9, -32127, true);
|
|
test(isTestingGet, "Int16", 14, -2, true);
|
|
test(isTestingGet, "Int16", 1e12, undefined, true);
|
|
|
|
// Big endian.
|
|
test(isTestingGet, "Int16", 0, 1);
|
|
test(isTestingGet, "Int16", undefined, 1);
|
|
test(isTestingGet, "Int16", 5, 25958);
|
|
test(isTestingGet, "Int16", 9, -32382);
|
|
test(isTestingGet, "Int16", 14, -257);
|
|
test(isTestingGet, "Int16", 1e12, undefined);
|
|
|
|
// Little endian.
|
|
test(isTestingGet, "Uint16", 0, 256, true);
|
|
test(isTestingGet, "Uint16", undefined, 256, true);
|
|
test(isTestingGet, "Uint16", 5, 26213, true);
|
|
test(isTestingGet, "Uint16", 9, 33409, true);
|
|
test(isTestingGet, "Uint16", 14, 65534, true);
|
|
test(isTestingGet, "Uint16", 1e12, undefined, true);
|
|
|
|
// Big endian.
|
|
test(isTestingGet, "Uint16", 0, 1);
|
|
test(isTestingGet, "Uint16", undefined, 1);
|
|
test(isTestingGet, "Uint16", 5, 25958);
|
|
test(isTestingGet, "Uint16", 9, 33154);
|
|
test(isTestingGet, "Uint16", 14, 65279);
|
|
test(isTestingGet, "Uint16", 1e12, undefined);
|
|
|
|
// Little endian.
|
|
test(isTestingGet, "Int32", 0, 50462976, true);
|
|
test(isTestingGet, "Int32", undefined, 50462976, true);
|
|
test(isTestingGet, "Int32", 3, 1717920771, true);
|
|
test(isTestingGet, "Int32", 6, -2122291354, true);
|
|
test(isTestingGet, "Int32", 9, -58490239, true);
|
|
test(isTestingGet, "Int32", 12,-66052, true);
|
|
test(isTestingGet, "Int32", 1e12, undefined, true);
|
|
|
|
// Big endian.
|
|
test(isTestingGet, "Int32", 0, 66051);
|
|
test(isTestingGet, "Int32", undefined, 66051);
|
|
test(isTestingGet, "Int32", 3, 56911206);
|
|
test(isTestingGet, "Int32", 6, 1718059137);
|
|
test(isTestingGet, "Int32", 9, -2122152964);
|
|
test(isTestingGet, "Int32", 12, -50462977);
|
|
test(isTestingGet, "Int32", 1e12, undefined);
|
|
|
|
// Little endian.
|
|
test(isTestingGet, "Uint32", 0, 50462976, true);
|
|
test(isTestingGet, "Uint32", undefined, 50462976, true);
|
|
test(isTestingGet, "Uint32", 3, 1717920771, true);
|
|
test(isTestingGet, "Uint32", 6, 2172675942, true);
|
|
test(isTestingGet, "Uint32", 9, 4236477057, true);
|
|
test(isTestingGet, "Uint32", 12,4294901244, true);
|
|
test(isTestingGet, "Uint32", 1e12, undefined, true);
|
|
|
|
// Big endian.
|
|
test(isTestingGet, "Uint32", 0, 66051);
|
|
test(isTestingGet, "Uint32", undefined, 66051);
|
|
test(isTestingGet, "Uint32", 3, 56911206);
|
|
test(isTestingGet, "Uint32", 6, 1718059137);
|
|
test(isTestingGet, "Uint32", 9, 2172814332);
|
|
test(isTestingGet, "Uint32", 12, 4244504319);
|
|
test(isTestingGet, "Uint32", 1e12, undefined);
|
|
}
|
|
|
|
function testFloat(isTestingGet, func, array, start, expected) {
|
|
// Little endian.
|
|
createDataView(array, 0, true, start);
|
|
test(isTestingGet, func, 0, expected, true);
|
|
test(isTestingGet, func, undefined, expected, true);
|
|
createDataView(array, 3, true, start);
|
|
test(isTestingGet, func, 3, expected, true);
|
|
createDataView(array, 7, true, start);
|
|
test(isTestingGet, func, 7, expected, true);
|
|
createDataView(array, 10, true, start);
|
|
test(isTestingGet, func, 10, expected, true);
|
|
test(isTestingGet, func, 1e12, undefined, true);
|
|
|
|
// Big endian.
|
|
createDataView(array, 0, false);
|
|
test(isTestingGet, func, 0, expected, false);
|
|
test(isTestingGet, func, undefined, expected, false);
|
|
createDataView(array, 3, false);
|
|
test(isTestingGet, func, 3, expected, false);
|
|
createDataView(array, 7, false);
|
|
test(isTestingGet, func, 7, expected, false);
|
|
createDataView(array, 10, false);
|
|
test(isTestingGet, func, 10, expected, false);
|
|
test(isTestingGet, func, 1e12, undefined, false);
|
|
}
|
|
|
|
function runFloatTestCases(isTestingGet, start) {
|
|
testFloat(isTestingGet, "Float32",
|
|
isTestingGet ? [0, 0, 32, 65] : initialArray, start, 10);
|
|
|
|
testFloat(isTestingGet, "Float32",
|
|
isTestingGet ? [164, 112, 157, 63] : initialArray,
|
|
start, 1.2300000190734863);
|
|
testFloat(isTestingGet, "Float32",
|
|
isTestingGet ? [95, 53, 50, 199] : initialArray,
|
|
start, -45621.37109375);
|
|
testFloat(isTestingGet, "Float32",
|
|
isTestingGet ? [255, 255, 255, 127] : initialArray,
|
|
start, NaN);
|
|
testFloat(isTestingGet, "Float32",
|
|
isTestingGet ? [255, 255, 255, 255] : initialArray,
|
|
start, -NaN);
|
|
|
|
testFloat(isTestingGet, "Float64",
|
|
isTestingGet ? [0, 0, 0, 0, 0, 0, 36, 64] : initialArray,
|
|
start, 10);
|
|
testFloat(isTestingGet, "Float64",
|
|
isTestingGet ? [174, 71, 225, 122, 20, 174, 243, 63] : initialArray,
|
|
start, 1.23);
|
|
testFloat(isTestingGet, "Float64",
|
|
isTestingGet ? [181, 55, 248, 30, 242, 179, 87, 193] : initialArray,
|
|
start, -6213576.4839);
|
|
testFloat(isTestingGet, "Float64",
|
|
isTestingGet ? [255, 255, 255, 255, 255, 255, 255, 127] : initialArray,
|
|
start, NaN);
|
|
testFloat(isTestingGet, "Float64",
|
|
isTestingGet ? [255, 255, 255, 255, 255, 255, 255, 255] : initialArray,
|
|
start, -NaN);
|
|
}
|
|
|
|
function runNegativeIndexTests(isTestingGet) {
|
|
createDataView(intArray1, 0, true, 0, 16);
|
|
|
|
test(isTestingGet, "Int8", -1, 0);
|
|
test(isTestingGet, "Int8", -2, 0);
|
|
|
|
test(isTestingGet, "Uint8", -1, 0);
|
|
test(isTestingGet, "Uint8", -2, 0);
|
|
|
|
test(isTestingGet, "Int16", -1, 1);
|
|
test(isTestingGet, "Int16", -2, 1);
|
|
test(isTestingGet, "Int16", -3, 1);
|
|
|
|
test(isTestingGet, "Uint16", -1, 1);
|
|
test(isTestingGet, "Uint16", -2, 1);
|
|
test(isTestingGet, "Uint16", -3, 1);
|
|
|
|
test(isTestingGet, "Int32", -1, 66051);
|
|
test(isTestingGet, "Int32", -3, 66051);
|
|
test(isTestingGet, "Int32", -5, 66051);
|
|
|
|
test(isTestingGet, "Uint32", -1, 66051);
|
|
test(isTestingGet, "Uint32", -3, 66051);
|
|
test(isTestingGet, "Uint32", -5, 66051);
|
|
|
|
createDataView([0, 0, 0, 0, 0, 0, 0, 0], 0, true, 0, 8);
|
|
|
|
test(isTestingGet, "Float32", -1, 0);
|
|
test(isTestingGet, "Float32", -3, 0);
|
|
test(isTestingGet, "Float32", -5, 0);
|
|
|
|
test(isTestingGet, "Float64", -1, 0);
|
|
test(isTestingGet, "Float64", -5, 0);
|
|
test(isTestingGet, "Float64", -9, 0);
|
|
}
|
|
|
|
|
|
function TestGetters() {
|
|
runIntegerTestCases(true, intArray1, 0, 16);
|
|
runFloatTestCases(true, 0);
|
|
|
|
runIntegerTestCases(true, intArray2, 3, 2);
|
|
runFloatTestCases(true, 3);
|
|
|
|
runNegativeIndexTests(true);
|
|
}
|
|
|
|
function TestSetters() {
|
|
runIntegerTestCases(false, initialArray, 0, 16);
|
|
runFloatTestCases(false);
|
|
|
|
runIntegerTestCases(false, initialArray, 3, 2);
|
|
runFloatTestCases(false, 7);
|
|
|
|
runNegativeIndexTests(false);
|
|
}
|
|
|
|
TestGetters();
|
|
TestSetters();
|
|
|
|
function CheckOutOfRangeInt8(value, expected) {
|
|
var view = new DataView(new ArrayBuffer(100));
|
|
assertSame(undefined, view.setInt8(0, value));
|
|
assertSame(expected, view.getInt8(0));
|
|
assertSame(undefined, view.setInt8(0, value, true));
|
|
assertSame(expected, view.getInt8(0, true));
|
|
}
|
|
|
|
function CheckOutOfRangeUint8(value, expected) {
|
|
var view = new DataView(new ArrayBuffer(100));
|
|
assertSame(undefined, view.setUint8(0, value));
|
|
assertSame(expected, view.getUint8(0));
|
|
assertSame(undefined, view.setUint8(0, value, true));
|
|
assertSame(expected, view.getUint8(0, true));
|
|
}
|
|
|
|
function CheckOutOfRangeInt16(value, expected) {
|
|
var view = new DataView(new ArrayBuffer(100));
|
|
assertSame(undefined, view.setInt16(0, value));
|
|
assertSame(expected, view.getInt16(0));
|
|
assertSame(undefined, view.setInt16(0, value, true));
|
|
assertSame(expected, view.getInt16(0, true));
|
|
}
|
|
|
|
function CheckOutOfRangeUint16(value, expected) {
|
|
var view = new DataView(new ArrayBuffer(100));
|
|
assertSame(undefined, view.setUint16(0, value));
|
|
assertSame(expected, view.getUint16(0));
|
|
assertSame(undefined, view.setUint16(0, value, true));
|
|
assertSame(expected, view.getUint16(0, true));
|
|
}
|
|
|
|
function CheckOutOfRangeInt32(value, expected) {
|
|
var view = new DataView(new ArrayBuffer(100));
|
|
assertSame(undefined, view.setInt32(0, value));
|
|
assertSame(expected, view.getInt32(0));
|
|
assertSame(undefined, view.setInt32(0, value, true));
|
|
assertSame(expected, view.getInt32(0, true));
|
|
}
|
|
|
|
function CheckOutOfRangeUint32(value, expected) {
|
|
var view = new DataView(new ArrayBuffer(100));
|
|
assertSame(undefined, view.setUint32(0, value));
|
|
assertSame(expected, view.getUint32(0));
|
|
assertSame(undefined, view.setUint32(0, value, true));
|
|
assertSame(expected, view.getUint32(0, true));
|
|
}
|
|
|
|
function TestOutOfRange() {
|
|
CheckOutOfRangeInt8(0x80, -0x80);
|
|
CheckOutOfRangeInt8(0x1000, 0);
|
|
CheckOutOfRangeInt8(-0x81, 0x7F);
|
|
|
|
CheckOutOfRangeUint8(0x100, 0);
|
|
CheckOutOfRangeUint8(0x1000, 0);
|
|
CheckOutOfRangeUint8(-0x80, 0x80);
|
|
CheckOutOfRangeUint8(-1, 0xFF);
|
|
CheckOutOfRangeUint8(-0xFF, 1);
|
|
|
|
CheckOutOfRangeInt16(0x8000, -0x8000);
|
|
CheckOutOfRangeInt16(0x10000, 0);
|
|
CheckOutOfRangeInt16(-0x8001, 0x7FFF);
|
|
|
|
CheckOutOfRangeUint16(0x10000, 0);
|
|
CheckOutOfRangeUint16(0x100000, 0);
|
|
CheckOutOfRangeUint16(-0x8000, 0x8000);
|
|
CheckOutOfRangeUint16(-1, 0xFFFF);
|
|
CheckOutOfRangeUint16(-0xFFFF, 1);
|
|
|
|
CheckOutOfRangeInt32(0x80000000, -0x80000000);
|
|
CheckOutOfRangeInt32(0x100000000, 0);
|
|
CheckOutOfRangeInt32(-0x80000001, 0x7FFFFFFF);
|
|
|
|
CheckOutOfRangeUint32(0x100000000, 0);
|
|
CheckOutOfRangeUint32(0x1000000000, 0);
|
|
CheckOutOfRangeUint32(-0x80000000, 0x80000000);
|
|
CheckOutOfRangeUint32(-1, 0xFFFFFFFF);
|
|
CheckOutOfRangeUint32(-0xFFFFFFFF, 1);
|
|
}
|
|
|
|
TestOutOfRange();
|
|
|
|
function TestGeneralAccessors() {
|
|
var a = new DataView(new ArrayBuffer(256));
|
|
function CheckAccessor(name) {
|
|
var f = a[name];
|
|
assertThrows(function() { f(); }, TypeError);
|
|
f.call(a, 0, 0); // should not throw
|
|
assertThrows(function() { f.call({}, 0, 0); }, TypeError);
|
|
f.call(a);
|
|
f.call(a, 1); // should not throw
|
|
}
|
|
CheckAccessor("getUint8");
|
|
CheckAccessor("setUint8");
|
|
CheckAccessor("getInt8");
|
|
CheckAccessor("setInt8");
|
|
CheckAccessor("getUint16");
|
|
CheckAccessor("setUint16");
|
|
CheckAccessor("getInt16");
|
|
CheckAccessor("setInt16");
|
|
CheckAccessor("getUint32");
|
|
CheckAccessor("setUint32");
|
|
CheckAccessor("getInt32");
|
|
CheckAccessor("setInt32");
|
|
CheckAccessor("getFloat32");
|
|
CheckAccessor("setFloat32");
|
|
CheckAccessor("getFloat64");
|
|
CheckAccessor("setFloat64");
|
|
}
|
|
|
|
TestGeneralAccessors();
|
|
|
|
function TestInsufficientArguments() {
|
|
var a = new DataView(new ArrayBuffer(256));
|
|
function CheckInsuficientArguments(type) {
|
|
var expectedValue = type === "Float32" || type === "Float64" ? NaN : 0;
|
|
var offset = getElementSize(type);
|
|
|
|
assertSame(undefined, a["set" + type](0, 7));
|
|
assertSame(undefined, a["set" + type]());
|
|
assertSame(expectedValue, a["get" + type]());
|
|
|
|
assertSame(undefined, a["set" + type](offset, 7));
|
|
assertSame(undefined, a["set" + type](offset));
|
|
assertSame(expectedValue, a["get" + type](offset));
|
|
}
|
|
|
|
CheckInsuficientArguments("Uint8");
|
|
CheckInsuficientArguments("Int8");
|
|
CheckInsuficientArguments("Uint16");
|
|
CheckInsuficientArguments("Int16");
|
|
CheckInsuficientArguments("Uint32");
|
|
CheckInsuficientArguments("Int32");
|
|
CheckInsuficientArguments("Float32");
|
|
CheckInsuficientArguments("Float64");
|
|
}
|
|
|
|
TestInsufficientArguments();
|