13e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// Copyright 2009 the V8 project authors. All rights reserved.
23e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// Redistribution and use in source and binary forms, with or without
33e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// modification, are permitted provided that the following conditions are
43e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// met:
53e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org//
63e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org//     * Redistributions of source code must retain the above copyright
73e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org//       notice, this list of conditions and the following disclaimer.
83e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org//     * Redistributions in binary form must reproduce the above
93e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org//       copyright notice, this list of conditions and the following
103e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org//       disclaimer in the documentation and/or other materials provided
113e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org//       with the distribution.
123e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org//     * Neither the name of Google Inc. nor the names of its
133e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org//       contributors may be used to endorse or promote products derived
143e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org//       from this software without specific prior written permission.
153e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org//
163e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
283e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgfunction ReturnArguments() {
293e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  return arguments;
303e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org}
313e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
323e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgfunction ReturnReceiver() {
333e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  return this;
343e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org}
353e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
363e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
373e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgfunction Global() {
383e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  return ReturnArguments.apply(this, arguments);
393e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org}
403e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
413e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(0, Global().length);
423e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(1, Global(1).length);
433e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(2, Global(2)[0]);
443e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(2, Global(3, 4).length);
453e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(3, Global(3, 4)[0]);
463e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(4, Global(3, 4)[1]);
473e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
483e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
493e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgfunction Local() {
503e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  var object = { f: ReturnArguments };
513e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  return object.f.apply(this, arguments);
523e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org}
533e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
543e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(0, Local().length);
553e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(1, Local(1).length);
563e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(2, Local(2)[0]);
573e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(2, Local(3, 4).length);
583e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(3, Local(3, 4)[0]);
593e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(4, Local(3, 4)[1]);
603e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
613e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
623e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgfunction ShadowArguments() {
633e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  var arguments = [3, 4];
643e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  return ReturnArguments.apply(this, arguments);
653e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org}
663e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
673e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(2, ShadowArguments().length);
683e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(3, ShadowArguments()[0]);
693e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(4, ShadowArguments()[1]);
703e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
713e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
723e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgfunction NonObjectReceiver(receiver) {
733e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  return ReturnReceiver.apply(receiver, arguments);
743e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org}
753e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
76160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.orgassertEquals(Object(42), NonObjectReceiver(42));
773e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals("object", typeof NonObjectReceiver(42));
78160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.orgassertInstanceof(NonObjectReceiver(42), Number);
79160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.orgassertSame(this, NonObjectReceiver(null));
80160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.orgassertSame(this, NonObjectReceiver(void 0));
813e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
823e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
833e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgfunction FunctionReceiver() {
843e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  return ReturnReceiver.apply(Object, arguments);
853e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org}
863e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
873e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertTrue(Object === FunctionReceiver());
883e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
893e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
903e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgfunction ShadowApply() {
913e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  function f() { return 42; }
923e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  f.apply = function() { return 87; }
933e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  return f.apply(this, arguments);
943e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org}
953e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
963e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(87, ShadowApply());
973e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(87, ShadowApply(1));
983e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(87, ShadowApply(1, 2));
993e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
1003e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
1013e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgfunction CallNonFunction() {
1023e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  var object = { apply: Function.prototype.apply };
1033e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  return object.apply(this, arguments);
1043e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org}
1053e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
1063e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertThrows(CallNonFunction, TypeError);
1073e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
1083e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
1093e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// Make sure that the stack after the apply optimization is
1103e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// in a valid state.
1113e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgfunction SimpleStackCheck() {
1123e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  var sentinel = 42;
1133e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  var result = ReturnArguments.apply(this, arguments);
1143e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  assertTrue(result != null);
1153e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  assertEquals(42, sentinel);
1163e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org}
1173e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
1183e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgSimpleStackCheck();
1193e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
1203e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
1213e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgfunction ShadowArgumentsWithConstant() {
1223e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  var arguments = null;
1233e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  return ReturnArguments.apply(this, arguments);
1243e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org}
1253e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
1263e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(0, ShadowArgumentsWithConstant().length);
1273e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(0, ShadowArgumentsWithConstant(1).length);
1283e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(0, ShadowArgumentsWithConstant(1, 2).length);
1293e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
1303e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org
1313e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// Make sure we can deal with unfolding lots of arguments on the
1323e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org// stack even in the presence of the apply optimizations.
1333e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgvar array = new Array(2048);
1343e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgassertEquals(2048, Global.apply(this, array).length);
135