// 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

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

function dummy_func(val) {
  let builder = new WasmModuleBuilder();
  builder.addFunction('dummy', kSig_i_v)
      .addBody([kExprI32Const, val])
      .exportAs('dummy');
  return builder.instantiate().exports.dummy;
}

let kSig_v_iri = makeSig([kWasmI32, kWasmAnyRef, kWasmI32], []);
let kSig_v_iai = makeSig([kWasmI32, kWasmAnyFunc, kWasmI32], []);
let kSig_r_i = makeSig([kWasmI32], [kWasmAnyRef]);

const builder = new WasmModuleBuilder();
const size = 10;
const maximum = size;
const import_ref =
    builder.addImportedTable('imp', 'table_ref', size, maximum, kWasmAnyRef);
const import_func =
    builder.addImportedTable('imp', 'table_func', size, maximum, kWasmAnyFunc);
const internal_ref = builder.addTable(kWasmAnyRef, size, maximum).index;
const internal_func = builder.addTable(kWasmAnyFunc, size, maximum).index;

// Add fill and get functions for the anyref tables.
for (index of [import_ref, internal_ref]) {
  builder.addFunction(`fill${index}`, kSig_v_iri)
      .addBody([
        kExprGetLocal, 0, kExprGetLocal, 1, kExprGetLocal, 2, kNumericPrefix,
        kExprTableFill, index
      ])
      .exportFunc();

  builder.addFunction(`get${index}`, kSig_r_i)
      .addBody([kExprGetLocal, 0, kExprTableGet, index])
      .exportFunc();
}

// Add fill and call functions for the anyfunc tables.
const sig_index = builder.addType(kSig_i_v);
for (index of [import_func, internal_func]) {
  builder.addFunction(`fill${index}`, kSig_v_iai)
      .addBody([
        kExprGetLocal, 0, kExprGetLocal, 1, kExprGetLocal, 2, kNumericPrefix,
        kExprTableFill, index
      ])
      .exportFunc();

  builder.addFunction(`call${index}`, kSig_i_i)
      .addBody([kExprGetLocal, 0, kExprCallIndirect, sig_index, index])
      .exportFunc();
}

const table_ref =
    new WebAssembly.Table({element: 'anyref', initial: size, maximum: maximum});
const table_func = new WebAssembly.Table(
    {element: 'anyfunc', initial: size, maximum: maximum});

const instance =
    builder.instantiate({imp: {table_ref: table_ref, table_func: table_func}});

function checkAnyRefTable(getter, start, count, value) {
  for (i = 0; i < count; ++i) {
    assertEquals(value, getter(start + i));
  }
}

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

  checkAnyRefTable(instance.exports[`get${import_ref}`], 0, size, null);
  checkAnyRefTable(instance.exports[`get${internal_ref}`], 0, size, null);
})();

(function testAnyRefTableFill() {
  print(arguments.callee.name);
  // Fill table and check the content.
  let start = 1;
  let value = {foo: 23};
  let count = 3;
  instance.exports[`fill${import_ref}`](start, value, count);
  checkAnyRefTable(instance.exports[`get${import_ref}`], start, count, value);
  value = 'foo';
  instance.exports[`fill${internal_ref}`](start, value, count);
  checkAnyRefTable(instance.exports[`get${internal_ref}`], start, count, value);
})();

(function testAnyRefTableFillOOB() {
  print(arguments.callee.name);
  // Fill table out-of-bounds, check if the table got filled as much as
  // possible.
  let start = 7;
  let value = {foo: 27};
  // {maximum + 4} elements definitely don't fit into the table.
  let count = maximum + 4;
  assertTraps(
      kTrapTableOutOfBounds,
      () => instance.exports[`fill${import_ref}`](start, value, count));
  checkAnyRefTable(
      instance.exports[`get${import_ref}`], start, size - start, value);

  value = 45;
  assertTraps(
      kTrapTableOutOfBounds,
      () => instance.exports[`fill${internal_ref}`](start, value, count));
  checkAnyRefTable(
      instance.exports[`get${internal_ref}`], start, size - start, value);
})();

(function testAnyRefTableFillOOBCountZero() {
  print(arguments.callee.name);
  // Fill 0 elements at an oob position. This should trap.
  let start = size + 32;
  let value = 'bar';
  assertTraps(
      kTrapTableOutOfBounds,
      () => instance.exports[`fill${import_ref}`](start, value, 0));
  assertTraps(
      kTrapTableOutOfBounds,
      () => instance.exports[`fill${internal_ref}`](start, value, 0));
})();

function checkAnyFuncTable(call, start, count, value) {
  for (i = 0; i < count; ++i) {
    if (value) {
      assertEquals(value, call(start + i));
    } else {
      assertTraps(kTrapFuncSigMismatch, () => call(start + i));
    }
  }
}

(function testAnyRefTableIsUninitialized() {
  print(arguments.callee.name);
  // Check that the table is uninitialized.
  checkAnyFuncTable(instance.exports[`call${import_func}`], 0, size);
  checkAnyFuncTable(instance.exports[`call${internal_func}`], 0, size);
})();

(function testAnyFuncTableFill() {
  print(arguments.callee.name);
  // Fill and check the result.
  let start = 1;
  let value = 44;
  let count = 3;
  instance.exports[`fill${import_func}`](start, dummy_func(value), count);
  checkAnyFuncTable(
      instance.exports[`call${import_func}`], start, count, value);
  value = 21;
  instance.exports[`fill${internal_func}`](start, dummy_func(value), count);
  checkAnyFuncTable(
      instance.exports[`call${internal_func}`], start, count, value);
})();

(function testAnyFuncTableFillOOB() {
  print(arguments.callee.name);
  // Fill table out-of-bounds, check if the table got filled as much as
  // possible.
  let start = 7;
  let value = 38;
  // {maximum + 4} elements definitely don't fit into the table.
  let count = maximum + 4;
  assertTraps(
      kTrapTableOutOfBounds,
      () => instance.exports[`fill${import_func}`](
          start, dummy_func(value), count));
  checkAnyFuncTable(
      instance.exports[`call${import_func}`], start, size - start, value);

  value = 46;
  assertTraps(
      kTrapTableOutOfBounds,
      () => instance.exports[`fill${internal_func}`](
          start, dummy_func(value), count));
  checkAnyFuncTable(
      instance.exports[`call${internal_func}`], start, size - start, value);
})();

(function testAnyFuncTableFillOOBCountZero() {
  print(arguments.callee.name);
  // Fill 0 elements at an oob position. This should trap.
  let start = size + 32;
  let value = dummy_func(33);
  assertTraps(
      kTrapTableOutOfBounds,
      () => instance.exports[`fill${import_func}`](start, null, 0));
  assertTraps(
      kTrapTableOutOfBounds,
      () => instance.exports[`fill${internal_func}`](start, null, 0));

  // Check that table.fill at position `size` is still valid.
  instance.exports[`fill${import_func}`](size, null, 0);
  instance.exports[`fill${internal_func}`](size, null, 0);
})();
