// Copyright 2016 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-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");

// Collect the Callsite objects instead of just a string:
Error.prepareStackTrace = function(error, frames) {
  return frames;
};

function testTrapLocations(instance, expected_stack_length) {
  function testWasmTrap(value, reason, position) {
    let function_name = arguments.callee.name;
    try {
      instance.exports.main(value);
      fail('expected wasm exception');
    } catch (e) {
      assertEquals(kTrapMsgs[reason], e.message, 'trap reason');
      // Check that the trapping function is the one which was called from this
      // function.
      assertTrue(
          e.stack[1].toString().startsWith(function_name), 'stack depth');
      assertEquals(0, e.stack[0].getLineNumber(), 'wasmFunctionIndex');
      assertEquals(position, e.stack[0].getPosition(), 'position');
    }
  }

  // The actual tests:
  testWasmTrap(0, kTrapDivByZero, 14);
  testWasmTrap(1, kTrapMemOutOfBounds, 15);
  testWasmTrap(2, kTrapUnreachable, 28);
  testWasmTrap(3, kTrapFuncInvalid, 32);
}

var builder = new WasmModuleBuilder();
builder.addMemory(0, 1, false);
var sig_index = builder.addType(kSig_i_v)

// Build a function to resemble this code:
//   if (idx < 2) {
//     return load(-2 / idx);
//   } else if (idx == 2) {
//     unreachable;
//   } else {
//     return call_indirect(idx);
//   }
// There are four different traps which are triggered by different input values:
// (0) division by zero; (1) mem oob; (2) unreachable; (3) invalid call target
// Each of them also has a different location where it traps.
builder.addFunction("main", kSig_i_i)
  .addBody([
      // offset 1
        kExprBlock, kWasmI32,
            kExprGetLocal, 0,
            kExprI32Const, 2,
          kExprI32LtU,
        kExprIf, kWasmStmt,
        // offset 9
              kExprI32Const, 0x7e /* -2 */,
              kExprGetLocal, 0,
            kExprI32DivU,
          // offset 15
          kExprI32LoadMem, 0, 0,
          kExprBr, 1,
        kExprEnd,
        // offset 21
            kExprGetLocal, 0,
            kExprI32Const, 2,
          kExprI32Eq,
        kExprIf, kWasmStmt,
          kExprUnreachable,
        kExprEnd,
        // offset 30
        kExprGetLocal, 0,
        kExprCallIndirect, sig_index, kTableZero,
      kExprEnd,
  ])
  .exportAs("main");
builder.appendToTable([0]);

let buffer = builder.toBuffer();

// Test async compilation and instantiation.
assertPromiseResult(WebAssembly.instantiate(buffer), pair => {
  testTrapLocations(pair.instance, 5);
});

// Test sync compilation and instantiation.
testTrapLocations(builder.instantiate(), 4);
