|  | // 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(); |