// 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


// Note in general that "arguments.foo" and "var o = arguments; o.foo"
// are treated differently by full-codegen, and so both cases need to be
// tested.

function TestDirectArgumentsIteratorProperty() {
  assertTrue(arguments.hasOwnProperty(Symbol.iterator));
  assertFalse(arguments.propertyIsEnumerable(Symbol.iterator));
  var descriptor = Object.getOwnPropertyDescriptor(arguments, Symbol.iterator);
  assertTrue(descriptor.writable);
  assertFalse(descriptor.enumerable);
  assertTrue(descriptor.configurable);
  assertEquals(descriptor.value, [][Symbol.iterator]);
  assertEquals(arguments[Symbol.iterator], [][Symbol.iterator]);
}
TestDirectArgumentsIteratorProperty();


function TestIndirectArgumentsIteratorProperty() {
  var o = arguments;
  assertTrue(o.hasOwnProperty(Symbol.iterator));
  assertFalse(o.propertyIsEnumerable(Symbol.iterator));
  assertEquals(o[Symbol.iterator], [][Symbol.iterator]);
}
TestIndirectArgumentsIteratorProperty();


function assertIteratorResult(value, done, result) {
  assertEquals({value: value, done: done}, result);
}


function TestDirectValues1(a, b, c) {
  var iterator = arguments[Symbol.iterator]();
  assertIteratorResult(a, false, iterator.next());
  assertIteratorResult(b, false, iterator.next());
  assertIteratorResult(c, false, iterator.next());
  assertIteratorResult(undefined, true, iterator.next());
}
TestDirectValues1(1, 2, 3);


function TestIndirectValues1(a, b, c) {
  var args = arguments;
  var iterator = args[Symbol.iterator]();
  assertIteratorResult(a, false, iterator.next());
  assertIteratorResult(b, false, iterator.next());
  assertIteratorResult(c, false, iterator.next());
  assertIteratorResult(undefined, true, iterator.next());
}
TestIndirectValues1(1, 2, 3);


function TestDirectValues2(a, b, c) {
  var iterator = arguments[Symbol.iterator]();
  assertIteratorResult(a, false, iterator.next());
  assertIteratorResult(b, false, iterator.next());
  assertIteratorResult(c, false, iterator.next());
  assertIteratorResult(undefined, true, iterator.next());

  arguments[3] = 4;
  arguments.length = 4;
  assertIteratorResult(undefined, true, iterator.next());
}
TestDirectValues2(1, 2, 3);


function TestIndirectValues2(a, b, c) {
  var args = arguments;
  var iterator = args[Symbol.iterator]();
  assertIteratorResult(a, false, iterator.next());
  assertIteratorResult(b, false, iterator.next());
  assertIteratorResult(c, false, iterator.next());
  assertIteratorResult(undefined, true, iterator.next());

  arguments[3] = 4;
  arguments.length = 4;
  assertIteratorResult(undefined, true, iterator.next());
}
TestIndirectValues2(1, 2, 3);


function TestDirectValues3(a, b, c) {
  var iterator = arguments[Symbol.iterator]();
  assertIteratorResult(a, false, iterator.next());
  assertIteratorResult(b, false, iterator.next());

  arguments.length = 2;
  assertIteratorResult(undefined, true, iterator.next());
}
TestDirectValues3(1, 2, 3);


function TestIndirectValues3(a, b, c) {
  var args = arguments;
  var iterator = args[Symbol.iterator]();
  assertIteratorResult(a, false, iterator.next());
  assertIteratorResult(b, false, iterator.next());

  arguments.length = 2;
  assertIteratorResult(undefined, true, iterator.next());
}
TestIndirectValues3(1, 2, 3);


function TestDirectValues4(a, b, c) {
  var iterator = arguments[Symbol.iterator]();
  assertIteratorResult(a, false, iterator.next());
  assertIteratorResult(b, false, iterator.next());
  assertIteratorResult(c, false, iterator.next());

  arguments.length = 4;
  assertIteratorResult(undefined, false, iterator.next());
  assertIteratorResult(undefined, true, iterator.next());
}
TestDirectValues4(1, 2, 3);


