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

  optimize = empty_func;
  clearFunctionTypeFeedback = empty_func;
  deoptimizeFunction = empty_func;
} else {
  optimize = function(name) {
    %OptimizeFunctionOnNextCall(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; });

  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;
  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; }
  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; }
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;
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);
