// Copyright 2019 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: --expose-wasm --experimental-wasm-anyref --experimental-wasm-return-call

load("test/mjsunit/wasm/wasm-module-builder.js");

(function IndirectCallToNonZeroTable() {
  print(arguments.callee.name);

  const builder = new WasmModuleBuilder();
  const placeholder = builder.addTable(kWasmAnyFunc, 3).index;
  const table1 = builder.addTable(kWasmAnyFunc, 3).index;
  const table2 = builder.addTable(kWasmAnyFunc, 5).index;
  const sig_index = builder.addType(kSig_i_v);
  const other_sig = builder.addType(kSig_i_i);

  const v1 = 16;
  const v2 = 26;
  const v3 = 36;
  const v4 = 46;
  const v5 = 56;

  const f_unreachable = builder.addFunction('unreachable', sig_index)
    .addBody([kExprUnreachable]).index;
  const f1 = builder.addFunction('f1', sig_index)
    .addBody([kExprI32Const, v1])
    .index;
  const f2 = builder.addFunction('f2', sig_index)
    .addBody([kExprI32Const, v2])
    .index;
  const f3 = builder.addFunction('f3', sig_index)
    .addBody([kExprI32Const, v3])
    .index;
  const f4 = builder.addFunction('f4', sig_index)
    .addBody([kExprI32Const, v4])
    .index;
  const f5 = builder.addFunction('f5', sig_index)
    .addBody([kExprI32Const, v5])
    .index;

  builder.addFunction('call1', kSig_i_i)
    .addBody([kExprGetLocal, 0,   // function index
      kExprCallIndirect, sig_index, table1])
    .exportAs('call1');
  builder.addFunction('return_call1', kSig_i_i)
    .addBody([kExprGetLocal, 0,   // function index
      kExprReturnCallIndirect, sig_index, table1])
    .exportAs('return_call1');
  builder.addFunction('call2', kSig_i_i)
    .addBody([kExprGetLocal, 0,   // function index
      kExprCallIndirect, sig_index, table2])
    .exportAs('call2');
  builder.addFunction('return_call2', kSig_i_i)
    .addBody([kExprGetLocal, 0,   // function index
      kExprReturnCallIndirect, sig_index, table2])
    .exportAs('return_call2');

  builder.addFunction('call_invalid_sig', kSig_i_i)
    .addBody([kExprGetLocal, 0, kExprGetLocal, 0,   // function index + param
      kExprCallIndirect, other_sig, table2])
    .exportAs('call_invalid_sig');
  builder.addFunction('return_call_invalid_sig', kSig_i_i)
    .addBody([kExprGetLocal, 0, kExprGetLocal, 0,   // function index + param
      kExprReturnCallIndirect, other_sig, table2])
    .exportAs('return_call_invalid_sig');

  // We want to crash if we call through the table with index 0.
  builder.addElementSegment(placeholder, 0, false,
    [f_unreachable, f_unreachable, f_unreachable]);
  builder.addElementSegment(table1, 0, false, [f1, f2, f3]);
  // Keep one slot in table2 uninitialized. We should trap if we call it.
  builder.addElementSegment(table2, 1, false,
    [f_unreachable, f_unreachable, f4, f5]);

  const instance = builder.instantiate();

  assertEquals(v1, instance.exports.call1(0));
  assertEquals(v2, instance.exports.call1(1));
  assertEquals(v3, instance.exports.call1(2));
  assertTraps(kTrapFuncInvalid, () => instance.exports.call1(3));
  assertEquals(v1, instance.exports.return_call1(0));
  assertEquals(v2, instance.exports.return_call1(1));
  assertEquals(v3, instance.exports.return_call1(2));
  assertTraps(kTrapFuncInvalid, () => instance.exports.return_call1(3));

  // Try to call through the uninitialized table entry.
  assertTraps(kTrapFuncSigMismatch, () => instance.exports.call2(0));
  assertEquals(v4, instance.exports.call2(3));
  assertEquals(v5, instance.exports.call2(4));
  assertTraps(kTrapFuncSigMismatch,
    () => instance.exports.call_invalid_sig(4));
  assertTraps(kTrapFuncSigMismatch, () => instance.exports.return_call2(0));
  assertEquals(v4, instance.exports.return_call2(3));
  assertEquals(v5, instance.exports.return_call2(4));
  assertTraps(kTrapFuncSigMismatch,
    () => instance.exports.return_call_invalid_sig(4));
})();

