Commit 5eb63e48 authored by dslomov@chromium.org's avatar dslomov@chromium.org

Change DataView accessors behavior for insufficient args.

ES6 spec for DataView is not fully finished, but Blink, WebKit and
Firefox agree in that for DataView use of getters/setters with no
arguments should result in exceptions, while undefined offset argument
is the same as zero.

R=bmeurer@chromium.org, rossberg@chromium.org

Review URL: https://codereview.chromium.org/18313007

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15607 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6efe8ca2
...@@ -259,6 +259,9 @@ function DataViewGetInt8(offset, little_endian) { ...@@ -259,6 +259,9 @@ function DataViewGetInt8(offset, little_endian) {
throw MakeTypeError('incompatible_method_reciever', throw MakeTypeError('incompatible_method_reciever',
['DataView.getInt8', this]); ['DataView.getInt8', this]);
} }
if (%_ArgumentsLength() < 1) {
throw MakeTypeError('invalid_argument');
}
return %DataViewGetInt8(this, return %DataViewGetInt8(this,
ToPositiveDataViewOffset(offset), ToPositiveDataViewOffset(offset),
!!little_endian); !!little_endian);
...@@ -269,6 +272,9 @@ function DataViewSetInt8(offset, value, little_endian) { ...@@ -269,6 +272,9 @@ function DataViewSetInt8(offset, value, little_endian) {
throw MakeTypeError('incompatible_method_reciever', throw MakeTypeError('incompatible_method_reciever',
['DataView.setInt8', this]); ['DataView.setInt8', this]);
} }
if (%_ArgumentsLength() < 1) {
throw MakeTypeError('invalid_argument');
}
%DataViewSetInt8(this, %DataViewSetInt8(this,
ToPositiveDataViewOffset(offset), ToPositiveDataViewOffset(offset),
TO_NUMBER_INLINE(value), TO_NUMBER_INLINE(value),
...@@ -280,6 +286,9 @@ function DataViewGetUint8(offset, little_endian) { ...@@ -280,6 +286,9 @@ function DataViewGetUint8(offset, little_endian) {
throw MakeTypeError('incompatible_method_reciever', throw MakeTypeError('incompatible_method_reciever',
['DataView.getUint8', this]); ['DataView.getUint8', this]);
} }
if (%_ArgumentsLength() < 1) {
throw MakeTypeError('invalid_argument');
}
return %DataViewGetUint8(this, return %DataViewGetUint8(this,
ToPositiveDataViewOffset(offset), ToPositiveDataViewOffset(offset),
!!little_endian); !!little_endian);
...@@ -290,6 +299,9 @@ function DataViewSetUint8(offset, value, little_endian) { ...@@ -290,6 +299,9 @@ function DataViewSetUint8(offset, value, little_endian) {
throw MakeTypeError('incompatible_method_reciever', throw MakeTypeError('incompatible_method_reciever',
['DataView.setUint8', this]); ['DataView.setUint8', this]);
} }
if (%_ArgumentsLength() < 1) {
throw MakeTypeError('invalid_argument');
}
%DataViewSetUint8(this, %DataViewSetUint8(this,
ToPositiveDataViewOffset(offset), ToPositiveDataViewOffset(offset),
TO_NUMBER_INLINE(value), TO_NUMBER_INLINE(value),
...@@ -301,6 +313,9 @@ function DataViewGetInt16(offset, little_endian) { ...@@ -301,6 +313,9 @@ function DataViewGetInt16(offset, little_endian) {
throw MakeTypeError('incompatible_method_reciever', throw MakeTypeError('incompatible_method_reciever',
['DataView.getInt16', this]); ['DataView.getInt16', this]);
} }
if (%_ArgumentsLength() < 1) {
throw MakeTypeError('invalid_argument');
}
return %DataViewGetInt16(this, return %DataViewGetInt16(this,
ToPositiveDataViewOffset(offset), ToPositiveDataViewOffset(offset),
!!little_endian); !!little_endian);
...@@ -311,6 +326,9 @@ function DataViewSetInt16(offset, value, little_endian) { ...@@ -311,6 +326,9 @@ function DataViewSetInt16(offset, value, little_endian) {
throw MakeTypeError('incompatible_method_reciever', throw MakeTypeError('incompatible_method_reciever',
['DataView.setInt16', this]); ['DataView.setInt16', this]);
} }
if (%_ArgumentsLength() < 1) {
throw MakeTypeError('invalid_argument');
}
%DataViewSetInt16(this, %DataViewSetInt16(this,
ToPositiveDataViewOffset(offset), ToPositiveDataViewOffset(offset),
TO_NUMBER_INLINE(value), TO_NUMBER_INLINE(value),
...@@ -322,6 +340,9 @@ function DataViewGetUint16(offset, little_endian) { ...@@ -322,6 +340,9 @@ function DataViewGetUint16(offset, little_endian) {
throw MakeTypeError('incompatible_method_reciever', throw MakeTypeError('incompatible_method_reciever',
['DataView.getUint16', this]); ['DataView.getUint16', this]);
} }
if (%_ArgumentsLength() < 1) {
throw MakeTypeError('invalid_argument');
}
return %DataViewGetUint16(this, return %DataViewGetUint16(this,
ToPositiveDataViewOffset(offset), ToPositiveDataViewOffset(offset),
!!little_endian); !!little_endian);
...@@ -332,6 +353,9 @@ function DataViewSetUint16(offset, value, little_endian) { ...@@ -332,6 +353,9 @@ function DataViewSetUint16(offset, value, little_endian) {
throw MakeTypeError('incompatible_method_reciever', throw MakeTypeError('incompatible_method_reciever',
['DataView.setUint16', this]); ['DataView.setUint16', this]);
} }
if (%_ArgumentsLength() < 1) {
throw MakeTypeError('invalid_argument');
}
%DataViewSetUint16(this, %DataViewSetUint16(this,
ToPositiveDataViewOffset(offset), ToPositiveDataViewOffset(offset),
TO_NUMBER_INLINE(value), TO_NUMBER_INLINE(value),
...@@ -343,6 +367,9 @@ function DataViewGetInt32(offset, little_endian) { ...@@ -343,6 +367,9 @@ function DataViewGetInt32(offset, little_endian) {
throw MakeTypeError('incompatible_method_reciever', throw MakeTypeError('incompatible_method_reciever',
['DataView.getInt32', this]); ['DataView.getInt32', this]);
} }
if (%_ArgumentsLength() < 1) {
throw MakeTypeError('invalid_argument');
}
return %DataViewGetInt32(this, return %DataViewGetInt32(this,
ToPositiveDataViewOffset(offset), ToPositiveDataViewOffset(offset),
!!little_endian); !!little_endian);
...@@ -353,6 +380,9 @@ function DataViewSetInt32(offset, value, little_endian) { ...@@ -353,6 +380,9 @@ function DataViewSetInt32(offset, value, little_endian) {
throw MakeTypeError('incompatible_method_reciever', throw MakeTypeError('incompatible_method_reciever',
['DataView.setInt32', this]); ['DataView.setInt32', this]);
} }
if (%_ArgumentsLength() < 2) {
throw MakeTypeError('invalid_argument');
}
%DataViewSetInt32(this, %DataViewSetInt32(this,
ToPositiveDataViewOffset(offset), ToPositiveDataViewOffset(offset),
TO_NUMBER_INLINE(value), TO_NUMBER_INLINE(value),
...@@ -364,6 +394,9 @@ function DataViewGetUint32(offset, little_endian) { ...@@ -364,6 +394,9 @@ function DataViewGetUint32(offset, little_endian) {
throw MakeTypeError('incompatible_method_reciever', throw MakeTypeError('incompatible_method_reciever',
['DataView.getUint32', this]); ['DataView.getUint32', this]);
} }
if (%_ArgumentsLength() < 1) {
throw MakeTypeError('invalid_argument');
}
return %DataViewGetUint32(this, return %DataViewGetUint32(this,
ToPositiveDataViewOffset(offset), ToPositiveDataViewOffset(offset),
!!little_endian); !!little_endian);
...@@ -374,6 +407,9 @@ function DataViewSetUint32(offset, value, little_endian) { ...@@ -374,6 +407,9 @@ function DataViewSetUint32(offset, value, little_endian) {
throw MakeTypeError('incompatible_method_reciever', throw MakeTypeError('incompatible_method_reciever',
['DataView.setUint32', this]); ['DataView.setUint32', this]);
} }
if (%_ArgumentsLength() < 1) {
throw MakeTypeError('invalid_argument');
}
%DataViewSetUint32(this, %DataViewSetUint32(this,
ToPositiveDataViewOffset(offset), ToPositiveDataViewOffset(offset),
TO_NUMBER_INLINE(value), TO_NUMBER_INLINE(value),
...@@ -385,6 +421,9 @@ function DataViewGetFloat32(offset, little_endian) { ...@@ -385,6 +421,9 @@ function DataViewGetFloat32(offset, little_endian) {
throw MakeTypeError('incompatible_method_reciever', throw MakeTypeError('incompatible_method_reciever',
['DataView.getFloat32', this]); ['DataView.getFloat32', this]);
} }
if (%_ArgumentsLength() < 1) {
throw MakeTypeError('invalid_argument');
}
return %DataViewGetFloat32(this, return %DataViewGetFloat32(this,
ToPositiveDataViewOffset(offset), ToPositiveDataViewOffset(offset),
!!little_endian); !!little_endian);
...@@ -395,6 +434,9 @@ function DataViewSetFloat32(offset, value, little_endian) { ...@@ -395,6 +434,9 @@ function DataViewSetFloat32(offset, value, little_endian) {
throw MakeTypeError('incompatible_method_reciever', throw MakeTypeError('incompatible_method_reciever',
['DataView.setFloat32', this]); ['DataView.setFloat32', this]);
} }
if (%_ArgumentsLength() < 1) {
throw MakeTypeError('invalid_argument');
}
%DataViewSetFloat32(this, %DataViewSetFloat32(this,
ToPositiveDataViewOffset(offset), ToPositiveDataViewOffset(offset),
TO_NUMBER_INLINE(value), TO_NUMBER_INLINE(value),
...@@ -406,9 +448,8 @@ function DataViewGetFloat64(offset, little_endian) { ...@@ -406,9 +448,8 @@ function DataViewGetFloat64(offset, little_endian) {
throw MakeTypeError('incompatible_method_reciever', throw MakeTypeError('incompatible_method_reciever',
['DataView.getFloat64', this]); ['DataView.getFloat64', this]);
} }
offset = TO_INTEGER(offset); if (%_ArgumentsLength() < 1) {
if (offset < 0) { throw MakeTypeError('invalid_argument');
throw MakeRangeError("invalid_data_view_accessor_offset");
} }
return %DataViewGetFloat64(this, return %DataViewGetFloat64(this,
ToPositiveDataViewOffset(offset), ToPositiveDataViewOffset(offset),
...@@ -420,9 +461,8 @@ function DataViewSetFloat64(offset, value, little_endian) { ...@@ -420,9 +461,8 @@ function DataViewSetFloat64(offset, value, little_endian) {
throw MakeTypeError('incompatible_method_reciever', throw MakeTypeError('incompatible_method_reciever',
['DataView.setFloat64', this]); ['DataView.setFloat64', this]);
} }
offset = TO_INTEGER(offset); if (%_ArgumentsLength() < 1) {
if (offset < 0) { throw MakeTypeError('invalid_argument');
throw MakeRangeError("invalid_data_view_accessor_offset");
} }
%DataViewSetFloat64(this, %DataViewSetFloat64(this,
ToPositiveDataViewOffset(offset), ToPositiveDataViewOffset(offset),
......
...@@ -62,7 +62,10 @@ function getElementSize(func) { ...@@ -62,7 +62,10 @@ function getElementSize(func) {
function checkGet(func, index, expected, littleEndian) { function checkGet(func, index, expected, littleEndian) {
function doGet() { function doGet() {
return view["get" + func](index, littleEndian); if (littleEndian != undefined)
return view["get" + func](index, littleEndian);
else
return view["get" + func](index);
} }
if (index >=0 && index + getElementSize(func) - 1 < view.byteLength) if (index >=0 && index + getElementSize(func) - 1 < view.byteLength)
assertSame(expected, doGet()); assertSame(expected, doGet());
...@@ -72,7 +75,10 @@ function checkGet(func, index, expected, littleEndian) { ...@@ -72,7 +75,10 @@ function checkGet(func, index, expected, littleEndian) {
function checkSet(func, index, value, littleEndian) { function checkSet(func, index, value, littleEndian) {
function doSet() { function doSet() {
view["set" + func](index, value, littleEndian); if (littleEndian != undefined)
view["set" + func](index, value, littleEndian);
else
view["set" + func](index, value);
} }
if (index >= 0 && if (index >= 0 &&
index + getElementSize(func) - 1 < view.byteLength) { index + getElementSize(func) - 1 < view.byteLength) {
...@@ -105,39 +111,46 @@ function runIntegerTestCases(isTestingGet, array, start, length) { ...@@ -105,39 +111,46 @@ function runIntegerTestCases(isTestingGet, array, start, length) {
createDataView(array, 0, true, start, length); createDataView(array, 0, true, start, length);
test(isTestingGet, "Int8", 0, 0); test(isTestingGet, "Int8", 0, 0);
test(isTestingGet, "Int8", undefined, 0);
test(isTestingGet, "Int8", 8, -128); test(isTestingGet, "Int8", 8, -128);
test(isTestingGet, "Int8", 15, -1); test(isTestingGet, "Int8", 15, -1);
test(isTestingGet, "Uint8", 0, 0); test(isTestingGet, "Uint8", 0, 0);
test(isTestingGet, "Uint8", undefined, 0);
test(isTestingGet, "Uint8", 8, 128); test(isTestingGet, "Uint8", 8, 128);
test(isTestingGet, "Uint8", 15, 255); test(isTestingGet, "Uint8", 15, 255);
// Little endian. // Little endian.
test(isTestingGet, "Int16", 0, 256, true); test(isTestingGet, "Int16", 0, 256, true);
test(isTestingGet, "Int16", undefined, 256, true);
test(isTestingGet, "Int16", 5, 26213, true); test(isTestingGet, "Int16", 5, 26213, true);
test(isTestingGet, "Int16", 9, -32127, true); test(isTestingGet, "Int16", 9, -32127, true);
test(isTestingGet, "Int16", 14, -2, true); test(isTestingGet, "Int16", 14, -2, true);
// Big endian. // Big endian.
test(isTestingGet, "Int16", 0, 1); test(isTestingGet, "Int16", 0, 1);
test(isTestingGet, "Int16", undefined, 1);
test(isTestingGet, "Int16", 5, 25958); test(isTestingGet, "Int16", 5, 25958);
test(isTestingGet, "Int16", 9, -32382); test(isTestingGet, "Int16", 9, -32382);
test(isTestingGet, "Int16", 14, -257); test(isTestingGet, "Int16", 14, -257);
// Little endian. // Little endian.
test(isTestingGet, "Uint16", 0, 256, true); test(isTestingGet, "Uint16", 0, 256, true);
test(isTestingGet, "Uint16", undefined, 256, true);
test(isTestingGet, "Uint16", 5, 26213, true); test(isTestingGet, "Uint16", 5, 26213, true);
test(isTestingGet, "Uint16", 9, 33409, true); test(isTestingGet, "Uint16", 9, 33409, true);
test(isTestingGet, "Uint16", 14, 65534, true); test(isTestingGet, "Uint16", 14, 65534, true);
// Big endian. // Big endian.
test(isTestingGet, "Uint16", 0, 1); test(isTestingGet, "Uint16", 0, 1);
test(isTestingGet, "Uint16", undefined, 1);
test(isTestingGet, "Uint16", 5, 25958); test(isTestingGet, "Uint16", 5, 25958);
test(isTestingGet, "Uint16", 9, 33154); test(isTestingGet, "Uint16", 9, 33154);
test(isTestingGet, "Uint16", 14, 65279); test(isTestingGet, "Uint16", 14, 65279);
// Little endian. // Little endian.
test(isTestingGet, "Int32", 0, 50462976, true); test(isTestingGet, "Int32", 0, 50462976, true);
test(isTestingGet, "Int32", undefined, 50462976, true);
test(isTestingGet, "Int32", 3, 1717920771, true); test(isTestingGet, "Int32", 3, 1717920771, true);
test(isTestingGet, "Int32", 6, -2122291354, true); test(isTestingGet, "Int32", 6, -2122291354, true);
test(isTestingGet, "Int32", 9, -58490239, true); test(isTestingGet, "Int32", 9, -58490239, true);
...@@ -145,6 +158,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) { ...@@ -145,6 +158,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) {
// Big endian. // Big endian.
test(isTestingGet, "Int32", 0, 66051); test(isTestingGet, "Int32", 0, 66051);
test(isTestingGet, "Int32", undefined, 66051);
test(isTestingGet, "Int32", 3, 56911206); test(isTestingGet, "Int32", 3, 56911206);
test(isTestingGet, "Int32", 6, 1718059137); test(isTestingGet, "Int32", 6, 1718059137);
test(isTestingGet, "Int32", 9, -2122152964); test(isTestingGet, "Int32", 9, -2122152964);
...@@ -152,6 +166,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) { ...@@ -152,6 +166,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) {
// Little endian. // Little endian.
test(isTestingGet, "Uint32", 0, 50462976, true); test(isTestingGet, "Uint32", 0, 50462976, true);
test(isTestingGet, "Uint32", undefined, 50462976, true);
test(isTestingGet, "Uint32", 3, 1717920771, true); test(isTestingGet, "Uint32", 3, 1717920771, true);
test(isTestingGet, "Uint32", 6, 2172675942, true); test(isTestingGet, "Uint32", 6, 2172675942, true);
test(isTestingGet, "Uint32", 9, 4236477057, true); test(isTestingGet, "Uint32", 9, 4236477057, true);
...@@ -159,6 +174,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) { ...@@ -159,6 +174,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) {
// Big endian. // Big endian.
test(isTestingGet, "Uint32", 0, 66051); test(isTestingGet, "Uint32", 0, 66051);
test(isTestingGet, "Uint32", undefined, 66051);
test(isTestingGet, "Uint32", 3, 56911206); test(isTestingGet, "Uint32", 3, 56911206);
test(isTestingGet, "Uint32", 6, 1718059137); test(isTestingGet, "Uint32", 6, 1718059137);
test(isTestingGet, "Uint32", 9, 2172814332); test(isTestingGet, "Uint32", 9, 2172814332);
...@@ -169,6 +185,7 @@ function testFloat(isTestingGet, func, array, start, expected) { ...@@ -169,6 +185,7 @@ function testFloat(isTestingGet, func, array, start, expected) {
// Little endian. // Little endian.
createDataView(array, 0, true, start); createDataView(array, 0, true, start);
test(isTestingGet, func, 0, expected, true); test(isTestingGet, func, 0, expected, true);
test(isTestingGet, func, undefined, expected, true);
createDataView(array, 3, true, start); createDataView(array, 3, true, start);
test(isTestingGet, func, 3, expected, true); test(isTestingGet, func, 3, expected, true);
createDataView(array, 7, true, start); createDataView(array, 7, true, start);
...@@ -179,6 +196,7 @@ function testFloat(isTestingGet, func, array, start, expected) { ...@@ -179,6 +196,7 @@ function testFloat(isTestingGet, func, array, start, expected) {
// Big endian. // Big endian.
createDataView(array, 0, false); createDataView(array, 0, false);
test(isTestingGet, func, 0, expected, false); test(isTestingGet, func, 0, expected, false);
test(isTestingGet, func, undefined, expected, false);
createDataView(array, 3, false); createDataView(array, 3, false);
test(isTestingGet, func, 3, expected, false); test(isTestingGet, func, 3, expected, false);
createDataView(array, 7, false); createDataView(array, 7, false);
...@@ -286,8 +304,10 @@ function TestGeneralAccessors() { ...@@ -286,8 +304,10 @@ function TestGeneralAccessors() {
var a = new DataView(new ArrayBuffer(256)); var a = new DataView(new ArrayBuffer(256));
function CheckAccessor(name) { function CheckAccessor(name) {
var f = a[name]; var f = a[name];
assertThrows(function() { f(); }, TypeError);
f.call(a, 0, 0); // should not throw f.call(a, 0, 0); // should not throw
assertThrows(function() { f.call({}, 0, 0); }, TypeError); assertThrows(function() { f.call({}, 0, 0); }, TypeError);
assertThrows(function() { f.call(a); }, TypeError);
} }
CheckAccessor("getUint8"); CheckAccessor("getUint8");
CheckAccessor("setUint8"); CheckAccessor("setUint8");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment