blob: 80d474fb87ee6c7670bb19d1f17ba6a22281f8e8 [file] [log] [blame]
// 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.
// Test setting and removing breakpoints in Wasm.
// Similar tests exist as inspector tests already, but inspector tests are not
// run concurrently in multiple isolates (see `run-tests.py --isolates`).
load('test/mjsunit/wasm/wasm-module-builder.js');
const builder = new WasmModuleBuilder();
const body_a = [
kExprLocalGet, 0, // local.get i0
kExprI32Const, 1, // i32.const 1
kExprI32Add // i32.add i0 1
];
const fun_a = builder.addFunction('a', kSig_i_i).addBody(body_a).exportFunc();
const body_b = [
kExprLocalGet, 0, // local.get i0
kExprCallFunction, fun_a.index, // call a
kExprLocalGet, 1, // local.get i1
kExprI32Sub, // i32.sub a(i0) i1
kExprCallFunction, fun_a.index, // call a
];
const fun_b = builder.addFunction('b', kSig_i_ii).addBody(body_b).exportFunc();
const instance = builder.instantiate();
Debug = debug.Debug;
const a_localget_offset = body_a.indexOf(kExprLocalGet);
const a_const_offset = body_a.indexOf(kExprI32Const);
const a_add_offset = body_a.indexOf(kExprI32Add);
const b_sub_offset = body_b.indexOf(kExprI32Sub);
const expected_breaks = [
`a:1:${fun_a.body_offset + a_add_offset}`, // break in a at i32.add
`b:1:${fun_b.body_offset + b_sub_offset}`, // break in b at i32.sub
`a:1:${fun_a.body_offset + a_localget_offset}`, // break in a at local.get i0
`a:1:${fun_a.body_offset + a_const_offset}` // break in a at i32.const 1
];
let error;
function onBreak(event, exec_state, data) {
try {
if (event != Debug.DebugEvent.Break) return;
if (error) return;
const pos =
[data.functionName(), data.sourceLine(), data.sourceColumn()].join(':');
const loc = [pos, data.sourceLineText()].join(':');
print(`Break at ${loc}`);
assertTrue(expected_breaks.length > 0, 'expecting more breaks');
const expected_pos = expected_breaks.shift();
assertEquals(expected_pos, pos);
// When we stop in b, we add another breakpoint in a at offset 0 and remove
// the existing breakpoint.
if (data.functionName() == 'b') {
Debug.setBreakPoint(instance.exports.a, 0, a_localget_offset);
Debug.clearBreakPoint(breakpoint_a);
}
// When we stop at a at local.get, we set another breakpoint *in the same
// function*, one instruction later (at i32.const).
if (data.functionName() == 'a' &&
data.sourceColumn() == fun_a.body_offset) {
Debug.setBreakPoint(instance.exports.a, 0, a_const_offset);
}
} catch (e) {
if (!error) error = e;
}
}
Debug.setListener(onBreak);
const breakpoint_a = Debug.setBreakPoint(instance.exports.a, 0, a_add_offset);
const breakpoint_b = Debug.setBreakPoint(instance.exports.b, 0, b_sub_offset);
print('Running b(11).');
const result = instance.exports.b(11);
print('Returned from wasm.');
if (error) throw error;
assertEquals(0, expected_breaks.length, 'all breaks were hit');