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