blob: 14a65646b3c7134d346c09971a304b5dd954bc73 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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('Tests to ensure that Function.apply works correctly for Arrays, arguments and array-like objects.');
25
26function argumentsApply1(a, b, c)
27{
28 function t(a, b, c)
29 {
30 return a;
31 }
32 return t.apply(null, arguments);
33}
34
35function argumentsApply2(a, b, c)
36{
37 function t(a, b, c)
38 {
39 return b;
40 }
41 return t.apply(null, arguments);
42}
43
44function argumentsApply3(a, b, c)
45{
46 function t(a, b, c)
47 {
48 return c;
49 }
50 return t.apply(null, arguments);
51}
52
53function argumentsApplyLength(a, b, c)
54{
55 function t(a, b, c)
56 {
57 return arguments.length;
58 }
59 return t.apply(null, arguments);
60}
61var executedAdditionalArgument = false;
62function argumentsApplyExcessArguments(a, b, c)
63{
64 function t(a, b, c)
65 {
66 return arguments.length;
67 }
68 return t.apply(null, arguments, executedAdditionalArgument = true);
69}
70
71shouldBe("argumentsApply1(1, 2, 3)", "1");
72shouldBe("argumentsApply2(1, 2, 3)", "2");
73shouldBe("argumentsApply3(1, 2, 3)", "3");
74shouldBe("argumentsApplyLength(1, 2, 3)", "3");
75shouldBe("argumentsApplyExcessArguments(1, 2, 3)", "3");
76shouldBeTrue("executedAdditionalArgument");
77
78function arrayApply1(array)
79{
80 function t(a, b, c)
81 {
82 return a;
83 }
84 return t.apply(null, array);
85}
86
87function arrayApply2(array)
88{
89 function t(a, b, c)
90 {
91 return b;
92 }
93 return t.apply(null, array);
94}
95
96function arrayApply3(array)
97{
98 function t(a, b, c)
99 {
100 return c;
101 }
102 return t.apply(null, array);
103}
104
105function arrayApplyLength(array)
106{
107 function t(a, b, c)
108 {
109 return arguments.length;
110 }
111 return t.apply(null, array);
112}
113
114shouldBe("arrayApply1([1, 2, 3])", "1");
115shouldBe("arrayApply2([1, 2, 3])", "2");
116shouldBe("arrayApply3([1, 2, 3])", "3");
117shouldBe("arrayApplyLength([1, 2, 3])", "3");
118
119
120function argumentsApplyDelete1(a, b, c)
121{
122 function t(a, b, c)
123 {
124 return a;
125 }
126 delete arguments[1];
127 return t.apply(null, arguments);
128}
129
130function argumentsApplyDelete2(a, b, c)
131{
132 function t(a, b, c)
133 {
134 return b;
135 }
136 delete arguments[1];
137 return t.apply(null, arguments);
138}
139
140function argumentsApplyDelete3(a, b, c)
141{
142 function t(a, b, c)
143 {
144 return c;
145 }
146 delete arguments[1];
147 return t.apply(null, arguments);
148}
149
150function argumentsApplyDeleteLength(a, b, c)
151{
152 function t(a, b, c)
153 {
154 return arguments.length;
155 }
156 delete arguments[1];
157 return t.apply(null, arguments);
158}
159
160shouldBe("argumentsApplyDelete1(1, 2, 3)", "1");
161shouldBe("argumentsApplyDelete2(1, 2, 3)", "undefined");
162shouldBe("argumentsApplyDelete3(1, 2, 3)", "3");
163shouldBe("argumentsApplyDeleteLength(1, 2, 3)", "3");
164
165
166function arrayApplyDelete1(array)
167{
168 function t(a, b, c)
169 {
170 return a;
171 }
172 delete array[1];
173 return t.apply(null, array);
174}
175
176function arrayApplyDelete2(array)
177{
178 function t(a, b, c)
179 {
180 return b;
181 }
182 delete array[1];
183 return t.apply(null, array);
184}
185
186function arrayApplyDelete3(array)
187{
188 function t(a, b, c)
189 {
190 return c;
191 }
192 delete array[1];
193 return t.apply(null, array);
194}
195
196function arrayApplyDeleteLength(array)
197{
198 function t(a, b, c)
199 {
200 return arguments.length;
201 }
202 delete array[1];
203 return t.apply(null, array);
204}
205
206shouldBe("arrayApplyDelete1([1, 2, 3])", "1");
207shouldBe("arrayApplyDelete2([1, 2, 3])", "undefined");
208shouldBe("arrayApplyDelete3([1, 2, 3])", "3");
209shouldBe("arrayApplyDeleteLength([1, 2, 3])", "3");
210
211
212function argumentsApplyChangeLength1()
213{
214 function f() {
215 return arguments.length;
216 };
217 arguments.length = 2;
218 return f.apply(null, arguments);
219}
220
221
222function argumentsApplyChangeLength2()
223{
224 function f(a) {
225 return arguments.length;
226 };
227 arguments.length = 2;
228 return f.apply(null, arguments);
229}
230
231
232function argumentsApplyChangeLength3()
233{
234 function f(a, b, c) {
235 return arguments.length;
236 };
237 arguments.length = 2;
238 return f.apply(null, arguments);
239};
240
241function argumentsApplyChangeLength4()
242{
243 function f() {
244 return arguments.length;
245 };
246 arguments.length = 0;
247 return f.apply(null, arguments);
248};
249
250function argumentsApplyChangeLength5()
251{
252 function f() {
253 return arguments.length;
254 };
255 arguments.length = "Not A Number";
256 return f.apply(null, arguments);
257}
258
259shouldBe("argumentsApplyChangeLength1(1)", "2");
260shouldBe("argumentsApplyChangeLength2(1)", "2");
261shouldBe("argumentsApplyChangeLength3(1)", "2");
262shouldBe("argumentsApplyChangeLength4(1)", "0");
263shouldBe("argumentsApplyChangeLength5(1)", "0");
264
265function arrayApplyChangeLength1()
266{
267 function f() {
268 return arguments.length;
269 };
270 var array = [];
271 array.length = 2;
272 return f.apply(null, array);
273}
274
275function arrayApplyChangeLength2()
276{
277 function f(a) {
278 return arguments.length;
279 };
280 var array = [];
281 array.length = 2;
282 return f.apply(null, array);
283}
284
285function arrayApplyChangeLength3()
286{
287 function f(a, b, c) {
288 return arguments.length;
289 };
290 var array = [];
291 array.length = 2;
292 return f.apply(null, array);
293}
294
295function arrayApplyChangeLength4()
296{
297 function f() {
298 return arguments.length;
299 };
300 var array = [1];
301 array.length = 0;
302 return f.apply(null, array);
303};
304
305shouldBe("arrayApplyChangeLength1()", "2");
306shouldBe("arrayApplyChangeLength2()", "2");
307shouldBe("arrayApplyChangeLength3()", "2");
308shouldBe("arrayApplyChangeLength4()", "0");
309
310shouldBe("var a = []; a.length = 0xFFFE; [].constructor.apply('', a).length", "0xFFFE");
311shouldBe("var a = []; a.length = 0xFFFF; [].constructor.apply('', a).length", "0xFFFF");
312shouldBe("var a = []; a.length = 0x10000; [].constructor.apply('', a).length", "0x10000");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000313shouldBe("var a = []; a.length = 0x10001; [].constructor.apply('', a).length", "0x10001");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000314shouldThrow("var a = []; a.length = 0xFFFFFFFE; [].constructor.apply('', a).length");
315shouldThrow("var a = []; a.length = 0xFFFFFFFF; [].constructor.apply('', a).length");
316
317// ES5 permits apply with array-like objects.
318shouldBe("(function(a,b,c,d){ return d ? -1 : (a+b+c); }).apply(undefined, {length:3, 0:100, 1:20, 2:3})", '123');