Revert of Implement %TypedArray%.prototype.{map,filter,some,reduce,reduceRight} ...
authormachenbach <machenbach@chromium.org>
Tue, 19 May 2015 16:56:00 +0000 (09:56 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 19 May 2015 16:55:45 +0000 (16:55 +0000)
Reason for revert:
[Sheriff] Breaks win nosnap:
http://build.chromium.org/p/client.v8/builders/V8%20Win32%20-%20nosnap%20-%20shared/builds/6872

Original issue's description:
> Implement %TypedArray%.prototype.{map,filter,some,reduce,reduceRight}
>
> This patch adds implementations for additional TypedArray methods
> from the ES6 spec, together with tests adapted from array code.
>
> R=arv@chromium.org
> BUG=v8:3578
> LOG=Y
>
> Committed: https://crrev.com/59ef8c5f3282f01b5990b3a46a2a3a829b699a13
> Cr-Commit-Position: refs/heads/master@{#28488}

TBR=arv@chromium.org,dehrenberg@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:3578

Review URL: https://codereview.chromium.org/1143833002

Cr-Commit-Position: refs/heads/master@{#28489}

src/array.js
src/harmony-typedarray.js
test/mjsunit/harmony/typedarray-iteration.js [deleted file]
test/mjsunit/harmony/typedarray-reduce.js [deleted file]

index a7c37e1..93378cf 100644 (file)
@@ -12,11 +12,6 @@ var $arraySplice;
 var $arrayUnshift;
 var $innerArrayForEach;
 var $innerArrayEvery;
-var $innerArrayFilter;
-var $innerArrayMap;
-var $innerArrayReduce;
-var $innerArrayReduceRight;
-var $innerArraySome;
 
 (function(global, shared, exports) {
 
@@ -1155,7 +1150,14 @@ function ArraySort(comparefn) {
 // The following functions cannot be made efficient on sparse arrays while
 // preserving the semantics, since the calls to the receiver function can add
 // or delete elements from the array.
-function InnerArrayFilter(f, receiver, array, length) {
+function ArrayFilter(f, receiver) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.filter");
+
+  // Pull out the length so that modifications to the length in the
+  // loop will not affect the looping and side effects are visible.
+  var array = $toObject(this);
+  var length = $toUint32(array.length);
+
   if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f);
   var needs_wrapper = false;
   if (IS_NULL(receiver)) {
@@ -1184,17 +1186,6 @@ function InnerArrayFilter(f, receiver, array, length) {
   return result;
 }
 
-function ArrayFilter(f, receiver) {
-  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.filter");
-
-  // Pull out the length so that modifications to the length in the
-  // loop will not affect the looping and side effects are visible.
-  var array = $toObject(this);
-  var length = $toUint32(array.length);
-
-  return InnerArrayFilter(f, receiver, array, length);
-}
-
 function InnerArrayForEach(f, receiver, array, length) {
   if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f);
   var needs_wrapper = false;
@@ -1228,7 +1219,16 @@ function ArrayForEach(f, receiver) {
 }
 
 
-function InnerArraySome(f, receiver, array, length) {
+// Executes the function once for each element present in the
+// array until it finds one where callback returns true.
+function ArraySome(f, receiver) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.some");
+
+  // Pull out the length so that modifications to the length in the
+  // loop will not affect the looping and side effects are visible.
+  var array = $toObject(this);
+  var length = TO_UINT32(array.length);
+
   if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f);
   var needs_wrapper = false;
   if (IS_NULL(receiver)) {
@@ -1252,19 +1252,6 @@ function InnerArraySome(f, receiver, array, length) {
 }
 
 
-// Executes the function once for each element present in the
-// array until it finds one where callback returns true.
-function ArraySome(f, receiver) {
-  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.some");
-
-  // Pull out the length so that modifications to the length in the
-  // loop will not affect the looping and side effects are visible.
-  var array = $toObject(this);
-  var length = TO_UINT32(array.length);
-  return InnerArraySome(f, receiver, array, length);
-}
-
-
 function InnerArrayEvery(f, receiver, array, length) {
   if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f);
   var needs_wrapper = false;
@@ -1299,7 +1286,14 @@ function ArrayEvery(f, receiver) {
 }
 
 
-function InnerArrayMap(f, receiver, array, length) {
+function ArrayMap(f, receiver) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map");
+
+  // Pull out the length so that modifications to the length in the
+  // loop will not affect the looping and side effects are visible.
+  var array = $toObject(this);
+  var length = TO_UINT32(array.length);
+
   if (!IS_SPEC_FUNCTION(f)) throw MakeTypeError(kCalledNonCallable, f);
   var needs_wrapper = false;
   if (IS_NULL(receiver)) {
@@ -1326,17 +1320,6 @@ function InnerArrayMap(f, receiver, array, length) {
 }
 
 
-function ArrayMap(f, receiver) {
-  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map");
-
-  // Pull out the length so that modifications to the length in the
-  // loop will not affect the looping and side effects are visible.
-  var array = $toObject(this);
-  var length = TO_UINT32(array.length);
-  return InnerArrayMap(f, receiver, array, length);
-}
-
-
 function ArrayIndexOf(element, index) {
   CHECK_OBJECT_COERCIBLE(this, "Array.prototype.indexOf");
 
@@ -1447,14 +1430,21 @@ function ArrayLastIndexOf(element, index) {
 }
 
 
-function InnerArrayReduce(callback, current, array, length, argumentsLength) {
+function ArrayReduce(callback, current) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduce");
+
+  // Pull out the length so that modifications to the length in the
+  // loop will not affect the looping and side effects are visible.
+  var array = $toObject(this);
+  var length = $toUint32(array.length);
+
   if (!IS_SPEC_FUNCTION(callback)) {
     throw MakeTypeError(kCalledNonCallable, callback);
   }
 
   var is_array = IS_ARRAY(array);
   var i = 0;
-  find_initial: if (argumentsLength < 2) {
+  find_initial: if (%_ArgumentsLength() < 2) {
     for (; i < length; i++) {
       if (HAS_INDEX(array, i, is_array)) {
         current = array[i++];
@@ -1477,27 +1467,21 @@ function InnerArrayReduce(callback, current, array, length, argumentsLength) {
 }
 
 
-function ArrayReduce(callback, current) {
-  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduce");
+function ArrayReduceRight(callback, current) {
+  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduceRight");
 
-  // Pull out the length so that modifications to the length in the
-  // loop will not affect the looping and side effects are visible.
+  // Pull out the length so that side effects are visible before the
+  // callback function is checked.
   var array = $toObject(this);
   var length = $toUint32(array.length);
-  return InnerArrayReduce(callback, current, array, length,
-                          %_ArgumentsLength());
-}
 
-
-function InnerArrayReduceRight(callback, current, array, length,
-                               argumentsLength) {
   if (!IS_SPEC_FUNCTION(callback)) {
     throw MakeTypeError(kCalledNonCallable, callback);
   }
 
   var is_array = IS_ARRAY(array);
   var i = length - 1;
-  find_initial: if (argumentsLength < 2) {
+  find_initial: if (%_ArgumentsLength() < 2) {
     for (; i >= 0; i--) {
       if (HAS_INDEX(array, i, is_array)) {
         current = array[i--];
@@ -1519,18 +1503,6 @@ function InnerArrayReduceRight(callback, current, array, length,
   return current;
 }
 
-
-function ArrayReduceRight(callback, current) {
-  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduceRight");
-
-  // Pull out the length so that side effects are visible before the
-  // callback function is checked.
-  var array = $toObject(this);
-  var length = $toUint32(array.length);
-  return InnerArrayReduceRight(callback, current, array, length,
-                               %_ArgumentsLength());
-}
-
 // ES5, 15.4.3.2
 function ArrayIsArray(obj) {
   return IS_ARRAY(obj);
@@ -1635,12 +1607,7 @@ $arraySlice = ArraySlice;
 $arraySplice = ArraySplice;
 $arrayUnshift = ArrayUnshift;
 
-$innerArrayEvery = InnerArrayEvery;
-$innerArrayFilter = InnerArrayFilter;
 $innerArrayForEach = InnerArrayForEach;
-$innerArrayMap = InnerArrayMap;
-$innerArrayReduce = InnerArrayReduce;
-$innerArrayReduceRight = InnerArrayReduceRight;
-$innerArraySome = InnerArraySome;
+$innerArrayEvery = InnerArrayEvery;
 
 });
index b1115f4..90679e0 100644 (file)
@@ -30,28 +30,6 @@ DECLARE_GLOBALS(Array)
 
 // -------------------------------------------------------------------
 
-function ConstructTypedArray(constructor, array) {
-  // TODO(littledan): This is an approximation of the spec, which requires
-  // that only real TypedArray classes should be accepted (22.2.2.1.1)
-  if (!IS_SPEC_OBJECT(constructor) || IS_UNDEFINED(constructor.prototype) ||
-      !%HasOwnProperty(constructor.prototype, "BYTES_PER_ELEMENT")) {
-    throw MakeTypeError(kNotTypedArray);
-  }
-
-  // TODO(littledan): The spec requires that, rather than directly calling
-  // the constructor, a TypedArray is created with the proper proto and
-  // underlying size and element size, and elements are put in one by one.
-  // By contrast, this would allow subclasses to make a radically different
-  // constructor with different semantics.
-  return new constructor(array);
-}
-
-function ConstructTypedArrayLike(typedArray, arrayContents) {
-  // TODO(littledan): The spec requires that we actuallly use
-  // typedArray.constructor[Symbol.species] (bug v8:4093)
-  return new typedArray.constructor(arrayContents);
-}
-
 function TypedArrayCopyWithin(target, start, end) {
   if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
 
@@ -83,7 +61,7 @@ function TypedArrayForEach(f, receiver) {
 %FunctionSetLength(TypedArrayForEach, 1);
 
 // ES6 draft 04-05-14 section 22.2.3.8
-function TypedArrayFill(value, start, end) {
+function TypedArrayFill(value, start , end) {
   if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
 
   var length = %_TypedArrayGetLength(this);
@@ -92,16 +70,6 @@ function TypedArrayFill(value, start, end) {
 }
 %FunctionSetLength(TypedArrayFill, 1);
 
-// ES6 draft 07-15-13, section 22.2.3.9
-function TypedArrayFilter(predicate, thisArg) {
-  if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
-
-  var length = %_TypedArrayGetLength(this);
-  var array = $innerArrayFilter(predicate, thisArg, this, length);
-  return ConstructTypedArrayLike(this, array);
-}
-%FunctionSetLength(TypedArrayFilter, 1);
-
 // ES6 draft 07-15-13, section 22.2.3.10
 function TypedArrayFind(predicate, thisArg) {
   if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
@@ -123,52 +91,6 @@ function TypedArrayFindIndex(predicate, thisArg) {
 %FunctionSetLength(TypedArrayFindIndex, 1);
 
 
-// ES6 draft 07-15-13, section 22.2.3.18
-function TypedArrayMap(predicate, thisArg) {
-  if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
-
-  // TODO(littledan): Preallocate rather than making an intermediate
-  // array, for better performance.
-  var length = %_TypedArrayGetLength(this);
-  var array = $innerArrayMap(predicate, thisArg, this, length);
-  return ConstructTypedArrayLike(this, array);
-}
-%FunctionSetLength(TypedArrayMap, 1);
-
-
-// ES6 draft 07-15-13, section 22.2.3.19
-function TypedArrayReduce(callback, current) {
-  if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
-
-  var length = %_TypedArrayGetLength(this);
-  return $innerArrayReduce(callback, current, this, length,
-                           %_ArgumentsLength());
-}
-%FunctionSetLength(TypedArrayReduce, 1);
-
-
-// ES6 draft 07-15-13, section 22.2.3.19
-function TypedArrayReduceRight(callback, current) {
-  if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
-
-  var length = %_TypedArrayGetLength(this);
-  return $innerArrayReduceRight(callback, current, this, length,
-                                %_ArgumentsLength());
-}
-%FunctionSetLength(TypedArrayReduceRight, 1);
-
-
-// ES6 draft 05-05-15, section 22.2.3.24
-function TypedArraySome(f, receiver) {
-  if (!%IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
-
-  var length = %_TypedArrayGetLength(this);
-
-  return $innerArraySome(f, receiver, this, length);
-}
-%FunctionSetLength(TypedArraySome, 1);
-
-
 // ES6 draft 08-24-14, section 22.2.2.2
 function TypedArrayOf() {
   var length = %_ArgumentsLength();
@@ -215,15 +137,10 @@ macro EXTEND_TYPED_ARRAY(NAME)
   $installFunctions(GlobalNAME.prototype, DONT_ENUM, [
     "copyWithin", TypedArrayCopyWithin,
     "every", TypedArrayEvery,
-    "fill", TypedArrayFill,
-    "filter", TypedArrayFilter,
+    "forEach", TypedArrayForEach,
     "find", TypedArrayFind,
     "findIndex", TypedArrayFindIndex,
-    "forEach", TypedArrayForEach,
-    "map", TypedArrayMap,
-    "reduce", TypedArrayReduce,
-    "reduceRight", TypedArrayReduceRight,
-    "some", TypedArraySome
+    "fill", TypedArrayFill
   ]);
 endmacro
 
diff --git a/test/mjsunit/harmony/typedarray-iteration.js b/test/mjsunit/harmony/typedarray-iteration.js
deleted file mode 100644 (file)
index 85c5091..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright 2015 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
-
-// Tests for standard TypedArray array iteration functions.
-
-var typedArrayConstructors = [
-  Uint8Array,
-  Int8Array,
-  Uint16Array,
-  Int16Array,
-  Uint32Array,
-  Int32Array,
-  Uint8ClampedArray,
-  Float32Array,
-  Float64Array
-];
-
-function assertArrayLikeEquals(expected, value, type) {
-  assertEquals(value.__proto__, type.prototype);
-  assertEquals(expected.length, value.length);
-  for (var i = 0; i < value.length; ++i) {
-    assertEquals(expected[i], value[i]);
-  }
-}
-
-for (var constructor of typedArrayConstructors) {
-  (function TypedArrayFilterTest() {
-    // Simple use.
-    var a = new constructor([0, 1]);
-    assertArrayLikeEquals([0], a.filter(function(n) { return n == 0; }),
-                          constructor);
-    assertArrayLikeEquals([0, 1], a, constructor);
-
-    // Use specified object as this object when calling the function.
-    var o = { value: 42 }
-    a = new constructor([1, 42, 3, 42, 4]);
-    assertArrayLikeEquals([42, 42], a.filter(function(n) {
-      return this.value == n
-    }, o), constructor);
-
-    // Modify original array.
-    a = new constructor([1, 42, 3, 42, 4]);
-    assertArrayLikeEquals([42, 42], a.filter(function(n, index, array) {
-      array[index] = 43; return 42 == n;
-    }), constructor);
-    assertArrayLikeEquals([43, 43, 43, 43, 43], a, constructor);
-
-    // Create a new object in each function call when receiver is a
-    // primitive value. See ECMA-262, Annex C.
-    a = [];
-    new constructor([1, 2]).filter(function() { a.push(this) }, '');
-    assertTrue(a[0] !== a[1]);
-
-    // Do not create a new object otherwise.
-    a = [];
-    new constructor([1, 2]).filter(function() { a.push(this) }, {});
-    assertEquals(a[0], a[1]);
-
-    // In strict mode primitive values should not be coerced to an object.
-    a = [];
-    new constructor([1, 2]).filter(function() {
-      'use strict';
-      a.push(this);
-    }, '');
-    assertEquals('', a[0]);
-    assertEquals(a[0], a[1]);
-
-    // Calling this method on other types is a TypeError
-    assertThrows(function() {
-      constructor.prototype.filter.call([], function() {});
-    }, TypeError);
-
-    // Shadowing the length property doesn't change anything
-    a = new constructor([1, 2]);
-    Object.defineProperty(a, 'length', { value: 1 });
-    assertArrayLikeEquals([2], a.filter(function(elt) {
-      return elt == 2;
-    }), constructor);
-  })();
-
-  (function TypedArrayMapTest() {
-    var a = new constructor([0, 1, 2, 3, 4]);
-
-    // Simple use.
-    var result = [1, 2, 3, 4, 5];
-    assertArrayLikeEquals(result, a.map(function(n) { return n + 1; }),
-                          constructor);
-    assertEquals(a, a);
-
-    // Use specified object as this object when calling the function.
-    var o = { delta: 42 }
-    result = [42, 43, 44, 45, 46];
-    assertArrayLikeEquals(result, a.map(function(n) {
-      return this.delta + n;
-    }, o), constructor);
-
-    // Modify original array.
-    a = new constructor([0, 1, 2, 3, 4]);
-    result = [1, 2, 3, 4, 5];
-    assertArrayLikeEquals(result, a.map(function(n, index, array) {
-      array[index] = n + 1;
-      return n + 1;
-    }), constructor);
-    assertArrayLikeEquals(result, a, constructor);
-
-    // Create a new object in each function call when receiver is a
-    // primitive value. See ECMA-262, Annex C.
-    a = [];
-    new constructor([1, 2]).map(function() { a.push(this) }, '');
-    assertTrue(a[0] !== a[1]);
-
-    // Do not create a new object otherwise.
-    a = [];
-    new constructor([1, 2]).map(function() { a.push(this) }, {});
-    assertEquals(a[0], a[1]);
-
-    // In strict mode primitive values should not be coerced to an object.
-    a = [];
-    new constructor([1, 2]).map(function() { 'use strict'; a.push(this); }, '');
-    assertEquals('', a[0]);
-    assertEquals(a[0], a[1]);
-
-    // Test that the result is converted to the right type
-    assertArrayLikeEquals([3, 3], new constructor([1, 2]).map(function() {
-      return "3";
-    }), constructor);
-    if (constructor !== Float32Array && constructor !== Float64Array) {
-      assertArrayLikeEquals([0, 0], new constructor([1, 2]).map(function() {
-        return NaN;
-      }), constructor);
-    }
-  })();
-
-  //
-  // %TypedArray%.prototype.some
-  //
-  (function TypedArraySomeTest() {
-    var a = new constructor([0, 1, 2, 3, 4]);
-
-    // Simple use.
-    assertTrue(a.some(function(n) { return n == 3}));
-    assertFalse(a.some(function(n) { return n == 5}));
-
-    // Use specified object as this object when calling the function.
-    var o = { element: 42 };
-    a = new constructor([1, 42, 3]);
-    assertTrue(a.some(function(n) { return this.element == n; }, o));
-    a = new constructor([1]);
-    assertFalse(a.some(function(n) { return this.element == n; }, o));
-
-    // Modify original array.
-    a = new constructor([0, 1, 2, 3]);
-    assertTrue(a.some(function(n, index, array) {
-      array[index] = n + 1;
-      return n == 2;
-    }));
-    assertArrayLikeEquals([1, 2, 3, 3], a, constructor);
-
-    // Create a new object in each function call when receiver is a
-    // primitive value. See ECMA-262, Annex C.
-    a = [];
-    new constructor([1, 2]).some(function() { a.push(this) }, '');
-    assertTrue(a[0] !== a[1]);
-
-    // Do not create a new object otherwise.
-    a = [];
-    new constructor([1, 2]).some(function() { a.push(this) }, {});
-    assertEquals(a[0], a[1]);
-
-    // In strict mode primitive values should not be coerced to an object.
-    a = [];
-    new constructor([1, 2]).some(function() {
-      'use strict';
-      a.push(this);
-    }, '');
-    assertEquals('', a[0]);
-    assertEquals(a[0], a[1]);
-
-    // Calling this method on other types is a TypeError
-    assertThrows(function() {
-      constructor.prototype.some.call([], function() {});
-    }, TypeError);
-
-    // Shadowing the length property doesn't change anything
-    a = new constructor([1, 2]);
-    Object.defineProperty(a, 'length', { value: 1 });
-    assertEquals(true, a.some(function(elt) { return elt == 2; }));
-    assertEquals(false, Array.prototype.some.call(a, function(elt) {
-      return elt == 2;
-    }));
-  })();
-
-}
diff --git a/test/mjsunit/harmony/typedarray-reduce.js b/test/mjsunit/harmony/typedarray-reduce.js
deleted file mode 100644 (file)
index 15bb0ba..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-// Copyright 2015 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 clone(v) {
-  // Shallow-copies arrays, returns everything else verbatim.
-  if (v instanceof Array) {
-    // Shallow-copy an array.
-    var newArray = new Array(v.length);
-    for (var i in v) {
-      newArray[i] = v[i];
-    }
-    return newArray;
-  }
-  return v;
-}
-
-
-// Creates a callback function for reduce/reduceRight that tests the number
-// of arguments and otherwise behaves as "func", but which also
-// records all calls in an array on the function (as arrays of arguments
-// followed by result).
-function makeRecorder(func, testName) {
-  var record = [];
-  var f = function recorder(a, b, i, s) {
-    assertEquals(4, arguments.length,
-                 testName + "(number of arguments: " + arguments.length + ")");
-    assertEquals("number", typeof(i), testName + "(index must be number)");
-    assertEquals(s[i], b, testName + "(current argument is at index)");
-    if (record.length > 0) {
-      var prevRecord = record[record.length - 1];
-      var prevResult = prevRecord[prevRecord.length - 1];
-      assertEquals(prevResult, a,
-                   testName + "(prev result -> current input)");
-    }
-    var args = [clone(a), clone(b), i, clone(s)];
-    var result = func.apply(this, arguments);
-    args.push(clone(result));
-    record.push(args);
-    return result;
-  };
-  f.record = record;
-  return f;
-}
-
-
-function testReduce(type,
-                    testName,
-                    expectedResult,
-                    expectedCalls,
-                    array,
-                    combine,
-                    init) {
-  var rec = makeRecorder(combine);
-  var result;
-  var performsCall;
-  if (arguments.length > 6) {
-    result = array[type](rec, init);
-  } else {
-    result = array[type](rec);
-  }
-  var calls = rec.record;
-  assertEquals(expectedCalls.length, calls.length,
-               testName + " (number of calls)");
-  for (var i = 0; i < expectedCalls.length; i++) {
-    assertEquals(expectedCalls[i], calls[i],
-                 testName + " (call " + (i + 1) + ")");
-  }
-  assertEquals(expectedResult, result, testName + " (result)");
-}
-
-
-function sum(a, b) { return a + b; }
-function prod(a, b) { return a * b; }
-function dec(a, b, i, arr) { return a + b * Math.pow(10, arr.length - i - 1); }
-function accumulate(acc, elem, i) { acc[i] = elem; return acc; }
-
-for (var constructor of typedArrayConstructors) {
-  // ---- Test Reduce[Left]
-
-  var simpleArray = new constructor([2,4,6])
-
-  testReduce("reduce", "SimpleReduceSum", 12,
-             [[0, 2, 0, simpleArray, 2],
-              [2, 4, 1, simpleArray, 6],
-              [6, 6, 2, simpleArray, 12]],
-             simpleArray, sum, 0);
-
-  testReduce("reduce", "SimpleReduceProd", 48,
-             [[1, 2, 0, simpleArray, 2],
-              [2, 4, 1, simpleArray, 8],
-              [8, 6, 2, simpleArray, 48]],
-             simpleArray, prod, 1);
-
-  testReduce("reduce", "SimpleReduceDec", 246,
-             [[0, 2, 0, simpleArray, 200],
-              [200, 4, 1, simpleArray, 240],
-              [240, 6, 2, simpleArray, 246]],
-             simpleArray, dec, 0);
-
-  testReduce("reduce", "SimpleReduceAccumulate", [2, 4, 6],
-             [[[], 2, 0, simpleArray, [2]],
-              [[2], 4, 1, simpleArray, [2, 4]],
-              [[2,4], 6, 2, simpleArray, [2, 4, 6]]],
-             simpleArray, accumulate, []);
-
-
-  testReduce("reduce", "EmptyReduceSum", 0, [], [], sum, 0);
-  testReduce("reduce", "EmptyReduceProd", 1, [], [], prod, 1);
-  testReduce("reduce", "EmptyReduceDec", 0, [], [], dec, 0);
-  testReduce("reduce", "EmptyReduceAccumulate", [], [], [], accumulate, []);
-
-  testReduce("reduce", "EmptyReduceSumNoInit", 0, [], [0], sum);
-  testReduce("reduce", "EmptyReduceProdNoInit", 1, [], [1], prod);
-  testReduce("reduce", "EmptyReduceDecNoInit", 0, [], [0], dec);
-  testReduce("reduce", "EmptyReduceAccumulateNoInit", [], [], [[]], accumulate);
-
-  // ---- Test ReduceRight
-
-  testReduce("reduceRight", "SimpleReduceRightSum", 12,
-             [[0, 6, 2, simpleArray, 6],
-              [6, 4, 1, simpleArray, 10],
-              [10, 2, 0, simpleArray, 12]],
-             simpleArray, sum, 0);
-
-  testReduce("reduceRight", "SimpleReduceRightProd", 48,
-             [[1, 6, 2, simpleArray, 6],
-              [6, 4, 1, simpleArray, 24],
-              [24, 2, 0, simpleArray, 48]],
-             simpleArray, prod, 1);
-
-  testReduce("reduceRight", "SimpleReduceRightDec", 246,
-             [[0, 6, 2, simpleArray, 6],
-              [6, 4, 1, simpleArray, 46],
-              [46, 2, 0, simpleArray, 246]],
-             simpleArray, dec, 0);
-
-
-  testReduce("reduceRight", "EmptyReduceRightSum", 0, [], [], sum, 0);
-  testReduce("reduceRight", "EmptyReduceRightProd", 1, [], [], prod, 1);
-  testReduce("reduceRight", "EmptyReduceRightDec", 0, [], [], dec, 0);
-  testReduce("reduceRight", "EmptyReduceRightAccumulate", [],
-             [], [], accumulate, []);
-
-  testReduce("reduceRight", "EmptyReduceRightSumNoInit", 0, [], [0], sum);
-  testReduce("reduceRight", "EmptyReduceRightProdNoInit", 1, [], [1], prod);
-  testReduce("reduceRight", "EmptyReduceRightDecNoInit", 0, [], [0], dec);
-  testReduce("reduceRight", "EmptyReduceRightAccumulateNoInit",
-             [], [], [[]], accumulate);
-
-  // Ignore non-array properties:
-
-  var arrayPlus = [1,2,3];
-  arrayPlus[-1] = NaN;
-  arrayPlus[Math.pow(2,32)] = NaN;
-  arrayPlus[NaN] = NaN;
-  arrayPlus["00"] = NaN;
-  arrayPlus["02"] = NaN;
-  arrayPlus["-0"] = NaN;
-
-  testReduce("reduce", "ArrayWithNonElementPropertiesReduce", 6,
-             [[0, 1, 0, arrayPlus, 1],
-              [1, 2, 1, arrayPlus, 3],
-              [3, 3, 2, arrayPlus, 6],
-             ], arrayPlus, sum, 0);
-
-  testReduce("reduceRight", "ArrayWithNonElementPropertiesReduceRight", 6,
-             [[0, 3, 2, arrayPlus, 3],
-              [3, 2, 1, arrayPlus, 5],
-              [5, 1, 0, arrayPlus, 6],
-             ], arrayPlus, sum, 0);
-
-
-  // Test error conditions:
-
-  var exception = false;
-  try {
-    new constructor([1]).reduce("not a function");
-  } catch (e) {
-    exception = true;
-    assertTrue(e instanceof TypeError,
-               "reduce callback not a function not throwing TypeError");
-    assertTrue(e.message.indexOf(" is not a function") >= 0,
-               "reduce non function TypeError type");
-  }
-  assertTrue(exception);
-
-  exception = false;
-  try {
-    new constructor([1]).reduceRight("not a function");
-  } catch (e) {
-    exception = true;
-    assertTrue(e instanceof TypeError,
-               "reduceRight callback not a function not throwing TypeError");
-    assertTrue(e.message.indexOf(" is not a function") >= 0,
-               "reduceRight non function TypeError type");
-  }
-  assertTrue(exception);
-
-  exception = false;
-  try {
-    new constructor([]).reduce(sum);
-  } catch (e) {
-    exception = true;
-    assertTrue(e instanceof TypeError,
-               "reduce no initial value not throwing TypeError");
-    assertEquals("Reduce of empty array with no initial value", e.message,
-                 "reduce no initial TypeError type");
-  }
-  assertTrue(exception);
-
-  exception = false;
-  try {
-    new constructor([]).reduceRight(sum);
-  } catch (e) {
-    exception = true;
-    assertTrue(e instanceof TypeError,
-               "reduceRight no initial value not throwing TypeError");
-    assertEquals("Reduce of empty array with no initial value", e.message,
-                 "reduceRight no initial TypeError type");
-  }
-  assertTrue(exception);
-
-  // Reduce fails when called on non-TypedArrays
-  assertThrows(function() {
-    constructor.prototype.reduce.call([], function() {}, null);
-  }, TypeError);
-  assertThrows(function() {
-    constructor.prototype.reduceRight.call([], function() {}, null);
-  }, TypeError);
-
-  // Shadowing length doesn't affect every, unlike Array.prototype.every
-  var a = new constructor([1, 2]);
-  Object.defineProperty(a, 'length', {value: 1});
-  assertEquals(a.reduce(sum, 0), 3);
-  assertEquals(Array.prototype.reduce.call(a, sum, 0), 1);
-  assertEquals(a.reduceRight(sum, 0), 3);
-  assertEquals(Array.prototype.reduceRight.call(a, sum, 0), 1);
-
-  assertEquals(1, constructor.prototype.reduce.length);
-  assertEquals(1, constructor.prototype.reduceRight.length);
-}