// 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 TestGetAndSet() {
function addTableWithAccessors(builder, type, size, name) {
  const table = builder.addTable(type, size);
  const set_sig = makeSig([kWasmI32, type], []);
  builder.addFunction('set_' + name, set_sig)
      .addBody([kExprGetLocal, 0,
          kExprGetLocal, 1,
          kExprTableSet, table.index])
      .exportFunc();

  const get_sig = makeSig([kWasmI32], [type]);
  builder.addFunction('get_' + name, get_sig)
      .addBody([kExprGetLocal, 0, kExprTableGet, table.index])
      .exportFunc();
}

const builder = new WasmModuleBuilder();

addTableWithAccessors(builder, kWasmAnyFunc, 10, 'table_func1');
addTableWithAccessors(builder, kWasmAnyRef, 20, 'table_ref1');
addTableWithAccessors(builder, kWasmAnyRef, 9, 'table_ref2');
addTableWithAccessors(builder, kWasmAnyFunc, 12, 'table_func2');

let exports = builder.instantiate().exports;
const dummy_ref = {foo : 1, bar : 3};
const dummy_func = exports.set_table_func1;

(function testTableGetInitialValue() {
  print(arguments.callee.name);
  // Tables are initialized with `null`.
  assertSame(null, exports.get_table_func1(1));
  assertSame(null, exports.get_table_func2(2));
  assertSame(null, exports.get_table_ref1(3));
  assertSame(null, exports.get_table_ref2(4));
})();

(function testTableGetOOB() {
  print(arguments.callee.name);
  assertSame(null, exports.get_table_func2(11));
  assertTraps(kTrapTableOutOfBounds, () => exports.get_table_func1(11));
  assertTraps(kTrapTableOutOfBounds, () => exports.get_table_func2(21));
  assertTraps(kTrapTableOutOfBounds, () => exports.get_table_func1(-1));
  assertTraps(kTrapTableOutOfBounds, () => exports.get_table_func2(-2));
  assertSame(null, exports.get_table_ref1(14));
  assertTraps(kTrapTableOutOfBounds, () => exports.get_table_ref2(14));
  assertTraps(kTrapTableOutOfBounds, () => exports.get_table_ref1(44));
  assertTraps(kTrapTableOutOfBounds, () => exports.get_table_ref2(-1));
  assertTraps(kTrapTableOutOfBounds, () => exports.get_table_ref1(-4));
})();

(function testTableSetOOB() {
  print(arguments.callee.name);
  exports.set_table_func2(11, dummy_func);
  assertTraps(kTrapTableOutOfBounds, () => exports.set_table_func1(11, dummy_func));
  assertTraps(kTrapTableOutOfBounds, () => exports.set_table_func2(21, dummy_func));
  exports.set_table_ref1(14, dummy_ref);
  assertTraps(kTrapTableOutOfBounds, () => exports.set_table_ref2(14, dummy_ref));
  assertTraps(kTrapTableOutOfBounds, () => exports.set_table_ref1(44, dummy_ref));
})();

(function testTableSet() {
  print(arguments.callee.name);
  assertSame(null, exports.get_table_func1(3));
  exports.set_table_func1(3, dummy_func);
  assertSame(dummy_func, exports.get_table_func1(3));
  assertSame(null, exports.get_table_func2(3));

  assertSame(null, exports.get_table_func2(7));
  exports.set_table_func2(7, dummy_func);
  assertSame(dummy_func, exports.get_table_func2(7));
  assertSame(null, exports.get_table_func1(7));

  assertSame(null, exports.get_table_ref1(3));
  exports.set_table_ref1(3, dummy_ref);
  assertSame(dummy_ref, exports.get_table_ref1(3));
  assertSame(null, exports.get_table_ref2(3));

  assertSame(null, exports.get_table_ref2(7));
  exports.set_table_ref2(7, dummy_ref);
  assertSame(dummy_ref, exports.get_table_ref2(7));
  assertSame(null, exports.get_table_ref1(7));
})();

(function testSetFunctionTableInvalidType() {
  print(arguments.callee.name);
  assertThrows(() => exports.set_table_func2(7, dummy_ref), TypeError);
})();
})();

(function testGetFunctionFromInitializedTable() {
  print(arguments.callee.name);
  const value1 = 11;
  const value2 = 22;
  const value3 = 13;

  const builder = new WasmModuleBuilder();
  const t1 = builder.addTable(kWasmAnyFunc, 10).index;
  const t2 = builder.addTable(kWasmAnyFunc, 12).index;

  const f1 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, value1]);
  const f2 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, value2]);
  const f3 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, value3]);
  builder.addFunction('get_t1', kSig_a_i)
      .addBody([kExprGetLocal, 0, kExprTableGet, t1])
      .exportFunc();
  builder.addFunction('get_t2', kSig_a_i)
      .addBody([kExprGetLocal, 0, kExprTableGet, t2])
      .exportFunc();

  const offset1 = 3;
  const offset2 = 9;
  builder.addElementSegment(t1, offset1, false, [f1.index, f2.index]);
  builder.addElementSegment(t2, offset2, false, [f3.index, f1.index]);

  const instance = builder.instantiate();

  assertEquals(value1, instance.exports.get_t1(offset1)());
  assertEquals(value2, instance.exports.get_t1(offset1 + 1)());
  assertEquals(value3, instance.exports.get_t2(offset2)());
  assertEquals(value1, instance.exports.get_t2(offset2 + 1)());
})();

(function testRefFuncInTableIsCallable() {
  print(arguments.callee.name);
  const expected = 54;
  const index = 3;
  const builder = new WasmModuleBuilder();
  const table_index = builder.addTable(kWasmAnyFunc, 15, 15).index;
  const sig_index = builder.addType(kSig_i_v);
  const function_index = builder.addFunction('hidden', sig_index)
                             .addBody([kExprI32Const, expected])
                             .index;

  builder.addFunction('main', kSig_i_v)
      .addBody([
        kExprI32Const, index,                      // entry index
        kExprRefFunc, function_index,              // function reference
        kExprTableSet, table_index,                // --
        kExprI32Const, index,                      // entry index
        kExprCallIndirect, sig_index, table_index  // --

      ])
      .exportFunc();

  const instance = builder.instantiate();
  assertEquals(expected, instance.exports.main());
})();
