// Copyright 2018 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: --allow-natives-syntax --opt --no-always-opt

function runTest(f, message, mkICTraining, deoptArg) {
  function test(f, message, ictraining, deoptArg) {
    // Train the call ic to the maps.
    let t = ictraining;

    // We put the training data into local variables
    // to ensure their maps are kepts alive. If the
    // maps die, gc *may* deoptimize {f}, which makes
    // the test flaky.
    let t1 = t();
    let t2 = t();
    let t3 = t();

    for (let a of t1) {
      f(a.arr, () => a.el);
    }
    for (let a of t2) {
      f(a.arr, () => a.el);
    }
    %OptimizeFunctionOnNextCall(f);
    message += " trained with" + JSON.stringify(t());
    if (deoptArg == undefined) {
      // Make sure the optimized function can handle
      // all trained maps without deopt.
      for (let a of t3) {
        message += " for args " + JSON.stringify(a) + " should have been optimized";
        f(a.arr, () => a.el);
        assertOptimized(f, undefined, message);
      }
    } else {
      // Trigger deopt, causing no-speculation bit to be set.
      let a1 = deoptArg;
      let a2 = deoptArg;
      message += " for args " + JSON.stringify(a1);
      message_unoptimized = message + " should have been unoptimized"
      message_optimized = message + " should have been unoptimized"
      f(a1.arr, () => a1.el);
      assertUnoptimized(f, undefined, message_unoptimized);
      %OptimizeFunctionOnNextCall(f);
      // No speculation should protect against further deopts.
      f(a2.arr, () => a2.el);
      assertOptimized(f, undefined,  message_optimized);
    }
  }

  // Get function as a string.
  var testString = test.toString();
  // Remove the function header..
  testString = testString.replace(new RegExp("[^\n]*"), "let f = " + f.toString() + ";");
  // ..and trailing '}'.
  testString = testString.replace(new RegExp("[^\n]*$"), "");
  // Substitute parameters.
  testString = testString.replace(new RegExp("ictraining", 'g'), mkICTraining.toString());
  testString = testString.replace(new RegExp("deoptArg", 'g'),
    deoptArg ? JSON.stringify(deoptArg) : "undefined");

  var modTest = new Function("message", testString);
  //print(modTest);
  modTest(message);
}

let checks = {
  smiReceiver:
    { mkTrainingArguments : () => [{arr:[1], el:3}],
      deoptingArguments   : [{arr:[0.1], el:1}, {arr:[{}], el:1}]
    },
  objectReceiver:
    { mkTrainingArguments : () => [{arr:[{}], el:0.1}],
      deoptingArguments : []
    },
  multipleSmiReceivers:
    { mkTrainingArguments : () => { let b = [1]; b.x=3; return [{arr:[1], el:3}, {arr:b, el:3}] },
      deoptingArguments : [{arr:[0.1], el:1}, {arr:[{}], el:1}]
    },
  multipleSmiReceiversPackedUnpacked:
    { mkTrainingArguments : () => { let b = [1]; b[100] = 3; return [{arr:[1], el:3}, {arr:b, el:3}] },
      deoptingArguments : [{arr:[0.1], el:1}, {arr:[{}], el:1}]
    },
  multipleDoubleReceivers:
    { mkTrainingArguments : () => { let b = [0.1]; b.x=0.3; return [{arr:[0.1], el:0.3}, {arr:b, el:0.3}] },
      deoptingArguments : [{arr:[{}], el:true}, {arr:[1], el:true}]
    },
  multipleDoubleReceiversPackedUnpacked:
    { mkTrainingArguments : () => { let b = [0.1]; b[100] = 0.3; return [{arr:[0.1], el:0.3}, {arr:b, el:0.3}] },
      deoptingArguments : [{arr:[{}], el:true}, {arr:[1], el:true}]
    },
  multipleMixedReceivers:
    { mkTrainingArguments : () => { let b = [0.1]; b.x=0.3; return [{arr:[1], el:0.3}, {arr:[{}], el:true}, {arr:b, el:0.3}] },
      deoptingArguments : []
    },
  multipleMixedReceiversPackedUnpacked:
    { mkTrainingArguments : () => { let b = [0.1]; b[100] = 0.3; return [{arr:[1], el:0.3}, {arr:[{}], el:true}, {arr:b, el:0.3}] },
      deoptingArguments : []
    },
};

const functions = {
  push_reliable: (a,g) => { let b = g(); return a.push(2, b); },
  push_unreliable: (a,g) => { return a.push(2, g()); },
  pop_reliable: (a,g) => { let b = g(); return a.pop(2, b); },
  pop_unreliable: (a,g) => { return a.pop(2, g()); },
  shift_reliable: (a,g) => { let b = g(); return a.shift(2, b); },
  shift_unreliable: (a,g) => { return a.shift(2, g()); }
}

Object.keys(checks).forEach(
  key => {
    let check = checks[key];

    for (fnc in functions) {
      runTest(functions[fnc], "test-reliable-" + key, check.mkTrainingArguments);
      // Test each deopting arg separately.
      for (let deoptArg of check.deoptingArguments) {
        runTest(functions[fnc], "testDeopt-reliable-" + key, check.mkTrainingArguments, deoptArg);
      }
    }
  }
);
