| // Copyright 2008 the V8 project authors. All rights reserved. | 
 | // Redistribution and use in source and binary forms, with or without | 
 | // modification, are permitted provided that the following conditions are | 
 | // met: | 
 | // | 
 | //     * Redistributions of source code must retain the above copyright | 
 | //       notice, this list of conditions and the following disclaimer. | 
 | //     * Redistributions in binary form must reproduce the above | 
 | //       copyright notice, this list of conditions and the following | 
 | //       disclaimer in the documentation and/or other materials provided | 
 | //       with the distribution. | 
 | //     * Neither the name of Google Inc. nor the names of its | 
 | //       contributors may be used to endorse or promote products derived | 
 | //       from this software without specific prior written permission. | 
 | // | 
 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
 |  | 
 | // This test attempts to test the inline caching for keyed access. | 
 |  | 
 | // ---------------------------------------------------------------------- | 
 | // Prototype accessor. | 
 | // ---------------------------------------------------------------------- | 
 | var runTest = function() { | 
 |   var initial_P = 'prototype'; | 
 |   var P = initial_P; | 
 |   var H = 'hasOwnProperty'; | 
 |  | 
 |   var f = function() {}; | 
 |  | 
 |   function prototypeTest(change_index) { | 
 |     for (var i = 0; i < 10; i++) { | 
 |       var property = f[P]; | 
 |       if (i <= change_index) { | 
 |         assertEquals(f.prototype, property); | 
 |       } else { | 
 |         assertEquals(f.hasOwnProperty, property); | 
 |       } | 
 |       if (i == change_index) P = H; | 
 |     } | 
 |     P = initial_P; | 
 |   } | 
 |  | 
 |   for (var i = 0; i < 10; i++) prototypeTest(i); | 
 |  | 
 |   f.prototype = 43; | 
 |  | 
 |   for (var i = 0; i < 10; i++) prototypeTest(i); | 
 | } | 
 |  | 
 | runTest(); | 
 |  | 
 | // ---------------------------------------------------------------------- | 
 | // Array length accessor. | 
 | // ---------------------------------------------------------------------- | 
 | runTest = function() { | 
 |   var initial_L = 'length'; | 
 |   var L = initial_L; | 
 |   var zero = '0'; | 
 |  | 
 |   var a = new Array(10); | 
 |  | 
 |   function arrayLengthTest(change_index) { | 
 |     for (var i = 0; i < 10; i++) { | 
 |       var l = a[L]; | 
 |       if (i <= change_index) { | 
 |         assertEquals(10, l); | 
 |       } else { | 
 |         assertEquals(undefined, l); | 
 |       } | 
 |       if (i == change_index) L = zero; | 
 |     } | 
 |     L = initial_L; | 
 |   } | 
 |  | 
 |   for (var i = 0; i < 10; i++) arrayLengthTest(i); | 
 | } | 
 |  | 
 | runTest(); | 
 |  | 
 | // ---------------------------------------------------------------------- | 
 | // String length accessor. | 
 | // ---------------------------------------------------------------------- | 
 | runTest = function() { | 
 |   var initial_L = 'length'; | 
 |   var L = initial_L; | 
 |   var zero = '0'; | 
 |  | 
 |   var s = "asdf" | 
 |  | 
 |   function stringLengthTest(change_index) { | 
 |     for (var i = 0; i < 10; i++) { | 
 |       var l = s[L]; | 
 |       if (i <= change_index) { | 
 |         assertEquals(4, l); | 
 |       } else { | 
 |         assertEquals('a', l); | 
 |       } | 
 |       if (i == change_index) L = zero; | 
 |     } | 
 |     L = initial_L; | 
 |   } | 
 |  | 
 |   for (var i = 0; i < 10; i++) stringLengthTest(i); | 
 | } | 
 |  | 
 | runTest(); | 
 |  | 
 | // ---------------------------------------------------------------------- | 
 | // Field access. | 
 | // ---------------------------------------------------------------------- | 
 | runTest = function() { | 
 |   var o = { x: 42, y: 43 } | 
 |  | 
 |   var initial_X = 'x'; | 
 |   var X = initial_X; | 
 |   var Y = 'y'; | 
 |  | 
 |   function fieldTest(change_index) { | 
 |     for (var i = 0; i < 10; i++) { | 
 |       var property = o[X]; | 
 |       if (i <= change_index) { | 
 |         assertEquals(42, property); | 
 |       } else { | 
 |         assertEquals(43, property); | 
 |       } | 
 |       if (i == change_index) X = Y; | 
 |     } | 
 |     X = initial_X; | 
 |   }; | 
 |  | 
 |   for (var i = 0; i < 10; i++) fieldTest(i); | 
 | } | 
 |  | 
 | runTest(); | 
 |  | 
 |  | 
 | // ---------------------------------------------------------------------- | 
 | // Indexed access. | 
 | // ---------------------------------------------------------------------- | 
 | runTest = function() { | 
 |   var o = [ 42, 43 ]; | 
 |  | 
 |   function test(o) { | 
 |     var initial_X = 0; | 
 |     var X = initial_X; | 
 |     var Y = 1; | 
 |  | 
 |     function fieldTest(change_index) { | 
 |       for (var i = 0; i < 10; i++) { | 
 |         var property = o[X]; | 
 |         if (i <= change_index) { | 
 |           assertEquals(42, property); | 
 |         } else { | 
 |           assertEquals(43, property); | 
 |         } | 
 |         if (i == change_index) X = Y; | 
 |       } | 
 |       X = initial_X; | 
 |     }; | 
 |  | 
 |     for (var i = 0; i < 10; i++) fieldTest(i); | 
 |   } | 
 |   test(o); | 
 |  | 
 |   // Non-extensible | 
 |   var b =  Object.preventExtensions(o); | 
 |   test(b); | 
 |  | 
 |   // Sealed | 
 |   var c =  Object.seal(o); | 
 |   test(c); | 
 |  | 
 |   // Frozen | 
 |   var d =  Object.freeze(o); | 
 |   test(d); | 
 | } | 
 |  | 
 | runTest(); | 
 |  | 
 | // ---------------------------------------------------------------------- | 
 | // Indexed access for packed/holey elements | 
 | // ---------------------------------------------------------------------- | 
 | runTest = function() { | 
 |   var o = [ 'a', 43 ]; | 
 |  | 
 |   function test(o, holey=false) { | 
 |     var initial_X = 0; | 
 |     var X = initial_X; | 
 |     var Y = 1; | 
 |  | 
 |     function fieldTest(change_index) { | 
 |       for (var i = 0; i < 10; i++) { | 
 |         var property = o[X]; | 
 |         if (i <= change_index) { | 
 |           if (holey) { | 
 |             assertEquals(undefined, property); | 
 |           } else { | 
 |             assertEquals('a', property); | 
 |           } | 
 |         } else { | 
 |           if (holey) { | 
 |             assertEquals('a', property); | 
 |           } | 
 |           else { | 
 |             assertEquals(43, property); | 
 |           } | 
 |         } | 
 |         if (i == change_index) X = Y; | 
 |       } | 
 |       X = initial_X; | 
 |     }; | 
 |  | 
 |     for (var i = 0; i < 10; i++) fieldTest(i); | 
 |   } | 
 |   test(o); | 
 |  | 
 |   // Packed | 
 |   // Non-extensible | 
 |   var b =  Object.preventExtensions(o); | 
 |   test(b); | 
 |  | 
 |   // Sealed | 
 |   var c =  Object.seal(o); | 
 |   test(c); | 
 |  | 
 |   // Frozen | 
 |   var d =  Object.freeze(o); | 
 |   test(d); | 
 |  | 
 |   // Holey | 
 |   // Non-extensible | 
 |   o = [, 'a']; | 
 |   var b =  Object.preventExtensions(o); | 
 |   test(b, true); | 
 |  | 
 |   // Sealed | 
 |   var c =  Object.seal(o); | 
 |   test(c, true); | 
 |  | 
 |   // Frozen | 
 |   var d =  Object.freeze(o); | 
 |   test(d, true); | 
 | } | 
 |  | 
 | runTest(); | 
 |  | 
 |  | 
 | // ---------------------------------------------------------------------- | 
 | // Constant function access. | 
 | // ---------------------------------------------------------------------- | 
 | runTest = function() { | 
 |   function fun() { }; | 
 |  | 
 |   var o = new Object(); | 
 |   o.f = fun; | 
 |   o.x = 42; | 
 |  | 
 |   var initial_F = 'f'; | 
 |   var F = initial_F; | 
 |   var X = 'x' | 
 |  | 
 |   function constantFunctionTest(change_index) { | 
 |     for (var i = 0; i < 10; i++) { | 
 |       var property = o[F]; | 
 |       if (i <= change_index) { | 
 |         assertEquals(fun, property); | 
 |       } else { | 
 |         assertEquals(42, property); | 
 |       } | 
 |       if (i == change_index) F = X; | 
 |     } | 
 |     F = initial_F; | 
 |   }; | 
 |  | 
 |   for (var i = 0; i < 10; i++) constantFunctionTest(i); | 
 | } | 
 |  | 
 | runTest(); | 
 |  | 
 | // ---------------------------------------------------------------------- | 
 | // Keyed store field. | 
 | // ---------------------------------------------------------------------- | 
 |  | 
 | runTest = function() { | 
 |   var o = { x: 42, y: 43 } | 
 |  | 
 |   var initial_X = 'x'; | 
 |   var X = initial_X; | 
 |   var Y = 'y'; | 
 |  | 
 |   function fieldTest(change_index) { | 
 |     for (var i = 0; i < 10; i++) { | 
 |       o[X] = X; | 
 |       var property = o[X]; | 
 |       if (i <= change_index) { | 
 |         assertEquals('x', property); | 
 |       } else { | 
 |         assertEquals('y', property); | 
 |       } | 
 |       if (i == change_index) X = Y; | 
 |     } | 
 |     X = initial_X; | 
 |   }; | 
 |  | 
 |   for (var i = 0; i < 10; i++) fieldTest(i); | 
 | } | 
 |  | 
 | runTest(); |