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