summaryrefslogtreecommitdiffstats
path: root/chromium/v8/src/typedarray.js
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/src/typedarray.js')
-rw-r--r--chromium/v8/src/typedarray.js359
1 files changed, 193 insertions, 166 deletions
diff --git a/chromium/v8/src/typedarray.js b/chromium/v8/src/typedarray.js
index 0a06ebbdd42..d2f5ae86923 100644
--- a/chromium/v8/src/typedarray.js
+++ b/chromium/v8/src/typedarray.js
@@ -1,29 +1,6 @@
// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
"use strict";
@@ -48,130 +25,167 @@ FUNCTION(9, Uint8ClampedArray, 1)
endmacro
macro TYPED_ARRAY_CONSTRUCTOR(ARRAY_ID, NAME, ELEMENT_SIZE)
- function NAMEConstructByArrayBuffer(obj, buffer, byteOffset, length) {
- var bufferByteLength = %ArrayBufferGetByteLength(buffer);
- var offset;
- if (IS_UNDEFINED(byteOffset)) {
- offset = 0;
- } else {
- offset = ToPositiveInteger(byteOffset, "invalid_typed_array_length");
+function NAMEConstructByArrayBuffer(obj, buffer, byteOffset, length) {
+ if (!IS_UNDEFINED(byteOffset)) {
+ byteOffset =
+ ToPositiveInteger(byteOffset, "invalid_typed_array_length");
+ }
+ if (!IS_UNDEFINED(length)) {
+ length = ToPositiveInteger(length, "invalid_typed_array_length");
+ }
- if (offset % ELEMENT_SIZE !== 0) {
- throw MakeRangeError("invalid_typed_array_alignment",
- "start offset", "NAME", ELEMENT_SIZE);
- }
- if (offset > bufferByteLength) {
- throw MakeRangeError("invalid_typed_array_offset");
- }
- }
+ var bufferByteLength = %_ArrayBufferGetByteLength(buffer);
+ var offset;
+ if (IS_UNDEFINED(byteOffset)) {
+ offset = 0;
+ } else {
+ offset = byteOffset;
- var newByteLength;
- var newLength;
- if (IS_UNDEFINED(length)) {
- if (bufferByteLength % ELEMENT_SIZE !== 0) {
- throw MakeRangeError("invalid_typed_array_alignment",
- "byte length", "NAME", ELEMENT_SIZE);
- }
- newByteLength = bufferByteLength - offset;
- newLength = newByteLength / ELEMENT_SIZE;
- } else {
- var newLength = ToPositiveInteger(length, "invalid_typed_array_length");
- newByteLength = newLength * ELEMENT_SIZE;
+ if (offset % ELEMENT_SIZE !== 0) {
+ throw MakeRangeError("invalid_typed_array_alignment",
+ ["start offset", "NAME", ELEMENT_SIZE]);
}
- if ((offset + newByteLength > bufferByteLength)
- || (newLength > %MaxSmi())) {
- throw MakeRangeError("invalid_typed_array_length");
+ if (offset > bufferByteLength) {
+ throw MakeRangeError("invalid_typed_array_offset");
}
- %TypedArrayInitialize(obj, ARRAY_ID, buffer, offset, newByteLength);
}
- function NAMEConstructByLength(obj, length) {
- var l = IS_UNDEFINED(length) ?
- 0 : ToPositiveInteger(length, "invalid_typed_array_length");
- if (l > %MaxSmi()) {
- throw MakeRangeError("invalid_typed_array_length");
+ var newByteLength;
+ var newLength;
+ if (IS_UNDEFINED(length)) {
+ if (bufferByteLength % ELEMENT_SIZE !== 0) {
+ throw MakeRangeError("invalid_typed_array_alignment",
+ ["byte length", "NAME", ELEMENT_SIZE]);
}
- var byteLength = l * ELEMENT_SIZE;
+ newByteLength = bufferByteLength - offset;
+ newLength = newByteLength / ELEMENT_SIZE;
+ } else {
+ var newLength = length;
+ newByteLength = newLength * ELEMENT_SIZE;
+ }
+ if ((offset + newByteLength > bufferByteLength)
+ || (newLength > %_MaxSmi())) {
+ throw MakeRangeError("invalid_typed_array_length");
+ }
+ %_TypedArrayInitialize(obj, ARRAY_ID, buffer, offset, newByteLength);
+}
+
+function NAMEConstructByLength(obj, length) {
+ var l = IS_UNDEFINED(length) ?
+ 0 : ToPositiveInteger(length, "invalid_typed_array_length");
+ if (l > %_MaxSmi()) {
+ throw MakeRangeError("invalid_typed_array_length");
+ }
+ var byteLength = l * ELEMENT_SIZE;
+ if (byteLength > %_TypedArrayMaxSizeInHeap()) {
var buffer = new $ArrayBuffer(byteLength);
- %TypedArrayInitialize(obj, ARRAY_ID, buffer, 0, byteLength);
+ %_TypedArrayInitialize(obj, ARRAY_ID, buffer, 0, byteLength);
+ } else {
+ %_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength);
}
+}
- function NAMEConstructByArrayLike(obj, arrayLike) {
- var length = arrayLike.length;
- var l = ToPositiveInteger(length, "invalid_typed_array_length");
- if (l > %MaxSmi()) {
- throw MakeRangeError("invalid_typed_array_length");
- }
- if(!%TypedArrayInitializeFromArrayLike(obj, ARRAY_ID, arrayLike, l)) {
- for (var i = 0; i < l; i++) {
- // It is crucial that we let any execptions from arrayLike[i]
- // propagate outside the function.
- obj[i] = arrayLike[i];
- }
+function NAMEConstructByArrayLike(obj, arrayLike) {
+ var length = arrayLike.length;
+ var l = ToPositiveInteger(length, "invalid_typed_array_length");
+
+ if (l > %_MaxSmi()) {
+ throw MakeRangeError("invalid_typed_array_length");
+ }
+ if(!%TypedArrayInitializeFromArrayLike(obj, ARRAY_ID, arrayLike, l)) {
+ for (var i = 0; i < l; i++) {
+ // It is crucial that we let any execptions from arrayLike[i]
+ // propagate outside the function.
+ obj[i] = arrayLike[i];
}
}
+}
- function NAMEConstructor(arg1, arg2, arg3) {
-
- if (%_IsConstructCall()) {
- if (IS_ARRAYBUFFER(arg1)) {
- NAMEConstructByArrayBuffer(this, arg1, arg2, arg3);
- } else if (IS_NUMBER(arg1) || IS_STRING(arg1) ||
- IS_BOOLEAN(arg1) || IS_UNDEFINED(arg1)) {
- NAMEConstructByLength(this, arg1);
- } else {
- NAMEConstructByArrayLike(this, arg1);
- }
+function NAMEConstructor(arg1, arg2, arg3) {
+ if (%_IsConstructCall()) {
+ if (IS_ARRAYBUFFER(arg1)) {
+ NAMEConstructByArrayBuffer(this, arg1, arg2, arg3);
+ } else if (IS_NUMBER(arg1) || IS_STRING(arg1) ||
+ IS_BOOLEAN(arg1) || IS_UNDEFINED(arg1)) {
+ NAMEConstructByLength(this, arg1);
} else {
- throw MakeTypeError("constructor_not_function", ["NAME"])
+ NAMEConstructByArrayLike(this, arg1);
}
+ } else {
+ throw MakeTypeError("constructor_not_function", ["NAME"])
}
-endmacro
-
-TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTOR)
+}
-function TypedArrayGetBuffer() {
+function NAME_GetBuffer() {
+ if (!(%_ClassOf(this) === 'NAME')) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ["NAME.buffer", this]);
+ }
return %TypedArrayGetBuffer(this);
}
-function TypedArrayGetByteLength() {
- return %TypedArrayGetByteLength(this);
+function NAME_GetByteLength() {
+ if (!(%_ClassOf(this) === 'NAME')) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ["NAME.byteLength", this]);
+ }
+ return %_ArrayBufferViewGetByteLength(this);
}
-function TypedArrayGetByteOffset() {
- return %TypedArrayGetByteOffset(this);
+function NAME_GetByteOffset() {
+ if (!(%_ClassOf(this) === 'NAME')) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ["NAME.byteOffset", this]);
+ }
+ return %_ArrayBufferViewGetByteOffset(this);
}
-function TypedArrayGetLength() {
- return %TypedArrayGetLength(this);
+function NAME_GetLength() {
+ if (!(%_ClassOf(this) === 'NAME')) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ["NAME.length", this]);
+ }
+ 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 $NAME = global.NAME;
- 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);
+function NAMESubArray(begin, end) {
+ if (!(%_ClassOf(this) === 'NAME')) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ["NAME.subarray", this]);
+ }
+ var beginInt = TO_INTEGER(begin);
+ if (!IS_UNDEFINED(end)) {
+ end = TO_INTEGER(end);
+ }
+
+ var srcLength = %_TypedArrayGetLength(this);
+ if (beginInt < 0) {
+ beginInt = MathMax(0, srcLength + beginInt);
+ } else {
+ beginInt = MathMin(srcLength, beginInt);
+ }
+
+ var endInt = IS_UNDEFINED(end) ? srcLength : 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 =
+ %_ArrayBufferViewGetByteOffset(this) + beginInt * ELEMENT_SIZE;
+ return new $NAME(%TypedArrayGetBuffer(this),
+ beginByteOffset, newLength);
}
+endmacro
+
+TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTOR)
+
function TypedArraySetFromArrayLike(target, source, sourceLength, offset) {
if (offset > 0) {
@@ -243,6 +257,10 @@ function TypedArraySet(obj, offset) {
if (intOffset < 0) {
throw MakeTypeError("typed_array_set_negative_offset");
}
+
+ if (intOffset > %_MaxSmi()) {
+ throw MakeRangeError("typed_array_set_source_too_large");
+ }
switch (%TypedArraySetFastCases(this, obj, intOffset)) {
// These numbers should be synchronized with runtime.cc.
case 0: // TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE
@@ -275,34 +293,34 @@ function TypedArraySet(obj, offset) {
// -------------------------------------------------------------------
-function SetupTypedArray(constructor, fun, elementSize) {
+function SetupTypedArrays() {
+macro SETUP_TYPED_ARRAY(ARRAY_ID, NAME, ELEMENT_SIZE)
%CheckIsBootstrapping();
- %SetCode(constructor, fun);
- %FunctionSetPrototype(constructor, new $Object());
+ %SetCode(global.NAME, NAMEConstructor);
+ %FunctionSetPrototype(global.NAME, new $Object());
- %SetProperty(constructor, "BYTES_PER_ELEMENT", elementSize,
+ %SetProperty(global.NAME, "BYTES_PER_ELEMENT", ELEMENT_SIZE,
READ_ONLY | DONT_ENUM | DONT_DELETE);
- %SetProperty(constructor.prototype,
- "constructor", constructor, DONT_ENUM);
- %SetProperty(constructor.prototype,
- "BYTES_PER_ELEMENT", elementSize,
+ %SetProperty(global.NAME.prototype,
+ "constructor", global.NAME, DONT_ENUM);
+ %SetProperty(global.NAME.prototype,
+ "BYTES_PER_ELEMENT", ELEMENT_SIZE,
READ_ONLY | DONT_ENUM | DONT_DELETE);
- InstallGetter(constructor.prototype, "buffer", TypedArrayGetBuffer);
- InstallGetter(constructor.prototype, "byteOffset", TypedArrayGetByteOffset);
- InstallGetter(constructor.prototype, "byteLength", TypedArrayGetByteLength);
- InstallGetter(constructor.prototype, "length", TypedArrayGetLength);
+ InstallGetter(global.NAME.prototype, "buffer", NAME_GetBuffer);
+ InstallGetter(global.NAME.prototype, "byteOffset", NAME_GetByteOffset);
+ InstallGetter(global.NAME.prototype, "byteLength", NAME_GetByteLength);
+ InstallGetter(global.NAME.prototype, "length", NAME_GetLength);
- InstallFunctions(constructor.prototype, DONT_ENUM, $Array(
- "subarray", CreateSubArray(elementSize, constructor),
+ InstallFunctions(global.NAME.prototype, DONT_ENUM, $Array(
+ "subarray", NAMESubArray,
"set", TypedArraySet
));
-}
-
-macro SETUP_TYPED_ARRAY(ARRAY_ID, NAME, ELEMENT_SIZE)
- SetupTypedArray (global.NAME, NAMEConstructor, ELEMENT_SIZE);
endmacro
TYPED_ARRAYS(SETUP_TYPED_ARRAY)
+}
+
+SetupTypedArrays();
// --------------------------- DataView -----------------------------
@@ -313,24 +331,33 @@ function DataViewConstructor(buffer, byteOffset, byteLength) { // length = 3
if (!IS_ARRAYBUFFER(buffer)) {
throw MakeTypeError('data_view_not_array_buffer', []);
}
- var bufferByteLength = %ArrayBufferGetByteLength(buffer);
- var offset = IS_UNDEFINED(byteOffset) ?
- 0 : ToPositiveInteger(byteOffset, 'invalid_data_view_offset');
+ if (!IS_UNDEFINED(byteOffset)) {
+ byteOffset = ToPositiveInteger(byteOffset, 'invalid_data_view_offset');
+ }
+ if (!IS_UNDEFINED(byteLength)) {
+ byteLength = TO_INTEGER(byteLength);
+ }
+
+ var bufferByteLength = %_ArrayBufferGetByteLength(buffer);
+
+ var offset = IS_UNDEFINED(byteOffset) ? 0 : byteOffset;
if (offset > bufferByteLength) {
throw MakeRangeError('invalid_data_view_offset');
}
- var length = IS_UNDEFINED(byteLength) ?
- bufferByteLength - offset : TO_INTEGER(byteLength);
+
+ var length = IS_UNDEFINED(byteLength)
+ ? bufferByteLength - offset
+ : byteLength;
if (length < 0 || offset + length > bufferByteLength) {
throw new MakeRangeError('invalid_data_view_length');
}
- %DataViewInitialize(this, buffer, offset, length);
+ %_DataViewInitialize(this, buffer, offset, length);
} else {
throw MakeTypeError('constructor_not_function', ["DataView"]);
}
}
-function DataViewGetBuffer() {
+function DataViewGetBufferJS() {
if (!IS_DATAVIEW(this)) {
throw MakeTypeError('incompatible_method_receiver',
['DataView.buffer', this]);
@@ -343,7 +370,7 @@ function DataViewGetByteOffset() {
throw MakeTypeError('incompatible_method_receiver',
['DataView.byteOffset', this]);
}
- return %DataViewGetByteOffset(this);
+ return %_ArrayBufferViewGetByteOffset(this);
}
function DataViewGetByteLength() {
@@ -351,7 +378,7 @@ function DataViewGetByteLength() {
throw MakeTypeError('incompatible_method_receiver',
['DataView.byteLength', this]);
}
- return %DataViewGetByteLength(this);
+ return %_ArrayBufferViewGetByteLength(this);
}
macro DATA_VIEW_TYPES(FUNCTION)
@@ -371,7 +398,7 @@ function ToPositiveDataViewOffset(offset) {
macro DATA_VIEW_GETTER_SETTER(TYPENAME)
-function DataViewGetTYPENAME(offset, little_endian) {
+function DataViewGetTYPENAMEJS(offset, little_endian) {
if (!IS_DATAVIEW(this)) {
throw MakeTypeError('incompatible_method_receiver',
['DataView.getTYPENAME', this]);
@@ -384,7 +411,7 @@ function DataViewGetTYPENAME(offset, little_endian) {
!!little_endian);
}
-function DataViewSetTYPENAME(offset, value, little_endian) {
+function DataViewSetTYPENAMEJS(offset, value, little_endian) {
if (!IS_DATAVIEW(this)) {
throw MakeTypeError('incompatible_method_receiver',
['DataView.setTYPENAME', this]);
@@ -411,34 +438,34 @@ function SetupDataView() {
// Set up constructor property on the DataView prototype.
%SetProperty($DataView.prototype, "constructor", $DataView, DONT_ENUM);
- InstallGetter($DataView.prototype, "buffer", DataViewGetBuffer);
+ InstallGetter($DataView.prototype, "buffer", DataViewGetBufferJS);
InstallGetter($DataView.prototype, "byteOffset", DataViewGetByteOffset);
InstallGetter($DataView.prototype, "byteLength", DataViewGetByteLength);
InstallFunctions($DataView.prototype, DONT_ENUM, $Array(
- "getInt8", DataViewGetInt8,
- "setInt8", DataViewSetInt8,
+ "getInt8", DataViewGetInt8JS,
+ "setInt8", DataViewSetInt8JS,
- "getUint8", DataViewGetUint8,
- "setUint8", DataViewSetUint8,
+ "getUint8", DataViewGetUint8JS,
+ "setUint8", DataViewSetUint8JS,
- "getInt16", DataViewGetInt16,
- "setInt16", DataViewSetInt16,
+ "getInt16", DataViewGetInt16JS,
+ "setInt16", DataViewSetInt16JS,
- "getUint16", DataViewGetUint16,
- "setUint16", DataViewSetUint16,
+ "getUint16", DataViewGetUint16JS,
+ "setUint16", DataViewSetUint16JS,
- "getInt32", DataViewGetInt32,
- "setInt32", DataViewSetInt32,
+ "getInt32", DataViewGetInt32JS,
+ "setInt32", DataViewSetInt32JS,
- "getUint32", DataViewGetUint32,
- "setUint32", DataViewSetUint32,
+ "getUint32", DataViewGetUint32JS,
+ "setUint32", DataViewSetUint32JS,
- "getFloat32", DataViewGetFloat32,
- "setFloat32", DataViewSetFloat32,
+ "getFloat32", DataViewGetFloat32JS,
+ "setFloat32", DataViewSetFloat32JS,
- "getFloat64", DataViewGetFloat64,
- "setFloat64", DataViewSetFloat64
+ "getFloat64", DataViewGetFloat64JS,
+ "setFloat64", DataViewSetFloat64JS
));
}