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
This commit is contained in:
parent
e6570d43ba
commit
9e2c046f5c
@ -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) {
|
||||
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");
|
||||
}
|
||||
|
||||
var newByteLength;
|
||||
var newLength;
|
||||
if (IS_UNDEFINED(length)) {
|
||||
if (bufferByteLength % elementSize !== 0) {
|
||||
throw MakeRangeError("invalid_typed_array_alignment",
|
||||
"start offset", name, elementSize);
|
||||
"byte length", name, elementSize);
|
||||
}
|
||||
var bufferByteLength = %ArrayBufferGetByteLength(buffer);
|
||||
if (offset >= bufferByteLength) {
|
||||
throw MakeRangeError("invalid_typed_array_offset");
|
||||
}
|
||||
|
||||
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;
|
||||
} else {
|
||||
var newLength = TO_POSITIVE_INTEGER(length);
|
||||
newByteLength = newLength * elementSize;
|
||||
}
|
||||
if (newByteLength > bufferByteLength) {
|
||||
throw MakeRangeError("invalid_typed_array_length");
|
||||
}
|
||||
%TypedArrayInitialize(this, arrayId, buffer, offset, newByteLength);
|
||||
newByteLength = bufferByteLength - offset;
|
||||
newLength = newByteLength / elementSize;
|
||||
} else {
|
||||
return new constructor(buffer, byteOffset, length);
|
||||
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);
|
||||
}
|
||||
|
||||
return function (arg1, arg2, arg3) {
|
||||
if (%_IsConstructCall()) {
|
||||
if (IS_ARRAYBUFFER(arg1)) {
|
||||
ConstructByArrayBuffer(this, arg1, arg2, arg3);
|
||||
} else {
|
||||
ConstructByLength(this, arg1);
|
||||
}
|
||||
} else {
|
||||
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,
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user