diff options
Diffstat (limited to 'chromium/v8/src/typedarray.js')
-rw-r--r-- | chromium/v8/src/typedarray.js | 359 |
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 )); } |