function TestIndirectValues4(a, b, c) {
  var args = arguments;
  var iterator = args[Symbol.iterator]();
  assertIteratorResult(a, false, iterator.next());
  assertIteratorResult(b, false, iterator.next());
  assertIteratorResult(c, false, iterator.next());

  arguments.length = 4;
  assertIteratorResult(undefined, false, iterator.next());
  assertIteratorResult(undefined, true, iterator.next());
}
TestIndirectValues4(1, 2, 3);


function TestForOf() {
  var i = 0;
  for (var value of arguments) {
    assertEquals(arguments[i++], value);
  }

  assertEquals(arguments.length, i);
}
TestForOf(1, 2, 3, 4, 5);


function TestAssignmentToIterator() {
  var i = 0;
  arguments[Symbol.iterator] = [].entries;
  for (var entry of arguments) {
    assertEquals([i, arguments[i]], entry);
    i++;
  }

  assertEquals(arguments.length, i);
}
TestAssignmentToIterator(1, 2, 3, 4, 5);


// Regression test for crbug.com/521484.
function TestAssignmentToIterator2() {
  var i = 0;
  arguments.__defineGetter__('callee', function(){});
  arguments.__defineGetter__('length', function(){ return 1 });
  arguments[Symbol.iterator] = [].entries;
  for (var entry of arguments) {
    assertEquals([i, arguments[i]], entry);
    i++;
  }

  assertEquals(arguments.length, i);
}
TestAssignmentToIterator2(1, 2, 3, 4, 5);

function TestArgumentsMutation() {
  var i = 0;
  for (var x of arguments) {
    assertEquals(arguments[i], x);
    arguments[i+1] *= 2;
    i++;
  }

  assertEquals(arguments.length, i);
}
TestArgumentsMutation(1, 2, 3, 4, 5);


function TestSloppyArgumentsAliasing(a0, a1, a2, a3, a4) {
  var i = 0;
  for (var x of arguments) {
    assertEquals(arguments[i], x);
    a0 = a1; a1 = a2; a3 = a4;
    i++;
  }

  assertEquals(arguments.length, i);
}
TestSloppyArgumentsAliasing(1, 2, 3, 4, 5);


function TestStrictArgumentsAliasing(a0, a1, a2, a3, a4) {
  "use strict";
  var i = 0;
  for (var x of arguments) {
    a0 = a1; a1 = a2; a3 = a4;
    assertEquals(arguments[i], x);
    i++;
  }

  assertEquals(arguments.length, i);
}
TestStrictArgumentsAliasing(1, 2, 3, 4, 5);


function TestArgumentsAsProto() {
  "use strict";

  var o = {__proto__:arguments};
  assertSame([][Symbol.iterator], o[Symbol.iterator]);
  // Make o dict-mode.
  %OptimizeObjectForAddingMultipleProperties(o, 0);
  assertFalse(o.hasOwnProperty(Symbol.iterator));
  assertSame([][Symbol.iterator], o[Symbol.iterator]);
  o[Symbol.iterator] = 10;
  assertTrue(o.hasOwnProperty(Symbol.iterator));
  assertEquals(10, o[Symbol.iterator]);
  assertSame([][Symbol.iterator], arguments[Symbol.iterator]);

  // Frozen o.
  o = Object.freeze({__proto__:arguments});
  assertSame([][Symbol.iterator], o[Symbol.iterator]);
  assertFalse(o.hasOwnProperty(Symbol.iterator));
  assertSame([][Symbol.iterator], o[Symbol.iterator]);
  assertThrows(function () { o[Symbol.iterator] = 10 });
  assertFalse(o.hasOwnProperty(Symbol.iterator));
  assertEquals([][Symbol.iterator], o[Symbol.iterator]);
  assertSame([][Symbol.iterator], arguments[Symbol.iterator]);
}
TestArgumentsAsProto();