(function IndirectCallToImportedNonZeroTable() {
  print(arguments.callee.name);

  const table_size = 10;
  const placeholder = new WebAssembly.Table(
    { initial: table_size, maximum: table_size, element: "anyfunc" });
  const table = new WebAssembly.Table(
    { initial: table_size, maximum: table_size, element: "anyfunc" });

  const builder = new WasmModuleBuilder();
  builder.addImportedTable("m", "placeholder", table_size, table_size);
  const t1 = builder.addImportedTable("m", "table", table_size, table_size);

  // We initialize the module twice and put the function f1 in the table at
  // the index defined by {g}. Thereby we can initialize the table at different
  // slots for different instances. The function f1 also returns {g} so that we
  // can see that actually different functions get called.
  const g = builder.addImportedGlobal("m", "base", kWasmI32);

  const sig_index = builder.addType(kSig_i_v);
  const f1 = builder.addFunction("foo", sig_index)
    .addBody([kExprGetGlobal, g, kExprI32Const, 12, kExprI32Add]);

  builder.addFunction('call', kSig_i_i)
    .addBody([kExprGetLocal, 0,   // function index
      kExprCallIndirect, sig_index, t1])
    .exportAs('call');

  builder.addElementSegment(t1, g, true, [f1.index]);
  const base1 = 3;
  const base2 = 5;

  const instance1 = builder.instantiate({
    m: {
      placeholder: placeholder,
      table: table,
      base: base1
    }
  });

  const instance2 = builder.instantiate({
    m: {
      placeholder: placeholder,
      table: table,
      base: base2
    }
  });

  assertEquals(base1 + 12, instance1.exports.call(base1));
  assertEquals(base2 + 12, instance1.exports.call(base2));
  assertEquals(base1 + 12, instance2.exports.call(base1));
  assertEquals(base2 + 12, instance2.exports.call(base2));
})();

function js_div(a, b) { return (a / b) | 0; }

(function CallImportedFunction() {
  let kTableSize = 10;
  print(arguments.callee.name);

  var builder = new WasmModuleBuilder();

  let div = builder.addImport("q", "js_div", kSig_i_ii);
  builder.addImportedTable("q", "placeholder", kTableSize, kTableSize);
  let table_index = builder.addImportedTable("q", "table", kTableSize, kTableSize);
  let g = builder.addImportedGlobal("q", "base", kWasmI32);

  let sig_index = builder.addType(kSig_i_ii);
  builder.addFunction("placeholder", sig_index)
    .addBody([kExprGetLocal, 0]);

  builder.addElementSegment(table_index, g, true, [div]);
  builder.addFunction("main", kSig_i_ii)
    .addBody([
      kExprI32Const, 55,  // --
      kExprGetLocal, 0,   // --
      kExprGetLocal, 1,   // --
      kExprCallIndirect, 0, table_index])  // --
    .exportAs("main");

  let m = new WebAssembly.Module(builder.toBuffer());

  let table = new WebAssembly.Table({
    element: "anyfunc",
    initial: kTableSize,
    maximum: kTableSize
  });
  let placeholder = new WebAssembly.Table({
    element: "anyfunc",
    initial: kTableSize,
    maximum: kTableSize
  });

  let instance = new WebAssembly.Instance(m, {
    q: {
      base: 0, table: table, placeholder: placeholder,
      js_div: js_div
    }
  });

  assertEquals(13, instance.exports.main(4, 0));
})();
