spread-call-optimization.js (5479B)
1 // Tests when |arguments| are used in optimized spread calls. 2 3 function testBasic() { 4 // Return the number of arguments. 5 function argslen() { return arguments.length; } 6 7 // Return the first argument. 8 function arg0() { return arguments[0]; } 9 10 // Return the argument at the request index. 11 function argIndex(i) { return arguments[i]; } 12 13 // Call the above functions when no formals are present. 14 function noFormalsLen() { return argslen(...arguments); } 15 function noFormals0() { return arg0(...arguments); } 16 function noFormalsIndex() { return argIndex(...arguments); } 17 18 // Call the above functions when some formals are present. 19 function formalsLen(x, y, z) { return argslen(...arguments); } 20 function formals0(x, y, z) { return arg0(...arguments); } 21 function formalsIndex(x, y, z) { return argIndex(...arguments); } 22 23 // Call the above functions when a rest argument is present. 24 function restLen(...rest) { return argslen(...arguments); } 25 function rest0(...rest) { return arg0(...arguments); } 26 function restIndex(...rest) { return argIndex(...arguments); } 27 28 // Call the above functions when default parameters are present. 29 function defaultLen(x = 0) { return argslen(...arguments); } 30 function default0(x = 0) { return arg0(...arguments); } 31 function defaultIndex(x = 0) { return argIndex(...arguments); } 32 33 for (let i = 0; i < 100; ++i) { 34 assertEq(noFormalsLen(), 0); 35 assertEq(noFormalsLen(1), 1); 36 assertEq(noFormalsLen(1, 2, 3), 3); 37 38 assertEq(formalsLen(), 0); 39 assertEq(formalsLen(1), 1); 40 assertEq(formalsLen(1, 2, 3), 3); 41 42 assertEq(restLen(), 0); 43 assertEq(restLen(1), 1); 44 assertEq(restLen(1, 2, 3), 3); 45 46 assertEq(defaultLen(), 0); 47 assertEq(defaultLen(1), 1); 48 assertEq(defaultLen(1, 2, 3), 3); 49 50 assertEq(noFormals0(), undefined); 51 assertEq(noFormals0(100), 100); 52 assertEq(noFormals0(100, 200, 300), 100); 53 54 assertEq(formals0(), undefined); 55 assertEq(formals0(100), 100); 56 assertEq(formals0(100, 200, 300), 100); 57 58 assertEq(rest0(), undefined); 59 assertEq(rest0(100), 100); 60 assertEq(rest0(100, 200, 300), 100); 61 62 assertEq(default0(), undefined); 63 assertEq(default0(100), 100); 64 assertEq(default0(100, 200, 300), 100); 65 66 assertEq(noFormalsIndex(), undefined); 67 assertEq(noFormalsIndex(0), 0); 68 assertEq(noFormalsIndex(0, 100), 0); 69 assertEq(noFormalsIndex(0, 100, 200, 300), 0); 70 assertEq(noFormalsIndex(1, 100), 100); 71 assertEq(noFormalsIndex(1, 100, 200, 300), 100); 72 73 assertEq(formalsIndex(), undefined); 74 assertEq(formalsIndex(0), 0); 75 assertEq(formalsIndex(0, 100), 0); 76 assertEq(formalsIndex(0, 100, 200, 300), 0); 77 assertEq(formalsIndex(1, 100), 100); 78 assertEq(formalsIndex(1, 100, 200, 300), 100); 79 80 assertEq(restIndex(), undefined); 81 assertEq(restIndex(0), 0); 82 assertEq(restIndex(0, 100), 0); 83 assertEq(restIndex(0, 100, 200, 300), 0); 84 assertEq(restIndex(1, 100), 100); 85 assertEq(restIndex(1, 100, 200, 300), 100); 86 87 assertEq(defaultIndex(), undefined); 88 assertEq(defaultIndex(0), 0); 89 assertEq(defaultIndex(0, 100), 0); 90 assertEq(defaultIndex(0, 100, 200, 300), 0); 91 assertEq(defaultIndex(1, 100), 100); 92 assertEq(defaultIndex(1, 100, 200, 300), 100); 93 } 94 } 95 testBasic(); 96 97 function testOverriddenIterator() { 98 function g(x) { 99 return x; 100 } 101 102 function f(i) { 103 if (i === 100) { 104 arguments[Symbol.iterator] = function() { 105 return ["bad"].values(); 106 }; 107 } 108 return g(...arguments); 109 } 110 111 for (let i = 0; i <= 150; ++i) { 112 assertEq(f(i), i !== 100 ? i : "bad"); 113 } 114 } 115 testOverriddenIterator(); 116 117 function testOverriddenLength() { 118 function g(x, y = 0) { 119 return x + y; 120 } 121 122 function f(i) { 123 if (i === 100) { 124 arguments.length = 1; 125 } 126 return g(...arguments); 127 } 128 129 for (let i = 0; i <= 150; ++i) { 130 assertEq(f(i, i), i !== 100 ? i * 2 : i); 131 } 132 } 133 testOverriddenLength(); 134 135 function testOverriddenElement() { 136 function g(x, y) { 137 return x + y; 138 } 139 140 function f(i) { 141 if (i === 100) { 142 arguments[1] = 0; 143 } 144 return g(...arguments); 145 } 146 147 for (let i = 0; i <= 150; ++i) { 148 assertEq(f(i, i), i !== 100 ? i * 2 : i); 149 } 150 } 151 testOverriddenElement(); 152 153 function testDeletedElement() { 154 function g(x, y = 0) { 155 return x + y; 156 } 157 158 function f(i) { 159 if (i === 100) { 160 delete arguments[1]; 161 } 162 return g(...arguments); 163 } 164 165 for (let i = 0; i <= 150; ++i) { 166 assertEq(f(i, i), i !== 100 ? i * 2 : i); 167 } 168 } 169 testDeletedElement(); 170 171 function testForwardedArg() { 172 function g(x, y) { 173 return x + y; 174 } 175 176 function f(i) { 177 function closedOver() { 178 if (i === 100) i = 0; 179 } 180 closedOver(); 181 return g(...arguments); 182 } 183 184 for (let i = 0; i <= 150; ++i) { 185 assertEq(f(i, i), i !== 100 ? i * 2 : i); 186 } 187 } 188 testForwardedArg(); 189 190 function testModifiedArrayIteratorPrototype() { 191 function g(x, y) { 192 return x + y; 193 } 194 195 const ArrayIteratorPrototype = Reflect.getPrototypeOf([][Symbol.iterator]()); 196 const ArrayIteratorPrototypeNext = ArrayIteratorPrototype.next; 197 function newNext() { 198 var result = ArrayIteratorPrototypeNext.call(this); 199 if (!result.done) { 200 result.value *= 2; 201 } 202 return result; 203 } 204 205 function f(i) { 206 if (i === 100) { 207 ArrayIteratorPrototype.next = newNext; 208 } 209 return g(...arguments); 210 } 211 212 for (let i = 0; i <= 150; ++i) { 213 assertEq(f(i, i), i < 100 ? i * 2 : i * 4); 214 } 215 } 216 testModifiedArrayIteratorPrototype();