|
1 /* |
|
2 * Any copyright is dedicated to the Public Domain. |
|
3 * http://creativecommons.org/licenses/publicdomain/ |
|
4 */ |
|
5 |
|
6 var gTestfile = 'strict-arguments.js'; |
|
7 var BUGNUMBER = 516255; |
|
8 var summary = |
|
9 "ES5 strict mode: arguments objects of strict mode functions must copy " + |
|
10 "argument values"; |
|
11 |
|
12 print(BUGNUMBER + ": " + summary); |
|
13 |
|
14 /************** |
|
15 * BEGIN TEST * |
|
16 **************/ |
|
17 |
|
18 function arrayEvery(arr, fun) |
|
19 { |
|
20 return Array.prototype.every.call(arr, fun); |
|
21 } |
|
22 |
|
23 function arraysEqual(a1, a2) |
|
24 { |
|
25 return a1.length === a2.length && |
|
26 arrayEvery(a1, function(v, i) { return v === a2[i]; }); |
|
27 } |
|
28 |
|
29 |
|
30 /************************ |
|
31 * NON-STRICT ARGUMENTS * |
|
32 ************************/ |
|
33 |
|
34 var obj = {}; |
|
35 |
|
36 function noargs() { return arguments; } |
|
37 |
|
38 assertEq(arraysEqual(noargs(), []), true); |
|
39 assertEq(arraysEqual(noargs(1), [1]), true); |
|
40 assertEq(arraysEqual(noargs(2, obj, 8), [2, obj, 8]), true); |
|
41 |
|
42 function args(a) { return arguments; } |
|
43 |
|
44 assertEq(arraysEqual(args(), []), true); |
|
45 assertEq(arraysEqual(args(1), [1]), true); |
|
46 assertEq(arraysEqual(args(1, obj), [1, obj]), true); |
|
47 assertEq(arraysEqual(args("foopy"), ["foopy"]), true); |
|
48 |
|
49 function assign(a) |
|
50 { |
|
51 a = 17; |
|
52 return arguments; |
|
53 } |
|
54 |
|
55 assertEq(arraysEqual(assign(1), [17]), true); |
|
56 |
|
57 function getLaterAssign(a) |
|
58 { |
|
59 var o = arguments; |
|
60 a = 17; |
|
61 return o; |
|
62 } |
|
63 |
|
64 assertEq(arraysEqual(getLaterAssign(1), [17]), true); |
|
65 |
|
66 function assignElementGetParameter(a) |
|
67 { |
|
68 arguments[0] = 17; |
|
69 return a; |
|
70 } |
|
71 |
|
72 assertEq(assignElementGetParameter(42), 17); |
|
73 |
|
74 function assignParameterGetElement(a) |
|
75 { |
|
76 a = 17; |
|
77 return arguments[0]; |
|
78 } |
|
79 |
|
80 assertEq(assignParameterGetElement(42), 17); |
|
81 |
|
82 function assignArgSub(x, y) |
|
83 { |
|
84 arguments[0] = 3; |
|
85 return arguments[0]; |
|
86 } |
|
87 |
|
88 assertEq(assignArgSub(1), 3); |
|
89 |
|
90 function assignArgSubParamUse(x, y) |
|
91 { |
|
92 arguments[0] = 3; |
|
93 assertEq(x, 3); |
|
94 return arguments[0]; |
|
95 } |
|
96 |
|
97 assertEq(assignArgSubParamUse(1), 3); |
|
98 |
|
99 function assignArgumentsElement(x, y) |
|
100 { |
|
101 arguments[0] = 3; |
|
102 return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations |
|
103 } |
|
104 |
|
105 assertEq(assignArgumentsElement(1), 3); |
|
106 |
|
107 function assignArgumentsElementParamUse(x, y) |
|
108 { |
|
109 arguments[0] = 3; |
|
110 assertEq(x, 3); |
|
111 return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations |
|
112 } |
|
113 |
|
114 assertEq(assignArgumentsElementParamUse(1), 3); |
|
115 |
|
116 /******************** |
|
117 * STRICT ARGUMENTS * |
|
118 ********************/ |
|
119 |
|
120 function strictNoargs() |
|
121 { |
|
122 "use strict"; |
|
123 return arguments; |
|
124 } |
|
125 |
|
126 assertEq(arraysEqual(strictNoargs(), []), true); |
|
127 assertEq(arraysEqual(strictNoargs(1), [1]), true); |
|
128 assertEq(arraysEqual(strictNoargs(1, obj), [1, obj]), true); |
|
129 |
|
130 function strictArgs(a) |
|
131 { |
|
132 "use strict"; |
|
133 return arguments; |
|
134 } |
|
135 |
|
136 assertEq(arraysEqual(strictArgs(), []), true); |
|
137 assertEq(arraysEqual(strictArgs(1), [1]), true); |
|
138 assertEq(arraysEqual(strictArgs(1, obj), [1, obj]), true); |
|
139 |
|
140 function strictAssign(a) |
|
141 { |
|
142 "use strict"; |
|
143 a = 17; |
|
144 return arguments; |
|
145 } |
|
146 |
|
147 assertEq(arraysEqual(strictAssign(), []), true); |
|
148 assertEq(arraysEqual(strictAssign(1), [1]), true); |
|
149 assertEq(arraysEqual(strictAssign(1, obj), [1, obj]), true); |
|
150 |
|
151 var upper; |
|
152 function strictAssignAfter(a) |
|
153 { |
|
154 "use strict"; |
|
155 upper = arguments; |
|
156 a = 42; |
|
157 return upper; |
|
158 } |
|
159 |
|
160 assertEq(arraysEqual(strictAssignAfter(), []), true); |
|
161 assertEq(arraysEqual(strictAssignAfter(17), [17]), true); |
|
162 assertEq(arraysEqual(strictAssignAfter(obj), [obj]), true); |
|
163 |
|
164 function strictMaybeAssignOuterParam(p) |
|
165 { |
|
166 "use strict"; |
|
167 function inner() { p = 17; } |
|
168 return arguments; |
|
169 } |
|
170 |
|
171 assertEq(arraysEqual(strictMaybeAssignOuterParam(), []), true); |
|
172 assertEq(arraysEqual(strictMaybeAssignOuterParam(42), [42]), true); |
|
173 assertEq(arraysEqual(strictMaybeAssignOuterParam(obj), [obj]), true); |
|
174 |
|
175 function strictAssignOuterParam(p) |
|
176 { |
|
177 "use strict"; |
|
178 function inner() { p = 17; } |
|
179 inner(); |
|
180 return arguments; |
|
181 } |
|
182 |
|
183 assertEq(arraysEqual(strictAssignOuterParam(), []), true); |
|
184 assertEq(arraysEqual(strictAssignOuterParam(17), [17]), true); |
|
185 assertEq(arraysEqual(strictAssignOuterParam(obj), [obj]), true); |
|
186 |
|
187 function strictAssignOuterParamPSYCH(p) |
|
188 { |
|
189 "use strict"; |
|
190 function inner(p) { p = 17; } |
|
191 inner(); |
|
192 return arguments; |
|
193 } |
|
194 |
|
195 assertEq(arraysEqual(strictAssignOuterParamPSYCH(), []), true); |
|
196 assertEq(arraysEqual(strictAssignOuterParamPSYCH(17), [17]), true); |
|
197 assertEq(arraysEqual(strictAssignOuterParamPSYCH(obj), [obj]), true); |
|
198 |
|
199 function strictEval(code, p) |
|
200 { |
|
201 "use strict"; |
|
202 eval(code); |
|
203 return arguments; |
|
204 } |
|
205 |
|
206 assertEq(arraysEqual(strictEval("1", 2), ["1", 2]), true); |
|
207 assertEq(arraysEqual(strictEval("arguments"), ["arguments"]), true); |
|
208 assertEq(arraysEqual(strictEval("p = 2"), ["p = 2"]), true); |
|
209 assertEq(arraysEqual(strictEval("p = 2", 17), ["p = 2", 17]), true); |
|
210 assertEq(arraysEqual(strictEval("arguments[0] = 17"), [17]), true); |
|
211 assertEq(arraysEqual(strictEval("arguments[0] = 17", 42), [17, 42]), true); |
|
212 |
|
213 function strictMaybeNestedEval(code, p) |
|
214 { |
|
215 "use strict"; |
|
216 function inner() { eval(code); } |
|
217 return arguments; |
|
218 } |
|
219 |
|
220 assertEq(arraysEqual(strictMaybeNestedEval("1", 2), ["1", 2]), true); |
|
221 assertEq(arraysEqual(strictMaybeNestedEval("arguments"), ["arguments"]), true); |
|
222 assertEq(arraysEqual(strictMaybeNestedEval("p = 2"), ["p = 2"]), true); |
|
223 assertEq(arraysEqual(strictMaybeNestedEval("p = 2", 17), ["p = 2", 17]), true); |
|
224 |
|
225 function strictNestedEval(code, p) |
|
226 { |
|
227 "use strict"; |
|
228 function inner() { eval(code); } |
|
229 inner(); |
|
230 return arguments; |
|
231 } |
|
232 |
|
233 assertEq(arraysEqual(strictNestedEval("1", 2), ["1", 2]), true); |
|
234 assertEq(arraysEqual(strictNestedEval("arguments"), ["arguments"]), true); |
|
235 assertEq(arraysEqual(strictNestedEval("p = 2"), ["p = 2"]), true); |
|
236 assertEq(arraysEqual(strictNestedEval("p = 2", 17), ["p = 2", 17]), true); |
|
237 assertEq(arraysEqual(strictNestedEval("arguments[0] = 17"), ["arguments[0] = 17"]), true); |
|
238 assertEq(arraysEqual(strictNestedEval("arguments[0] = 17", 42), ["arguments[0] = 17", 42]), true); |
|
239 |
|
240 function strictAssignArguments(a) |
|
241 { |
|
242 "use strict"; |
|
243 arguments[0] = 42; |
|
244 return a; |
|
245 } |
|
246 |
|
247 assertEq(strictAssignArguments(), undefined); |
|
248 assertEq(strictAssignArguments(obj), obj); |
|
249 assertEq(strictAssignArguments(17), 17); |
|
250 |
|
251 function strictAssignParameterGetElement(a) |
|
252 { |
|
253 "use strict"; |
|
254 a = 17; |
|
255 return arguments[0]; |
|
256 } |
|
257 |
|
258 assertEq(strictAssignParameterGetElement(42), 42); |
|
259 |
|
260 function strictAssignArgSub(x, y) |
|
261 { |
|
262 "use strict"; |
|
263 arguments[0] = 3; |
|
264 return arguments[0]; |
|
265 } |
|
266 |
|
267 assertEq(strictAssignArgSub(1), 3); |
|
268 |
|
269 function strictAssignArgSubParamUse(x, y) |
|
270 { |
|
271 "use strict"; |
|
272 arguments[0] = 3; |
|
273 assertEq(x, 1); |
|
274 return arguments[0]; |
|
275 } |
|
276 |
|
277 assertEq(strictAssignArgSubParamUse(1), 3); |
|
278 |
|
279 function strictAssignArgumentsElement(x, y) |
|
280 { |
|
281 "use strict"; |
|
282 arguments[0] = 3; |
|
283 return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations |
|
284 } |
|
285 |
|
286 assertEq(strictAssignArgumentsElement(1), 3); |
|
287 |
|
288 function strictAssignArgumentsElementParamUse(x, y) |
|
289 { |
|
290 "use strict"; |
|
291 arguments[0] = 3; |
|
292 assertEq(x, 1); |
|
293 return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations |
|
294 } |
|
295 |
|
296 assertEq(strictAssignArgumentsElementParamUse(1), 3); |
|
297 |
|
298 function strictNestedAssignShadowVar(p) |
|
299 { |
|
300 "use strict"; |
|
301 function inner() |
|
302 { |
|
303 var p = 12; |
|
304 function innermost() { p = 1776; return 12; } |
|
305 return innermost(); |
|
306 } |
|
307 return arguments; |
|
308 } |
|
309 |
|
310 assertEq(arraysEqual(strictNestedAssignShadowVar(), []), true); |
|
311 assertEq(arraysEqual(strictNestedAssignShadowVar(99), [99]), true); |
|
312 assertEq(arraysEqual(strictNestedAssignShadowVar(""), [""]), true); |
|
313 assertEq(arraysEqual(strictNestedAssignShadowVar(obj), [obj]), true); |
|
314 |
|
315 function strictNestedAssignShadowCatch(p) |
|
316 { |
|
317 "use strict"; |
|
318 function inner() |
|
319 { |
|
320 try |
|
321 { |
|
322 } |
|
323 catch (p) |
|
324 { |
|
325 var f = function innermost() { p = 1776; return 12; }; |
|
326 f(); |
|
327 } |
|
328 } |
|
329 return arguments; |
|
330 } |
|
331 |
|
332 assertEq(arraysEqual(strictNestedAssignShadowCatch(), []), true); |
|
333 assertEq(arraysEqual(strictNestedAssignShadowCatch(99), [99]), true); |
|
334 assertEq(arraysEqual(strictNestedAssignShadowCatch(""), [""]), true); |
|
335 assertEq(arraysEqual(strictNestedAssignShadowCatch(obj), [obj]), true); |
|
336 |
|
337 function strictNestedAssignShadowCatchCall(p) |
|
338 { |
|
339 "use strict"; |
|
340 function inner() |
|
341 { |
|
342 try |
|
343 { |
|
344 } |
|
345 catch (p) |
|
346 { |
|
347 var f = function innermost() { p = 1776; return 12; }; |
|
348 f(); |
|
349 } |
|
350 } |
|
351 inner(); |
|
352 return arguments; |
|
353 } |
|
354 |
|
355 assertEq(arraysEqual(strictNestedAssignShadowCatchCall(), []), true); |
|
356 assertEq(arraysEqual(strictNestedAssignShadowCatchCall(99), [99]), true); |
|
357 assertEq(arraysEqual(strictNestedAssignShadowCatchCall(""), [""]), true); |
|
358 assertEq(arraysEqual(strictNestedAssignShadowCatchCall(obj), [obj]), true); |
|
359 |
|
360 function strictNestedAssignShadowFunction(p) |
|
361 { |
|
362 "use strict"; |
|
363 function inner() |
|
364 { |
|
365 function p() { } |
|
366 p = 1776; |
|
367 } |
|
368 return arguments; |
|
369 } |
|
370 |
|
371 assertEq(arraysEqual(strictNestedAssignShadowFunction(), []), true); |
|
372 assertEq(arraysEqual(strictNestedAssignShadowFunction(99), [99]), true); |
|
373 assertEq(arraysEqual(strictNestedAssignShadowFunction(""), [""]), true); |
|
374 assertEq(arraysEqual(strictNestedAssignShadowFunction(obj), [obj]), true); |
|
375 |
|
376 function strictNestedAssignShadowFunctionCall(p) |
|
377 { |
|
378 "use strict"; |
|
379 function inner() |
|
380 { |
|
381 function p() { } |
|
382 p = 1776; |
|
383 } |
|
384 return arguments; |
|
385 } |
|
386 |
|
387 assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(), []), true); |
|
388 assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(99), [99]), true); |
|
389 assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(""), [""]), true); |
|
390 assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(obj), [obj]), true); |
|
391 |
|
392 function strictNestedShadowAndMaybeEval(code, p) |
|
393 { |
|
394 "use strict"; |
|
395 function inner(p) { eval(code); } |
|
396 return arguments; |
|
397 } |
|
398 |
|
399 assertEq(arraysEqual(strictNestedShadowAndMaybeEval("1", 2), ["1", 2]), true); |
|
400 assertEq(arraysEqual(strictNestedShadowAndMaybeEval("arguments"), ["arguments"]), true); |
|
401 assertEq(arraysEqual(strictNestedShadowAndMaybeEval("p = 2"), ["p = 2"]), true); |
|
402 assertEq(arraysEqual(strictNestedShadowAndMaybeEval("p = 2", 17), ["p = 2", 17]), true); |
|
403 assertEq(arraysEqual(strictNestedShadowAndMaybeEval("arguments[0] = 17"), ["arguments[0] = 17"]), true); |
|
404 assertEq(arraysEqual(strictNestedShadowAndMaybeEval("arguments[0] = 17", 42), ["arguments[0] = 17", 42]), true); |
|
405 |
|
406 function strictNestedShadowAndEval(code, p) |
|
407 { |
|
408 "use strict"; |
|
409 function inner(p) { eval(code); } |
|
410 return arguments; |
|
411 } |
|
412 |
|
413 assertEq(arraysEqual(strictNestedShadowAndEval("1", 2), ["1", 2]), true); |
|
414 assertEq(arraysEqual(strictNestedShadowAndEval("arguments"), ["arguments"]), true); |
|
415 assertEq(arraysEqual(strictNestedShadowAndEval("p = 2"), ["p = 2"]), true); |
|
416 assertEq(arraysEqual(strictNestedShadowAndEval("p = 2", 17), ["p = 2", 17]), true); |
|
417 assertEq(arraysEqual(strictNestedShadowAndEval("arguments[0] = 17"), ["arguments[0] = 17"]), true); |
|
418 assertEq(arraysEqual(strictNestedShadowAndEval("arguments[0] = 17", 42), ["arguments[0] = 17", 42]), true); |
|
419 |
|
420 function strictEvalContainsMutation(code) |
|
421 { |
|
422 "use strict"; |
|
423 return eval(code); |
|
424 } |
|
425 |
|
426 assertEq(arraysEqual(strictEvalContainsMutation("code = 17; arguments"), ["code = 17; arguments"]), true); |
|
427 assertEq(arraysEqual(strictEvalContainsMutation("arguments[0] = 17; arguments"), [17]), true); |
|
428 assertEq(strictEvalContainsMutation("arguments[0] = 17; code"), "arguments[0] = 17; code"); |
|
429 |
|
430 function strictNestedAssignShadowFunctionName(p) |
|
431 { |
|
432 "use strict"; |
|
433 function inner() |
|
434 { |
|
435 function p() { p = 1776; } |
|
436 p(); |
|
437 } |
|
438 inner(); |
|
439 return arguments; |
|
440 } |
|
441 |
|
442 assertEq(arraysEqual(strictNestedAssignShadowFunctionName(), []), true); |
|
443 assertEq(arraysEqual(strictNestedAssignShadowFunctionName(99), [99]), true); |
|
444 assertEq(arraysEqual(strictNestedAssignShadowFunctionName(""), [""]), true); |
|
445 assertEq(arraysEqual(strictNestedAssignShadowFunctionName(obj), [obj]), true); |
|
446 |
|
447 |
|
448 /******************************************************************************/ |
|
449 |
|
450 if (typeof reportCompare === "function") |
|
451 reportCompare(true, true); |
|
452 |
|
453 print("All tests passed!"); |