text: // Copyright 2014 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.
  
  load('../base.js');
  
  let array;
  // Initialize func variable to ensure the first test doesn't benefit from
  // global object property tracking.
  let func = 0;
  let this_arg;
  let result;
  const array_size = 100;
  const max_index = array_size - 1;
  
  // newClosure is a handy function to get a fresh
  // closure unpolluted by IC feedback for a 2nd-order array builtin
  // test.
  function newClosure(name, generic = false) {
    if (generic) {
      return new Function(
        `result = Array.prototype.${name}.call(array, func, this_arg);`);
    }
    return new Function(`result = array.${name}(func, this_arg);`);
  }
  
  function MakeHoley(array) {
    for (let i =0; i < array.length; i+=2) {
      delete array[i];
    }
    assert(%HasHoleyElements(array));
  }
  
  function SmiSetup() {
    array = Array.from({ length: array_size }, (_, i) => i);
    assert(%HasSmiElements(array));
  }
  
  function HoleySmiSetup() {
    SmiSetup();
    MakeHoley(array);
    assert(%HasSmiElements(array));
  }
  
  function DoubleSetup() {
    array = Array.from({ length: array_size }, (_, i) => i + 0.5);
    assert(%HasDoubleElements(array));
  }
  
  function HoleyDoubleSetup() {
    DoubleSetup();
    MakeHoley(array);
    assert(%HasDoubleElements(array));
  }
  
  function FastSetup() {
    array = Array.from({ length: array_size }, (_, i) => `value ${i}`);
    assert(%HasObjectElements(array));
  }
  
  function HoleyFastSetup() {
    FastSetup();
    MakeHoley(array);
    assert(%HasObjectElements(array));
  }
  
  function DictionarySetup() {
    array = [];
    // Add a large index to force dictionary elements.
    array[1000000] = 0;
    var len = array.length;
    for (var i = 0; i < len; i++) {
      if (i % 100 === 0) {
        array[i] = i;
      }
    }
    assert(%HasDictionaryElements(array));
  }
  
  function ObjectSetup() {
    array = { length: array_size };
    for (var i = 0; i < array_size; i++) {
      array[i] = i;
    }
    assert(%HasObjectElements(array));
    assert(%HasHoleyElements(array));
  }
  
  
  const ARRAY_SETUP = {
    PACKED_SMI: SmiSetup,
    HOLEY_SMI: HoleySmiSetup,
    PACKED_DOUBLE: DoubleSetup,
    HOLEY_DOUBLE: HoleyDoubleSetup,
    PACKED: FastSetup,
    HOLEY: HoleyFastSetup,
    DICTIONARY: DictionarySetup,
  }
  
  function DefineHigherOrderTests(tests) {
    let i = 0;
    while (i < tests.length) {
       const [name, testFunc, setupFunc, callback] = tests[i++];
  
       let setupFuncWrapper = () => {
         func = callback;
         this_arg = undefined;
         setupFunc();
       };
       createSuite(name, 1000, testFunc, setupFuncWrapper);
    }
  }
  
  // Higher-order Array builtins.
  load('filter.js');
  load('map.js');
  load('every.js');
  load('some.js');
  load('for-each.js');
  load('reduce.js');
  load('reduce-right.js');
  load('find.js');
  load('find-index.js');
  
  // Other Array builtins.
  load('from.js');
  load('of.js');
  load('join.js');
  load('to-string.js');
  load('slice.js');
  load('copy-within.js');
  
  var success = true;
  
  function PrintResult(name, result) {
    print(name + '-Array(Score): ' + result);
  }
  
  function PrintStep(name) {}
  
  function PrintError(name, error) {
    PrintResult(name, error);
    success = false;
  }
  
  
  BenchmarkSuite.config.doWarmup = undefined;
  BenchmarkSuite.config.doDeterministic = undefined;
  
  BenchmarkSuite.RunSuites({ NotifyResult: PrintResult,
                             NotifyError: PrintError,
                             NotifyStep: PrintStep });
  