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 function TestArgumentsMutation() { 164 var i = 0; 165 for (var x of arguments) { 166 assertEquals(arguments[i], x); 167 arguments[i+1] *= 2; 168 i++; 169 } 170 171 assertEquals(arguments.length, i); 172 } 173 TestArgumentsMutation(1, 2, 3, 4, 5); 174 175 176 function TestSloppyArgumentsAliasing(a0, a1, a2, a3, a4) { 177 var i = 0; 178 for (var x of arguments) { 179 assertEquals(arguments[i], x); 180 a0 = a1; a1 = a2; a3 = a4; 181 i++; 182 } 183 184 assertEquals(arguments.length, i); 185 } 186 TestSloppyArgumentsAliasing(1, 2, 3, 4, 5); 187 188 189 function TestStrictArgumentsAliasing(a0, a1, a2, a3, a4) { 190 "use strict"; 191 var i = 0; 192 for (var x of arguments) { 193 a0 = a1; a1 = a2; a3 = a4; 194 assertEquals(arguments[i], x); 195 i++; 196 } 197 198 assertEquals(arguments.length, i); 199 } 200 TestStrictArgumentsAliasing(1, 2, 3, 4, 5); 201 202 203 function TestArgumentsAsProto() { 204 "use strict"; 205 206 var o = {__proto__:arguments}; 207 assertSame([][Symbol.iterator], o[Symbol.iterator]); 208 // Make o dict-mode. 209 %OptimizeObjectForAddingMultipleProperties(o, 0); 210 assertFalse(o.hasOwnProperty(Symbol.iterator)); 211 assertSame([][Symbol.iterator], o[Symbol.iterator]); 212 o[Symbol.iterator] = 10; 213 assertTrue(o.hasOwnProperty(Symbol.iterator)); 214 assertEquals(10, o[Symbol.iterator]); 215 assertSame([][Symbol.iterator], arguments[Symbol.iterator]); 216 217 // Frozen o. 218 o = Object.freeze({__proto__:arguments}); 219 assertSame([][Symbol.iterator], o[Symbol.iterator]); 220 assertFalse(o.hasOwnProperty(Symbol.iterator)); 221 assertSame([][Symbol.iterator], o[Symbol.iterator]); 222 // This should throw, but currently it doesn't, because 223 // ExecutableAccessorInfo callbacks don't see the current strict mode. 224 // See note in accessors.cc:SetPropertyOnInstanceIfInherited. 225 o[Symbol.iterator] = 10; 226 assertFalse(o.hasOwnProperty(Symbol.iterator)); 227 assertEquals([][Symbol.iterator], o[Symbol.iterator]); 228 assertSame([][Symbol.iterator], arguments[Symbol.iterator]); 229 } 230 TestArgumentsAsProto(); 231