Index: src/typedarray.js |
diff --git a/src/typedarray.js b/src/typedarray.js |
index ac7e6c8520e1674ed8e443c0f659df37e746bc5b..fcdbdc6a6481d6910888a3357dac580cd1a4d1da 100644 |
--- a/src/typedarray.js |
+++ b/src/typedarray.js |
@@ -67,7 +67,7 @@ function NAMEConstructByArrayBuffer(obj, buffer, byteOffset, length) { |
|| (newLength > %_MaxSmi())) { |
throw MakeRangeError("invalid_typed_array_length"); |
} |
- %_TypedArrayInitialize(obj, ARRAY_ID, buffer, offset, newByteLength); |
+ %_TypedArrayInitialize(obj, ARRAY_ID, buffer, offset, newByteLength, false); |
} |
function NAMEConstructByLength(obj, length) { |
@@ -79,9 +79,9 @@ function NAMEConstructByLength(obj, 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, false); |
} else { |
- %_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength); |
+ %_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength, false); |
} |
} |
@@ -483,3 +483,197 @@ function SetupDataView() { |
} |
SetupDataView(); |
+ |
+// --------------- Shared Typed Arrays --------------------- |
+macro SHARED_TYPED_ARRAYS(FUNCTION) |
+// arrayIds below should be synchronized with Runtime_TypedArrayInitialize. |
+FUNCTION(1, SharedUint8Array, 1) |
+FUNCTION(2, SharedInt8Array, 1) |
+FUNCTION(3, SharedUint16Array, 2) |
+FUNCTION(4, SharedInt16Array, 2) |
+FUNCTION(5, SharedUint32Array, 4) |
+FUNCTION(6, SharedInt32Array, 4) |
+FUNCTION(7, SharedFloat32Array, 4) |
+FUNCTION(8, SharedFloat64Array, 8) |
+FUNCTION(9, SharedUint8ClampedArray, 1) |
+endmacro |
+ |
+macro SHARED_TYPED_ARRAY_CONSTRUCTOR(ARRAY_ID, NAME, ELEMENT_SIZE) |
+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"); |
+ } |
+ |
+ var bufferByteLength = %_ArrayBufferGetByteLength(buffer); |
+ var offset; |
+ if (IS_UNDEFINED(byteOffset)) { |
+ offset = 0; |
+ } else { |
+ offset = byteOffset; |
+ |
+ 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 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 = length; |
+ newByteLength = newLength * ELEMENT_SIZE; |
+ } |
+ if ((offset + newByteLength > bufferByteLength) |
+ || (newLength > %_MaxSmi())) { |
+ throw MakeRangeError("invalid_typed_array_length"); |
+ } |
+ %_TypedArrayInitialize(obj, ARRAY_ID, buffer, offset, newByteLength, true); |
+} |
+ |
+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 $SharedArrayBuffer(byteLength); |
+ %_TypedArrayInitialize(obj, ARRAY_ID, buffer, 0, byteLength, true); |
+ } else { |
+ %_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength, true); |
+ } |
+} |
+ |
+function NAMEConstructor(arg1, arg2, arg3) { |
+ if (%_IsConstructCall()) { |
+ if (IS_SHAREDARRAYBUFFER(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("invalid_argument"); |
+ } |
+ } else { |
+ throw MakeTypeError("constructor_not_function", ["NAME"]) |
+ } |
+} |
+ |
+function NAME_GetBuffer() { |
+ if (!(%_ClassOf(this) === 'NAME')) { |
+ throw MakeTypeError('incompatible_method_receiver', |
+ ["NAME.buffer", this]); |
+ } |
+ return %TypedArrayGetBuffer(this); |
+} |
+ |
+function NAME_GetByteLength() { |
+ if (!(%_ClassOf(this) === 'NAME')) { |
+ throw MakeTypeError('incompatible_method_receiver', |
+ ["NAME.byteLength", this]); |
+ } |
+ return %_ArrayBufferViewGetByteLength(this); |
+} |
+ |
+function NAME_GetByteOffset() { |
+ if (!(%_ClassOf(this) === 'NAME')) { |
+ throw MakeTypeError('incompatible_method_receiver', |
+ ["NAME.byteOffset", this]); |
+ } |
+ return %_ArrayBufferViewGetByteOffset(this); |
+} |
+ |
+function NAME_GetLength() { |
+ if (!(%_ClassOf(this) === 'NAME')) { |
+ throw MakeTypeError('incompatible_method_receiver', |
+ ["NAME.length", this]); |
+ } |
+ return %_TypedArrayGetLength(this); |
+} |
+ |
+var $NAME = global.NAME; |
+ |
+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 = $max(0, srcLength + beginInt); |
+ } else { |
+ beginInt = $min(srcLength, beginInt); |
+ } |
+ |
+ var endInt = IS_UNDEFINED(end) ? srcLength : end; |
+ if (endInt < 0) { |
+ endInt = $max(0, srcLength + endInt); |
+ } else { |
+ endInt = $min(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 |
+ |
+SHARED_TYPED_ARRAYS(SHARED_TYPED_ARRAY_CONSTRUCTOR) |
+ |
+ |
+function SetupSharedTypedArrays() { |
+macro SETUP_SHARED_TYPED_ARRAY(ARRAY_ID, NAME, ELEMENT_SIZE) |
+ %CheckIsBootstrapping(); |
+ %SetCode(global.NAME, NAMEConstructor); |
+ %FunctionSetPrototype(global.NAME, new $Object()); |
+ |
+ %AddNamedProperty(global.NAME, "BYTES_PER_ELEMENT", ELEMENT_SIZE, |
+ READ_ONLY | DONT_ENUM | DONT_DELETE); |
+ %AddNamedProperty(global.NAME.prototype, |
+ "constructor", global.NAME, DONT_ENUM); |
+ %AddNamedProperty(global.NAME.prototype, |
+ "BYTES_PER_ELEMENT", ELEMENT_SIZE, |
+ READ_ONLY | DONT_ENUM | DONT_DELETE); |
+ InstallGetter(global.NAME.prototype, "buffer", NAME_GetBuffer); |
+ InstallGetter(global.NAME.prototype, "byteOffset", NAME_GetByteOffset, |
+ DONT_ENUM | DONT_DELETE); |
+ InstallGetter(global.NAME.prototype, "byteLength", NAME_GetByteLength, |
+ DONT_ENUM | DONT_DELETE); |
+ InstallGetter(global.NAME.prototype, "length", NAME_GetLength, |
+ DONT_ENUM | DONT_DELETE); |
+ InstallGetter(global.NAME.prototype, symbolToStringTag, |
+ TypedArrayGetToStringTag); |
+ InstallFunctions(global.NAME.prototype, DONT_ENUM, $Array( |
+ "subarray", NAMESubArray, |
+ "set", TypedArraySet |
+ )); |
+endmacro |
+ |
+SHARED_TYPED_ARRAYS(SETUP_SHARED_TYPED_ARRAY) |
+} |
+ |
+SetupSharedTypedArrays(); |