1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2008 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction f0() {
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return this;
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction f1(a) {
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return a;
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
36257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertSame(this, f0.apply(), "1-0");
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
38257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertSame(this, f0.apply(this), "2a");
39257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertSame(this, f0.apply(this, new Array(1)), "2b");
40257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertSame(this, f0.apply(this, new Array(2)), "2c");
41257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertSame(this, f0.apply(this, new Array(4242)), "2d");
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
43257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertSame(this, f0.apply(null), "3a");
44257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertSame(this, f0.apply(null, new Array(1)), "3b");
45257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertSame(this, f0.apply(null, new Array(2)), "3c");
46257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertSame(this, f0.apply(this, new Array(4242)), "3d");
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
48257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertSame(this, f0.apply(void 0), "4a");
49257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertSame(this, f0.apply(void 0, new Array(1)), "4b");
50257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertSame(this, f0.apply(void 0, new Array(2)), "4c");
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
52257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertEquals(void 0, f1.apply(), "1-1");
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
54257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertEquals(void 0, f1.apply(this), "5a");
55257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertEquals(void 0, f1.apply(this, new Array(1)), "5b");
56257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertEquals(void 0, f1.apply(this, new Array(2)), "5c");
57257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertEquals(void 0, f1.apply(this, new Array(4242)), "5d");
58257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertEquals(42, f1.apply(this, new Array(42, 43)), "5e");
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals("foo", f1.apply(this, new Array("foo", "bar", "baz", "bo")), "5f");
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
61257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertEquals(void 0, f1.apply(null), "6a");
62257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertEquals(void 0, f1.apply(null, new Array(1)), "6b");
63257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertEquals(void 0, f1.apply(null, new Array(2)), "6c");
64257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertEquals(void 0, f1.apply(null, new Array(4242)), "6d");
65257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertEquals(42, f1.apply(null, new Array(42, 43)), "6e");
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals("foo", f1.apply(null, new Array("foo", "bar", "baz", "bo")), "6f");
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
68257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertEquals(void 0, f1.apply(void 0), "7a");
69257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertEquals(void 0, f1.apply(void 0, new Array(1)), "7b");
70257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertEquals(void 0, f1.apply(void 0, new Array(2)), "7c");
71257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertEquals(void 0, f1.apply(void 0, new Array(4242)), "7d");
72257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochassertEquals(42, f1.apply(void 0, new Array(42, 43)), "7e");
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals("foo", f1.apply(void 0, new Array("foo", "bar", "ba", "b")), "7f");
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvar arr = new Array(42, "foo", "fish", "horse");
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction j(a, b, c, d, e, f, g, h, i, j, k, l) {
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return "" + a + b + c + d + e + f + g + h + i + j + k + l;
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvar expect = "42foofishhorse";
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfor (var i = 0; i < 8; i++)
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  expect += "undefined";
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals(expect, j.apply(undefined, arr), "apply to undefined");
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertThrows("f0.apply(this, 1);");
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertThrows("f0.apply(this, 1, 2);");
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertThrows("f0.apply(this, 1, new Array(2));");
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction f() {
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var doo = "";
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (var i = 0; i < arguments.length; i++) {
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    doo += arguments[i];
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return doo;
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
973bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals("42foofishhorse", f.apply(this, arr), "apply to this");
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction s() {
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var doo = this;
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (var i = 0; i < arguments.length; i++) {
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    doo += arguments[i];
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return doo;
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals("bar42foofishhorse", s.apply("bar", arr), "apply to string");
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction al() {
111257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  assertEquals(Object(345), this);
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return arguments.length + arguments[arguments.length - 1];
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfor (var j = 1; j < 0x40000000; j <<= 1) {
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  try {
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var a = new Array(j);
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    a[j - 1] = 42;
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    assertEquals(42 + j, al.apply(345, a));
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } catch (e) {
1213bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    assertTrue(e.toString().indexOf("Maximum call stack size exceeded") != -1);
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (; j < 0x40000000; j <<= 1) {
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      var caught = false;
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      try {
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        a = new Array(j);
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        a[j - 1] = 42;
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        al.apply(345, a);
1289dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen        assertUnreachable("Apply of array with length " + a.length +
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          " should have thrown");
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      } catch (e) {
1313bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch        assertTrue(e.toString().indexOf("Maximum call stack size exceeded") != -1);
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        caught = true;
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      assertTrue(caught, "exception not caught");
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    break;
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvar primes = new Array(0);
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction isPrime(possible_prime) {
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (var d = 0; d < primes.length; d++) {
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var p = primes[d];
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (possible_prime % p == 0)
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return false;
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (p * p > possible_prime)
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return true;
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return true;
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfor (var i = 2; i < 10000; i++) {
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (isPrime(i)) {
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    primes.push(i);
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals(1229, primes.length);
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvar same_primes = Array.prototype.constructor.apply(Array, primes);
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfor (var i = 0; i < primes.length; i++)
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  assertEquals(primes[i], same_primes[i], "prime" + primes[i]);
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals(primes.length, same_primes.length, "prime-length");
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockArray.prototype["1"] = "sep";
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvar holey = new Array(3);
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockholey[0] = "mor";
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockholey[2] = "er";
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals("morseper", String.prototype.concat.apply("", holey),
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             "moreseper0");
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals("morseper", String.prototype.concat.apply("", holey, 1),
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             "moreseper1");
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals("morseper", String.prototype.concat.apply("", holey, 1, 2),
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             "moreseper2");
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals("morseper", String.prototype.concat.apply("", holey, 1, 2, 3),
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             "morseper3");
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals("morseper", String.prototype.concat.apply("", holey, 1, 2, 3, 4),
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             "morseper4");
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockprimes[0] = "";
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockprimes[1] = holey;
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertThrows("String.prototype.concat.apply.apply('foo', primes)");
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockassertEquals("morseper",
189257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    String.prototype.concat.apply.apply(String.prototype.concat, primes),
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "moreseper-prime");
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdelete(Array.prototype["1"]);
1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Check correct handling of non-array argument lists.
1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochassertSame(this, f0.apply(this, {}), "non-array-1");
1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochassertSame(this, f0.apply(this, { length:1 }), "non-array-2");
1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochassertEquals(void 0, f1.apply(this, { length:1 }), "non-array-3");
1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochassertEquals(void 0, f1.apply(this, { 0:"foo" }), "non-array-4");
1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochassertEquals("foo", f1.apply(this, { length:1, 0:"foo" }), "non-array-5");
200