macro TYPED_ARRAY_HARMONY_ADDITIONS(ARRAY_ID, NAME, ELEMENT_SIZE)
+// ES6 draft 05-05-15, section 22.2.3.7
+function NAMEEvery(f /* thisArg */) { // length == 1
+ if (!%IsTypedArray(this)) {
+ throw MakeTypeError('not_typed_array', []);
+ }
+ if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f);
+
+ var length = %_TypedArrayGetLength(this);
+ var receiver;
+
+ if (%_ArgumentsLength() > 1) {
+ receiver = %_Arguments(1);
+ }
+
+ var needs_wrapper = false;
+ if (IS_NULL(receiver)) {
+ if (%IsSloppyModeFunction(mapfn)) receiver = UNDEFINED;
+ } else if (!IS_UNDEFINED(receiver)) {
+ needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
+ }
+
+ var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
+ for (var i = 0; i < length; i++) {
+ var element = this[i];
+ // Prepare break slots for debugger step in.
+ if (stepping) %DebugPrepareStepInIfStepping(f);
+ var new_receiver = needs_wrapper ? $toObject(receiver) : receiver;
+ if (!%_CallFunction(new_receiver, TO_OBJECT_INLINE(element), i, this, f)) {
+ return false;
+ }
+ }
+ return true;
+}
+
// ES6 draft 08-24-14, section 22.2.3.12
function NAMEForEach(f /* thisArg */) { // length == 1
if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
// Set up non-enumerable functions on the prototype object.
$installFunctions(GlobalNAME.prototype, DONT_ENUM, [
+ "every", NAMEEvery,
"forEach", NAMEForEach
]);
endmacro
--- /dev/null
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-arrays --allow-natives-syntax
+
+var typedArrayConstructors = [
+ Uint8Array,
+ Int8Array,
+ Uint16Array,
+ Int16Array,
+ Uint32Array,
+ Int32Array,
+ Uint8ClampedArray,
+ Float32Array,
+ Float64Array];
+
+function CheckTypedArrayIsNeutered(array) {
+ assertEquals(0, array.byteLength);
+ assertEquals(0, array.byteOffset);
+ assertEquals(0, array.length);
+}
+
+function TestTypedArrayForEach(constructor) {
+ assertEquals(1, constructor.prototype.every.length);
+
+ var a = new constructor(3);
+ a[0] = 0;
+ a[1] = 1;
+ a[2] = 2;
+
+ var result = a.every(function (n) { return n < 2; });
+ assertFalse(result);
+
+ var result = a.every(function (n) { return n > 2; });
+ assertFalse(result);
+
+ var result = a.every(function (n) { return n >= 0; });
+ assertEquals(true, result);
+
+ // Use specified object as this object when calling the function.
+ var o = { value: 42 };
+ result = a.every(function (n, index, array) { return n == index && n < this.value; }, o);
+ assertEquals(true, result);
+
+ // Early exit happens when appropriate
+ count = 0;
+ result = a.every(function () { count++; return false; });
+ assertEquals(1, count);
+ assertFalse(result);
+
+ // Modify the original array.
+ count = 0;
+ result = a.every(function (n, index, array) {
+ array[index] = n + 1; count++; return true;
+ });
+ assertEquals(3, count);
+ assertEquals(true, result);
+ assertArrayEquals([1, 2, 3], a);
+
+ // Check that values passed as second argument are wrapped into
+ // objects when calling into sloppy mode functions.
+ function CheckWrapping(value, wrapper) {
+ var wrappedValue = new wrapper(value);
+
+ a.every(function () {
+ assertEquals("object", typeof this);
+ assertEquals(wrappedValue, this);
+ }, value);
+
+ a.every(function () {
+ "use strict";
+ assertEquals(typeof value, typeof this);
+ assertEquals(value, this);
+ }, value);
+ }
+ CheckWrapping(true, Boolean);
+ CheckWrapping(false, Boolean);
+ CheckWrapping("xxx", String);
+ CheckWrapping(42, Number);
+ CheckWrapping(3.14, Number);
+ CheckWrapping({}, Object);
+
+ // Neutering the buffer backing the typed array mid-way should
+ // still make .forEach() finish, and the array should keep being
+ // empty after neutering it.
+ count = 0;
+ a = new constructor(2);
+ result = a.every(function (n, index, array) {
+ if (count > 0) %ArrayBufferNeuter(array.buffer);
+ array[index] = n + 1;
+ count++;
+ return count > 1 ? array[index] === undefined : true;
+ });
+ assertEquals(2, count);
+ assertEquals(true, result);
+ CheckTypedArrayIsNeutered(a);
+ assertEquals(undefined, a[0]);
+
+ // The method must work for typed arrays created from ArrayBuffer.
+ // The length of the ArrayBuffer is chosen so it is a multiple of
+ // all lengths of the typed array items.
+ a = new constructor(new ArrayBuffer(64));
+ count = 0;
+ result = a.every(function (n) { return n == 0; });
+ assertEquals(result, true);
+
+ // Externalizing the array mid-way accessing the .buffer property
+ // should work.
+ a = new constructor(2);
+ count = 0;
+ var buffer = undefined;
+ a.every(function (n, index, array) {
+ if (count++ > 0)
+ buffer = array.buffer;
+ return true;
+ });
+ assertEquals(2, count);
+ assertTrue(!!buffer);
+ assertEquals("ArrayBuffer", %_ClassOf(buffer));
+ assertSame(buffer, a.buffer);
+
+ // The %TypedArray%.every() method should not work when
+ // transplanted to objects that are not typed arrays.
+ assertThrows(function () { constructor.prototype.every.call([1, 2, 3], function (x) {}) }, TypeError);
+ assertThrows(function () { constructor.prototype.every.call("abc", function (x) {}) }, TypeError);
+ assertThrows(function () { constructor.prototype.every.call({}, function (x) {}) }, TypeError);
+ assertThrows(function () { constructor.prototype.every.call(0, function (x) {}) }, TypeError);
+
+ // Method must be useable on instances of other typed arrays.
+ for (var i = 0; i < typedArrayConstructors.length; i++) {
+ count = 0;
+ a = new typedArrayConstructors[i](4);
+ constructor.prototype.every.call(a, function (x) { count++; return true; });
+ assertEquals(a.length, count);
+ }
+}
+
+for (i = 0; i < typedArrayConstructors.length; i++) {
+ TestTypedArrayForEach(typedArrayConstructors[i]);
+}