blob: 0849840abe4747e24e2e2bb54427b36f4ab79b20 [file] [log] [blame]
// Copyright 2016 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.
// Flags: --expose-wasm
utils.load('test/inspector/wasm-inspector-test.js');
InspectorTest.log("Tests how wasm scripts are reported");
let contextGroup = new InspectorTest.ContextGroup();
let sessions = [
// Main session.
trackScripts(),
// Extra session to verify that all inspectors get same messages.
// See https://bugs.chromium.org/p/v8/issues/detail?id=9725.
trackScripts(),
];
// Create module with given custom sections.
function createModule(...customSections) {
var builder = new WasmModuleBuilder();
builder.addFunction('nopFunction', kSig_v_v).addBody([kExprNop]);
builder.addFunction('main', kSig_v_v)
.addBody([kExprBlock, kWasmStmt, kExprI32Const, 2, kExprDrop, kExprEnd])
.exportAs('main');
for (var { name, value } of customSections) {
builder.addCustomSection(name, value);
}
return builder.toArray();
}
function testFunction(bytes) {
// Compilation triggers registration of wasm scripts.
new WebAssembly.Module(new Uint8Array(bytes));
}
// Generate stable IDs.
let scriptIds = {};
function nextStableId(id) {
if (!(id in scriptIds)) {
scriptIds[id] = Object.keys(scriptIds).length;
}
return scriptIds[id];
}
contextGroup.addScript(testFunction.toString(), 0, 0, 'v8://test/testFunction');
InspectorTest.log(
'Check that each inspector gets a wasm script at module creation time.');
// Sample .debug_info section.
// Content doesn't matter, as we don't try to parse it in V8,
// but should be non-empty to check that we're skipping it correctly.
const embeddedDWARFSection = {
name: '.debug_info',
value: [1, 2, 3, 4, 5]
};
// Sample external_debug_info section set to "abc".
const externalDWARFSection = {
name: 'external_debug_info',
value: [3, 97, 98, 99]
};
// Sample sourceMappingURL section set to "abc".
const sourceMapSection = {
name: 'sourceMappingURL',
value: [3, 97, 98, 99]
};
sessions[0]
.Protocol.Runtime
.evaluate({
'expression': `//# sourceURL=v8://test/runTestRunction
// no debug info
testFunction([${createModule()}]);
// shared script for identical modules
testFunction([${createModule()}]);
// External DWARF
testFunction([${createModule(externalDWARFSection)}]);
// Embedded DWARF
testFunction([${createModule(embeddedDWARFSection)}]);
// Source map
testFunction([${createModule(sourceMapSection)}]);
// SourceMap + External DWARF
testFunction([${createModule(sourceMapSection, externalDWARFSection)}]);
// External DWARF + SourceMap (different order)
testFunction([${createModule(externalDWARFSection, sourceMapSection)}]);
// Embedded DWARF + External DWARF
testFunction([${
createModule(embeddedDWARFSection, externalDWARFSection)}]);
// External + Embedded DWARF (different order)
testFunction([${
createModule(externalDWARFSection, embeddedDWARFSection)}]);
// Embedded DWARF + source map
testFunction([${createModule(embeddedDWARFSection, sourceMapSection)}]);
// Source map + Embedded DWARF (different order)
testFunction([${createModule(sourceMapSection, embeddedDWARFSection)}]);
`
})
.then(
() => (
// At this point all scripts were parsed.
// Stop tracking and wait for script sources in each session.
Promise.all(sessions.map(session => session.getScripts()))))
.catch(err => {
InspectorTest.log(err.stack);
})
.then(() => InspectorTest.completeTest());
function trackScripts(debuggerParams) {
let {id: sessionId, Protocol} = contextGroup.connect();
let scripts = [];
Protocol.Debugger.enable(debuggerParams);
Protocol.Debugger.onScriptParsed(handleScriptParsed);
async function loadScript({
url,
scriptId,
sourceMapURL,
startColumn,
endColumn,
codeOffset,
debugSymbols
}) {
let stableId = nextStableId(scriptId);
InspectorTest.log(`Session #${sessionId}: Script #${
scripts.length} parsed. URL: ${url}. Script ID: ${
stableId}, Source map URL: ${sourceMapURL}, debug symbols: ${
debugSymbols.type}:${debugSymbols.externalURL}. module begin: ${
startColumn}, module end: ${endColumn}, code offset: ${codeOffset}`);
let {result: {scriptSource, bytecode}} =
await Protocol.Debugger.getScriptSource({scriptId});
if (bytecode) {
if (scriptSource) {
InspectorTest.log('Unexpected scriptSource with bytecode: ');
InspectorTest.log(scriptSource);
}
// Binary value is represented as base64 in JSON, decode it.
bytecode = InspectorTest.decodeBase64(bytecode);
// Check that it can be parsed back to a WebAssembly module.
let module = new WebAssembly.Module(bytecode);
scriptSource =
`
Raw: ${Array.from(bytecode, b => ('0' + b.toString(16)).slice(-2)).join(' ')}
Imports: [${
WebAssembly.Module.imports(module)
.map(i => `${i.name}: ${i.kind} from "${i.module}"`)
.join(', ')}]
Exports: [${
WebAssembly.Module.exports(module)
.map(e => `${e.name}: ${e.kind}`)
.join(', ')}]
`.trim();
}
InspectorTest.log(`Session #${sessionId}: Source for ${url}:`);
InspectorTest.log(scriptSource);
}
function handleScriptParsed({params}) {
if (params.url.startsWith('wasm://')) {
scripts.push(loadScript(params));
}
}
return {
Protocol,
getScripts: () => Promise.all(scripts),
};
}