v8/test/inspector/protocol-test.js
clemensh 12cdb31b2f [inspector] Introduce debug::WasmScript
*and* report all "virtual" wasm scripts right when the wasm script is
registered at the inspector.

WasmScript is a subtype of Script, with the cast checking that it is
actually a wasm script.
This layout makes it quite easy to implement functionality that is only
available for wasm scripts, and allows to later directly use the
WasmCompiledModule instead of the i::Script for backing the
debug::WasmScript. We might also add virtual methods to
provide different implementations for GetSourcePosition, Source and
others.

DisassembleWasmFunction now also becomes a method of this class instead
of a static function on the DebugInterface.

The WasmTranslation now uses the new WasmScript type instead of the
Script wrapper, and also registers all virtual wasm scripts immediately
when the wasm script is made public to the inspector (when the wasm
module is created).

R=yangguo@chromium.org,dgozman@chromium.org,titzer@chromium.org
BUG=chromium:613110,chromium:659715

Review-Url: https://codereview.chromium.org/2531163010
Cr-Commit-Position: refs/heads/master@{#41519}
2016-12-06 13:20:36 +00:00

205 lines
6.2 KiB
JavaScript

// 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.
InspectorTest = {};
InspectorTest._dispatchTable = new Map();
InspectorTest._requestId = 0;
InspectorTest._dumpInspectorProtocolMessages = false;
InspectorTest._eventHandler = {};
Protocol = new Proxy({}, {
get: function(target, agentName, receiver) {
return new Proxy({}, {
get: function(target, methodName, receiver) {
const eventPattern = /^on(ce)?([A-Z][A-Za-z0-9]+)/;
var match = eventPattern.exec(methodName);
if (!match) {
return (args) => InspectorTest._sendCommandPromise(`${agentName}.${methodName}`, args || {});
} else {
var eventName = match[2];
eventName = eventName.charAt(0).toLowerCase() + eventName.slice(1);
if (match[1])
return (args) => InspectorTest._waitForEventPromise(`${agentName}.${eventName}`, args || {});
else
return (listener) => { InspectorTest._eventHandler[`${agentName}.${eventName}`] = listener };
}
}
});
}
});
InspectorTest.log = print.bind(null);
InspectorTest.logMessage = function(originalMessage)
{
var message = JSON.parse(JSON.stringify(originalMessage));
if (message.id)
message.id = "<messageId>";
const nonStableFields = new Set(["objectId", "scriptId", "exceptionId", "timestamp", "executionContextId", "callFrameId", "breakpointId"]);
var objects = [ message ];
while (objects.length) {
var object = objects.shift();
for (var key in object) {
if (nonStableFields.has(key))
object[key] = `<${key}>`;
else if (typeof object[key] === "object")
objects.push(object[key]);
}
}
InspectorTest.logObject(message);
return originalMessage;
}
InspectorTest.logObject = function(object, title)
{
var lines = [];
function dumpValue(value, prefix, prefixWithName)
{
if (typeof value === "object" && value !== null) {
if (value instanceof Array)
dumpItems(value, prefix, prefixWithName);
else
dumpProperties(value, prefix, prefixWithName);
} else {
lines.push(prefixWithName + String(value).replace(/\n/g, " "));
}
}
function dumpProperties(object, prefix, firstLinePrefix)
{
prefix = prefix || "";
firstLinePrefix = firstLinePrefix || prefix;
lines.push(firstLinePrefix + "{");
var propertyNames = Object.keys(object);
propertyNames.sort();
for (var i = 0; i < propertyNames.length; ++i) {
var name = propertyNames[i];
if (!object.hasOwnProperty(name))
continue;
var prefixWithName = " " + prefix + name + " : ";
dumpValue(object[name], " " + prefix, prefixWithName);
}
lines.push(prefix + "}");
}
function dumpItems(object, prefix, firstLinePrefix)
{
prefix = prefix || "";
firstLinePrefix = firstLinePrefix || prefix;
lines.push(firstLinePrefix + "[");
for (var i = 0; i < object.length; ++i)
dumpValue(object[i], " " + prefix, " " + prefix + "[" + i + "] : ");
lines.push(prefix + "]");
}
dumpValue(object, "", title || "");
InspectorTest.log(lines.join("\n"));
}
InspectorTest.completeTest = function()
{
Protocol.Debugger.disable().then(() => quit());
}
InspectorTest.completeTestAfterPendingTimeouts = function()
{
Protocol.Runtime.evaluate({
expression: "new Promise(resolve => setTimeout(resolve, 0))",
awaitPromise: true }).then(InspectorTest.completeTest);
}
InspectorTest.addScript = (string) => compileAndRunWithOrigin(string, "", 0, 0);
InspectorTest.addScriptWithUrl = (string, url) => compileAndRunWithOrigin(string, url, 0, 0);
InspectorTest.startDumpingProtocolMessages = function()
{
InspectorTest._dumpInspectorProtocolMessages = true;
}
InspectorTest.sendRawCommand = function(requestId, command, handler)
{
if (InspectorTest._dumpInspectorProtocolMessages)
print("frontend: " + command);
InspectorTest._dispatchTable.set(requestId, handler);
sendMessageToBackend(command);
}
InspectorTest.checkExpectation = function(fail, name, messageObject)
{
if (fail === !!messageObject.error) {
InspectorTest.log("PASS: " + name);
return true;
}
InspectorTest.log("FAIL: " + name + ": " + JSON.stringify(messageObject));
InspectorTest.completeTest();
return false;
}
InspectorTest.expectedSuccess = InspectorTest.checkExpectation.bind(null, false);
InspectorTest.expectedError = InspectorTest.checkExpectation.bind(null, true);
InspectorTest.runTestSuite = function(testSuite)
{
function nextTest()
{
if (!testSuite.length) {
InspectorTest.completeTest();
return;
}
var fun = testSuite.shift();
InspectorTest.log("\nRunning test: " + fun.name);
fun(nextTest);
}
nextTest();
}
InspectorTest._sendCommandPromise = function(method, params)
{
var requestId = ++InspectorTest._requestId;
var messageObject = { "id": requestId, "method": method, "params": params };
var fulfillCallback;
var promise = new Promise(fulfill => fulfillCallback = fulfill);
InspectorTest.sendRawCommand(requestId, JSON.stringify(messageObject), fulfillCallback);
return promise;
}
InspectorTest._waitForEventPromise = function(eventName)
{
return new Promise(fulfill => InspectorTest._eventHandler[eventName] = fullfillAndClearListener.bind(null, fulfill));
function fullfillAndClearListener(fulfill, result)
{
delete InspectorTest._eventHandler[eventName];
fulfill(result);
}
}
InspectorTest._dispatchMessage = function(messageObject)
{
if (InspectorTest._dumpInspectorProtocolMessages)
print("backend: " + JSON.stringify(messageObject));
try {
var messageId = messageObject["id"];
if (typeof messageId === "number") {
var handler = InspectorTest._dispatchTable.get(messageId);
if (handler) {
handler(messageObject);
InspectorTest._dispatchTable.delete(messageId);
}
} else {
var eventName = messageObject["method"];
var eventHandler = InspectorTest._eventHandler[eventName];
if (eventHandler)
eventHandler(messageObject);
}
} catch (e) {
InspectorTest.log("Exception when dispatching message: " + e + "\n" + e.stack + "\n message = " + JSON.stringify(messageObject, null, 2));
InspectorTest.completeTest();
}
}