058299a881
Previously V8 would wrap the WebAssembly.Memory backing stores into Uint8Arrays and report that as memories, but that's confusing to the developer, since that's not what's really being used. The way that DevTools presents the backing stores of memories, it's still perfectly possible to get hold of an Uint8Array if that's what the developer is looking for. To make it possible to easily identify the WebAssembly.Memory objects in the DevTools front-end (in particular for the memory inspector) we add a 'webassemblymemory' subtype to the Chrome DevTools Protocol. We also improve the description for the memories to include the number of active pages. Fixed: chromium:1155566 Screenshot: https://imgur.com/8enx57u.png Change-Id: I63dbabe0e372e9ad6dcc8e6642cdb743147a620c Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2574699 Reviewed-by: Clemens Backes <clemensb@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Auto-Submit: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#71641}
104 lines
3.6 KiB
JavaScript
104 lines
3.6 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, imports) {
|
|
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, imports);
|
|
}
|
|
|
|
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' || value.subtype == 'webassemblymemory') return value.description;
|
|
if (name == 'instance') return dumpInstanceProperties(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 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}`
|
|
}
|