wasm-step-after-trap.js 2.89 KB
Newer Older
1 2 3 4
// 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.

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

7 8 9 10 11 12 13
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.
14 15
builder.addFunction('div', kSig_i_iii, ['a', 'b', 'unused'])
    .addLocals(kWasmI32, 2, ['local_zero', 'local_const_11'])
16 17 18 19 20 21 22 23 24
    .addBody([
      kExprI32Const, 11,  // const 11
      kExprLocalSet, 4,   // set local #4 ('local_const_11')
      kExprLocalGet, 0,   // param 0
      kExprLocalGet, 1,   // param 1
      kExprI32DivS        // div
    ])
    .exportFunc();

25
const module_bytes = builder.toArray();
26 27 28 29 30

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

31
let actions = ['stepInto', 'resume', 'stepInto', 'resume'];
32 33 34 35 36 37 38 39 40
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();
41 42 43 44
  if (!action) {
    InspectorTest.log('ERROR: no more expected action');
    action = 'resume';
  }
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
  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());

65 66
InspectorTest.runAsyncTestSuite([
  async function test() {
67
    await Protocol.Runtime.enable();
68 69 70 71 72 73 74 75
    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()'});
  }
]);
76 77 78 79 80 81 82 83

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});
84 85 86
    for (let {name, value} of properties.result.result) {
      value = await WasmInspectorTest.getWasmValue(value);
      InspectorTest.log(`   ${name}: ${value}`);
87 88 89
    }
  }
}