// 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_setter_test(create_func, index, store_value) {
  var calls = 0;

  // Testcase: setter in prototype chain
  foo = function(a) { a[index] = store_value; }
  var a = create_func();
  var ap = [];
  ap.__defineSetter__(index, function() { calls++; });

  foo(a);
  foo(a);
  foo(a);
  delete a[index];

  assertEquals(0, calls);
  a.__proto__ = ap;
  foo(a);
  assertEquals(1, calls);
  optimize(foo);
  foo(a);
  assertEquals(2, calls);
  assertOptimized(foo);

  // Testcase: setter added on prototype chain object already in place.
  clearFunctionTypeFeedback(foo);
  deoptimizeFunction(foo);
  clearFunctionTypeFeedback(foo);
  calls = 0;
  a = create_func();
  var apap = [];
  a.__proto__ = apap;
  foo(a);
  foo(a);
  foo(a);
  delete a[index];
  apap.__defineSetter__(index, function() { calls++; });
  foo(a);
  foo(a);
  foo(a);
  assertEquals(3, calls);

  // Testcase: setter "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[index];

  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: setter 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[index];
  ap2.__proto__ = ap;
  foo(a);
  assertUnoptimized(foo);  // map shape change should deopt foo.
  assertEquals(1, calls);

  // Testcase: adding additional setters to a prototype chain that already has
  // one shouldn't deopt anything. (ie, we aren't changing the map shape).
  clearFunctionTypeFeedback(foo);
  calls = 0;

  a = create_func();
  a.__proto__ = ap2;
  bar = function(a) { a[index+1] = store_value; }
  bar(a);
  bar(a);
  bar(a);  // store should be generic
  optimize(bar);
  bar(a);
  assertOptimized(bar);
  assertEquals(0, calls);
  delete a[index+1];
  ap2.__defineSetter__(index+1, function() { calls++; });
  bar(a);
  assertOptimized(bar);
  assertEquals(1, calls);
}

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

var cf = [create_func_smi,
          create_func_double,
          create_func_fast,
          create_func_dictionary];

var values = [3, 3.5, true];

for(var c = 0; c < cf.length; c++) {
  for(var s = 0; s < values.length; s++) {
    base_setter_test(cf[c], 0, values[s]);
    base_setter_test(cf[c], 1, values[s]);
  }
}
