Revert of [inspector] console get all information from inspector when needed (patchset #4 id:60001 of https://codereview.chromium.org/2784713002/ )

Reason for revert:
Breaks layout tests:
https://build.chromium.org/p/client.v8.fyi/builders/V8-Blink%20Linux%2064/builds/14569

Original issue's description:
> [inspector] console get all information from inspector when needed
>
> With this CL we don't need to store reference to InspectedContext inside of JavaScript console object and able to get all required information from callback data.
> It allows us to implement console methods without taking in account how and where we create and store these methods:
> - later we can move console object implementation to builtins..
> - ..and install command line API methods smarter.
>
> BUG=chromium:588893
> R=dgozman@chromium.org
>
> Review-Url: https://codereview.chromium.org/2784713002
> Cr-Commit-Position: refs/heads/master@{#44212}
> Committed: 908cd38123

TBR=dgozman@chromium.org,kozyatinskiy@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=chromium:588893

Review-Url: https://codereview.chromium.org/2784603003
Cr-Commit-Position: refs/heads/master@{#44217}
This commit is contained in:
machenbach 2017-03-29 00:37:37 -07:00 committed by Commit bot
parent 1608919603
commit f11719ce79
9 changed files with 270 additions and 962 deletions

View File

@ -14,6 +14,23 @@
namespace v8_inspector { namespace v8_inspector {
namespace {
void clearContext(const v8::WeakCallbackInfo<v8::Global<v8::Context>>& data) {
// Inspected context is created in V8InspectorImpl::contextCreated method
// and destroyed in V8InspectorImpl::contextDestroyed.
// Both methods takes valid v8::Local<v8::Context> handle to the same context,
// it means that context is created before InspectedContext constructor and is
// always destroyed after InspectedContext destructor therefore this callback
// should be never called.
// It's possible only if inspector client doesn't call contextDestroyed which
// is considered an error.
CHECK(false);
data.GetParameter()->Reset();
}
} // namespace
InspectedContext::InspectedContext(V8InspectorImpl* inspector, InspectedContext::InspectedContext(V8InspectorImpl* inspector,
const V8ContextInfo& info, int contextId) const V8ContextInfo& info, int contextId)
: m_inspector(inspector), : m_inspector(inspector),
@ -27,18 +44,27 @@ InspectedContext::InspectedContext(V8InspectorImpl* inspector,
v8::Isolate* isolate = m_inspector->isolate(); v8::Isolate* isolate = m_inspector->isolate();
info.context->SetEmbedderData(static_cast<int>(v8::Context::kDebugIdIndex), info.context->SetEmbedderData(static_cast<int>(v8::Context::kDebugIdIndex),
v8::Int32::New(isolate, contextId)); v8::Int32::New(isolate, contextId));
m_context.SetWeak(&m_context, &clearContext,
v8::WeakCallbackType::kParameter);
v8::Local<v8::Object> global = info.context->Global(); v8::Local<v8::Object> global = info.context->Global();
v8::Local<v8::Object> console = v8::Local<v8::Object> console =
V8Console::createConsole(this, info.hasMemoryOnConsole); V8Console::createConsole(this, info.hasMemoryOnConsole);
if (!global if (!global
->Set(info.context, toV8StringInternalized(isolate, "console"), ->Set(info.context, toV8StringInternalized(isolate, "console"),
console) console)
.FromMaybe(false)) { .FromMaybe(false))
return; return;
} m_console.Reset(isolate, console);
m_console.SetWeak();
} }
InspectedContext::~InspectedContext() { InspectedContext::~InspectedContext() {
if (!m_console.IsEmpty()) {
v8::HandleScope scope(isolate());
V8Console::clearInspectedContextIfNeeded(context(),
m_console.Get(isolate()));
}
} }
// static // static

View File

@ -53,6 +53,7 @@ class InspectedContext {
const String16 m_auxData; const String16 m_auxData;
bool m_reported; bool m_reported;
std::unique_ptr<InjectedScript> m_injectedScript; std::unique_ptr<InjectedScript> m_injectedScript;
v8::Global<v8::Object> m_console;
DISALLOW_COPY_AND_ASSIGN(InspectedContext); DISALLOW_COPY_AND_ASSIGN(InspectedContext);
}; };

View File

@ -353,11 +353,15 @@ ConsoleAPIType V8ConsoleMessage::type() const { return m_type; }
// static // static
std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForConsoleAPI( std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForConsoleAPI(
v8::Local<v8::Context> v8Context, int contextId, int groupId, double timestamp, ConsoleAPIType type,
V8InspectorImpl* inspector, double timestamp, ConsoleAPIType type,
const std::vector<v8::Local<v8::Value>>& arguments, const std::vector<v8::Local<v8::Value>>& arguments,
std::unique_ptr<V8StackTraceImpl> stackTrace) { std::unique_ptr<V8StackTraceImpl> stackTrace,
v8::Isolate* isolate = v8Context->GetIsolate(); InspectedContext* inspectedContext) {
v8::Isolate* isolate = inspectedContext->isolate();
int contextId = inspectedContext->contextId();
int contextGroupId = inspectedContext->contextGroupId();
V8InspectorImpl* inspector = inspectedContext->inspector();
v8::Local<v8::Context> context = inspectedContext->context();
std::unique_ptr<V8ConsoleMessage> message( std::unique_ptr<V8ConsoleMessage> message(
new V8ConsoleMessage(V8MessageOrigin::kConsole, timestamp, String16())); new V8ConsoleMessage(V8MessageOrigin::kConsole, timestamp, String16()));
@ -376,8 +380,7 @@ std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForConsoleAPI(
v8::debug::EstimatedValueSize(isolate, arguments.at(i)); v8::debug::EstimatedValueSize(isolate, arguments.at(i));
} }
if (arguments.size()) if (arguments.size())
message->m_message = message->m_message = V8ValueStringBuilder::toString(arguments[0], context);
V8ValueStringBuilder::toString(arguments[0], v8Context);
v8::Isolate::MessageErrorLevel clientLevel = v8::Isolate::kMessageInfo; v8::Isolate::MessageErrorLevel clientLevel = v8::Isolate::kMessageInfo;
if (type == ConsoleAPIType::kDebug || type == ConsoleAPIType::kCount || if (type == ConsoleAPIType::kDebug || type == ConsoleAPIType::kCount ||
@ -394,7 +397,7 @@ std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForConsoleAPI(
if (type != ConsoleAPIType::kClear) { if (type != ConsoleAPIType::kClear) {
inspector->client()->consoleAPIMessage( inspector->client()->consoleAPIMessage(
groupId, clientLevel, toStringView(message->m_message), contextGroupId, clientLevel, toStringView(message->m_message),
toStringView(message->m_url), message->m_lineNumber, toStringView(message->m_url), message->m_lineNumber,
message->m_columnNumber, message->m_stackTrace.get()); message->m_columnNumber, message->m_stackTrace.get());
} }
@ -487,37 +490,8 @@ void V8ConsoleMessageStorage::clear() {
m_messages.clear(); m_messages.clear();
m_estimatedSize = 0; m_estimatedSize = 0;
if (V8InspectorSessionImpl* session = if (V8InspectorSessionImpl* session =
m_inspector->sessionForContextGroup(m_contextGroupId)) { m_inspector->sessionForContextGroup(m_contextGroupId))
session->releaseObjectGroup("console"); session->releaseObjectGroup("console");
}
m_data.clear();
}
bool V8ConsoleMessageStorage::shouldReportDeprecationMessage(
int contextId, const String16& method) {
std::set<String16>& reportedDeprecationMessages =
m_data[contextId].m_reportedDeprecationMessages;
auto it = reportedDeprecationMessages.find(method);
if (it != reportedDeprecationMessages.end()) return false;
reportedDeprecationMessages.insert(it, method);
return true;
}
int V8ConsoleMessageStorage::count(int contextId, const String16& id) {
return ++m_data[contextId].m_count[id];
}
void V8ConsoleMessageStorage::time(int contextId, const String16& id) {
m_data[contextId].m_time[id] = m_inspector->client()->currentTimeMS();
}
double V8ConsoleMessageStorage::timeEnd(int contextId, const String16& id) {
std::map<String16, double>& time = m_data[contextId].m_time;
auto it = time.find(id);
if (it == time.end()) return 0.0;
double elapsed = m_inspector->client()->currentTimeMS() - it->second;
time.erase(it);
return elapsed;
} }
void V8ConsoleMessageStorage::contextDestroyed(int contextId) { void V8ConsoleMessageStorage::contextDestroyed(int contextId) {
@ -526,8 +500,6 @@ void V8ConsoleMessageStorage::contextDestroyed(int contextId) {
m_messages[i]->contextDestroyed(contextId); m_messages[i]->contextDestroyed(contextId);
m_estimatedSize += m_messages[i]->estimatedSize(); m_estimatedSize += m_messages[i]->estimatedSize();
} }
auto it = m_data.find(contextId);
if (it != m_data.end()) m_data.erase(contextId);
} }
} // namespace v8_inspector } // namespace v8_inspector

View File

@ -6,8 +6,6 @@
#define V8_INSPECTOR_V8CONSOLEMESSAGE_H_ #define V8_INSPECTOR_V8CONSOLEMESSAGE_H_
#include <deque> #include <deque>
#include <map>
#include <set>
#include "include/v8.h" #include "include/v8.h"
#include "src/inspector/protocol/Console.h" #include "src/inspector/protocol/Console.h"
#include "src/inspector/protocol/Forward.h" #include "src/inspector/protocol/Forward.h"
@ -46,10 +44,9 @@ class V8ConsoleMessage {
~V8ConsoleMessage(); ~V8ConsoleMessage();
static std::unique_ptr<V8ConsoleMessage> createForConsoleAPI( static std::unique_ptr<V8ConsoleMessage> createForConsoleAPI(
v8::Local<v8::Context> v8Context, int contextId, int groupId, double timestamp, ConsoleAPIType,
V8InspectorImpl* inspector, double timestamp, ConsoleAPIType,
const std::vector<v8::Local<v8::Value>>& arguments, const std::vector<v8::Local<v8::Value>>& arguments,
std::unique_ptr<V8StackTraceImpl>); std::unique_ptr<V8StackTraceImpl>, InspectedContext*);
static std::unique_ptr<V8ConsoleMessage> createForException( static std::unique_ptr<V8ConsoleMessage> createForException(
double timestamp, const String16& detailedMessage, const String16& url, double timestamp, const String16& detailedMessage, const String16& url,
@ -115,23 +112,11 @@ class V8ConsoleMessageStorage {
void contextDestroyed(int contextId); void contextDestroyed(int contextId);
void clear(); void clear();
bool shouldReportDeprecationMessage(int contextId, const String16& method);
int count(int contextId, const String16& id);
void time(int contextId, const String16& id);
double timeEnd(int contextId, const String16& id);
private: private:
V8InspectorImpl* m_inspector; V8InspectorImpl* m_inspector;
int m_contextGroupId; int m_contextGroupId;
int m_estimatedSize = 0; int m_estimatedSize = 0;
std::deque<std::unique_ptr<V8ConsoleMessage>> m_messages; std::deque<std::unique_ptr<V8ConsoleMessage>> m_messages;
struct PerContextData {
std::set<String16> m_reportedDeprecationMessages;
std::map<String16, int> m_count;
std::map<String16, double> m_time;
};
std::map<int, PerContextData> m_data;
}; };
} // namespace v8_inspector } // namespace v8_inspector

View File

@ -23,31 +23,49 @@ namespace v8_inspector {
namespace { namespace {
v8::Local<v8::Private> inspectedContextPrivateKey(v8::Isolate* isolate) {
return v8::Private::ForApi(
isolate, toV8StringInternalized(isolate, "V8Console#InspectedContext"));
}
class ConsoleHelper { class ConsoleHelper {
public: public:
explicit ConsoleHelper(const v8::FunctionCallbackInfo<v8::Value>& info) explicit ConsoleHelper(const v8::FunctionCallbackInfo<v8::Value>& info)
: m_info(info), : m_info(info),
m_isolate(info.GetIsolate()), m_isolate(info.GetIsolate()),
m_context(info.GetIsolate()->GetCurrentContext()), m_context(info.GetIsolate()->GetCurrentContext()),
m_contextId(InspectedContext::contextId(m_context)) { m_inspectedContext(nullptr),
m_inspector = static_cast<V8InspectorImpl*>( m_inspectorClient(nullptr) {}
m_info.Data().As<v8::External>()->Value());
m_groupId = m_inspector->contextGroupId(m_contextId); v8::Local<v8::Object> ensureConsole() {
if (m_console.IsEmpty()) {
DCHECK(!m_info.Data().IsEmpty());
DCHECK(!m_info.Data()->IsUndefined());
m_console = m_info.Data().As<v8::Object>();
}
return m_console;
} }
V8InspectorImpl* inspector() { return m_inspector; } InspectedContext* ensureInspectedContext() {
if (m_inspectedContext) return m_inspectedContext;
v8::Local<v8::Object> console = ensureConsole();
int contextId() const { return m_contextId; } v8::Local<v8::Private> key = inspectedContextPrivateKey(m_isolate);
int groupId() const { return m_groupId; } v8::Local<v8::Value> inspectedContextValue;
if (!console->GetPrivate(m_context, key).ToLocal(&inspectedContextValue))
InjectedScript* injectedScript() { return nullptr;
InspectedContext* context = m_inspector->getContext(m_groupId, m_contextId); DCHECK(inspectedContextValue->IsExternal());
if (!context) return nullptr; m_inspectedContext = static_cast<InspectedContext*>(
return context->getInjectedScript(); inspectedContextValue.As<v8::External>()->Value());
return m_inspectedContext;
} }
V8ConsoleMessageStorage* consoleMessageStorage() { V8InspectorClient* ensureDebuggerClient() {
return inspector()->ensureConsoleMessageStorage(m_groupId); if (m_inspectorClient) return m_inspectorClient;
InspectedContext* inspectedContext = ensureInspectedContext();
if (!inspectedContext) return nullptr;
m_inspectorClient = inspectedContext->inspector()->client();
return m_inspectorClient;
} }
void reportCall(ConsoleAPIType type) { void reportCall(ConsoleAPIType type) {
@ -73,19 +91,20 @@ class ConsoleHelper {
void reportCall(ConsoleAPIType type, void reportCall(ConsoleAPIType type,
const std::vector<v8::Local<v8::Value>>& arguments) { const std::vector<v8::Local<v8::Value>>& arguments) {
InspectedContext* inspectedContext = ensureInspectedContext();
if (!inspectedContext) return;
int contextGroupId = inspectedContext->contextGroupId();
V8InspectorImpl* inspector = inspectedContext->inspector();
std::unique_ptr<V8ConsoleMessage> message = std::unique_ptr<V8ConsoleMessage> message =
V8ConsoleMessage::createForConsoleAPI( V8ConsoleMessage::createForConsoleAPI(
m_context, m_contextId, m_groupId, m_inspector, inspector->client()->currentTimeMS(), type, arguments,
m_inspector->client()->currentTimeMS(), type, arguments, inspector->debugger()->captureStackTrace(false), inspectedContext);
m_inspector->debugger()->captureStackTrace(false)); inspector->ensureConsoleMessageStorage(contextGroupId)
consoleMessageStorage()->addMessage(std::move(message)); ->addMessage(std::move(message));
} }
void reportDeprecatedCall(const char* id, const String16& message) { void reportDeprecatedCall(const char* id, const String16& message) {
if (!consoleMessageStorage()->shouldReportDeprecationMessage(m_contextId, if (checkAndSetPrivateFlagOnConsole(id, false)) return;
id)) {
return;
}
std::vector<v8::Local<v8::Value>> arguments(1, std::vector<v8::Local<v8::Value>> arguments(1,
toV8String(m_isolate, message)); toV8String(m_isolate, message));
reportCall(ConsoleAPIType::kWarning, arguments); reportCall(ConsoleAPIType::kWarning, arguments);
@ -126,6 +145,56 @@ class ConsoleHelper {
return func; return func;
} }
v8::MaybeLocal<v8::Map> privateMap(const char* name) {
v8::Local<v8::Object> console = ensureConsole();
v8::Local<v8::Private> privateKey =
v8::Private::ForApi(m_isolate, toV8StringInternalized(m_isolate, name));
v8::Local<v8::Value> mapValue;
if (!console->GetPrivate(m_context, privateKey).ToLocal(&mapValue))
return v8::MaybeLocal<v8::Map>();
if (mapValue->IsUndefined()) {
v8::Local<v8::Map> map = v8::Map::New(m_isolate);
if (!console->SetPrivate(m_context, privateKey, map).FromMaybe(false))
return v8::MaybeLocal<v8::Map>();
return map;
}
return mapValue->IsMap() ? mapValue.As<v8::Map>()
: v8::MaybeLocal<v8::Map>();
}
int32_t getIntFromMap(v8::Local<v8::Map> map, const String16& key,
int32_t defaultValue) {
v8::Local<v8::String> v8Key = toV8String(m_isolate, key);
if (!map->Has(m_context, v8Key).FromMaybe(false)) return defaultValue;
v8::Local<v8::Value> intValue;
if (!map->Get(m_context, v8Key).ToLocal(&intValue)) return defaultValue;
return static_cast<int32_t>(intValue.As<v8::Integer>()->Value());
}
void setIntOnMap(v8::Local<v8::Map> map, const String16& key, int32_t value) {
v8::Local<v8::String> v8Key = toV8String(m_isolate, key);
if (!map->Set(m_context, v8Key, v8::Integer::New(m_isolate, value))
.ToLocal(&map))
return;
}
double getDoubleFromMap(v8::Local<v8::Map> map, const String16& key,
double defaultValue) {
v8::Local<v8::String> v8Key = toV8String(m_isolate, key);
if (!map->Has(m_context, v8Key).FromMaybe(false)) return defaultValue;
v8::Local<v8::Value> intValue;
if (!map->Get(m_context, v8Key).ToLocal(&intValue)) return defaultValue;
return intValue.As<v8::Number>()->Value();
}
void setDoubleOnMap(v8::Local<v8::Map> map, const String16& key,
double value) {
v8::Local<v8::String> v8Key = toV8String(m_isolate, key);
if (!map->Set(m_context, v8Key, v8::Number::New(m_isolate, value))
.ToLocal(&map))
return;
}
V8ProfilerAgentImpl* profilerAgent() { V8ProfilerAgentImpl* profilerAgent() {
if (V8InspectorSessionImpl* session = currentSession()) { if (V8InspectorSessionImpl* session = currentSession()) {
if (session && session->profilerAgent()->enabled()) if (session && session->profilerAgent()->enabled())
@ -143,7 +212,10 @@ class ConsoleHelper {
} }
V8InspectorSessionImpl* currentSession() { V8InspectorSessionImpl* currentSession() {
return m_inspector->sessionForContextGroup(m_groupId); InspectedContext* inspectedContext = ensureInspectedContext();
if (!inspectedContext) return nullptr;
return inspectedContext->inspector()->sessionForContextGroup(
inspectedContext->contextGroupId());
} }
private: private:
@ -151,9 +223,26 @@ class ConsoleHelper {
v8::Isolate* m_isolate; v8::Isolate* m_isolate;
v8::Local<v8::Context> m_context; v8::Local<v8::Context> m_context;
v8::Local<v8::Object> m_console; v8::Local<v8::Object> m_console;
V8InspectorImpl* m_inspector = nullptr; InspectedContext* m_inspectedContext;
int m_contextId; V8InspectorClient* m_inspectorClient;
int m_groupId;
bool checkAndSetPrivateFlagOnConsole(const char* name, bool defaultValue) {
v8::Local<v8::Object> console = ensureConsole();
v8::Local<v8::Private> key =
v8::Private::ForApi(m_isolate, toV8StringInternalized(m_isolate, name));
v8::Local<v8::Value> flagValue;
if (!console->GetPrivate(m_context, key).ToLocal(&flagValue))
return defaultValue;
DCHECK(flagValue->IsUndefined() || flagValue->IsBoolean());
if (flagValue->IsBoolean()) {
DCHECK(flagValue.As<v8::Boolean>()->Value());
return true;
}
if (!console->SetPrivate(m_context, key, v8::True(m_isolate))
.FromMaybe(false))
return defaultValue;
return false;
}
DISALLOW_COPY_AND_ASSIGN(ConsoleHelper); DISALLOW_COPY_AND_ASSIGN(ConsoleHelper);
}; };
@ -164,13 +253,13 @@ void returnDataCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
void createBoundFunctionProperty(v8::Local<v8::Context> context, void createBoundFunctionProperty(v8::Local<v8::Context> context,
v8::Local<v8::Object> console, v8::Local<v8::Object> console,
v8::Local<v8::Value> data, const char* name, const char* name,
v8::FunctionCallback callback, v8::FunctionCallback callback,
const char* description = nullptr) { const char* description = nullptr) {
v8::Local<v8::String> funcName = v8::Local<v8::String> funcName =
toV8StringInternalized(context->GetIsolate(), name); toV8StringInternalized(context->GetIsolate(), name);
v8::Local<v8::Function> func; v8::Local<v8::Function> func;
if (!v8::Function::New(context, callback, data, 0, if (!v8::Function::New(context, callback, console, 0,
v8::ConstructorBehavior::kThrow) v8::ConstructorBehavior::kThrow)
.ToLocal(&func)) .ToLocal(&func))
return; return;
@ -248,13 +337,18 @@ void V8Console::groupEndCallback(
void V8Console::clearCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { void V8Console::clearCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
ConsoleHelper helper(info); ConsoleHelper helper(info);
helper.inspector()->client()->consoleClear(helper.groupId()); InspectedContext* context = helper.ensureInspectedContext();
if (!context) return;
int contextGroupId = context->contextGroupId();
if (V8InspectorClient* client = helper.ensureDebuggerClient())
client->consoleClear(contextGroupId);
helper.reportCallWithDefaultArgument(ConsoleAPIType::kClear, helper.reportCallWithDefaultArgument(ConsoleAPIType::kClear,
String16("console.clear")); String16("console.clear"));
} }
void V8Console::countCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { void V8Console::countCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
ConsoleHelper helper(info); ConsoleHelper helper(info);
String16 title = helper.firstArgToString(String16()); String16 title = helper.firstArgToString(String16());
String16 identifier; String16 identifier;
if (title.isEmpty()) { if (title.isEmpty()) {
@ -268,8 +362,10 @@ void V8Console::countCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
identifier = title + "@"; identifier = title + "@";
} }
int count = v8::Local<v8::Map> countMap;
helper.consoleMessageStorage()->count(helper.contextId(), identifier); if (!helper.privateMap("V8Console#countMap").ToLocal(&countMap)) return;
int32_t count = helper.getIntFromMap(countMap, identifier, 0) + 1;
helper.setIntOnMap(countMap, identifier, count);
String16 countString = String16::fromInteger(count); String16 countString = String16::fromInteger(count);
helper.reportCallWithArgument( helper.reportCallWithArgument(
ConsoleAPIType::kCount, ConsoleAPIType::kCount,
@ -319,25 +415,33 @@ void V8Console::profileEndCallback(
static void timeFunction(const v8::FunctionCallbackInfo<v8::Value>& info, static void timeFunction(const v8::FunctionCallbackInfo<v8::Value>& info,
bool timelinePrefix) { bool timelinePrefix) {
ConsoleHelper helper(info); ConsoleHelper helper(info);
V8InspectorClient* client = helper.inspector()->client(); if (V8InspectorClient* client = helper.ensureDebuggerClient()) {
String16 protocolTitle = helper.firstArgToString("default"); String16 protocolTitle = helper.firstArgToString("default");
if (timelinePrefix) protocolTitle = "Timeline '" + protocolTitle + "'"; if (timelinePrefix) protocolTitle = "Timeline '" + protocolTitle + "'";
client->consoleTime(toStringView(protocolTitle)); client->consoleTime(toStringView(protocolTitle));
helper.consoleMessageStorage()->time(helper.contextId(), protocolTitle);
v8::Local<v8::Map> timeMap;
if (!helper.privateMap("V8Console#timeMap").ToLocal(&timeMap)) return;
helper.setDoubleOnMap(timeMap, protocolTitle, client->currentTimeMS());
}
} }
static void timeEndFunction(const v8::FunctionCallbackInfo<v8::Value>& info, static void timeEndFunction(const v8::FunctionCallbackInfo<v8::Value>& info,
bool timelinePrefix) { bool timelinePrefix) {
ConsoleHelper helper(info); ConsoleHelper helper(info);
V8InspectorClient* client = helper.inspector()->client(); if (V8InspectorClient* client = helper.ensureDebuggerClient()) {
String16 protocolTitle = helper.firstArgToString("default"); String16 protocolTitle = helper.firstArgToString("default");
if (timelinePrefix) protocolTitle = "Timeline '" + protocolTitle + "'"; if (timelinePrefix) protocolTitle = "Timeline '" + protocolTitle + "'";
client->consoleTimeEnd(toStringView(protocolTitle)); client->consoleTimeEnd(toStringView(protocolTitle));
double elapsed = helper.consoleMessageStorage()->timeEnd(helper.contextId(),
protocolTitle); v8::Local<v8::Map> timeMap;
String16 message = if (!helper.privateMap("V8Console#timeMap").ToLocal(&timeMap)) return;
protocolTitle + ": " + String16::fromDouble(elapsed) + "ms"; double elapsed = client->currentTimeMS() -
helper.reportCallWithArgument(ConsoleAPIType::kTimeEnd, message); helper.getDoubleFromMap(timeMap, protocolTitle, 0.0);
String16 message =
protocolTitle + ": " + String16::fromDouble(elapsed) + "ms";
helper.reportCallWithArgument(ConsoleAPIType::kTimeEnd, message);
}
} }
void V8Console::timelineCallback( void V8Console::timelineCallback(
@ -369,20 +473,23 @@ void V8Console::timeEndCallback(
void V8Console::timeStampCallback( void V8Console::timeStampCallback(
const v8::FunctionCallbackInfo<v8::Value>& info) { const v8::FunctionCallbackInfo<v8::Value>& info) {
ConsoleHelper helper(info); ConsoleHelper helper(info);
String16 title = helper.firstArgToString(String16()); if (V8InspectorClient* client = helper.ensureDebuggerClient()) {
helper.inspector()->client()->consoleTimeStamp(toStringView(title)); String16 title = helper.firstArgToString(String16());
client->consoleTimeStamp(toStringView(title));
}
} }
void V8Console::memoryGetterCallback( void V8Console::memoryGetterCallback(
const v8::FunctionCallbackInfo<v8::Value>& info) { const v8::FunctionCallbackInfo<v8::Value>& info) {
V8InspectorClient* client = ConsoleHelper(info).inspector()->client(); if (V8InspectorClient* client = ConsoleHelper(info).ensureDebuggerClient()) {
v8::Local<v8::Value> memoryValue; v8::Local<v8::Value> memoryValue;
if (!client if (!client
->memoryInfo(info.GetIsolate(), ->memoryInfo(info.GetIsolate(),
info.GetIsolate()->GetCurrentContext()) info.GetIsolate()->GetCurrentContext())
.ToLocal(&memoryValue)) .ToLocal(&memoryValue))
return; return;
info.GetReturnValue().Set(memoryValue); info.GetReturnValue().Set(memoryValue);
}
} }
void V8Console::memorySetterCallback( void V8Console::memorySetterCallback(
@ -503,9 +610,10 @@ void V8Console::unmonitorFunctionCallback(
void V8Console::lastEvaluationResultCallback( void V8Console::lastEvaluationResultCallback(
const v8::FunctionCallbackInfo<v8::Value>& info) { const v8::FunctionCallbackInfo<v8::Value>& info) {
ConsoleHelper helper(info); ConsoleHelper helper(info);
InjectedScript* injectedScript = helper.injectedScript(); InspectedContext* context = helper.ensureInspectedContext();
if (!injectedScript) return; if (!context) return;
info.GetReturnValue().Set(injectedScript->lastEvaluationResult()); if (InjectedScript* injectedScript = context->getInjectedScript())
info.GetReturnValue().Set(injectedScript->lastEvaluationResult());
} }
static void inspectImpl(const v8::FunctionCallbackInfo<v8::Value>& info, static void inspectImpl(const v8::FunctionCallbackInfo<v8::Value>& info,
@ -514,7 +622,9 @@ static void inspectImpl(const v8::FunctionCallbackInfo<v8::Value>& info,
if (!copyToClipboard) info.GetReturnValue().Set(info[0]); if (!copyToClipboard) info.GetReturnValue().Set(info[0]);
ConsoleHelper helper(info); ConsoleHelper helper(info);
InjectedScript* injectedScript = helper.injectedScript(); InspectedContext* context = helper.ensureInspectedContext();
if (!context) return;
InjectedScript* injectedScript = context->getInjectedScript();
if (!injectedScript) return; if (!injectedScript) return;
std::unique_ptr<protocol::Runtime::RemoteObject> wrappedObject; std::unique_ptr<protocol::Runtime::RemoteObject> wrappedObject;
protocol::Response response = protocol::Response response =
@ -525,10 +635,9 @@ static void inspectImpl(const v8::FunctionCallbackInfo<v8::Value>& info,
std::unique_ptr<protocol::DictionaryValue> hints = std::unique_ptr<protocol::DictionaryValue> hints =
protocol::DictionaryValue::create(); protocol::DictionaryValue::create();
if (copyToClipboard) hints->setBoolean("copyToClipboard", true); if (copyToClipboard) hints->setBoolean("copyToClipboard", true);
if (V8InspectorSessionImpl* session = helper.currentSession()) { if (V8InspectorSessionImpl* session = helper.currentSession())
session->runtimeAgent()->inspect(std::move(wrappedObject), session->runtimeAgent()->inspect(std::move(wrappedObject),
std::move(hints)); std::move(hints));
}
} }
void V8Console::inspectCallback( void V8Console::inspectCallback(
@ -568,53 +677,49 @@ v8::Local<v8::Object> V8Console::createConsole(
DCHECK(success); DCHECK(success);
USE(success); USE(success);
v8::Local<v8::External> data = createBoundFunctionProperty(context, console, "debug",
v8::External::New(isolate, inspectedContext->inspector());
createBoundFunctionProperty(context, console, data, "debug",
V8Console::debugCallback); V8Console::debugCallback);
createBoundFunctionProperty(context, console, data, "error", createBoundFunctionProperty(context, console, "error",
V8Console::errorCallback); V8Console::errorCallback);
createBoundFunctionProperty(context, console, data, "info", createBoundFunctionProperty(context, console, "info",
V8Console::infoCallback); V8Console::infoCallback);
createBoundFunctionProperty(context, console, data, "log", createBoundFunctionProperty(context, console, "log", V8Console::logCallback);
V8Console::logCallback); createBoundFunctionProperty(context, console, "warn",
createBoundFunctionProperty(context, console, data, "warn",
V8Console::warnCallback); V8Console::warnCallback);
createBoundFunctionProperty(context, console, data, "dir", createBoundFunctionProperty(context, console, "dir", V8Console::dirCallback);
V8Console::dirCallback); createBoundFunctionProperty(context, console, "dirxml",
createBoundFunctionProperty(context, console, data, "dirxml",
V8Console::dirxmlCallback); V8Console::dirxmlCallback);
createBoundFunctionProperty(context, console, data, "table", createBoundFunctionProperty(context, console, "table",
V8Console::tableCallback); V8Console::tableCallback);
createBoundFunctionProperty(context, console, data, "trace", createBoundFunctionProperty(context, console, "trace",
V8Console::traceCallback); V8Console::traceCallback);
createBoundFunctionProperty(context, console, data, "group", createBoundFunctionProperty(context, console, "group",
V8Console::groupCallback); V8Console::groupCallback);
createBoundFunctionProperty(context, console, data, "groupCollapsed", createBoundFunctionProperty(context, console, "groupCollapsed",
V8Console::groupCollapsedCallback); V8Console::groupCollapsedCallback);
createBoundFunctionProperty(context, console, data, "groupEnd", createBoundFunctionProperty(context, console, "groupEnd",
V8Console::groupEndCallback); V8Console::groupEndCallback);
createBoundFunctionProperty(context, console, data, "clear", createBoundFunctionProperty(context, console, "clear",
V8Console::clearCallback); V8Console::clearCallback);
createBoundFunctionProperty(context, console, data, "count", createBoundFunctionProperty(context, console, "count",
V8Console::countCallback); V8Console::countCallback);
createBoundFunctionProperty(context, console, data, "assert", createBoundFunctionProperty(context, console, "assert",
V8Console::assertCallback); V8Console::assertCallback);
createBoundFunctionProperty(context, console, data, "markTimeline", createBoundFunctionProperty(context, console, "markTimeline",
V8Console::markTimelineCallback); V8Console::markTimelineCallback);
createBoundFunctionProperty(context, console, data, "profile", createBoundFunctionProperty(context, console, "profile",
V8Console::profileCallback); V8Console::profileCallback);
createBoundFunctionProperty(context, console, data, "profileEnd", createBoundFunctionProperty(context, console, "profileEnd",
V8Console::profileEndCallback); V8Console::profileEndCallback);
createBoundFunctionProperty(context, console, data, "timeline", createBoundFunctionProperty(context, console, "timeline",
V8Console::timelineCallback); V8Console::timelineCallback);
createBoundFunctionProperty(context, console, data, "timelineEnd", createBoundFunctionProperty(context, console, "timelineEnd",
V8Console::timelineEndCallback); V8Console::timelineEndCallback);
createBoundFunctionProperty(context, console, data, "time", createBoundFunctionProperty(context, console, "time",
V8Console::timeCallback); V8Console::timeCallback);
createBoundFunctionProperty(context, console, data, "timeEnd", createBoundFunctionProperty(context, console, "timeEnd",
V8Console::timeEndCallback); V8Console::timeEndCallback);
createBoundFunctionProperty(context, console, data, "timeStamp", createBoundFunctionProperty(context, console, "timeStamp",
V8Console::timeStampCallback); V8Console::timeStampCallback);
const char* jsConsoleAssert = const char* jsConsoleAssert =
@ -642,7 +747,7 @@ v8::Local<v8::Object> V8Console::createConsole(
->Call(context, console, 0, nullptr); ->Call(context, console, 0, nullptr);
} }
if (hasMemoryAttribute) { if (hasMemoryAttribute)
console->SetAccessorProperty( console->SetAccessorProperty(
toV8StringInternalized(isolate, "memory"), toV8StringInternalized(isolate, "memory"),
v8::Function::New(context, V8Console::memoryGetterCallback, console, 0, v8::Function::New(context, V8Console::memoryGetterCallback, console, 0,
@ -653,11 +758,19 @@ v8::Local<v8::Object> V8Console::createConsole(
v8::ConstructorBehavior::kThrow) v8::ConstructorBehavior::kThrow)
.ToLocalChecked(), .ToLocalChecked(),
static_cast<v8::PropertyAttribute>(v8::None), v8::DEFAULT); static_cast<v8::PropertyAttribute>(v8::None), v8::DEFAULT);
}
console->SetPrivate(context, inspectedContextPrivateKey(isolate),
v8::External::New(isolate, inspectedContext));
return console; return console;
} }
void V8Console::clearInspectedContextIfNeeded(v8::Local<v8::Context> context,
v8::Local<v8::Object> console) {
v8::Isolate* isolate = context->GetIsolate();
console->SetPrivate(context, inspectedContextPrivateKey(isolate),
v8::External::New(isolate, nullptr));
}
v8::Local<v8::Object> V8Console::createCommandLineAPI( v8::Local<v8::Object> V8Console::createCommandLineAPI(
InspectedContext* inspectedContext) { InspectedContext* inspectedContext) {
v8::Local<v8::Context> context = inspectedContext->context(); v8::Local<v8::Context> context = inspectedContext->context();
@ -671,70 +784,68 @@ v8::Local<v8::Object> V8Console::createCommandLineAPI(
DCHECK(success); DCHECK(success);
USE(success); USE(success);
v8::Local<v8::External> data = createBoundFunctionProperty(context, commandLineAPI, "dir",
v8::External::New(isolate, inspectedContext->inspector());
createBoundFunctionProperty(context, commandLineAPI, data, "dir",
V8Console::dirCallback, V8Console::dirCallback,
"function dir(value) { [Command Line API] }"); "function dir(value) { [Command Line API] }");
createBoundFunctionProperty(context, commandLineAPI, data, "dirxml", createBoundFunctionProperty(context, commandLineAPI, "dirxml",
V8Console::dirxmlCallback, V8Console::dirxmlCallback,
"function dirxml(value) { [Command Line API] }"); "function dirxml(value) { [Command Line API] }");
createBoundFunctionProperty(context, commandLineAPI, data, "profile", createBoundFunctionProperty(context, commandLineAPI, "profile",
V8Console::profileCallback, V8Console::profileCallback,
"function profile(title) { [Command Line API] }"); "function profile(title) { [Command Line API] }");
createBoundFunctionProperty( createBoundFunctionProperty(
context, commandLineAPI, data, "profileEnd", context, commandLineAPI, "profileEnd", V8Console::profileEndCallback,
V8Console::profileEndCallback,
"function profileEnd(title) { [Command Line API] }"); "function profileEnd(title) { [Command Line API] }");
createBoundFunctionProperty(context, commandLineAPI, data, "clear", createBoundFunctionProperty(context, commandLineAPI, "clear",
V8Console::clearCallback, V8Console::clearCallback,
"function clear() { [Command Line API] }"); "function clear() { [Command Line API] }");
createBoundFunctionProperty( createBoundFunctionProperty(
context, commandLineAPI, data, "table", V8Console::tableCallback, context, commandLineAPI, "table", V8Console::tableCallback,
"function table(data, [columns]) { [Command Line API] }"); "function table(data, [columns]) { [Command Line API] }");
createBoundFunctionProperty(context, commandLineAPI, data, "keys", createBoundFunctionProperty(context, commandLineAPI, "keys",
V8Console::keysCallback, V8Console::keysCallback,
"function keys(object) { [Command Line API] }"); "function keys(object) { [Command Line API] }");
createBoundFunctionProperty(context, commandLineAPI, data, "values", createBoundFunctionProperty(context, commandLineAPI, "values",
V8Console::valuesCallback, V8Console::valuesCallback,
"function values(object) { [Command Line API] }"); "function values(object) { [Command Line API] }");
createBoundFunctionProperty( createBoundFunctionProperty(
context, commandLineAPI, data, "debug", V8Console::debugFunctionCallback, context, commandLineAPI, "debug", V8Console::debugFunctionCallback,
"function debug(function) { [Command Line API] }"); "function debug(function) { [Command Line API] }");
createBoundFunctionProperty( createBoundFunctionProperty(
context, commandLineAPI, data, "undebug", context, commandLineAPI, "undebug", V8Console::undebugFunctionCallback,
V8Console::undebugFunctionCallback,
"function undebug(function) { [Command Line API] }"); "function undebug(function) { [Command Line API] }");
createBoundFunctionProperty( createBoundFunctionProperty(
context, commandLineAPI, data, "monitor", context, commandLineAPI, "monitor", V8Console::monitorFunctionCallback,
V8Console::monitorFunctionCallback,
"function monitor(function) { [Command Line API] }"); "function monitor(function) { [Command Line API] }");
createBoundFunctionProperty( createBoundFunctionProperty(
context, commandLineAPI, data, "unmonitor", context, commandLineAPI, "unmonitor",
V8Console::unmonitorFunctionCallback, V8Console::unmonitorFunctionCallback,
"function unmonitor(function) { [Command Line API] }"); "function unmonitor(function) { [Command Line API] }");
createBoundFunctionProperty( createBoundFunctionProperty(
context, commandLineAPI, data, "inspect", V8Console::inspectCallback, context, commandLineAPI, "inspect", V8Console::inspectCallback,
"function inspect(object) { [Command Line API] }"); "function inspect(object) { [Command Line API] }");
createBoundFunctionProperty(context, commandLineAPI, data, "copy", createBoundFunctionProperty(context, commandLineAPI, "copy",
V8Console::copyCallback, V8Console::copyCallback,
"function copy(value) { [Command Line API] }"); "function copy(value) { [Command Line API] }");
createBoundFunctionProperty(context, commandLineAPI, data, "$_", createBoundFunctionProperty(context, commandLineAPI, "$_",
V8Console::lastEvaluationResultCallback); V8Console::lastEvaluationResultCallback);
createBoundFunctionProperty(context, commandLineAPI, data, "$0", createBoundFunctionProperty(context, commandLineAPI, "$0",
V8Console::inspectedObject0); V8Console::inspectedObject0);
createBoundFunctionProperty(context, commandLineAPI, data, "$1", createBoundFunctionProperty(context, commandLineAPI, "$1",
V8Console::inspectedObject1); V8Console::inspectedObject1);
createBoundFunctionProperty(context, commandLineAPI, data, "$2", createBoundFunctionProperty(context, commandLineAPI, "$2",
V8Console::inspectedObject2); V8Console::inspectedObject2);
createBoundFunctionProperty(context, commandLineAPI, data, "$3", createBoundFunctionProperty(context, commandLineAPI, "$3",
V8Console::inspectedObject3); V8Console::inspectedObject3);
createBoundFunctionProperty(context, commandLineAPI, data, "$4", createBoundFunctionProperty(context, commandLineAPI, "$4",
V8Console::inspectedObject4); V8Console::inspectedObject4);
inspectedContext->inspector()->client()->installAdditionalCommandLineAPI( inspectedContext->inspector()->client()->installAdditionalCommandLineAPI(
context, commandLineAPI); context, commandLineAPI);
commandLineAPI->SetPrivate(context, inspectedContextPrivateKey(isolate),
v8::External::New(isolate, inspectedContext));
return commandLineAPI; return commandLineAPI;
} }

View File

@ -19,6 +19,8 @@ class V8Console {
public: public:
static v8::Local<v8::Object> createConsole(InspectedContext*, static v8::Local<v8::Object> createConsole(InspectedContext*,
bool hasMemoryAttribute); bool hasMemoryAttribute);
static void clearInspectedContextIfNeeded(v8::Local<v8::Context>,
v8::Local<v8::Object> console);
static v8::Local<v8::Object> createCommandLineAPI(InspectedContext*); static v8::Local<v8::Object> createCommandLineAPI(InspectedContext*);
class CommandLineAPIScope { class CommandLineAPIScope {

View File

@ -75,8 +75,6 @@ InspectorTest.logMessage = function(originalMessage)
for (var key in object) { for (var key in object) {
if (nonStableFields.has(key)) if (nonStableFields.has(key))
object[key] = `<${key}>`; object[key] = `<${key}>`;
else if (typeof object[key] === "string" && object[key].match(/\d+:\d+:\d+:debug/))
object[key] = object[key].replace(/\d+/, '<scriptId>');
else if (typeof object[key] === "object") else if (typeof object[key] === "object")
objects.push(object[key]); objects.push(object[key]);
} }

View File

@ -1,612 +0,0 @@
Checks command line API.
Running test: testKeys
{
id : <messageId>
result : {
result : {
className : Function
description : function keys(object) { [Command Line API] }
objectId : <objectId>
type : function
}
}
}
{
id : <messageId>
result : {
result : {
type : object
value : [
[0] : a
]
}
}
}
{
id : <messageId>
result : {
result : {
type : object
value : [
[0] : a
]
}
}
}
Running test: testInspect
[object Object]
{
method : Runtime.inspectRequested
params : {
hints : {
}
object : {
className : Object
description : Object
objectId : <objectId>
type : object
}
}
}
{
method : Runtime.inspectRequested
params : {
hints : {
}
object : {
description : 239
type : number
value : 239
}
}
}
{
method : Runtime.inspectRequested
params : {
hints : {
}
object : {
description : -0
type : number
unserializableValue : -0
}
}
}
{
method : Runtime.inspectRequested
params : {
hints : {
copyToClipboard : true
}
object : {
type : string
value : hello
}
}
}
{
id : <messageId>
result : {
result : {
type : undefined
}
}
}
{
method : Runtime.inspectRequested
params : {
hints : {
}
object : {
className : Object
description : Object
objectId : <objectId>
type : object
}
}
}
Running test: testEvaluationResult
{
id : <messageId>
result : {
result : {
type : undefined
}
}
}
{
id : <messageId>
result : {
result : {
description : 42
type : number
value : 42
}
}
}
{
id : <messageId>
result : {
result : {
description : 42
type : number
value : 42
}
}
}
{
id : <messageId>
result : {
result : {
description : -0
type : number
unserializableValue : -0
}
}
}
{
id : <messageId>
result : {
result : {
type : object
value : {
}
}
}
}
Running test: testDebug
{
id : <messageId>
result : {
result : {
className : Function
description : function debug(function) { [Command Line API] }
objectId : <objectId>
type : function
}
}
}
{
id : <messageId>
result : {
result : {
className : Function
description : function undebug(function) { [Command Line API] }
objectId : <objectId>
type : function
}
}
}
foo (:0:16)
(anonymous) (:0:0)
[
[0] : <scriptId>:0:12:debug
]
foo (:0:16)
(anonymous) (:0:0)
[
[0] : <scriptId>:0:12:debug
]
Running test: testMonitor
{
id : <messageId>
result : {
result : {
className : Function
description : function monitor(function) { [Command Line API] }
objectId : <objectId>
type : function
}
}
}
{
id : <messageId>
result : {
result : {
className : Function
description : function unmonitor(function) { [Command Line API] }
objectId : <objectId>
type : function
}
}
}
function foo called
after first call
store functions..
function foo called
after first call
Running test: testProfile
{
id : <messageId>
result : {
result : {
className : Function
description : function profile(title) { [Command Line API] }
objectId : <objectId>
type : function
}
}
}
{
id : <messageId>
result : {
result : {
className : Function
description : function profileEnd(title) { [Command Line API] }
objectId : <objectId>
type : function
}
}
}
{
method : Profiler.consoleProfileStarted
params : {
id : 1
location : {
columnNumber : 1
lineNumber : 1
scriptId : <scriptId>
}
title : 42
}
}
{
method : Profiler.consoleProfileFinished
params : {
id : 1
location : {
columnNumber : 1
lineNumber : 1
scriptId : <scriptId>
}
profile : <profile>
title : 42
}
}
{
method : Profiler.consoleProfileStarted
params : {
id : 2
location : {
columnNumber : 6
lineNumber : 1
scriptId : <scriptId>
}
title : 239
}
}
{
method : Profiler.consoleProfileFinished
params : {
id : 2
location : {
columnNumber : 6
lineNumber : 1
scriptId : <scriptId>
}
profile : <profile>
title : 239
}
}
Running test: testDir
{
id : <messageId>
result : {
result : {
className : Function
description : function dir(value) { [Command Line API] }
objectId : <objectId>
type : function
}
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
className : Object
description : Object
objectId : <objectId>
preview : {
description : Object
overflow : false
properties : [
]
type : object
}
type : object
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : dir
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
description : 42
type : number
value : 42
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : dir
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
className : Object
description : Object
objectId : <objectId>
preview : {
description : Object
overflow : false
properties : [
]
type : object
}
type : object
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 5
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : dir
}
}
Running test: testDirXML
{
id : <messageId>
result : {
result : {
className : Function
description : function dirxml(value) { [Command Line API] }
objectId : <objectId>
type : function
}
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
className : Object
description : Object
objectId : <objectId>
preview : {
description : Object
overflow : false
properties : [
]
type : object
}
type : object
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : dirxml
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
description : 42
type : number
value : 42
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : dirxml
}
}
Running test: testTable
{
id : <messageId>
result : {
result : {
className : Function
description : function table(data, [columns]) { [Command Line API] }
objectId : <objectId>
type : function
}
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
className : Object
description : Object
objectId : <objectId>
preview : {
description : Object
overflow : false
properties : [
]
type : object
}
type : object
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : table
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
description : 42
type : number
value : 42
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : table
}
}
Running test: testClear
{
id : <messageId>
result : {
result : {
className : Function
description : function clear() { [Command Line API] }
objectId : <objectId>
type : function
}
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
type : string
value : console.clear
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : clear
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
type : string
value : console.clear
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 5
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : clear
}
}

View File

@ -1,175 +0,0 @@
// Copyright 2017 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.log('Checks command line API.');
InspectorTest.runAsyncTestSuite([
async function testKeys() {
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: 'keys', includeCommandLineAPI: true}));
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: 'keys({a : 1})', includeCommandLineAPI: true, returnByValue: true}));
Protocol.Runtime.evaluate({expression: 'this.keys = keys', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: 'this.keys({a : 1})', returnByValue: true}));
},
async function testInspect() {
InspectorTest.log(await Protocol.Runtime.evaluate({expression: 'inspect', includeCommandLineAPI: true}));
await Protocol.Runtime.enable();
Protocol.Runtime.onInspectRequested(InspectorTest.logMessage);
await Protocol.Runtime.evaluate({expression: 'inspect({})', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({expression: 'inspect(239)', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({expression: 'inspect(-0)', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({expression: 'copy(\'hello\')', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$0', includeCommandLineAPI: true}));
Protocol.Runtime.evaluate({expression: 'this.inspect = inspect', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({expression: 'this.inspect({})'});
Protocol.Runtime.onInspectRequested(null);
await Protocol.Runtime.disable();
},
async function testEvaluationResult() {
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true}));
await Protocol.Runtime.evaluate({expression: '42', objectGroup: 'console', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true}));
await Protocol.Runtime.evaluate({expression: '239', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true}));
await Protocol.Runtime.evaluate({expression: '-0', objectGroup: 'console', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true}));
await Protocol.Runtime.evaluate({expression: '({})', objectGroup: 'console', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true, returnByValue: true}));
},
async function testDebug() {
InspectorTest.setupScriptMap();
await Protocol.Debugger.enable();
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'debug', includeCommandLineAPI: true}));
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'undebug', includeCommandLineAPI: true}));
await Protocol.Runtime.evaluate({expression: 'function foo() {}'});
await Protocol.Runtime.evaluate({expression: 'debug(foo)', includeCommandLineAPI: true});
Protocol.Runtime.evaluate({ expression: 'foo()'});
let message = await Protocol.Debugger.oncePaused();
InspectorTest.logCallFrames(message.params.callFrames);
InspectorTest.logMessage(message.params.hitBreakpoints);
await Protocol.Debugger.resume();
await Protocol.Runtime.evaluate({expression: 'undebug(foo)', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({ expression: 'foo()'});
Protocol.Runtime.evaluate({
expression: 'this.debug = debug; this.undebug = undebug;', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({expression: 'this.debug(foo)'});
Protocol.Runtime.evaluate({ expression: 'foo()'});
message = await Protocol.Debugger.oncePaused();
InspectorTest.logCallFrames(message.params.callFrames);
InspectorTest.logMessage(message.params.hitBreakpoints);
await Protocol.Debugger.resume();
await Protocol.Runtime.evaluate({expression: 'this.undebug(foo)'});
await Protocol.Runtime.evaluate({expression: 'foo()'});
await Protocol.Debugger.disable();
},
async function testMonitor() {
await Protocol.Debugger.enable();
await Protocol.Runtime.enable();
Protocol.Runtime.onConsoleAPICalled(message => InspectorTest.log(message.params.args[0].value));
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'monitor', includeCommandLineAPI: true}));
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'unmonitor', includeCommandLineAPI: true}));
await Protocol.Runtime.evaluate({expression: 'function foo() {}'});
await Protocol.Runtime.evaluate({expression: 'monitor(foo)', includeCommandLineAPI: true});
Protocol.Runtime.evaluate({ expression: 'foo(); console.log(\'after first call\')'});
await Protocol.Runtime.evaluate({expression: 'unmonitor(foo)', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({ expression: 'foo()'});
Protocol.Runtime.evaluate({
expression: 'console.log(\'store functions..\'); this.monitor = monitor; this.unmonitor = unmonitor;', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({expression: 'this.monitor(foo)'});
Protocol.Runtime.evaluate({ expression: 'foo(); console.log(\'after first call\')'});
await Protocol.Runtime.evaluate({expression: 'this.unmonitor(foo)'});
await Protocol.Runtime.evaluate({ expression: 'foo()'});
Protocol.Runtime.onConsoleAPICalled(null);
await Protocol.Debugger.disable();
await Protocol.Runtime.disable();
},
async function testProfile() {
await Protocol.Profiler.enable();
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'profile', includeCommandLineAPI: true}));
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'profileEnd', includeCommandLineAPI: true}));
Protocol.Runtime.evaluate({expression: 'profile(42)', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Profiler.onceConsoleProfileStarted());
Protocol.Runtime.evaluate({expression: 'profileEnd(42)', includeCommandLineAPI: true});
let message = await Protocol.Profiler.onceConsoleProfileFinished();
message.params.profile = '<profile>';
InspectorTest.logMessage(message);
Protocol.Runtime.evaluate({
expression: 'this.profile = profile; this.profileEnd = profileEnd;', includeCommandLineAPI: true});
Protocol.Runtime.evaluate({expression: 'this.profile(239)'});
InspectorTest.logMessage(await Protocol.Profiler.onceConsoleProfileStarted());
Protocol.Runtime.evaluate({expression: 'this.profileEnd(239)'});
message = await Protocol.Profiler.onceConsoleProfileFinished();
message.params.profile = '<profile>';
InspectorTest.logMessage(message);
await Protocol.Profiler.disable();
},
async function testDir() {
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'dir', includeCommandLineAPI: true}));
await Protocol.Runtime.enable();
Protocol.Runtime.evaluate({expression: 'dir({})', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
Protocol.Runtime.evaluate({expression: 'dir(42)', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
Protocol.Runtime.evaluate({expression: 'this.dir = dir', includeCommandLineAPI: true});
Protocol.Runtime.evaluate({expression: 'this.dir({})'});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
await Protocol.Runtime.disable();
},
async function testDirXML() {
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'dirxml', includeCommandLineAPI: true}));
await Protocol.Runtime.enable();
Protocol.Runtime.evaluate({expression: 'dirxml({})', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
Protocol.Runtime.evaluate({expression: 'dirxml(42)', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
await Protocol.Runtime.disable();
},
async function testTable() {
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'table', includeCommandLineAPI: true}));
await Protocol.Runtime.enable();
Protocol.Runtime.evaluate({expression: 'table({})', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
Protocol.Runtime.evaluate({expression: 'table(42)', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
await Protocol.Runtime.disable();
},
async function testClear() {
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'clear', includeCommandLineAPI: true}));
await Protocol.Runtime.enable();
Protocol.Runtime.evaluate({expression: 'clear()', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
Protocol.Runtime.evaluate({expression: 'this.clear = clear', includeCommandLineAPI: true});
Protocol.Runtime.evaluate({expression: 'this.clear()'});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
await Protocol.Runtime.disable();
}
]);