// 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 --expose-gc --no-always-opt

var a = new Int32Array(1024);

// Test that we do not assert if the accessed index has not an int32 rep.
var v = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
function test_do_not_assert_on_non_int32(vector, base) {
  var r = 0;
  var a1 = base + 1;
  var a2 = base + 2;
  var a3 = base + 3;
  var a4 = base + 4;
  if (a1 == 2) {
    r += vector[a1];
    r += vector[a4];
    r += vector[a2];
    r += vector[a3];
  }
  return r;
}
test_do_not_assert_on_non_int32(v,1);
test_do_not_assert_on_non_int32(v,1);
test_do_not_assert_on_non_int32(v,"a");
test_do_not_assert_on_non_int32(v,"a");
%OptimizeFunctionOnNextCall(test_do_not_assert_on_non_int32);
test_do_not_assert_on_non_int32(v,0);

function test_base(a, base, condition) {
  a[base + 1] = 1;
  a[base + 4] = 2;
  a[base + 3] = 3;
  a[base + 2] = 4;
  a[base + 4] = base + 4;
  if (condition) {
    a[base + 1] = 1;
    a[base + 2] = 2;
    a[base + 2] = 3;
    a[base + 2] = 4;
    a[base + 4] = base + 4;
  } else {
    a[base + 6] = 1;
    a[base + 4] = 2;
    a[base + 3] = 3;
    a[base + 2] = 4;
    a[base + 4] = base - 4;
  }
}

function check_test_base(a, base, condition) {
  if (condition) {
    assertEquals(1, a[base + 1]);
    assertEquals(4, a[base + 2]);
    assertEquals(base + 4, a[base + 4]);
  } else {
    assertEquals(1, a[base + 6]);
    assertEquals(3, a[base + 3]);
    assertEquals(4, a[base + 2]);
    assertEquals(base - 4, a[base + 4]);
  }
}


test_base(a, 1, true);
test_base(a, 2, true);
test_base(a, 1, false);
test_base(a, 2, false);
%OptimizeFunctionOnNextCall(test_base);
test_base(a, 3, true);
check_test_base(a, 3, true);
test_base(a, 3, false);
check_test_base(a, 3, false);

// Test that we deopt on failed bounds checks.
var dictionary_map_array = new Int32Array(128);
test_base(dictionary_map_array, 5, true);
test_base(dictionary_map_array, 6, true);
test_base(dictionary_map_array, 5, false);
test_base(dictionary_map_array, 6, false);
%OptimizeFunctionOnNextCall(test_base);
test_base(dictionary_map_array, -2, true);
assertUnoptimized(test_base);

// Forget about the dictionary_map_array's map.
%ClearFunctionFeedback(test_base);

test_base(a, 5, true);
test_base(a, 6, true);
test_base(a, 5, false);
test_base(a, 6, false);
%OptimizeFunctionOnNextCall(test_base);
test_base(a, 2048, true);
assertUnoptimized(test_base);

function test_minus(base,cond) {
  a[base - 1] = 1;
  a[base - 2] = 2;
  a[base + 4] = 3;
  a[base] = 4;
  a[base + 4] = base + 4;
  if (cond) {
    a[base - 4] = 1;
    a[base + 5] = 2;
    a[base + 3] = 3;
    a[base + 2] = 4;
    a[base + 4] = base + 4;
  } else {
    a[base + 6] = 1;
    a[base + 4] = 2;
    a[base + 3] = 3;
    a[base + 2] = 4;
    a[base + 4] = base - 4;
  }
}

function check_test_minus(base,cond) {
  if (cond) {
    assertEquals(2, a[base + 5]);
    assertEquals(3, a[base + 3]);
    assertEquals(4, a[base + 2]);
    assertEquals(base + 4, a[base + 4]);
  } else {
    assertEquals(1, a[base + 6]);
    assertEquals(3, a[base + 3]);
    assertEquals(4, a[base + 2]);
    assertEquals(base - 4, a[base + 4]);
  }
}

test_minus(5,true);
test_minus(6,true);
%OptimizeFunctionOnNextCall(test_minus);
test_minus(7,true);
check_test_minus(7,true);
test_minus(7,false);
check_test_minus(7,false);

// Specific test on negative offsets.
var short_a = new Array(100);
for (var i = 0; i < short_a.length; i++) short_a[i] = 0;
function short_test(a, i) {
  a[i + 9] = 0;
  a[i - 10] = 0;
}
short_test(short_a, 50);
short_test(short_a, 50);
%OptimizeFunctionOnNextCall(short_test);
short_a.length = 10;
short_test(short_a, 0);
assertUnoptimized(test_base);


// A test for when we would modify a phi index.
var data_phi = [0, 1, 2, 3, 4, 5, 6, 7, 8];
function test_phi(a, base, check) {
  var index;
  if (check) {
    index = base + 1;
  } else {
    index = base + 2;
  }
  var result = a[index];
  result += a[index + 1];
  result += a[index - 1];
  return result;
}
var result_phi = 0;
result_phi = test_phi(data_phi, 3,  true);
assertEquals(12, result_phi);
result_phi = test_phi(data_phi, 3,  true);
assertEquals(12, result_phi);
%OptimizeFunctionOnNextCall(test_phi);
result_phi = test_phi(data_phi, 3,  true);
assertEquals(12, result_phi);


// A test for recursive decomposition
var data_composition_long = [0, 1, 2, 3, 4, 5, 6, 7, 8];
var data_composition_short = [0, 1, 2, 3, 4];
function test_composition(a, base0, check) {
  var base1 = ((base0 + 2));
  var base2 = ((base1 + 8) >> 2);
  var base3 = ((base2 + 6) >> 1);
  var base4 = ((base3 + 8) >> 1);

  var result = 0;
  result += a[base0];
  result += a[base1];
  result += a[base2];
  result += a[base3];
  result += a[base4];

  return result;
}
var result_composition = 0;
result_composition = test_composition(data_composition_long, 2);
assertEquals(19, result_composition);
result_composition = test_composition(data_composition_long, 2);
assertEquals(19, result_composition);
%OptimizeFunctionOnNextCall(test_composition);
result_composition = test_composition(data_composition_short, 2);
assertEquals(NaN, result_composition);


gc();
