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

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

function CreateDefaultBuilder() {
  const builder = new WasmModuleBuilder();

  const sig_index = kSig_i_dd;
  builder.addImport('mod', 'fun', sig_index);
  builder.addFunction('main', sig_index)
      .addBody([
        kExprLocalGet, 0,      // --
        kExprLocalGet, 1,      // --
        kExprCallFunction, 0,  // --
      ])                       // --
      .exportFunc();
  return builder;
}

function checkSuccessfulInstantiation(builder, ffi, handler) {
  // Test synchronous instantiation.
  const instance = builder.instantiate(ffi);
  if (handler) handler(instance);

  // Test asynchronous instantiation.
  assertPromiseResult(builder.asyncInstantiate(ffi), handler);
}

function checkFailingInstantiation(
    builder, ffi, error, message, prepend_context = true) {
  // Test synchronous instantiation.
  assertThrows(
      _ => builder.instantiate(ffi), error,
      (prepend_context ? 'WebAssembly.Instance(): ' : '') + message);

  // Test asynchronous instantiation.
  assertThrowsAsync(
      builder.asyncInstantiate(ffi), error,
      (prepend_context ? 'WebAssembly.instantiate(): ' : '') + message);
}

(function testValidFFI() {
  print(arguments.callee.name);
  let ffi = {'mod': {fun: print}};
  checkSuccessfulInstantiation(CreateDefaultBuilder(), ffi, undefined);
})();

(function testInvalidFFIs() {
  print(arguments.callee.name);
  checkFailingInstantiation(
      CreateDefaultBuilder(), 17, TypeError,
      'Argument 1 must be an object');
  checkFailingInstantiation(
      CreateDefaultBuilder(), {}, TypeError,
      'Import #0 module="mod" error: module is not an object or function');
  checkFailingInstantiation(
      CreateDefaultBuilder(), {mod: {}}, WebAssembly.LinkError,
      'Import #0 module="mod" function="fun" error: function import requires a callable');
  checkFailingInstantiation(
      CreateDefaultBuilder(), {mod: {fun: {}}}, WebAssembly.LinkError,
      'Import #0 module="mod" function="fun" error: function import requires a callable');
  checkFailingInstantiation(
      CreateDefaultBuilder(), {mod: {fun: 0}}, WebAssembly.LinkError,
      'Import #0 module="mod" function="fun" error: function import requires a callable');
})();

(function testImportWithInvalidSignature() {
  print(arguments.callee.name);
  // "fun" should have signature "i_dd"
  let builder = new WasmModuleBuilder();

  let sig_index = kSig_i_dd;
  builder.addFunction('exp', kSig_i_i)
      .addBody([
        kExprLocalGet,
        0,
      ])  // --
      .exportFunc();

  let exported = builder.instantiate().exports.exp;
  checkFailingInstantiation(
      CreateDefaultBuilder(), {mod: {fun: exported}}, WebAssembly.LinkError,
      'Import #0 module="mod" function="fun" error: imported function does not match the expected type');
})();

(function regression870646() {
  print(arguments.callee.name);
  const ffi = {mod: {fun: function() {}}};
  Object.defineProperty(ffi, 'mod', {
    get: function() {
      throw new Error('my_exception');
    }
  });

  checkFailingInstantiation(
      CreateDefaultBuilder(), ffi, Error, 'my_exception', false);
})();

// "fun" matches signature "i_dd"
(function testImportWithValidSignature() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();

  builder.addFunction('exp', kSig_i_dd)
      .addBody([
        kExprI32Const,
        33,
      ])  // --
      .exportFunc();

  let exported = builder.instantiate().exports.exp;

  checkSuccessfulInstantiation(
      CreateDefaultBuilder(), {mod: {fun: exported}},
      instance => assertEquals(33, instance.exports.main()));
})();

(function I64InSignature() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();

  builder.addMemory(1, 1, true);
  builder.addFunction('function_with_invalid_signature', kSig_l_ll)
    .addBody([           // --
      kExprLocalGet, 0,  // --
      kExprLocalGet, 1,  // --
      kExprI64Sub])      // --
    .exportFunc()

  checkSuccessfulInstantiation(
      builder, undefined,
      instance => assertEquals(
        instance.exports.function_with_invalid_signature(33n, 88n), -55n));
})();

(function I64ParamsInSignature() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();

  builder.addMemory(1, 1, true);
  builder.addFunction('function_with_invalid_signature', kSig_i_l)
      .addBody([kExprLocalGet, 0, kExprI32ConvertI64])
      .exportFunc();

  checkSuccessfulInstantiation(
      builder, undefined,
      instance => assertEquals(12,
          instance.exports.function_with_invalid_signature(12n)));

})();

(function I64JSImport() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let sig_index = builder.addType(kSig_i_i);
  let sig_i64_index = builder.addType(kSig_i_l);
  let index = builder.addImport('', 'func', sig_i64_index);
  builder.addFunction('main', sig_index)
      .addBody([
        kExprLocalGet, 0, kExprI64SConvertI32, kExprCallFunction, index  // --
      ])                                                                 // --
      .exportFunc();

  checkSuccessfulInstantiation(
      builder, {'': {func: _ => {}}},
      instance => assertEquals(0, instance.exports.main(1)));

})();

(function ImportI64ParamWithF64Return() {
  print(arguments.callee.name);
  // This tests that we generate correct code by using the correct return
  // register. See bug 6096.
  let builder = new WasmModuleBuilder();
  builder.addImport('', 'f', makeSig([kWasmI64], [kWasmF64]));
  builder.addFunction('main', kSig_v_v)
      .addBody([kExprI64Const, 0, kExprCallFunction, 0, kExprDrop])
      .exportFunc();

  checkSuccessfulInstantiation(
      builder, {'': {f: i => Number(i)}},
      instance => assertDoesNotThrow(instance.exports.main));
})();

(function ImportI64Return() {
  print(arguments.callee.name);
  // This tests that we generate correct code by using the correct return
  // register(s). See bug 6104.
  let builder = new WasmModuleBuilder();
  builder.addImport('', 'f', makeSig([], [kWasmI64]));
  builder.addFunction('main', kSig_v_v)
      .addBody([kExprCallFunction, 0, kExprDrop])
      .exportFunc();

  checkSuccessfulInstantiation(
      builder, {'': {f: _ => 1n}},
      instance => assertDoesNotThrow(instance.exports.main));
})();

(function ImportSymbolToNumberThrows() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let index = builder.addImport('', 'f', kSig_i_v);
  builder.addFunction('main', kSig_i_v)
      .addBody([kExprCallFunction, 0])
      .exportFunc();

  checkSuccessfulInstantiation(
      builder, {'': {f: _ => Symbol()}},
      instance => assertThrows(
          instance.exports.main, TypeError,
          'Cannot convert a Symbol value to a number'));
})();
