// 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-eh --allow-natives-syntax

// Note that this test does not pass --experimental-wasm-reftypes on purpose so
// that we make sure the two flags can be controlled separately/independently.

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

// First we just test that "exnref" global variables are allowed.
(function TestGlobalExnRefSupported() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let g = builder.addGlobal(kWasmExnRef);
  builder.addFunction("push_and_drop_exnref", kSig_v_v)
      .addBody([
        kExprGlobalGet, g.index,
        kExprDrop,
      ]).exportFunc();
  let instance = builder.instantiate();

  assertDoesNotThrow(instance.exports.push_and_drop_exnref);
})();

// Test default value that global "exnref" variables are initialized with.
(function TestGlobalExnRefDefaultValue() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let g = builder.addGlobal(kWasmExnRef);
  builder.addFunction('push_and_return_exnref', kSig_e_v)
      .addBody([kExprGlobalGet, g.index])
      .exportFunc();
  let instance = builder.instantiate();

  assertEquals(null, instance.exports.push_and_return_exnref());
})();

// Test storing a caught exception into an exported mutable "exnref" global.
(function TestGlobalExnRefSetCaught() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let except = builder.addException(kSig_v_i);
  let g = builder.addGlobal(kWasmExnRef, true).exportAs("exn");
  builder.addFunction('catch_and_set_exnref', kSig_v_i)
      .addBody([
        kExprTry, kWasmStmt,
          kExprLocalGet, 0,
          kExprThrow, except,
        kExprCatch,
          kExprGlobalSet, g.index,
        kExprEnd,
      ]).exportFunc();
  let instance = builder.instantiate();

  assertDoesNotThrow(() => instance.exports.catch_and_set_exnref(23));
  let exception = instance.exports.exn.value;  // Exported mutable global.
  assertInstanceof(exception, WebAssembly.RuntimeError);
  assertEquals(except, %GetWasmExceptionId(exception, instance));
})();

// Test storing a parameter into an exported mutable "exnref" global.
(function TestGlobalExnRefSetParameter() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let g = builder.addGlobal(kWasmExnRef, true).exportAs("exn");
  builder.addFunction('set_param_exnref', kSig_v_e)
      .addBody([
        kExprTry, kWasmStmt,
          kExprLocalGet, 0,
          kExprRethrow,
        kExprCatch,
          kExprGlobalSet, g.index,
        kExprEnd,
      ]).exportFunc();
  let exception = "my fancy exception";
  let instance = builder.instantiate();

  assertDoesNotThrow(() => instance.exports.set_param_exnref(exception));
  assertEquals(exception, instance.exports.exn.value);
})();

// Test loading an imported "exnref" global and re-throwing the exception.
(function TestGlobalExnRefGetImportedAndRethrow() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let g_index = builder.addImportedGlobal("m", "exn", kWasmExnRef);
  builder.addFunction('rethrow_exnref', kSig_v_v)
      .addBody([
        kExprGlobalGet, g_index,
        kExprRethrow,
      ]).exportFunc();
  let exception = "my fancy exception";
  let instance = builder.instantiate({ "m": { "exn": exception }});

  assertThrowsEquals(() => instance.exports.rethrow_exnref(), exception);
})();

// Test loading an exported mutable "exnref" being changed from the outside.
(function TestGlobalExnRefGetExportedMutableAndRethrow() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let g = builder.addGlobal(kWasmExnRef, true).exportAs("exn");
  builder.addFunction('rethrow_exnref', kSig_v_v)
      .addBody([
        kExprGlobalGet, g.index,
        kExprRethrow,
      ]).exportFunc();
  let instance = builder.instantiate();

  let exception1 = instance.exports.exn.value = "my fancy exception";
  assertThrowsEquals(() => instance.exports.rethrow_exnref(), exception1);
  let exception2 = instance.exports.exn.value = "an even fancier exception";
  assertThrowsEquals(() => instance.exports.rethrow_exnref(), exception2);
})();

// Test loading an imported mutable "exnref" being changed from the outside.
(function TestGlobalExnRefGetImportedMutableAndRethrow() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let g_index = builder.addImportedGlobal("m", "exn", kWasmExnRef, true);
  builder.addFunction('rethrow_exnref', kSig_v_v)
      .addBody([
        kExprGlobalGet, g_index,
        kExprRethrow,
      ]).exportFunc();
  let exception1 = "my fancy exception";
  let desc = { value: 'exnref', mutable: true };
  let mutable_global = new WebAssembly.Global(desc, exception1);
  let instance = builder.instantiate({ "m": { "exn": mutable_global }});

  assertThrowsEquals(() => instance.exports.rethrow_exnref(), exception1);
  let exception2 = mutable_global.value = "an even fancier exception";
  assertThrowsEquals(() => instance.exports.rethrow_exnref(), exception2);
})();

// Test custom initialization index for a global "exnref" variable.
(function TestGlobalExnRefInitIndex() {
  print(arguments.callee.name);
  let builder = new WasmModuleBuilder();
  let g1_index = builder.addImportedGlobal("m", "exn", kWasmExnRef);
  let g2 = builder.addGlobal(kWasmExnRef);
  g2.init_index = g1_index;  // Initialize {g2} to equal {g1}.
  builder.addFunction('push_and_return_exnref', kSig_e_v)
      .addBody([kExprGlobalGet, g2.index])
      .exportFunc();
  let exception = { x: "my fancy exception" };
  let instance = builder.instantiate({ "m": { "exn": exception }});

  assertSame(exception, instance.exports.push_and_return_exnref());
})();
