Home | History | Annotate | Download | only in mjsunit
      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 
     28 function ReturnArguments() {
     29   return arguments;
     30 }
     31 
     32 function ReturnReceiver() {
     33   return this;
     34 }
     35 
     36 
     37 function Global() {
     38   return ReturnArguments.apply(this, arguments);
     39 }
     40 
     41 assertEquals(0, Global().length);
     42 assertEquals(1, Global(1).length);
     43 assertEquals(2, Global(2)[0]);
     44 assertEquals(2, Global(3, 4).length);
     45 assertEquals(3, Global(3, 4)[0]);
     46 assertEquals(4, Global(3, 4)[1]);
     47 
     48 
     49 function Local() {
     50   var object = { f: ReturnArguments };
     51   return object.f.apply(this, arguments);
     52 }
     53 
     54 assertEquals(0, Local().length);
     55 assertEquals(1, Local(1).length);
     56 assertEquals(2, Local(2)[0]);
     57 assertEquals(2, Local(3, 4).length);
     58 assertEquals(3, Local(3, 4)[0]);
     59 assertEquals(4, Local(3, 4)[1]);
     60 
     61 
     62 function ShadowArguments() {
     63   var arguments = [3, 4];
     64   return ReturnArguments.apply(this, arguments);
     65 }
     66 
     67 assertEquals(2, ShadowArguments().length);
     68 assertEquals(3, ShadowArguments()[0]);
     69 assertEquals(4, ShadowArguments()[1]);
     70 
     71 
     72 function NonObjectReceiver(receiver) {
     73   return ReturnReceiver.apply(receiver, arguments);
     74 }
     75 
     76 assertEquals(42, NonObjectReceiver(42));
     77 assertEquals("object", typeof NonObjectReceiver(42));
     78 assertTrue(NonObjectReceiver(42) instanceof Number);
     79 assertTrue(this === NonObjectReceiver(null));
     80 assertTrue(this === NonObjectReceiver(void 0));
     81 
     82 
     83 function FunctionReceiver() {
     84   return ReturnReceiver.apply(Object, arguments);
     85 }
     86 
     87 assertTrue(Object === FunctionReceiver());
     88 
     89 
     90 function ShadowApply() {
     91   function f() { return 42; }
     92   f.apply = function() { return 87; }
     93   return f.apply(this, arguments);
     94 }
     95 
     96 assertEquals(87, ShadowApply());
     97 assertEquals(87, ShadowApply(1));
     98 assertEquals(87, ShadowApply(1, 2));
     99 
    100 
    101 function CallNonFunction() {
    102   var object = { apply: Function.prototype.apply };
    103   return object.apply(this, arguments);
    104 }
    105 
    106 assertThrows(CallNonFunction, TypeError);
    107 
    108 
    109 // Make sure that the stack after the apply optimization is
    110 // in a valid state.
    111 function SimpleStackCheck() {
    112   var sentinel = 42;
    113   var result = ReturnArguments.apply(this, arguments);
    114   assertTrue(result != null);
    115   assertEquals(42, sentinel);
    116 }
    117 
    118 SimpleStackCheck();
    119 
    120 
    121 function ShadowArgumentsWithConstant() {
    122   var arguments = null;
    123   return ReturnArguments.apply(this, arguments);
    124 }
    125 
    126 assertEquals(0, ShadowArgumentsWithConstant().length);
    127 assertEquals(0, ShadowArgumentsWithConstant(1).length);
    128 assertEquals(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.
    133 var array = new Array(2048);
    134 assertEquals(2048, Global.apply(this, array).length);
    135