1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Flags: --allow-natives-syntax 6 7 8 // Note in general that "arguments.foo" and "var o = arguments; o.foo" 9 // are treated differently by full-codegen, and so both cases need to be 10 // tested. 11 12 function TestDirectArgumentsIteratorProperty() { 13 assertTrue(arguments.hasOwnProperty(Symbol.iterator)); 14 assertFalse(arguments.propertyIsEnumerable(Symbol.iterator)); 15 var descriptor = Object.getOwnPropertyDescriptor(arguments, Symbol.iterator); 16 assertTrue(descriptor.writable); 17 assertFalse(descriptor.enumerable); 18 assertTrue(descriptor.configurable); 19 assertEquals(descriptor.value, [][Symbol.iterator]); 20 assertEquals(arguments[Symbol.iterator], [][Symbol.iterator]); 21 } 22 TestDirectArgumentsIteratorProperty(); 23 24 25 function TestIndirectArgumentsIteratorProperty() { 26 var o = arguments; 27 assertTrue(o.hasOwnProperty(Symbol.iterator)); 28 assertFalse(o.propertyIsEnumerable(Symbol.iterator)); 29 assertEquals(o[Symbol.iterator], [][Symbol.iterator]); 30 } 31 TestIndirectArgumentsIteratorProperty(); 32 33 34 function assertIteratorResult(value, done, result) { 35 assertEquals({value: value, done: done}, result); 36 } 37 38 39 function TestDirectValues1(a, b, c) { 40 var iterator = arguments[Symbol.iterator](); 41 assertIteratorResult(a, false, iterator.next()); 42 assertIteratorResult(b, false, iterator.next()); 43 assertIteratorResult(c, false, iterator.next()); 44 assertIteratorResult(undefined, true, iterator.next()); 45 } 46 TestDirectValues1(1, 2, 3); 47 48 49 function TestIndirectValues1(a, b, c) { 50 var args = arguments; 51 var iterator = args[Symbol.iterator](); 52 assertIteratorResult(a, false, iterator.next()); 53 assertIteratorResult(b, false, iterator.next()); 54 assertIteratorResult(c, false, iterator.next()); 55 assertIteratorResult(undefined, true, iterator.next()); 56 } 57 TestIndirectValues1(1, 2, 3); 58 59 60 function TestDirectValues2(a, b, c) { 61 var iterator = arguments[Symbol.iterator](); 62 assertIteratorResult(a, false, iterator.next()); 63 assertIteratorResult(b, false, iterator.next()); 64 assertIteratorResult(c, false, iterator.next()); 65 assertIteratorResult(undefined, true, iterator.next()); 66 67 arguments[3] = 4; 68 arguments.length = 4; 69 assertIteratorResult(undefined, true, iterator.next()); 70 } 71 TestDirectValues2(1, 2, 3); 72 73 74 function TestIndirectValues2(a, b, c) { 75 var args = arguments; 76 var iterator = args[Symbol.iterator](); 77 assertIteratorResult(a, false, iterator.next()); 78 assertIteratorResult(b, false, iterator.next()); 79 assertIteratorResult(c, false, iterator.next()); 80 assertIteratorResult(undefined, true, iterator.next()); 81 82 arguments[3] = 4; 83 arguments.length = 4; 84 assertIteratorResult(undefined, true, iterator.next()); 85 } 86 TestIndirectValues2(1, 2, 3); 87 88 89 function TestDirectValues3(a, b, c) { 90 var iterator = arguments[Symbol.iterator](); 91 assertIteratorResult(a, false, iterator.next()); 92 assertIteratorResult(b, false, iterator.next()); 93 94 arguments.length = 2; 95 assertIteratorResult(undefined, true, iterator.next()); 96 } 97 TestDirectValues3(1, 2, 3); 98 99 100 function TestIndirectValues3(a, b, c) { 101 var args = arguments; 102 var iterator = args[Symbol.iterator](); 103 assertIteratorResult(a, false, iterator.next()); 104 assertIteratorResult(b, false, iterator.next()); 105 106 arguments.length = 2; 107 assertIteratorResult(undefined, true, iterator.next()); 108 } 109 TestIndirectValues3(1, 2, 3); 110 111 112 function TestDirectValues4(a, b, c) { 113 var iterator = arguments[Symbol.iterator](); 114 assertIteratorResult(a, false, iterator.next()); 115 assertIteratorResult(b, false, iterator.next()); 116 assertIteratorResult(c, false, iterator.next()); 117 118 arguments.length = 4; 119 assertIteratorResult(undefined, false, iterator.next()); 120 assertIteratorResult(undefined, true, iterator.next()); 121 } 122 TestDirectValues4(1, 2, 3); 123 124 125 function TestIndirectValues4(a, b, c) { 126 var args = arguments; 127 var iterator = args[Symbol.iterator](); 128 assertIteratorResult(a, false, iterator.next()); 129 assertIteratorResult(b, false, iterator.next()); 130 assertIteratorResult(c, false, iterator.next()); 131 132 arguments.length = 4; 133 assertIteratorResult(undefined, false, iterator.next()); 134 assertIteratorResult(undefined, true, iterator.next()); 135 } 136 TestIndirectValues4(1, 2, 3); 137 138 139 function TestForOf() { 140 var i = 0; 141 for (var value of arguments) { 142 assertEquals(arguments[i++], value); 143 } 144 145 assertEquals(arguments.length, i); 146 } 147 TestForOf(1, 2, 3, 4, 5); 148 149 150 function TestAssignmentToIterator() { 151 var i = 0; 152 arguments[Symbol.iterator] = [].entries; 153 for (var entry of arguments) { 154 assertEquals([i, arguments[i]], entry); 155 i++; 156 } 157 158 assertEquals(arguments.length, i); 159 } 160 TestAssignmentToIterator(1, 2, 3, 4, 5); 161 162 163 // Regression test for crbug.com/521484. 164 function TestAssignmentToIterator2() { 165 var i = 0; 166 arguments.__defineGetter__('callee', function(){}); 167 arguments.__defineGetter__('length', function(){ return 1 }); 168 arguments[Symbol.iterator] = [].entries; 169 for (var entry of arguments) { 170 assertEquals([i, arguments[i]], entry); 171 i++; 172 } 173 174 assertEquals(arguments.length, i); 175 } 176 TestAssignmentToIterator2(1, 2, 3, 4, 5); 177 178 function TestArgumentsMutation() { 179 var i = 0; 180 for (var x of arguments) { 181 assertEquals(arguments[i], x); 182 arguments[i+1] *= 2; 183 i++; 184 } 185 186 assertEquals(arguments.length, i); 187 } 188 TestArgumentsMutation(1, 2, 3, 4, 5); 189 190 191 function TestSloppyArgumentsAliasing(a0, a1, a2, a3, a4) { 192 var i = 0; 193 for (var x of arguments) { 194 assertEquals(arguments[i], x); 195 a0 = a1; a1 = a2; a3 = a4; 196 i++; 197 } 198 199 assertEquals(arguments.length, i); 200 } 201 TestSloppyArgumentsAliasing(1, 2, 3, 4, 5); 202 203 204 function TestStrictArgumentsAliasing(a0, a1, a2, a3, a4) { 205 "use strict"; 206 var i = 0; 207 for (var x of arguments) { 208 a0 = a1; a1 = a2; a3 = a4; 209 assertEquals(arguments[i], x); 210 i++; 211 } 212 213 assertEquals(arguments.length, i); 214 } 215 TestStrictArgumentsAliasing(1, 2, 3, 4, 5); 216 217 218 function TestArgumentsAsProto() { 219 "use strict"; 220 221 var o = {__proto__:arguments}; 222 assertSame([][Symbol.iterator], o[Symbol.iterator]); 223 // Make o dict-mode. 224 %OptimizeObjectForAddingMultipleProperties(o, 0); 225 assertFalse(o.hasOwnProperty(Symbol.iterator)); 226 assertSame([][Symbol.iterator], o[Symbol.iterator]); 227 o[Symbol.iterator] = 10; 228 assertTrue(o.hasOwnProperty(Symbol.iterator)); 229 assertEquals(10, o[Symbol.iterator]); 230 assertSame([][Symbol.iterator], arguments[Symbol.iterator]); 231 232 // Frozen o. 233 o = Object.freeze({__proto__:arguments}); 234 assertSame([][Symbol.iterator], o[Symbol.iterator]); 235 assertFalse(o.hasOwnProperty(Symbol.iterator)); 236 assertSame([][Symbol.iterator], o[Symbol.iterator]); 237 assertThrows(function () { o[Symbol.iterator] = 10 }); 238 assertFalse(o.hasOwnProperty(Symbol.iterator)); 239 assertEquals([][Symbol.iterator], o[Symbol.iterator]); 240 assertSame([][Symbol.iterator], arguments[Symbol.iterator]); 241 } 242 TestArgumentsAsProto(); 243