summaryrefslogtreecommitdiff
path: root/deps/v8/test/inspector/debugger/wasm-step-after-trap.js
blob: 7d396c5e1ce398b16d8ccc09f7d3bb0b4565ae88 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// 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)
    .addLocals(
        {i32_count: 2}, ['a', 'b', 'unused', '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}`);
    }
  }
}