b38c136948
It makes inspector tests a lot more readable if the opcode of the pause location is being printed. Since we already have a list of all opcodes available in wasm-module-builder.js, we can just reuse that to build a reverse lookup map. This CL implements this for single-byte opcodes only, which is enough for all tests that we currently have. It will have to be extended for prefixed opcodes once that is being used. R=thibaudm@chromium.org, kimanh@chromium.org Change-Id: I085fea99d2f5f2dc6cc084448e5f7444cce5c78b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2474789 Commit-Queue: Clemens Backes <clemensb@chromium.org> Reviewed-by: Kim-Anh Tran <kimanh@chromium.org> Reviewed-by: Thibaud Michaud <thibaudm@chromium.org> Cr-Commit-Position: refs/heads/master@{#70578}
122 lines
4.2 KiB
JavaScript
122 lines
4.2 KiB
JavaScript
// 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/mjsunit/wasm/wasm-module-builder.js');
|
|
|
|
WasmInspectorTest = {}
|
|
InspectorTest.getWasmOpcodeName = getOpcodeName;
|
|
|
|
WasmInspectorTest.evalWithUrl = (code, url) =>
|
|
Protocol.Runtime
|
|
.evaluate({'expression': code + '\n//# sourceURL=v8://test/' + url})
|
|
.then(printIfFailure);
|
|
|
|
WasmInspectorTest.instantiateFromBuffer = function(bytes) {
|
|
var buffer = new ArrayBuffer(bytes.length);
|
|
var view = new Uint8Array(buffer);
|
|
for (var i = 0; i < bytes.length; ++i) {
|
|
view[i] = bytes[i] | 0;
|
|
}
|
|
const module = new WebAssembly.Module(buffer);
|
|
return new WebAssembly.Instance(module);
|
|
}
|
|
|
|
WasmInspectorTest.instantiate = async function(bytes, instance_name = 'instance') {
|
|
const instantiate_code = `var ${instance_name} = (${WasmInspectorTest.instantiateFromBuffer})(${JSON.stringify(bytes)});`;
|
|
await WasmInspectorTest.evalWithUrl(instantiate_code, 'instantiate');
|
|
}
|
|
|
|
WasmInspectorTest.dumpScopeProperties = async function(message) {
|
|
printIfFailure(message);
|
|
for (var value of message.result.result) {
|
|
var value_str = await getScopeValues(value.name, value.value);
|
|
InspectorTest.log(' ' + value.name + ': ' + value_str);
|
|
}
|
|
}
|
|
|
|
WasmInspectorTest.getWasmValue = function(wasmValue) {
|
|
return typeof (wasmValue.value) === 'undefined' ?
|
|
wasmValue.unserializableValue :
|
|
wasmValue.value;
|
|
}
|
|
|
|
function printIfFailure(message) {
|
|
if (!message.result) {
|
|
InspectorTest.logMessage(message);
|
|
}
|
|
return message;
|
|
}
|
|
|
|
async function getScopeValues(name, value) {
|
|
if (value.type == 'object') {
|
|
if (value.subtype == 'typedarray') return value.description;
|
|
if (name == 'instance') return dumpInstanceProperties(value);
|
|
if (name == 'function tables') return dumpTables(value);
|
|
|
|
let msg = await Protocol.Runtime.getProperties({objectId: value.objectId});
|
|
printIfFailure(msg);
|
|
const printProperty = function(elem) {
|
|
const wasmValue = WasmInspectorTest.getWasmValue(elem.value);
|
|
return `"${elem.name}": ${wasmValue} (${elem.value.subtype})`;
|
|
}
|
|
return msg.result.result.map(printProperty).join(', ');
|
|
}
|
|
return WasmInspectorTest.getWasmValue(value) + ' (' + value.subtype + ')';
|
|
}
|
|
|
|
function recursiveGetPropertiesWrapper(value, depth) {
|
|
return recursiveGetProperties({result: {result: [value]}}, depth);
|
|
}
|
|
|
|
async function recursiveGetProperties(value, depth) {
|
|
if (depth > 0) {
|
|
const properties = await Promise.all(value.result.result.map(
|
|
x => {return Protocol.Runtime.getProperties({objectId: x.value.objectId});}));
|
|
const recursiveProperties = await Promise.all(properties.map(
|
|
x => {return recursiveGetProperties(x, depth - 1);}));
|
|
return recursiveProperties.flat();
|
|
}
|
|
return value;
|
|
}
|
|
|
|
async function dumpTables(tablesObj) {
|
|
let msg = await Protocol.Runtime.getProperties({objectId: tablesObj.objectId});
|
|
var tables_str = [];
|
|
for (var table of msg.result.result) {
|
|
const func_entries = await recursiveGetPropertiesWrapper(table, 2);
|
|
var functions = [];
|
|
for (var func of func_entries) {
|
|
for (var value of func.result.result) {
|
|
functions.push(`${value.name}: ${value.value.description}`);
|
|
}
|
|
}
|
|
const functions_str = functions.join(', ');
|
|
tables_str.push(` ${table.name}: ${functions_str}`);
|
|
}
|
|
return '\n' + tables_str.join('\n');
|
|
}
|
|
|
|
async function dumpInstanceProperties(instanceObj) {
|
|
function invokeGetter(property) {
|
|
return this[JSON.parse(property)];
|
|
}
|
|
|
|
const exportsName = 'exports';
|
|
let exportsObj = await Protocol.Runtime.callFunctionOn(
|
|
{objectId: instanceObj.objectId,
|
|
functionDeclaration: invokeGetter.toString(),
|
|
arguments: [{value: JSON.stringify(exportsName)}]
|
|
});
|
|
printIfFailure(exportsObj);
|
|
let exports = await Protocol.Runtime.getProperties(
|
|
{objectId: exportsObj.result.result.objectId});
|
|
printIfFailure(exports);
|
|
|
|
const printExports = function(value) {
|
|
return `"${value.name}" (${value.value.className})`;
|
|
}
|
|
const formattedExports = exports.result.result.map(printExports).join(', ');
|
|
return `${exportsName}: ${formattedExports}`
|
|
}
|