Home | History | Annotate | Download | only in mjsunit
      1 // Copyright 2010 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 // A test for keyed call ICs.
     29 
     30 var toStringName = 'toString';
     31 var global = this;
     32 
     33 function globalFunction1() {
     34   return 'function1';
     35 }
     36 
     37 function globalFunction2() {
     38   return 'function2';
     39 }
     40 
     41 assertEquals("[object global]", this[toStringName]());
     42 assertEquals("[object global]", global[toStringName]());
     43 
     44 function testGlobals() {
     45   assertEquals("[object global]", this[toStringName]());
     46   assertEquals("[object global]", global[toStringName]());
     47 }
     48 
     49 testGlobals();
     50 
     51 
     52 function F() {}
     53 
     54 F.prototype.one = function() {return 'one'; }
     55 F.prototype.two = function() {return 'two'; }
     56 F.prototype.three = function() {return 'three'; }
     57 
     58 var keys =
     59     ['one', 'one', 'one',  'one', 'two', 'two', 'one', 'three', 'one', 'two'];
     60 
     61 function testKeyTransitions() {
     62   var i, key, result, message;
     63 
     64   var f = new F();
     65 
     66   // Custom call generators
     67   var array = [];
     68   for (i = 0; i != 10; i++) {
     69     key = (i < 8) ? 'push' : 'pop';
     70     array[key](i);
     71   }
     72 
     73   assertEquals(6, array.length);
     74   for (i = 0; i != array.length; i++) {
     75     assertEquals(i, array[i]);
     76   }
     77 
     78   for (i = 0; i != 10; i++) {
     79     key = (i < 3) ? 'pop' : 'push';
     80     array[key](i);
     81   }
     82 
     83   assertEquals(10, array.length);
     84   for (i = 0; i != array.length; i++) {
     85     assertEquals(i, array[i]);
     86   }
     87 
     88   var string = 'ABCDEFGHIJ';
     89   for (i = 0; i != 10; i++) {
     90     key = ((i < 5) ? 'charAt' : 'charCodeAt');
     91     result = string[key](i);
     92     message = '\'' + string + '\'[\'' + key + '\'](' + i + ')';
     93     if (i < 5) {
     94       assertEquals(string.charAt(i), result, message);
     95     } else {
     96       assertEquals(string.charCodeAt(i), result, message);
     97     }
     98   }
     99 
    100   for (i = 0; i != 10; i++) {
    101     key = ((i < 5) ? 'charCodeAt' : 'charAt');
    102     result = string[key](i);
    103     message = '\'' + string + '\'[\'' + key + '\'](' + i + ')';
    104     if (i < 5) {
    105       assertEquals(string.charCodeAt(i), result, message);
    106     } else {
    107       assertEquals(string.charAt(i), result, message);
    108     }
    109   }
    110 
    111   // Function is a constant property
    112   key = 'one';
    113   for (i = 0; i != 10; i++) {
    114     assertEquals(key, f[key]());
    115     if (i == 5) {
    116       key = 'two';  // the name change should case a miss
    117     }
    118   }
    119 
    120   // Function is a fast property
    121   f.field = function() { return 'field'; }
    122   key = 'field';
    123   for (i = 0; i != 10; i++) {
    124     assertEquals(key, f[key]());
    125     if (i == 5) {
    126       key = 'two';  // the name change should case a miss
    127     }
    128   }
    129 
    130   // Calling on slow case object
    131   f.prop = 0;
    132   delete f.prop; // force the object to the slow case
    133   f.four = function() { return 'four'; }
    134   f.five = function() { return 'five'; }
    135 
    136   key = 'four';
    137   for (i = 0; i != 10; i++) {
    138     assertEquals(key, f[key]());
    139     if (i == 5) {
    140       key = 'five';
    141     }
    142   }
    143 
    144   // Calling on global object
    145   key = 'globalFunction1';
    146   var expect = 'function1';
    147   for (i = 0; i != 10; i++) {
    148     assertEquals(expect, global[key]());
    149     if (i == 5) {
    150       key = 'globalFunction2';
    151       expect = 'function2';
    152     }
    153   }
    154 }
    155 
    156 testKeyTransitions();
    157 
    158 function testTypeTransitions() {
    159   var f = new F();
    160   var s = '';
    161   var m = 'one';
    162   var i;
    163 
    164   s = '';
    165   for (i = 0; i != 10; i++) {
    166     if (i == 5)  { F.prototype.one = function() { return '1'; } }
    167     s += f[m]();
    168   }
    169   assertEquals("oneoneoneoneone11111", s);
    170 
    171   s = '';
    172   for (i = 0; i != 10; i++) {
    173     if (i == 5)  { f.__proto__ = { one: function() { return 'I'; } } }
    174     s += f[m]();
    175   }
    176   assertEquals("11111IIIII", s);
    177 
    178   s = '';
    179   for (i = 0; i != 10; i++) {
    180     if (i == 5)  { f.one = function() { return 'ONE'; } }
    181     s += f[m]();
    182   }
    183   assertEquals("IIIIIONEONEONEONEONE", s);
    184 
    185   m = 'toString';
    186 
    187   s = '';
    188   var obj = { toString: function() { return '2'; } };
    189   for (i = 0; i != 10; i++) {
    190     if (i == 5)  { obj = "TWO"; }
    191     s += obj[m]();
    192   }
    193   assertEquals("22222TWOTWOTWOTWOTWO", s);
    194 
    195   s = '';
    196   obj = { toString: function() { return 'ONE'; } };
    197   m = 'toString';
    198   for (i = 0; i != 10; i++) {
    199     if (i == 5)  { obj = 1; }
    200     s += obj[m]();
    201   }
    202   assertEquals("ONEONEONEONEONE11111", s);
    203 }
    204 
    205 testTypeTransitions();
    206