Revision: 15298
Author: [email protected]
Date: Mon Jun 24 06:58:52 2013
Log: Update typed arrays behavior to match ES6 rev 15. Remove
TO_POSITIVE_INTEGER and throw on negative length arguments.
[email protected]
Review URL: https://codereview.chromium.org/17572009
http://code.google.com/p/v8/source/detail?r=15298
Modified:
/branches/bleeding_edge/src/arraybuffer.js
/branches/bleeding_edge/src/macros.py
/branches/bleeding_edge/src/messages.js
/branches/bleeding_edge/src/runtime.js
/branches/bleeding_edge/src/typedarray.js
/branches/bleeding_edge/test/mjsunit/harmony/dataview-accessors.js
/branches/bleeding_edge/test/mjsunit/harmony/typedarrays.js
=======================================
--- /branches/bleeding_edge/src/arraybuffer.js Mon May 6 09:19:27 2013
+++ /branches/bleeding_edge/src/arraybuffer.js Mon Jun 24 06:58:52 2013
@@ -31,12 +31,12 @@
// -------------------------------------------------------------------
-function ArrayBufferConstructor(byteLength) { // length = 1
+function ArrayBufferConstructor(length) { // length = 1
if (%_IsConstructCall()) {
- var l = TO_POSITIVE_INTEGER(byteLength);
- %ArrayBufferInitialize(this, l);
+ var byteLength =
ToPositiveInteger(length, 'invalid_array_buffer_length');
+ %ArrayBufferInitialize(this, byteLength);
} else {
- return new $ArrayBuffer(byteLength);
+ return new $ArrayBuffer(length);
}
}
@@ -70,6 +70,9 @@
fin = MathMin(relativeEnd, this.byteLength);
}
+ if (fin < first) {
+ fin = first;
+ }
var newLen = fin - first;
// TODO(dslomov): implement inheritance
var result = new $ArrayBuffer(newLen);
=======================================
--- /branches/bleeding_edge/src/macros.py Fri Jun 21 06:02:38 2013
+++ /branches/bleeding_edge/src/macros.py Mon Jun 24 06:58:52 2013
@@ -145,7 +145,6 @@
macro NUMBER_IS_NAN(arg) = (!%_IsSmi(%IS_VAR(arg)) && !(arg == arg));
macro NUMBER_IS_FINITE(arg) = (%_IsSmi(%IS_VAR(arg)) || ((arg == arg) &&
(arg != 1/0) && (arg != -1/0)));
macro TO_INTEGER(arg) = (%_IsSmi(%IS_VAR(arg)) ?
arg : %NumberToInteger(ToNumber(arg)));
-macro TO_POSITIVE_INTEGER(arg) = (%_IsSmi(%IS_VAR(arg)) ? (arg > 0 ? arg :
0) : %NumberToPositiveInteger(ToNumber(arg)));
macro TO_INTEGER_MAP_MINUS_ZERO(arg) = (%_IsSmi(%IS_VAR(arg)) ?
arg : %NumberToIntegerMapMinusZero(ToNumber(arg)));
macro TO_INT32(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : (arg >> 0));
macro TO_UINT32(arg) = (arg >>> 0);
=======================================
--- /branches/bleeding_edge/src/messages.js Fri Jun 21 06:02:38 2013
+++ /branches/bleeding_edge/src/messages.js Mon Jun 24 06:58:52 2013
@@ -112,13 +112,15 @@
// RangeError
invalid_array_length: ["Invalid array length"],
invalid_array_buffer_length: ["Invalid array buffer length"],
- invalid_typed_array_offset: ["Start offset is too large"],
- invalid_typed_array_length: ["Length is too large"],
+ invalid_typed_array_offset: ["Start offset is too large:"],
+ invalid_typed_array_length: ["Invalid typed array length"],
invalid_typed_array_alignment: ["%0", "of", "%1", "should be a multiple
of", "%3"],
typed_array_set_source_too_large:
["Source is too large"],
+ typed_array_set_negative_offset:
+ ["Start offset is negative"],
invalid_data_view_offset: ["Start offset is outside the bounds of
the buffer"],
- invalid_data_view_length: ["Length is too large"],
+ invalid_data_view_length: ["Invalid data view length"],
invalid_data_view_accessor_offset:
["Offset is outside the bounds of the
DataView"],
=======================================
--- /branches/bleeding_edge/src/runtime.js Wed Apr 3 10:06:22 2013
+++ /branches/bleeding_edge/src/runtime.js Mon Jun 24 06:58:52 2013
@@ -657,7 +657,6 @@
throw %MakeTypeError('cannot_convert_to_primitive', []);
}
-
// ECMA-262, section 8.6.2.6, page 28.
function DefaultString(x) {
@@ -675,6 +674,12 @@
throw %MakeTypeError('cannot_convert_to_primitive', []);
}
+
+function ToPositiveInteger(x, rangeErrorName) {
+ var i = TO_INTEGER(x);
+ if (i < 0) throw %MakeRangeError(rangeErrorName);
+ return i;
+}
// NOTE: Setting the prototype for Array must take place as early as
=======================================
--- /branches/bleeding_edge/src/typedarray.js Fri Jun 21 06:02:38 2013
+++ /branches/bleeding_edge/src/typedarray.js Mon Jun 24 06:58:52 2013
@@ -37,7 +37,7 @@
function CreateTypedArrayConstructor(name, elementSize, arrayId,
constructor) {
function ConstructByArrayBuffer(obj, buffer, byteOffset, length) {
- var offset = IS_UNDEFINED(byteOffset) ? 0 :
TO_POSITIVE_INTEGER(byteOffset);
+ var offset =
ToPositiveInteger(byteOffset, "invalid_typed_array_length")
if (offset % elementSize !== 0) {
throw MakeRangeError("invalid_typed_array_alignment",
@@ -58,7 +58,7 @@
newByteLength = bufferByteLength - offset;
newLength = newByteLength / elementSize;
} else {
- var newLength = TO_POSITIVE_INTEGER(length);
+ var newLength =
ToPositiveInteger(length, "invalid_typed_array_length");
newByteLength = newLength * elementSize;
}
if (offset + newByteLength > bufferByteLength) {
@@ -68,7 +68,7 @@
}
function ConstructByLength(obj, length) {
- var l = IS_UNDEFINED(length) ? 0 : TO_POSITIVE_INTEGER(length);
+ var l = ToPositiveInteger(length, "invalid_typed_array_length");
var byteLength = l * elementSize;
var buffer = new global.ArrayBuffer(byteLength);
%TypedArrayInitialize(obj, arrayId, buffer, 0, byteLength);
@@ -76,7 +76,7 @@
function ConstructByArrayLike(obj, arrayLike) {
var length = arrayLike.length;
- var l = IS_UNDEFINED(length) ? 0 : TO_POSITIVE_INTEGER(length);
+ var l = ToPositiveInteger(length, "invalid_typed_array_length");
var byteLength = l * elementSize;
var buffer = new $ArrayBuffer(byteLength);
%TypedArrayInitialize(obj, arrayId, buffer, 0, byteLength);
@@ -146,7 +146,10 @@
}
function TypedArraySet(obj, offset) {
- var intOffset = IS_UNDEFINED(offset) ? 0 : TO_POSITIVE_INTEGER(offset);
+ var intOffset = IS_UNDEFINED(offset) ? 0 : TO_INTEGER(offset);
+ if (intOffset < 0) {
+ throw MakeTypeError("typed_array_set_negative_offset");
+ }
if (%TypedArraySetFastCases(this, obj, intOffset))
return;
@@ -209,13 +212,13 @@
throw MakeTypeError('data_view_not_array_buffer', []);
}
var bufferByteLength = %ArrayBufferGetByteLength(buffer);
- var offset = IS_UNDEFINED(byteOffset) ? 0 :
TO_POSITIVE_INTEGER(byteOffset);
+ var offset = ToPositiveInteger(byteOffset, 'invalid_data_view_offset');
if (offset > bufferByteLength) {
- throw MakeRangeError('invalid_data_view_offset', []);
+ throw MakeRangeError('invalid_data_view_offset');
}
var length = IS_UNDEFINED(byteLength) ?
- bufferByteLength - offset : TO_POSITIVE_INTEGER(byteLength);
- if (offset + length > bufferByteLength) {
+ bufferByteLength - offset : TO_INTEGER(byteLength);
+ if (length < 0 || offset + length > bufferByteLength) {
throw new MakeRangeError('invalid_data_view_length');
}
%DataViewInitialize(this, buffer, offset, length);
@@ -247,13 +250,19 @@
}
return %DataViewGetByteLength(this);
}
+
+function ToPositiveDataViewOffset(offset) {
+ return ToPositiveInteger(offset, 'invalid_data_view_accessor_offset');
+}
function DataViewGetInt8(offset, little_endian) {
if (!IS_DATAVIEW(this)) {
throw MakeTypeError('incompatible_method_reciever',
['DataView.getInt8', this]);
}
- return %DataViewGetInt8(this,
TO_POSITIVE_INTEGER(offset), !!little_endian);
+ return %DataViewGetInt8(this,
+ ToPositiveDataViewOffset(offset),
+ !!little_endian);
}
function DataViewSetInt8(offset, value, little_endian) {
@@ -262,7 +271,7 @@
['DataView.setInt8', this]);
}
%DataViewSetInt8(this,
- TO_POSITIVE_INTEGER(offset),
+ ToPositiveDataViewOffset(offset),
TO_NUMBER_INLINE(value),
!!little_endian);
}
@@ -272,7 +281,9 @@
throw MakeTypeError('incompatible_method_reciever',
['DataView.getUint8', this]);
}
- return %DataViewGetUint8(this,
TO_POSITIVE_INTEGER(offset), !!little_endian);
+ return %DataViewGetUint8(this,
+ ToPositiveDataViewOffset(offset),
+ !!little_endian);
}
function DataViewSetUint8(offset, value, little_endian) {
@@ -281,7 +292,7 @@
['DataView.setUint8', this]);
}
%DataViewSetUint8(this,
- TO_POSITIVE_INTEGER(offset),
+ ToPositiveDataViewOffset(offset),
TO_NUMBER_INLINE(value),
!!little_endian);
}
@@ -291,7 +302,9 @@
throw MakeTypeError('incompatible_method_reciever',
['DataView.getInt16', this]);
}
- return %DataViewGetInt16(this,
TO_POSITIVE_INTEGER(offset), !!little_endian);
+ return %DataViewGetInt16(this,
+ ToPositiveDataViewOffset(offset),
+ !!little_endian);
}
function DataViewSetInt16(offset, value, little_endian) {
@@ -300,7 +313,7 @@
['DataView.setInt16', this]);
}
%DataViewSetInt16(this,
- TO_POSITIVE_INTEGER(offset),
+ ToPositiveDataViewOffset(offset),
TO_NUMBER_INLINE(value),
!!little_endian);
}
@@ -310,7 +323,9 @@
throw MakeTypeError('incompatible_method_reciever',
['DataView.getUint16', this]);
}
- return %DataViewGetUint16(this,
TO_POSITIVE_INTEGER(offset), !!little_endian);
+ return %DataViewGetUint16(this,
+ ToPositiveDataViewOffset(offset),
+ !!little_endian);
}
function DataViewSetUint16(offset, value, little_endian) {
@@ -319,7 +334,7 @@
['DataView.setUint16', this]);
}
%DataViewSetUint16(this,
- TO_POSITIVE_INTEGER(offset),
+ ToPositiveDataViewOffset(offset),
TO_NUMBER_INLINE(value),
!!little_endian);
}
@@ -329,7 +344,9 @@
throw MakeTypeError('incompatible_method_reciever',
['DataView.getInt32', this]);
}
- return %DataViewGetInt32(this,
TO_POSITIVE_INTEGER(offset), !!little_endian);
+ return %DataViewGetInt32(this,
+ ToPositiveDataViewOffset(offset),
+ !!little_endian);
}
function DataViewSetInt32(offset, value, little_endian) {
@@ -338,7 +355,7 @@
['DataView.setInt32', this]);
}
%DataViewSetInt32(this,
- TO_POSITIVE_INTEGER(offset),
+ ToPositiveDataViewOffset(offset),
TO_NUMBER_INLINE(value),
!!little_endian);
}
@@ -348,7 +365,9 @@
throw MakeTypeError('incompatible_method_reciever',
['DataView.getUint32', this]);
}
- return %DataViewGetUint32(this,
TO_POSITIVE_INTEGER(offset), !!little_endian);
+ return %DataViewGetUint32(this,
+ ToPositiveDataViewOffset(offset),
+ !!little_endian);
}
function DataViewSetUint32(offset, value, little_endian) {
@@ -357,7 +376,7 @@
['DataView.setUint32', this]);
}
%DataViewSetUint32(this,
- TO_POSITIVE_INTEGER(offset),
+ ToPositiveDataViewOffset(offset),
TO_NUMBER_INLINE(value),
!!little_endian);
}
@@ -367,7 +386,9 @@
throw MakeTypeError('incompatible_method_reciever',
['DataView.getFloat32', this]);
}
- return %DataViewGetFloat32(this,
TO_POSITIVE_INTEGER(offset), !!little_endian);
+ return %DataViewGetFloat32(this,
+ ToPositiveDataViewOffset(offset),
+ !!little_endian);
}
function DataViewSetFloat32(offset, value, little_endian) {
@@ -376,7 +397,7 @@
['DataView.setFloat32', this]);
}
%DataViewSetFloat32(this,
- TO_POSITIVE_INTEGER(offset),
+ ToPositiveDataViewOffset(offset),
TO_NUMBER_INLINE(value),
!!little_endian);
}
@@ -386,7 +407,13 @@
throw MakeTypeError('incompatible_method_reciever',
['DataView.getFloat64', this]);
}
- return %DataViewGetFloat64(this,
TO_POSITIVE_INTEGER(offset), !!little_endian);
+ offset = TO_INTEGER(offset);
+ if (offset < 0) {
+ throw MakeRangeError("invalid_data_view_accessor_offset");
+ }
+ return %DataViewGetFloat64(this,
+ ToPositiveDataViewOffset(offset),
+ !!little_endian);
}
function DataViewSetFloat64(offset, value, little_endian) {
@@ -394,8 +421,12 @@
throw MakeTypeError('incompatible_method_reciever',
['DataView.setFloat64', this]);
}
+ offset = TO_INTEGER(offset);
+ if (offset < 0) {
+ throw MakeRangeError("invalid_data_view_accessor_offset");
+ }
%DataViewSetFloat64(this,
- TO_POSITIVE_INTEGER(offset),
+ ToPositiveDataViewOffset(offset),
TO_NUMBER_INLINE(value),
!!little_endian);
}
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/dataview-accessors.js Fri
Jun 21 06:02:38 2013
+++ /branches/bleeding_edge/test/mjsunit/harmony/dataview-accessors.js Mon
Jun 24 06:58:52 2013
@@ -64,8 +64,7 @@
function doGet() {
return view["get" + func](index, littleEndian);
}
- if (index < 0) index = 0;
- if (index + getElementSize(func) - 1 < view.byteLength)
+ if (index >=0 && index + getElementSize(func) - 1 < view.byteLength)
assertSame(expected, doGet());
else
assertThrows(doGet, RangeError);
@@ -75,9 +74,8 @@
function doSet() {
view["set" + func](index, value, littleEndian);
}
- actualIndex = index < 0 ? 0 : index;
- if (actualIndex >= 0 &&
- actualIndex + getElementSize(func) - 1 < view.byteLength) {
+ if (index >= 0 &&
+ index + getElementSize(func) - 1 < view.byteLength) {
assertSame(undefined, doSet());
checkGet(func, index, value, littleEndian);
} else {
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/typedarrays.js Fri Jun 21
06:02:38 2013
+++ /branches/bleeding_edge/test/mjsunit/harmony/typedarrays.js Mon Jun 24
06:58:52 2013
@@ -35,14 +35,15 @@
function TestArrayBufferCreation() {
TestByteLength(1, 1);
TestByteLength(256, 256);
- TestByteLength(-10, 0);
TestByteLength(2.567, 2);
- TestByteLength(-2.567, 0);
TestByteLength("abc", 0);
TestByteLength(0, 0);
+ assertThrows(function() { new ArrayBuffer(-10); }, RangeError);
+ assertThrows(function() { new ArrayBuffer(-2.567); }, RangeError);
+
/* TODO[dslomov]: Reenable the test
assertThrows(function() {
var ab1 = new ArrayBuffer(0xFFFFFFFFFFFF)
@@ -89,6 +90,7 @@
TestSlice(0, 0, 1, 20);
TestSlice(100, 100, 0, 100);
TestSlice(100, 100, 0, 1000);
+
TestSlice(0, 100, 5, 1);
TestSlice(1, 100, -11, -10);
@@ -99,7 +101,7 @@
TestSlice(10, 100, 90, "100");
TestSlice(10, 100, "90", "100");
- TestSlice(0, 100, 90, "abc");
+ TestSlice(0, 100, 90, "abc");
TestSlice(10, 100, "abc", 10);
TestSlice(10, 100, 0.96, 10.96);
@@ -107,7 +109,6 @@
TestSlice(10, 100, 0.01, 10.01);
TestSlice(10, 100, 0.01, 10.96);
-
TestSlice(10, 100, 90);
TestSlice(10, 100, -10);
}
@@ -489,24 +490,15 @@
assertSame(256, d3c.byteOffset);
assertSame(0, d3c.byteLength);
- // weird args
- var d4 = new DataView(ab, -1);
+ var d4 = new DataView(ab, 1, 3.1415926);
assertSame(ab, d4.buffer);
- assertSame(0, d4.byteOffset);
- assertSame(256, d4.byteLength);
-
- var d5 = new DataView(ab, 1, -1);
- assertSame(ab, d5.buffer);
- assertSame(1, d5.byteOffset);
- assertSame(0, d5.byteLength);
-
- var d6 = new DataView(ab, 1, 3.1415926);
- assertSame(ab, d6.buffer);
- assertSame(1, d6.byteOffset);
- assertSame(3, d6.byteLength);
+ assertSame(1, d4.byteOffset);
+ assertSame(3, d4.byteLength);
// error cases
+ assertThrows(function() { new DataView(ab, -1); }, RangeError);
+ assertThrows(function() { new DataView(ab, 1, -1); }, RangeError);
assertThrows(function() { new DataView(); }, TypeError);
assertThrows(function() { new DataView([]); }, TypeError);
assertThrows(function() { new DataView(ab, 257); }, RangeError);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.