// 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();
