From 18d02d06f024d628cc9a2568d39a8223a0d3baae Mon Sep 17 00:00:00 2001 From: "dslomov@chromium.org" Date: Fri, 3 May 2013 09:43:44 +0000 Subject: [PATCH] Implement TypedArray.subarray method. R=rossberg@chromium.org Review URL: https://codereview.chromium.org/14740017 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14537 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/typedarray.js | 31 +++++++++++++++++++ test/mjsunit/harmony/typedarrays.js | 60 +++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/src/typedarray.js b/src/typedarray.js index daade13..1040f86 100644 --- a/src/typedarray.js +++ b/src/typedarray.js @@ -167,6 +167,33 @@ function TypedArrayGetLength() { return %TypedArrayGetLength(this); } +function CreateSubArray(elementSize, constructor) { + return function(begin, end) { + var srcLength = %TypedArrayGetLength(this); + var beginInt = TO_INTEGER(begin); + if (beginInt < 0) { + beginInt = MathMax(0, srcLength + beginInt); + } else { + beginInt = MathMin(srcLength, beginInt); + } + + var endInt = IS_UNDEFINED(end) ? srcLength : TO_INTEGER(end); + if (endInt < 0) { + endInt = MathMax(0, srcLength + endInt); + } else { + endInt = MathMin(endInt, srcLength); + } + if (endInt < beginInt) { + endInt = beginInt; + } + var newLength = endInt - beginInt; + var beginByteOffset = + %TypedArrayGetByteOffset(this) + beginInt * elementSize; + return new constructor(%TypedArrayGetBuffer(this), + beginByteOffset, newLength); + } +} + // ------------------------------------------------------------------- @@ -205,6 +232,10 @@ function SetupTypedArray(arrayId, name, constructor, elementSize) { InstallGetter(constructor.prototype, "byteOffset", TypedArrayGetByteOffset); InstallGetter(constructor.prototype, "byteLength", TypedArrayGetByteLength); InstallGetter(constructor.prototype, "length", TypedArrayGetLength); + + InstallFunctions(constructor.prototype, DONT_ENUM, $Array( + "subarray", CreateSubArray(elementSize, constructor) + )); } // arrayIds below should be synchronized with Runtime_TypedArrayInitialize. diff --git a/test/mjsunit/harmony/typedarrays.js b/test/mjsunit/harmony/typedarrays.js index ca76fe7..748b366 100644 --- a/test/mjsunit/harmony/typedarrays.js +++ b/test/mjsunit/harmony/typedarrays.js @@ -68,8 +68,16 @@ TestByteLengthNotWritable(); function TestSlice(expectedResultLen, initialLen, start, end) { var ab = new ArrayBuffer(initialLen); + var a1 = new Uint8Array(ab); + for (var i = 0; i < a1.length; i++) { + a1[i] = 0xCA; + } var slice = ab.slice(start, end); assertSame(expectedResultLen, slice.byteLength); + var a2 = new Uint8Array(slice); + for (var i = 0; i < a2.length; i++) { + assertSame(0xCA, a2[i]); + } } function TestArrayBufferSlice() { @@ -255,6 +263,58 @@ TestTypedArray(Float32Array, 4, 0.5); TestTypedArray(Float64Array, 8, 0.5); TestTypedArray(Uint8ClampedArray, 1, 0xFF); +function SubarrayTestCase(constructor, item, expectedResultLen, expectedStartIndex, + initialLen, start, end) { + var a = new constructor(initialLen); + var s = a.subarray(start, end); + assertSame(constructor, s.constructor); + assertSame(expectedResultLen, s.length); + if (s.length > 0) { + s[0] = item; + assertSame(item, a[expectedStartIndex]); + } +} + +function TestSubArray(constructor, item) { + SubarrayTestCase(constructor, item, 512, 512, 1024, 512, 1024); + SubarrayTestCase(constructor, item, 512, 512, 1024, 512); + + SubarrayTestCase(constructor, item, 0, undefined, 0, 1, 20); + SubarrayTestCase(constructor, item, 100, 0, 100, 0, 100); + SubarrayTestCase(constructor, item, 100, 0, 100, 0, 1000); + SubarrayTestCase(constructor, item, 0, undefined, 100, 5, 1); + + SubarrayTestCase(constructor, item, 1, 89, 100, -11, -10); + SubarrayTestCase(constructor, item, 9, 90, 100, -10, 99); + SubarrayTestCase(constructor, item, 0, undefined, 100, -10, 80); + SubarrayTestCase(constructor, item, 10,80, 100, 80, -10); + + SubarrayTestCase(constructor, item, 10,90, 100, 90, "100"); + SubarrayTestCase(constructor, item, 10,90, 100, "90", "100"); + + SubarrayTestCase(constructor, item, 0, undefined, 100, 90, "abc"); + SubarrayTestCase(constructor, item, 10,0, 100, "abc", 10); + + SubarrayTestCase(constructor, item, 10,0, 100, 0.96, 10.96); + SubarrayTestCase(constructor, item, 10,0, 100, 0.96, 10.01); + SubarrayTestCase(constructor, item, 10,0, 100, 0.01, 10.01); + SubarrayTestCase(constructor, item, 10,0, 100, 0.01, 10.96); + + + SubarrayTestCase(constructor, item, 10,90, 100, 90); + SubarrayTestCase(constructor, item, 10,90, 100, -10); +} + +TestSubArray(Uint8Array, 0xFF); +TestSubArray(Int8Array, -0x7F); +TestSubArray(Uint16Array, 0xFFFF); +TestSubArray(Int16Array, -0x7FFF); +TestSubArray(Uint32Array, 0xFFFFFFFF); +TestSubArray(Int32Array, -0x7FFFFFFF); +TestSubArray(Float32Array, 0.5); +TestSubArray(Float64Array, 0.5); +TestSubArray(Uint8ClampedArray, 0xFF); + function TestTypedArrayOutOfRange(constructor, value, result) { var a = new constructor(1); a[0] = value; -- 2.7.4