1// Copyright 2013 the V8 project authors. All rights reserved.
2// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions
6// are met:
7// 1.  Redistributions of source code must retain the above copyright
8//     notice, this list of conditions and the following disclaimer.
9// 2.  Redistributions in binary form must reproduce the above copyright
10//     notice, this list of conditions and the following disclaimer in the
11//     documentation and/or other materials provided with the distribution.
12//
13// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
24description(
25"This test thoroughly checks the behaviour of the 'arguments' object."
26);
27
28function access_1(a, b, c)
29{
30    return arguments[0];
31}
32
33function access_2(a, b, c)
34{
35    return arguments[1];
36}
37
38function access_3(a, b, c)
39{
40    return arguments[2];
41}
42
43function access_4(a, b, c)
44{
45    return arguments[3];
46}
47
48function access_5(a, b, c)
49{
50    return arguments[4];
51}
52
53function argumentLengthIs5() {
54    arguments.length = 5;
55    return arguments.length;
56}
57
58function duplicateArgumentAndReturnLast_call(a) {
59    Array.prototype.push.call(arguments, a);
60    return arguments[1];
61}
62
63function duplicateArgumentAndReturnFirst_call(a) {
64    Array.prototype.push.call(arguments, a);
65    return arguments[0];
66}
67
68function duplicateArgumentAndReturnLast_apply(a) {
69    Array.prototype.push.apply(arguments, arguments);
70    return arguments[1];
71}
72
73function duplicateArgumentAndReturnFirst_apply(a) {
74    Array.prototype.push.apply(arguments, arguments);
75    return arguments[0];
76}
77
78shouldBe("access_1(1, 2, 3)", "1");
79shouldBe("access_2(1, 2, 3)", "2");
80shouldBe("access_3(1, 2, 3)", "3");
81shouldBe("access_4(1, 2, 3)", "undefined");
82shouldBe("access_5(1, 2, 3)", "undefined");
83
84shouldBe("access_1(1)", "1");
85shouldBe("access_2(1)", "undefined");
86shouldBe("access_3(1)", "undefined");
87shouldBe("access_4(1)", "undefined");
88shouldBe("access_5(1)", "undefined");
89
90shouldBe("access_1(1, 2, 3, 4, 5)", "1");
91shouldBe("access_2(1, 2, 3, 4, 5)", "2");
92shouldBe("access_3(1, 2, 3, 4, 5)", "3");
93shouldBe("access_4(1, 2, 3, 4, 5)", "4");
94shouldBe("access_5(1, 2, 3, 4, 5)", "5");
95
96shouldBe("argumentLengthIs5()", "5");
97shouldBe("argumentLengthIs5(1,2,3,4,5)", "5");
98shouldBe("argumentLengthIs5(1,2,3,4,5,6,7,8,9,10)", "5");
99shouldBe("duplicateArgumentAndReturnLast_call(1)", "1");
100shouldBe("duplicateArgumentAndReturnFirst_call(1)", "1");
101shouldBe("duplicateArgumentAndReturnLast_apply(1)", "1");
102shouldBe("duplicateArgumentAndReturnFirst_apply(1)", "1");
103
104function f(a, b, c)
105{
106    return arguments;
107}
108
109function tear_off_equal_access_1(a, b, c)
110{
111    return f(a, b, c)[0];
112}
113
114function tear_off_equal_access_2(a, b, c)
115{
116    return f(a, b, c)[1];
117}
118
119function tear_off_equal_access_3(a, b, c)
120{
121    return f(a, b, c)[2];
122}
123
124function tear_off_equal_access_4(a, b, c)
125{
126    return f(a, b, c)[3];
127}
128
129function tear_off_equal_access_5(a, b, c)
130{
131    return f(a, b, c)[4];
132}
133
134shouldBe("tear_off_equal_access_1(1, 2, 3)", "1");
135shouldBe("tear_off_equal_access_2(1, 2, 3)", "2");
136shouldBe("tear_off_equal_access_3(1, 2, 3)", "3");
137shouldBe("tear_off_equal_access_4(1, 2, 3)", "undefined");
138shouldBe("tear_off_equal_access_5(1, 2, 3)", "undefined");
139
140function tear_off_too_few_access_1(a)
141{
142    return f(a)[0];
143}
144
145function tear_off_too_few_access_2(a)
146{
147    return f(a)[1];
148}
149
150function tear_off_too_few_access_3(a)
151{
152    return f(a)[2];
153}
154
155function tear_off_too_few_access_4(a)
156{
157    return f(a)[3];
158}
159
160function tear_off_too_few_access_5(a)
161{
162    return f(a)[4];
163}
164
165shouldBe("tear_off_too_few_access_1(1)", "1");
166shouldBe("tear_off_too_few_access_2(1)", "undefined");
167shouldBe("tear_off_too_few_access_3(1)", "undefined");
168shouldBe("tear_off_too_few_access_4(1)", "undefined");
169shouldBe("tear_off_too_few_access_5(1)", "undefined");
170
171function tear_off_too_many_access_1(a, b, c, d, e)
172{
173    return f(a, b, c, d, e)[0];
174}
175
176function tear_off_too_many_access_2(a, b, c, d, e)
177{
178    return f(a, b, c, d, e)[1];
179}
180
181function tear_off_too_many_access_3(a, b, c, d, e)
182{
183    return f(a, b, c, d, e)[2];
184}
185
186function tear_off_too_many_access_4(a, b, c, d, e)
187{
188    return f(a, b, c, d, e)[3];
189}
190
191function tear_off_too_many_access_5(a, b, c, d, e)
192{
193    return f(a, b, c, d, e)[4];
194}
195
196shouldBe("tear_off_too_many_access_1(1, 2, 3, 4, 5)", "1");
197shouldBe("tear_off_too_many_access_2(1, 2, 3, 4, 5)", "2");
198shouldBe("tear_off_too_many_access_3(1, 2, 3, 4, 5)", "3");
199shouldBe("tear_off_too_many_access_4(1, 2, 3, 4, 5)", "4");
200shouldBe("tear_off_too_many_access_5(1, 2, 3, 4, 5)", "5");
201
202function live_1(a, b, c)
203{
204    arguments[0] = 1;
205    return a;
206}
207
208function live_2(a, b, c)
209{
210    arguments[1] = 2;
211    return b;
212}
213
214function live_3(a, b, c)
215{
216    arguments[2] = 3;
217    return c;
218}
219
220shouldBe("live_1(0, 2, 3)", "1");
221shouldBe("live_2(1, 0, 3)", "2");
222shouldBe("live_3(1, 2, 0)", "3");
223
224// Arguments that were not provided are not live
225shouldBe("live_1(0)", "1");
226shouldBe("live_2(1)", "undefined");
227shouldBe("live_3(1)", "undefined");
228
229shouldBe("live_1(0, 2, 3, 4, 5)", "1");
230shouldBe("live_2(1, 0, 3, 4, 5)", "2");
231shouldBe("live_3(1, 2, 0, 4, 5)", "3");
232
233function extra_args_modify_4(a, b, c)
234{
235    arguments[3] = 4;
236    return arguments[3];
237}
238
239function extra_args_modify_5(a, b, c)
240{
241    arguments[4] = 5;
242    return arguments[4];
243}
244
245shouldBe("extra_args_modify_4(1, 2, 3, 0, 5)", "4");
246shouldBe("extra_args_modify_5(1, 2, 3, 4, 0)", "5");
247
248function tear_off_live_1(a, b, c)
249{
250    var args = arguments;
251    return function()
252    {
253        args[0] = 1;
254        return a;
255    };
256}
257
258function tear_off_live_2(a, b, c)
259{
260    var args = arguments;
261    return function()
262    {
263        args[1] = 2;
264        return b;
265    };
266}
267
268function tear_off_live_3(a, b, c)
269{
270    var args = arguments;
271    return function()
272    {
273        args[2] = 3;
274        return c;
275    };
276}
277
278shouldBe("tear_off_live_1(0, 2, 3)()", "1");
279shouldBe("tear_off_live_2(1, 0, 3)()", "2");
280shouldBe("tear_off_live_3(1, 2, 0)()", "3");
281
282// Arguments that were not provided are not live
283shouldBe("tear_off_live_1(0)()", "1");
284shouldBe("tear_off_live_2(1)()", "undefined");
285shouldBe("tear_off_live_3(1)()", "undefined");
286
287shouldBe("tear_off_live_1(0, 2, 3, 4, 5)()", "1");
288shouldBe("tear_off_live_2(1, 0, 3, 4, 5)()", "2");
289shouldBe("tear_off_live_3(1, 2, 0, 4, 5)()", "3");
290
291function tear_off_extra_args_modify_4(a, b, c)
292{
293    return function()
294    {
295        arguments[3] = 4;
296        return arguments[3];
297    }
298}
299
300function tear_off_extra_args_modify_5(a, b, c)
301{
302    return function()
303    {
304        arguments[4] = 5;
305        return arguments[4];
306    }
307}
308
309shouldBe("tear_off_extra_args_modify_4(1, 2, 3, 0, 5)()", "4");
310shouldBe("tear_off_extra_args_modify_5(1, 2, 3, 4, 0)()", "5");
311
312function delete_1(a, b, c)
313{
314    delete arguments[0];
315    return arguments[0];
316}
317
318function delete_2(a, b, c)
319{
320    delete arguments[1];
321    return arguments[1];
322}
323
324function delete_3(a, b, c)
325{
326    delete arguments[2];
327    return arguments[2];
328}
329
330function delete_4(a, b, c)
331{
332    delete arguments[3];
333    return arguments[3];
334}
335
336function delete_5(a, b, c)
337{
338    delete arguments[4];
339    return arguments[4];
340}
341
342shouldBe("delete_1(1, 2, 3)", "undefined");
343shouldBe("delete_2(1, 2, 3)", "undefined");
344shouldBe("delete_3(1, 2, 3)", "undefined");
345shouldBe("delete_4(1, 2, 3)", "undefined");
346shouldBe("delete_5(1, 2, 3)", "undefined");
347
348shouldBe("delete_1(1)", "undefined");
349shouldBe("delete_2(1)", "undefined");
350shouldBe("delete_3(1)", "undefined");
351shouldBe("delete_4(1)", "undefined");
352shouldBe("delete_5(1)", "undefined");
353
354shouldBe("delete_1(1, 2, 3, 4, 5)", "undefined");
355shouldBe("delete_2(1, 2, 3, 4, 5)", "undefined");
356shouldBe("delete_3(1, 2, 3, 4, 5)", "undefined");
357shouldBe("delete_4(1, 2, 3, 4, 5)", "undefined");
358shouldBe("delete_5(1, 2, 3, 4, 5)", "undefined");
359
360function tear_off_delete_1(a, b, c)
361{
362    return function()
363    {
364        delete arguments[0];
365        return arguments[0];
366    };
367}
368
369function tear_off_delete_2(a, b, c)
370{
371    return function()
372    {
373        delete arguments[1];
374        return arguments[1];
375    };
376}
377
378function tear_off_delete_3(a, b, c)
379{
380    return function()
381    {
382        delete arguments[2];
383        return arguments[2];
384    };
385}
386
387function tear_off_delete_4(a, b, c)
388{
389    return function()
390    {
391        delete arguments[3];
392        return arguments[3];
393    };
394}
395
396function tear_off_delete_5(a, b, c)
397{
398    return function()
399    {
400        delete arguments[4];
401        return arguments[4];
402    };
403}
404
405shouldBe("tear_off_delete_1(1, 2, 3)()", "undefined");
406shouldBe("tear_off_delete_2(1, 2, 3)()", "undefined");
407shouldBe("tear_off_delete_3(1, 2, 3)()", "undefined");
408shouldBe("tear_off_delete_4(1, 2, 3)()", "undefined");
409shouldBe("tear_off_delete_5(1, 2, 3)()", "undefined");
410
411shouldBe("tear_off_delete_1(1)()", "undefined");
412shouldBe("tear_off_delete_2(1)()", "undefined");
413shouldBe("tear_off_delete_3(1)()", "undefined");
414shouldBe("tear_off_delete_4(1)()", "undefined");
415shouldBe("tear_off_delete_5(1)()", "undefined");
416
417shouldBe("tear_off_delete_1(1, 2, 3, 4, 5)()", "undefined");
418shouldBe("tear_off_delete_2(1, 2, 3, 4, 5)()", "undefined");
419shouldBe("tear_off_delete_3(1, 2, 3, 4, 5)()", "undefined");
420shouldBe("tear_off_delete_4(1, 2, 3, 4, 5)()", "undefined");
421shouldBe("tear_off_delete_5(1, 2, 3, 4, 5)()", "undefined");
422
423function delete_not_live_1(a, b, c)
424{
425    delete arguments[0];
426    return a;
427}
428
429function delete_not_live_2(a, b, c)
430{
431    delete arguments[1];
432    return b;
433}
434
435function delete_not_live_3(a, b, c)
436{
437    delete arguments[2];
438    return c;
439}
440
441shouldBe("delete_not_live_1(1, 2, 3)", "1");
442shouldBe("delete_not_live_2(1, 2, 3)", "2");
443shouldBe("delete_not_live_3(1, 2, 3)", "3");
444
445shouldBe("delete_not_live_1(1)", "1");
446shouldBe("delete_not_live_2(1)", "undefined");
447shouldBe("delete_not_live_3(1)", "undefined");
448
449shouldBe("delete_not_live_1(1, 2, 3, 4, 5)", "1");
450shouldBe("delete_not_live_2(1, 2, 3, 4, 5)", "2");
451shouldBe("delete_not_live_3(1, 2, 3, 4, 5)", "3");
452
453function tear_off_delete_not_live_1(a, b, c)
454{
455    return function()
456    {
457        delete arguments[0];
458        return a;
459    };
460}
461
462function tear_off_delete_not_live_2(a, b, c)
463{
464    return function ()
465    {
466        delete arguments[1];
467        return b;
468    };
469}
470
471function tear_off_delete_not_live_3(a, b, c)
472{
473    return function()
474    {
475        delete arguments[2];
476        return c;
477    };
478}
479
480shouldBe("tear_off_delete_not_live_1(1, 2, 3)()", "1");
481shouldBe("tear_off_delete_not_live_2(1, 2, 3)()", "2");
482shouldBe("tear_off_delete_not_live_3(1, 2, 3)()", "3");
483
484shouldBe("tear_off_delete_not_live_1(1)()", "1");
485shouldBe("tear_off_delete_not_live_2(1)()", "undefined");
486shouldBe("tear_off_delete_not_live_3(1)()", "undefined");
487
488shouldBe("tear_off_delete_not_live_1(1, 2, 3, 4, 5)()", "1");
489shouldBe("tear_off_delete_not_live_2(1, 2, 3, 4, 5)()", "2");
490shouldBe("tear_off_delete_not_live_3(1, 2, 3, 4, 5)()", "3");
491
492function access_after_delete_named_2(a, b, c)
493{
494    delete arguments[0];
495    return b;
496}
497
498function access_after_delete_named_3(a, b, c)
499{
500    delete arguments[0];
501    return c;
502}
503
504function access_after_delete_named_4(a, b, c)
505{
506    delete arguments[0];
507    return arguments[3];
508}
509
510shouldBe("access_after_delete_named_2(1, 2, 3)", "2");
511shouldBe("access_after_delete_named_3(1, 2, 3)", "3");
512shouldBe("access_after_delete_named_4(1, 2, 3)", "undefined");
513
514shouldBe("access_after_delete_named_2(1)", "undefined");
515shouldBe("access_after_delete_named_3(1)", "undefined");
516shouldBe("access_after_delete_named_4(1)", "undefined");
517
518shouldBe("access_after_delete_named_2(1, 2, 3, 4)", "2");
519shouldBe("access_after_delete_named_3(1, 2, 3, 4)", "3");
520shouldBe("access_after_delete_named_4(1, 2, 3, 4)", "4");
521
522function access_after_delete_extra_1(a, b, c)
523{
524    delete arguments[3];
525    return a;
526}
527
528function access_after_delete_extra_2(a, b, c)
529{
530    delete arguments[3];
531    return b;
532}
533
534function access_after_delete_extra_3(a, b, c)
535{
536    delete arguments[3];
537    return c;
538}
539
540function access_after_delete_extra_5(a, b, c)
541{
542    delete arguments[3];
543    return arguments[4];
544}
545
546shouldBe("access_after_delete_extra_1(1, 2, 3)", "1");
547shouldBe("access_after_delete_extra_2(1, 2, 3)", "2");
548shouldBe("access_after_delete_extra_3(1, 2, 3)", "3");
549shouldBe("access_after_delete_extra_5(1, 2, 3)", "undefined");
550
551shouldBe("access_after_delete_extra_1(1)", "1");
552shouldBe("access_after_delete_extra_2(1)", "undefined");
553shouldBe("access_after_delete_extra_3(1)", "undefined");
554shouldBe("access_after_delete_extra_5(1)", "undefined");
555
556shouldBe("access_after_delete_extra_1(1, 2, 3, 4, 5)", "1");
557shouldBe("access_after_delete_extra_2(1, 2, 3, 4, 5)", "2");
558shouldBe("access_after_delete_extra_3(1, 2, 3, 4, 5)", "3");
559shouldBe("access_after_delete_extra_5(1, 2, 3, 4, 5)", "5");
560
561function argumentsParam(arguments)
562{
563    return arguments;
564}
565shouldBeTrue("argumentsParam(true)");
566
567var argumentsFunctionConstructorParam = new Function("arguments", "return arguments;");
568shouldBeTrue("argumentsFunctionConstructorParam(true)");
569
570function argumentsVarUndefined()
571{
572    var arguments;
573    return String(arguments);
574}
575shouldBe("argumentsVarUndefined()", "'[object Arguments]'");
576
577function argumentsConstUndefined()
578{
579    const arguments;
580    return String(arguments);
581}
582shouldBe("argumentsConstUndefined()", "'[object Arguments]'");
583
584function argumentCalleeInException() {
585    try {
586        throw "";
587    } catch (e) {
588        return arguments.callee;
589    }
590}
591shouldBe("argumentCalleeInException()", "argumentCalleeInException")
592
593function shadowedArgumentsApply(arguments) {
594    return function(a){ return a; }.apply(null, arguments);
595}
596
597function shadowedArgumentsLength(arguments) {
598    return arguments.length;
599}
600
601function shadowedArgumentsCallee(arguments) {
602    return arguments.callee;
603}
604
605function shadowedArgumentsIndex(arguments) {
606    return arguments[0]
607}
608
609shouldBeTrue("shadowedArgumentsApply([true])");
610shouldBe("shadowedArgumentsLength([])", '0');
611shouldThrow("shadowedArgumentsLength()");
612shouldBeUndefined("shadowedArgumentsCallee([])");
613shouldBeTrue("shadowedArgumentsIndex([true])");
614
615descriptor = (function(){ return Object.getOwnPropertyDescriptor(arguments, 1); })("zero","one","two");
616shouldBe("descriptor.value", '"one"');
617shouldBe("descriptor.writable", 'true');
618shouldBe("descriptor.enumerable", 'true');
619shouldBe("descriptor.configurable", 'true');
620
621// Test cases for [[DefineOwnProperty]] applied to the arguments object.
622(function(a0,a1,a2,a3){
623    Object.defineProperties(arguments, {
624        1: { get: function(){ return 201; } },
625        2: { value: 202, writable: false },
626        3: { writable: false },
627    });
628
629    // Test a0 is a live mapped argument.
630    shouldBeTrue(String( a0 === 100 ));
631    shouldBeTrue(String( arguments[0] === 100 ));
632    a0 = 300;
633    shouldBeTrue(String( a0 === 300 ));
634    shouldBeTrue(String( arguments[0] === 300 ));
635    arguments[0] = 400;
636    shouldBeTrue(String( a0 === 400 ));
637    shouldBeTrue(String( arguments[0] === 400 ));
638
639    // When a1 is redefined as an accessor, it is no longer live.
640    shouldBeTrue(String( a1 === 101 ));
641    shouldBeTrue(String( arguments[1] === 201 ));
642    a1 = 301;
643    shouldBeTrue(String( a1 === 301 ));
644    shouldBeTrue(String( arguments[1] === 201 ));
645    arguments[1] = 401;
646    shouldBeTrue(String( a1 === 301 ));
647    shouldBeTrue(String( arguments[1] === 201 ));
648
649    // When a2 is made read-only the value is set, but it is no longer live.
650    // (per 10.6 [[DefineOwnProperty]] 5.b.ii.1)
651    shouldBeTrue(String( a2 === 202 ));
652    shouldBeTrue(String( arguments[2] === 202 ));
653    a2 = 302;
654    shouldBeTrue(String( a2 === 302 ));
655    shouldBeTrue(String( arguments[2] === 202 ));
656    arguments[2] = 402;
657    shouldBeTrue(String( a2 === 302 ));
658    shouldBeTrue(String( arguments[2] === 202 ));
659
660    // When a3 is made read-only, it is no longer live.
661    // (per 10.6 [[DefineOwnProperty]] 5.b.ii.1)
662    shouldBeTrue(String( a3 === 103 ));
663    shouldBeTrue(String( arguments[3] === 103 ));
664    a3 = 303;
665    shouldBeTrue(String( a3 === 303 ));
666    shouldBeTrue(String( arguments[3] === 103 ));
667    arguments[3] = 403;
668    shouldBeTrue(String( a3 === 303 ));
669    shouldBeTrue(String( arguments[3] === 103 ));
670
671})(100,101,102,103);
672
673// Test cases for [[DefineOwnProperty]] applied to the arguments object.
674(function(arg){
675    shouldBeTrue(String( Object.getOwnPropertyDescriptor(arguments, 0).writable ));
676    shouldBeTrue(String( Object.getOwnPropertyDescriptor(arguments, 0).enumerable ));
677    Object.defineProperty(arguments, 0, { writable: false });
678    shouldBeFalse(String( Object.getOwnPropertyDescriptor(arguments, 0).writable ));
679    shouldBeTrue(String( Object.getOwnPropertyDescriptor(arguments, 0).enumerable ));
680    Object.defineProperty(arguments, 0, { enumerable: false });
681    shouldBeFalse(String( Object.getOwnPropertyDescriptor(arguments, 0).writable ));
682    shouldBeFalse(String( Object.getOwnPropertyDescriptor(arguments, 0).enumerable ));
683
684    delete arguments[1];
685    shouldBeUndefined(String( Object.getOwnPropertyDescriptor(arguments, 1) ));
686    Object.defineProperty(arguments, 1, { writable: true });
687    shouldBeTrue(String( Object.getOwnPropertyDescriptor(arguments, 1).writable ));
688    shouldBeFalse(String( Object.getOwnPropertyDescriptor(arguments, 1).enumerable ));
689})(0,1);
690