// Copyright 2020 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.

utils.load('test/inspector/wasm-inspector-test.js');

const {session, contextGroup, Protocol} =
    InspectorTest.start('Test scope inspection and stepping after a trap.');
session.setupScriptMap();

const builder = new WasmModuleBuilder();

// Create a function which computes the div of the first two arguments.
builder.addFunction('div', kSig_i_iii, ['a', 'b', 'unused'])
    .addLocals(kWasmI32, 2, ['local_zero', 'local_const_11'])
    .addBody([
      kExprI32Const, 11,  // const 11
      kExprLocalSet, 4,   // set local #4 ('local_const_11')
      kExprLocalGet, 0,   // param 0
      kExprLocalGet, 1,   // param 1
      kExprI32DivS        // div
    ])
    .exportFunc();

const module_bytes = builder.toArray();

function getShortLocationString(location) {
  return `${location.lineNumber}:${location.columnNumber}`;
}

let actions = ['stepInto', 'resume', 'stepInto', 'resume'];
Protocol.Debugger.onPaused(async msg => {
  InspectorTest.log('Paused at:');
  for (let [nr, frame] of msg.params.callFrames.entries()) {
    InspectorTest.log(`--- ${nr} ---`);
    await session.logSourceLocation(frame.location);
    if (/^wasm/.test(frame.url)) await printLocalScope(frame);
  }
  InspectorTest.log('-------------');
  let action = actions.shift();
  if (!action) {
    InspectorTest.log('ERROR: no more expected action');
    action = 'resume';
  }
  InspectorTest.log(`-> ${action}`);
  Protocol.Debugger[action]();
});

function call_div() {
  instance.exports.div(0, 1, 4711);  // does not trap
  try {
    instance.exports.div(1, 0, 4711);  // traps (div by zero)
  } catch (e) {
    e.stack;  // step target of first pause
  }
  try {
    instance.exports.div(0x80000000, -1, 4711);  // traps (unrepresentable)
  } catch (e) {
    e.stack;  // step target of second pause
  }
}

contextGroup.addScript(call_div.toString());

(async function test() {
  await Protocol.Debugger.enable();
  await Protocol.Debugger.setPauseOnExceptions({state: 'all'});
  InspectorTest.log('Instantiating.');
  await WasmInspectorTest.instantiate(module_bytes);
  InspectorTest.log('Calling div function.');
  await Protocol.Runtime.evaluate({'expression': 'call_div()'});
  InspectorTest.log('Finished.');
  InspectorTest.completeTest();
})();

async function printLocalScope(frame) {
  InspectorTest.log(`scope at ${frame.functionName} (${
      frame.location.lineNumber}:${frame.location.columnNumber}):`);
  for (let scope of frame.scopeChain) {
    if (scope.type != 'local') continue;
    let properties = await Protocol.Runtime.getProperties(
        {'objectId': scope.object.objectId});
    for (let value of properties.result.result) {
      InspectorTest.log(`   ${value.name}: ${value.value.value}`);
    }
  }
}
