// Copyright 2011 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.

// Flags: --allow-natives-syntax --noalways-opt --opt

// It's nice to run this in other browsers too.
var standalone = false;
if (standalone) {
  assertTrue = function(val) {
    if (val != true) {
      print("FAILURE");
    }
  }

  assertFalse = function(val) {
    if (val != false) {
      print("FAILURE");
    }
  }

  assertEquals = function(expected, val) {
    if (expected !== val) {
      print("FAILURE");
    }
  }

  empty_func = function(name) { }
  assertUnoptimized = empty_func;
  assertOptimized = empty_func;

  prepareForOptimize = emtpy_func;
  optimize = empty_func;
  clearFunctionTypeFeedback = empty_func;
  deoptimizeFunction = empty_func;
} else {
  optimize = function(name) {
    %OptimizeFunctionOnNextCall(name);
  }
  prepareForOptimize = function(name) {
    %PrepareFunctionForOptimization(name);
  }
  clearFunctionTypeFeedback = function(name) {
    %ClearFunctionFeedback(name);
  }
  deoptimizeFunction = function(name) {
    %DeoptimizeFunction(name);
  }
}

function base_getter_test(create_func) {
  var calls = 0;

  // Testcase: setter in prototype chain
  foo = function(a) { var x = a[0]; return x + 3; }
  var a = create_func();
  var ap = [];
  ap.__defineGetter__(0, function() { calls++; return 0; });

  prepareForOptimize(foo);
  foo(a);
  assertUnoptimized(foo);
  // Smi and Double elements transition the KeyedLoadIC to Generic state
  // here, because they miss twice with the same map when loading the hole.
  // For HOLEY_ELEMENTS, however, the IC knows how to convert the hole
  // to undefined if the prototype is the original array prototype, so it
  // stays monomorphic for now...
  foo(a);
  foo(a);
  delete a[0];

  assertEquals(0, calls);
  a.__proto__ = ap;
  // ...and later becomes polymorphic when it sees a second map. Optimized
  // code will therefore inline the elements access, and deopt right away
  // when it loads the hole from index [0].
  // Possible solutions:
  // - remove the convert_hole_to_undefined flag from the IC, to force it
  //   into generic state for all elements kinds. Cost: slower ICs in code
  //   that doesn't get optimized.
  // - teach Turbofan about the same trick: for holey elements with the
  //   original array prototype, convert hole to undefined inline. Cost:
  //   larger optimized code size, because the loads for different maps with
  //   the same elements kind can no longer be consolidated if they handle
  //   the hole differently.
  // - call "foo" twice after setting a.__proto__ and before optimizing it;
  //   this is the simplest fix so let's do that for now.
  foo(a);
  assertEquals(1, calls);
  foo(a);
  assertEquals(2, calls);
  optimize(foo);
  foo(a);
  assertEquals(3, calls);
  assertOptimized(foo);

  // Testcase: getter "deep" in prototype chain.
  clearFunctionTypeFeedback(foo);
  deoptimizeFunction(foo);
  clearFunctionTypeFeedback(foo);
  calls = 0;

  a = create_func();
  var ap2 = [];
  a.__proto__ = ap2;
  foo(a);
  foo(a);
  foo(a);
  delete a[0];

  assertEquals(0, calls);

  ap2.__proto__ = ap;  // "sneak" in a callback.
  // The sneak case should be caught by unoptimized code too.
  assertUnoptimized(foo);
  foo(a);
  foo(a);
  foo(a);
  assertEquals(3, calls);

  // Testcase: getter added after optimization (feedback is monomorphic)
  clearFunctionTypeFeedback(foo);
  deoptimizeFunction(foo);
  clearFunctionTypeFeedback(foo);
  calls = 0;

  a = create_func();
  ap2 = [];
  a.__proto__ = ap2;
  prepareForOptimize(foo);
  foo(a);
  foo(a);
  foo(a);
  optimize(foo);
  foo(a);
  assertOptimized(foo);
  delete a[0];
  ap2.__proto__ = ap;
  foo(a);
  assertOptimized(foo);  // getters don't require deopt on shape change.
  assertEquals(1, calls);

  // Testcase: adding additional getters to a prototype chain that already has
  // one shouldn't deopt anything.
  clearFunctionTypeFeedback(foo);
  calls = 0;

  a = create_func();
  a.__proto__ = ap2;
  bar = function(a) { return a[3] + 600; }
  prepareForOptimize(bar);
  bar(a);
  bar(a);
  bar(a);
  optimize(bar);
  bar(a);
  assertOptimized(bar);
  assertEquals(0, calls);
  delete a[3];
  ap2.__defineGetter__(3, function() { calls++; return 0; });
  bar(a);
  assertOptimized(bar);
  assertEquals(1, calls);

  // Reset the state of foo and bar.
  clearFunctionTypeFeedback(foo);
  deoptimizeFunction(foo);
  clearFunctionTypeFeedback(foo);

  clearFunctionTypeFeedback(bar);
  deoptimizeFunction(bar);
  clearFunctionTypeFeedback(bar);
}

// Verify that map transitions don't confuse us.
create_func_smi = function() { return [,,,,,,5]; }
create_func_double = function() { return [,,,,,,5.5]; }
create_func_fast = function() { return [,,,,,,true]; }

var cf = [create_func_smi,
          create_func_double,
          create_func_fast];

for(var c = 0; c < cf.length; c++) {
  base_getter_test(cf[c]);
}

// A special test for LoadKeyedHoleMode. Ensure that optimized is generated
// which sets ALLOW_RETURN_HOLE, then add a setter on the prototype that should
// cause the function to deoptimize.

var a = [3.5,,,3.5];
fun = function(a) { return a[0] + 5.5; }
prepareForOptimize(fun);
fun(a);
fun(a);
fun(a);  // should have a monomorphic KeyedLoadIC.
optimize(fun);
fun(a);
assertOptimized(fun);

// returning undefined shouldn't phase us.
delete a[0];
fun(a);
assertOptimized(fun);

// but messing up the prototype chain will.
a.__proto__ = [];
fun(a);
assertUnoptimized(fun);

// Construct a non-trivial prototype chain.
var a = [3.5,,,,3.5];
var ap = [,,3.5];
ap.__proto__ = a.__proto__;
a.__proto__ = ap;
prepareForOptimize(fun);
fun(a);
optimize(fun);
fun(a);
assertOptimized(fun);

var calls = 0;
delete a[0];
ap.__defineGetter__(0, function() { calls++; return 0; });
fun(a);
assertEquals(1, calls);
assertUnoptimized(fun);
