// 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-reftypes --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([kExprLocalGet, 0,   // function index
      kExprCallIndirect, sig_index, table1])
    .exportAs('call1');
  builder.addFunction('return_call1', kSig_i_i)
    .addBody([kExprLocalGet, 0,   // function index
      kExprReturnCallIndirect, sig_index, table1])
    .exportAs('return_call1');
  builder.addFunction('call2', kSig_i_i)
    .addBody([kExprLocalGet, 0,   // function index
      kExprCallIndirect, sig_index, table2])
    .exportAs('call2');
  builder.addFunction('return_call2', kSig_i_i)
    .addBody([kExprLocalGet, 0,   // function index
      kExprReturnCallIndirect, sig_index, table2])
    .exportAs('return_call2');

  builder.addFunction('call_invalid_sig', kSig_i_i)
    .addBody([kExprLocalGet, 0, kExprLocalGet, 0,   // function index + param
      kExprCallIndirect, other_sig, table2])
    .exportAs('call_invalid_sig');
  builder.addFunction('return_call_invalid_sig', kSig_i_i)
    .addBody([kExprLocalGet, 0, kExprLocalGet, 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(kTrapTableOutOfBounds, () => 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(kTrapTableOutOfBounds, () => 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([kExprGlobalGet, g, kExprI32Const, 12, kExprI32Add]);

  builder.addFunction('call', kSig_i_i)
    .addBody([kExprLocalGet, 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([kExprLocalGet, 0]);

  builder.addElementSegment(table_index, g, true, [div]);
  builder.addFunction("main", kSig_i_ii)
    .addBody([
      kExprI32Const, 55,  // --
      kExprLocalGet, 0,   // --
      kExprLocalGet, 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));
})();
