From 9e2c046f5c2e5ec469083386555188a341475a39 Mon Sep 17 00:00:00 2001 From: "dslomov@chromium.org" Date: Mon, 29 Apr 2013 16:16:31 +0000 Subject: [PATCH] TypedArray(length) constructor R=rossberg@chromium.org Review URL: https://codereview.chromium.org/14460008 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14486 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/typedarray.js | 77 ++++++++++++++++++++++--------------- test/mjsunit/harmony/typedarrays.js | 21 ++++++++++ 2 files changed, 66 insertions(+), 32 deletions(-) diff --git a/src/typedarray.js b/src/typedarray.js index 7549652..4e50f7f 100644 --- a/src/typedarray.js +++ b/src/typedarray.js @@ -85,42 +85,54 @@ function ArrayBufferSlice(start, end) { // --------------- Typed Arrays --------------------- function CreateTypedArrayConstructor(name, elementSize, arrayId, constructor) { - return function (buffer, byteOffset, length) { - if (%_IsConstructCall()) { - if (!IS_ARRAYBUFFER(buffer)) { - throw MakeTypeError("Type error!"); - } - var offset = IS_UNDEFINED(byteOffset) - ? 0 : offset = TO_POSITIVE_INTEGER(byteOffset); + function ConstructByArrayBuffer(obj, buffer, byteOffset, length) { + var offset = IS_UNDEFINED(byteOffset) + ? 0 : offset = TO_POSITIVE_INTEGER(byteOffset); + + if (offset % elementSize !== 0) { + throw MakeRangeError("invalid_typed_array_alignment", + "start offset", name, elementSize); + } + var bufferByteLength = %ArrayBufferGetByteLength(buffer); + if (offset >= bufferByteLength) { + throw MakeRangeError("invalid_typed_array_offset"); + } - if (offset % elementSize !== 0) { + var newByteLength; + var newLength; + if (IS_UNDEFINED(length)) { + if (bufferByteLength % elementSize !== 0) { throw MakeRangeError("invalid_typed_array_alignment", - "start offset", name, elementSize); - } - var bufferByteLength = %ArrayBufferGetByteLength(buffer); - if (offset >= bufferByteLength) { - throw MakeRangeError("invalid_typed_array_offset"); + "byte length", name, elementSize); } + newByteLength = bufferByteLength - offset; + newLength = newByteLength / elementSize; + } else { + var newLength = TO_POSITIVE_INTEGER(length); + newByteLength = newLength * elementSize; + } + if (newByteLength > bufferByteLength) { + throw MakeRangeError("invalid_typed_array_length"); + } + %TypedArrayInitialize(obj, arrayId, buffer, offset, newByteLength); + } + + function ConstructByLength(obj, length) { + var l = IS_UNDEFINED(length) ? 0 : TO_POSITIVE_INTEGER(length); + var byteLength = l * elementSize; + var buffer = new $ArrayBuffer(byteLength); + %TypedArrayInitialize(obj, arrayId, buffer, 0, byteLength); + } - var newByteLength; - var newLength; - if (IS_UNDEFINED(length)) { - if (bufferByteLength % elementSize !== 0) { - throw MakeRangeError("invalid_typed_array_alignment", - "byte length", name, elementSize); - } - newByteLength = bufferByteLength - offset; - newLength = newByteLength / elementSize; + return function (arg1, arg2, arg3) { + if (%_IsConstructCall()) { + if (IS_ARRAYBUFFER(arg1)) { + ConstructByArrayBuffer(this, arg1, arg2, arg3); } else { - var newLength = TO_POSITIVE_INTEGER(length); - newByteLength = newLength * elementSize; - } - if (newByteLength > bufferByteLength) { - throw MakeRangeError("invalid_typed_array_length"); + ConstructByLength(this, arg1); } - %TypedArrayInitialize(this, arrayId, buffer, offset, newByteLength); } else { - return new constructor(buffer, byteOffset, length); + return new constructor(arg1, arg2, arg3); } } } @@ -164,9 +176,10 @@ function SetUpArrayBuffer() { SetUpArrayBuffer(); function SetupTypedArray(arrayId, name, constructor, elementSize) { - var f = CreateTypedArrayConstructor(name, elementSize, - arrayId, constructor); - %SetCode(constructor, f); + %CheckIsBootstrapping(); + var fun = CreateTypedArrayConstructor(name, elementSize, + arrayId, constructor); + %SetCode(constructor, fun); %FunctionSetPrototype(constructor, new $Object()); %SetProperty(constructor.prototype, diff --git a/test/mjsunit/harmony/typedarrays.js b/test/mjsunit/harmony/typedarrays.js index 418d55e..2e03985 100644 --- a/test/mjsunit/harmony/typedarrays.js +++ b/test/mjsunit/harmony/typedarrays.js @@ -113,6 +113,27 @@ TestArrayBufferSlice(); function TestTypedArray(proto, elementSize, typicalElement) { var ab = new ArrayBuffer(256*elementSize); + var a0 = new proto(30); + assertSame(elementSize, a0.BYTES_PER_ELEMENT); + assertSame(30, a0.length); + assertSame(30*elementSize, a0.byteLength); + assertSame(0, a0.byteOffset); + assertSame(30*elementSize, a0.buffer.byteLength); + + var aLen0 = new proto(0); + assertSame(elementSize, aLen0.BYTES_PER_ELEMENT); + assertSame(0, aLen0.length); + assertSame(0, aLen0.byteLength); + assertSame(0, aLen0.byteOffset); + assertSame(0, aLen0.buffer.byteLength); + + var aOverBufferLen0 = new proto(ab, 128*elementSize, 0); + assertSame(ab, aOverBufferLen0.buffer); + assertSame(elementSize, aOverBufferLen0.BYTES_PER_ELEMENT); + assertSame(0, aOverBufferLen0.length); + assertSame(0, aOverBufferLen0.byteLength); + assertSame(128*elementSize, aOverBufferLen0.byteOffset); + var a1 = new proto(ab, 128*elementSize, 128); assertSame(ab, a1.buffer); assertSame(elementSize, a1.BYTES_PER_ELEMENT); -- 2.7.4