// 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: --allow-natives-syntax

var typedArrayConstructors = [
  Uint8Array,
  Int8Array,
  Uint16Array,
  Int16Array,
  Uint32Array,
  Int32Array,
  Uint8ClampedArray,
  Float32Array,
  Float64Array];

function CheckTypedArrayIsDetached(array) {
  assertEquals(0, array.byteLength);
  assertEquals(0, array.byteOffset);
  assertEquals(0, array.length);
}

function TestTypedArrayForEach(constructor) {
  assertEquals(1, constructor.prototype.forEach.length);

  var a = new constructor(2);
  a[0] = 0;
  a[1] = 1;

  var count = 0;
  a.forEach(function (n) { count++; });
  assertEquals(2, count);

  // Use specified object as this object when calling the function.
  var o = { value: 42 };
  var result = [];
  a.forEach(function (n, index, array) { result.push(this.value); }, o);
  assertArrayEquals([42, 42], result);

  // Modify the original array.
  count = 0;
  a.forEach(function (n, index, array) { array[index] = n + 1; count++ });
  assertEquals(2, count);
  assertArrayEquals([1, 2], 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.forEach(function () {
      assertEquals("object", typeof this);
      assertEquals(wrappedValue, this);
    }, value);

    a.forEach(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);

  // Throw before completing iteration, only the first element
  // should be modified when thorwing mid-way.
  count = 0;
  a[0] = 42;
  a[1] = 42;
  try {
    a.forEach(function (n, index, array) {
      if (count > 0) throw "meh";
      array[index] = n + 1;
      count++;
    });
  } catch (e) {
  }
  assertEquals(1, count);
  assertEquals(43, a[0]);
  assertEquals(42, a[1]);

  // Detaching the buffer backing the typed array mid-way should
  // still make .forEach() finish, but exiting early due to the missing
  // elements, and the array should keep being empty after detaching it.
  // TODO(dehrenberg): According to the ES6 spec, accessing or testing
  // for members on a detached TypedArray should throw, so really this
  // should throw in the third iteration. However, this behavior matches
  // the Khronos spec.
  a = new constructor(3);
  count = 0;
  a.forEach(function (n, index, array) {
    if (count > 0) %ArrayBufferDetach(array.buffer);
    array[index] = n + 1;
    count++;
  });
  assertEquals(2, count);
  CheckTypedArrayIsDetached(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;
  a.forEach(function (n) { count++ });
  assertEquals(a.length, count);

  // Externalizing the array mid-way accessing the .buffer property
  // should work.
  a = new constructor(2);
  count = 0;
  var buffer = undefined;
  a.forEach(function (n, index, array) {
    if (count++ > 0)
      buffer = array.buffer;
  });
  assertEquals(2, count);
  assertTrue(!!buffer);
  assertSame(buffer, a.buffer);

  // The %TypedArray%.forEach() method should not work when
  // transplanted to objects that are not typed arrays.
  assertThrows(function () { constructor.prototype.forEach.call([1, 2, 3], function (x) {}) }, TypeError);
  assertThrows(function () { constructor.prototype.forEach.call("abc", function (x) {}) }, TypeError);
  assertThrows(function () { constructor.prototype.forEach.call({}, function (x) {}) }, TypeError);
  assertThrows(function () { constructor.prototype.forEach.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.forEach.call(a, function (x) { count++ });
    assertEquals(a.length, count);
  }

  // Shadowing length doesn't affect forEach, unlike Array.prototype.forEach
  a = new constructor([1, 2]);
  Object.defineProperty(a, 'length', {value: 1});
  var x = 0;
  assertEquals(a.forEach(function(elt) { x += elt; }), undefined);
  assertEquals(x, 3);
  assertEquals(Array.prototype.forEach.call(a,
      function(elt) { x += elt; }), undefined);
  assertEquals(x, 4);

  // Detached Operation
  var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  %ArrayBufferDetach(array.buffer);
  assertThrows(() => array.forEach(() => true), TypeError);
}

for (i = 0; i < typedArrayConstructors.length; i++) {
  TestTypedArrayForEach(typedArrayConstructors[i]);
}
