1// Copyright 2009 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28function ReturnArguments() { 29 return arguments; 30} 31 32function ReturnReceiver() { 33 return this; 34} 35 36 37function Global() { 38 return ReturnArguments.apply(this, arguments); 39} 40 41assertEquals(0, Global().length); 42assertEquals(1, Global(1).length); 43assertEquals(2, Global(2)[0]); 44assertEquals(2, Global(3, 4).length); 45assertEquals(3, Global(3, 4)[0]); 46assertEquals(4, Global(3, 4)[1]); 47 48 49function Local() { 50 var object = { f: ReturnArguments }; 51 return object.f.apply(this, arguments); 52} 53 54assertEquals(0, Local().length); 55assertEquals(1, Local(1).length); 56assertEquals(2, Local(2)[0]); 57assertEquals(2, Local(3, 4).length); 58assertEquals(3, Local(3, 4)[0]); 59assertEquals(4, Local(3, 4)[1]); 60 61 62function ShadowArguments() { 63 var arguments = [3, 4]; 64 return ReturnArguments.apply(this, arguments); 65} 66 67assertEquals(2, ShadowArguments().length); 68assertEquals(3, ShadowArguments()[0]); 69assertEquals(4, ShadowArguments()[1]); 70 71 72function NonObjectReceiver(receiver) { 73 return ReturnReceiver.apply(receiver, arguments); 74} 75 76assertEquals(Object(42), NonObjectReceiver(42)); 77assertEquals("object", typeof NonObjectReceiver(42)); 78assertInstanceof(NonObjectReceiver(42), Number); 79assertSame(this, NonObjectReceiver(null)); 80assertSame(this, NonObjectReceiver(void 0)); 81 82 83function FunctionReceiver() { 84 return ReturnReceiver.apply(Object, arguments); 85} 86 87assertTrue(Object === FunctionReceiver()); 88 89 90function ShadowApply() { 91 function f() { return 42; } 92 f.apply = function() { return 87; } 93 return f.apply(this, arguments); 94} 95 96assertEquals(87, ShadowApply()); 97assertEquals(87, ShadowApply(1)); 98assertEquals(87, ShadowApply(1, 2)); 99 100 101function CallNonFunction() { 102 var object = { apply: Function.prototype.apply }; 103 return object.apply(this, arguments); 104} 105 106assertThrows(CallNonFunction, TypeError); 107 108 109// Make sure that the stack after the apply optimization is 110// in a valid state. 111function SimpleStackCheck() { 112 var sentinel = 42; 113 var result = ReturnArguments.apply(this, arguments); 114 assertTrue(result != null); 115 assertEquals(42, sentinel); 116} 117 118SimpleStackCheck(); 119 120 121function ShadowArgumentsWithConstant() { 122 var arguments = null; 123 return ReturnArguments.apply(this, arguments); 124} 125 126assertEquals(0, ShadowArgumentsWithConstant().length); 127assertEquals(0, ShadowArgumentsWithConstant(1).length); 128assertEquals(0, ShadowArgumentsWithConstant(1, 2).length); 129 130 131// Make sure we can deal with unfolding lots of arguments on the 132// stack even in the presence of the apply optimizations. 133var array = new Array(2048); 134assertEquals(2048, Global.apply(this, array).length); 135