// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --turbo-escape --allow-natives-syntax --no-always-opt
// Flags: --opt --turbo-filter=* --no-force-slow-path

"use strict";

let global = this;
let tests = {
  FastElementsKind() {
    let runners = {
      PACKED_SMI_ELEMENTS(array) {
        let sum = 0;
        for (let x of array) sum += x;
        return sum;
      },

      HOLEY_SMI_ELEMENTS(array) {
        let sum = 0;
        for (let x of array) {
          if (x) sum += x;
        }
        return sum;
      },

      PACKED_ELEMENTS(array) {
        let ret = "";
        for (let str of array) ret += `> ${str}`;
        return ret;
      },

      HOLEY_ELEMENTS(array) {
        let ret = "";
        for (let str of array) ret += `> ${str}`;
        return ret;
      },

      PACKED_DOUBLE_ELEMENTS(array) {
        let sum = 0.0;
        for (let x of array) sum += x;
          return sum;
      },

      // TODO(6587): Re-enable the below test case once we no longer deopt due
      // to non-truncating uses of {CheckFloat64Hole} nodes.
      /*HOLEY_DOUBLE_ELEMENTS(array) {
        let sum = 0.0;
        for (let x of array) {
          if (x) sum += x;
        }
        return sum;
      }*/
    };

    let tests = {
      PACKED_SMI_ELEMENTS: {
        array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
        expected: 55,
        array2: [1, 2, 3],
        expected2: 6
      },
      HOLEY_SMI_ELEMENTS: {
        array: [1, , 3, , 5, , 7, , 9, ,],
        expected: 25,
        array2: [1, , 3],
        expected2: 4
      },
      PACKED_ELEMENTS: {
        array: ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"],
        expected: "> a> b> c> d> e> f> g> h> i> j",
        array2: ["a", "b", "c"],
        expected2: "> a> b> c"
      },
      HOLEY_ELEMENTS: {
        array: ["a", , "c", , "e", , "g", , "i", ,],
        expected: "> a> undefined> c> undefined> e> undefined> g" +
                  "> undefined> i> undefined",
        array2: ["a", , "c"],
        expected2: "> a> undefined> c"
      },
      PACKED_DOUBLE_ELEMENTS: {
        array: [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0],
        expected: 5.5,
        array2: [0.6, 0.4, 0.2],
        expected2: 1.2
      },
      // TODO(6587): Re-enable the below test case once we no longer deopt due
      // to non-truncating uses of {CheckFloat64Hole} nodes.
      /*HOLEY_DOUBLE_ELEMENTS: {
        array: [0.1, , 0.3, , 0.5, , 0.7, , 0.9, ,],
        expected: 2.5,
        array2: [0.1, , 0.3],
        expected2: 0.4
      }*/
    };

    for (let key of Object.keys(runners)) {
      let fn = runners[key];
      let { array, expected, array2, expected2 } = tests[key];

      // Warmup:
      %PrepareFunctionForOptimization(fn);
      fn(array);
      fn(array);
      %OptimizeFunctionOnNextCall(fn);
      fn(array);

      assertOptimized(fn, '', key);
      assertEquals(expected, fn(array), key);
      assertOptimized(fn, '', key);

      // Check no deopt when another array with the same map is used
      assertTrue(%HaveSameMap(array, array2), key);
      assertOptimized(fn, '', key);
      assertEquals(expected2, fn(array2), key);

      // CheckMaps bailout
      let newArray = Object.defineProperty(
          [1, 2, 3], 2, { enumerable: false, configurable: false,
                          get() { return 7; } });
      fn(newArray);
      assertUnoptimized(fn, '', key);
    }
  },

  TypedArrays() {
    let tests = {
      Uint8Array: {
        array: new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, -1, 256]),
        expected: 291,
        array2: new Uint8Array([1, 2, 3]),
        expected2: 6
      },

      Int8Array: {
        array: new Int8Array([1, 2, 3, 4, 5, 6, 7, 8, -129, 128]),
        expected: 35,
        array2: new Int8Array([1, 2, 3]),
        expected2: 6
      },

      Uint16Array: {
        array: new Uint16Array([1, 2, 3, 4, 5, 6, 7, 8, -1, 0x10000]),
        expected: 65571,
        array2: new Uint16Array([1, 2, 3]),
        expected2: 6
      },

      Int16Array: {
        array: new Int16Array([1, 2, 3, 4, 5, 6, 7, 8, -32769, 0x7FFF]),
        expected: 65570,
        array2: new Int16Array([1, 2, 3]),
        expected2: 6
      },

      Uint32Array: {
        array: new Uint32Array([1, 2, 3, 4, 5, 6, 7, 8, -1, 0x100000000]),
        expected: 4294967331,
        array2: new Uint32Array([1, 2, 3]),
        expected2: 6
      },

      Int32Array: {
        array: new Int32Array([1, 2, 3, 4, 5, 6, 7, 8,
                               -2147483649, 0x7FFFFFFF]),
        expected: 4294967330,
        array2: new Int32Array([1, 2, 3]),
        expected2: 6
      },

      Float32Array: {
        array: new Float32Array([9.5, 8.0, 7.0, 7.0, 5.0, 4.0, 3.0, 2.0]),
        expected: 45.5,
        array2: new Float32Array([10.5, 5.5, 1.5]),
        expected2: 17.5
      },

      Float64Array: {
        array: new Float64Array([9.5, 8.0, 7.0, 7.0, 5.0, 4.0, 3.0, 2.0]),
        expected: 45.5,
        array2: new Float64Array([10.5, 5.5, 1.5]),
        expected2: 17.5
      },

      Uint8ClampedArray: {
        array: new Uint8ClampedArray([4.3, 7.45632, 3.14, 4.61, 5.0004, 6.493,
                                      7.12, 8, 1.7, 3.6]),
        expected: 51,
        array2: new Uint8ClampedArray([1, 2, 3]),
        expected2: 6
      }
    };

    for (let key of Object.keys(tests)) {
      let test = tests[key];
      let { array, expected, array2, expected2 } = test;

      let sum = function(array) {
        let ret = 0;
        for (let x of array) ret += x;
        return ret;
      };

      // Warmup
      %PrepareFunctionForOptimization(sum);
      sum(array);
      sum(array);
      %OptimizeFunctionOnNextCall(sum);
      assertEquals(expected, sum(array), key);

      assertOptimized(sum, '', key);

      // Not deoptimized when called on typed array of same type / map
      assertTrue(%HaveSameMap(array, array2));
      assertEquals(expected2, sum(array2), key);
      assertOptimized(sum, '', key);

      // Throw when detached
      let clone = new array.constructor(array);
      %ArrayBufferDetach(clone.buffer);
      assertThrows(() => sum(clone), TypeError);

      // Clear the slate for the next iteration.
      %DeoptimizeFunction(sum);
      %ClearFunctionFeedback(sum);
    }
  }
};

for (let name of Object.keys(tests)) {
  let test = tests[name];
  test();
}
