// 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'); let {session, contextGroup, Protocol} = InspectorTest.start('Tests if breakpoint set is first breakable location'); var builder = new WasmModuleBuilder(); // clang-format off var func_idx = builder.addFunction('helper', kSig_v_v) .addLocals(kWasmI32, 1) .addBody([ kExprNop, kExprI32Const, 12, kExprLocalSet, 0, ]).index; builder.addFunction('main', kSig_v_i) .addBody([ kExprLocalGet, 0, kExprIf, kWasmVoid, kExprBlock, kWasmVoid, kExprCallFunction, func_idx, kExprEnd, kExprEnd ]).exportAs('main'); // clang-format on var module_bytes = builder.toArray(); Protocol.Runtime.enable(); Protocol.Debugger.enable(); InspectorTest.runAsyncTestSuite([ async function test() { InspectorTest.log('Running test function...'); WasmInspectorTest.instantiate(module_bytes); const [, {params: wasmScript}] = await Protocol.Debugger.onceScriptParsed(2); await checkSetBreakpointForScript(wasmScript.scriptId); } ]); function printFailure(message) { if (!message.result) { InspectorTest.logMessage(message); } } async function checkSetBreakpointForScript(scriptId) { // If we try to set a breakpoint that is outside of any function, // setBreakpoint should not add any breakpoint. InspectorTest.log('Set breakpoint outside of any function: (0, 0).'); await checkSetBreakpointIsFirstBreakableLocation(scriptId, 0, 0, undefined); // If we try to set a breakpoint that is inside of a function and // the location is breakable, setBreakpoint is expected to add // a breakpoint at that location. InspectorTest.log('Set breakpoint at a breakable location: (0, 40).'); let breakable = true; await checkSetBreakpointIsFirstBreakableLocation(scriptId, 0, 40, breakable); // If we try to set a breakpoint that is inside of a function and // the location is not breakable, setBreakpoint is expected to add // a breakpoint at the next breakable location. InspectorTest.log('Set breakpoint at non-breakable location: (0, 42).') breakable = false; await checkSetBreakpointIsFirstBreakableLocation(scriptId, 0, 42, breakable); } async function checkSetBreakpointIsFirstBreakableLocation( scriptId, lineNumber, columnNumber, breakable) { // Choose an arbitrary end column number, as long as a breakable location is // contained. const endColumnNumber = columnNumber + 10; const possibleLocationsMsg = await Protocol.Debugger.getPossibleBreakpoints({ start: { lineNumber: lineNumber, columnNumber: columnNumber, scriptId: scriptId }, end: { lineNumber: lineNumber, columnNumber: endColumnNumber, scriptId: scriptId } }); const possibleLocations = possibleLocationsMsg.result.locations; const setLocationMsg = await setBreakpoint(scriptId, lineNumber, columnNumber); if (!setLocationMsg.result) { InspectorTest.log('Set breakpoint could not resolve break location.'); return; } var setLocation = setLocationMsg.result.actualLocation; // Check that setting a breakpoint at a line actually // sets the breakpoint at the first breakable location. locationIsEqual(setLocation, possibleLocations[0]); // Make sure that the selected locations for the test // are breakable/non breakable as expected. if (breakable === (setLocation.lineNumber === lineNumber && setLocation.columnNumber === columnNumber)) { InspectorTest.log( `Initial location is expected to be breakable: ${breakable}.`); }; } function locationIsEqual(locA, locB) { if (locA.lineNumber === locB.lineNumber && locA.columnNumber === locB.columnNumber) { InspectorTest.log( `Location match for (${locA.lineNumber}, ${locA.columnNumber}).`); } } async function setBreakpoint(id, lineNumber, columnNumber) { InspectorTest.log( `Setting breakpoint for id: ${id} at ${lineNumber}, ${columnNumber}.`); const location = { scriptId: id, lineNumber: lineNumber, columnNumber: columnNumber }; const msg = await Protocol.Debugger.setBreakpoint({location: location}); printFailure(msg); return msg; }