Commit 9cbdb715 authored by kozyatinskiy's avatar kozyatinskiy Committed by Commit bot

Revert of [inspector] console get all information from inspector when needed...

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

Reason for revert:
One more failed layout test.

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-Original-Commit-Position: refs/heads/master@{#44212}
> Committed: https://chromium.googlesource.com/v8/v8/+/908cd38123df33ce293e4c8d25e407f7ca915f4c
> Review-Url: https://codereview.chromium.org/2784713002
> Cr-Commit-Position: refs/heads/master@{#44238}
> Committed: https://chromium.googlesource.com/v8/v8/+/88f71126a5c067f98c75044bc26778f2e8ea2e79

TBR=dgozman@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/2778743007
Cr-Commit-Position: refs/heads/master@{#44246}
parent fa19266b
......@@ -14,6 +14,23 @@
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,
const V8ContextInfo& info, int contextId)
: m_inspector(inspector),
......@@ -27,18 +44,27 @@ InspectedContext::InspectedContext(V8InspectorImpl* inspector,
v8::Isolate* isolate = m_inspector->isolate();
info.context->SetEmbedderData(static_cast<int>(v8::Context::kDebugIdIndex),
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> console =
V8Console::createConsole(this, info.hasMemoryOnConsole);
if (!global
->Set(info.context, toV8StringInternalized(isolate, "console"),
console)
.FromMaybe(false)) {
.FromMaybe(false))
return;
}
m_console.Reset(isolate, console);
m_console.SetWeak();
}
InspectedContext::~InspectedContext() {
if (!m_console.IsEmpty()) {
v8::HandleScope scope(isolate());
V8Console::clearInspectedContextIfNeeded(context(),
m_console.Get(isolate()));
}
}
// static
......
......@@ -53,6 +53,7 @@ class InspectedContext {
const String16 m_auxData;
bool m_reported;
std::unique_ptr<InjectedScript> m_injectedScript;
v8::Global<v8::Object> m_console;
DISALLOW_COPY_AND_ASSIGN(InspectedContext);
};
......
......@@ -353,11 +353,15 @@ ConsoleAPIType V8ConsoleMessage::type() const { return m_type; }
// static
std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForConsoleAPI(
v8::Local<v8::Context> v8Context, int contextId, int groupId,
V8InspectorImpl* inspector, double timestamp, ConsoleAPIType type,
double timestamp, ConsoleAPIType type,
const std::vector<v8::Local<v8::Value>>& arguments,
std::unique_ptr<V8StackTraceImpl> stackTrace) {
v8::Isolate* isolate = v8Context->GetIsolate();
std::unique_ptr<V8StackTraceImpl> stackTrace,
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(
new V8ConsoleMessage(V8MessageOrigin::kConsole, timestamp, String16()));
......@@ -376,8 +380,7 @@ std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForConsoleAPI(
v8::debug::EstimatedValueSize(isolate, arguments.at(i));
}
if (arguments.size())
message->m_message =
V8ValueStringBuilder::toString(arguments[0], v8Context);
message->m_message = V8ValueStringBuilder::toString(arguments[0], context);
v8::Isolate::MessageErrorLevel clientLevel = v8::Isolate::kMessageInfo;
if (type == ConsoleAPIType::kDebug || type == ConsoleAPIType::kCount ||
......@@ -394,7 +397,7 @@ std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForConsoleAPI(
if (type != ConsoleAPIType::kClear) {
inspector->client()->consoleAPIMessage(
groupId, clientLevel, toStringView(message->m_message),
contextGroupId, clientLevel, toStringView(message->m_message),
toStringView(message->m_url), message->m_lineNumber,
message->m_columnNumber, message->m_stackTrace.get());
}
......@@ -487,37 +490,8 @@ void V8ConsoleMessageStorage::clear() {
m_messages.clear();
m_estimatedSize = 0;
if (V8InspectorSessionImpl* session =
m_inspector->sessionForContextGroup(m_contextGroupId)) {
m_inspector->sessionForContextGroup(m_contextGroupId))
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) {
......@@ -526,8 +500,6 @@ void V8ConsoleMessageStorage::contextDestroyed(int contextId) {
m_messages[i]->contextDestroyed(contextId);
m_estimatedSize += m_messages[i]->estimatedSize();
}
auto it = m_data.find(contextId);
if (it != m_data.end()) m_data.erase(contextId);
}
} // namespace v8_inspector
......@@ -6,8 +6,6 @@
#define V8_INSPECTOR_V8CONSOLEMESSAGE_H_
#include <deque>
#include <map>
#include <set>
#include "include/v8.h"
#include "src/inspector/protocol/Console.h"
#include "src/inspector/protocol/Forward.h"
......@@ -46,10 +44,9 @@ class V8ConsoleMessage {
~V8ConsoleMessage();
static std::unique_ptr<V8ConsoleMessage> createForConsoleAPI(
v8::Local<v8::Context> v8Context, int contextId, int groupId,
V8InspectorImpl* inspector, double timestamp, ConsoleAPIType,
double timestamp, ConsoleAPIType,
const std::vector<v8::Local<v8::Value>>& arguments,
std::unique_ptr<V8StackTraceImpl>);
std::unique_ptr<V8StackTraceImpl>, InspectedContext*);
static std::unique_ptr<V8ConsoleMessage> createForException(
double timestamp, const String16& detailedMessage, const String16& url,
......@@ -115,23 +112,11 @@ class V8ConsoleMessageStorage {
void contextDestroyed(int contextId);
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:
V8InspectorImpl* m_inspector;
int m_contextGroupId;
int m_estimatedSize = 0;
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
......
......@@ -23,31 +23,49 @@ namespace v8_inspector {
namespace {
v8::Local<v8::Private> inspectedContextPrivateKey(v8::Isolate* isolate) {
return v8::Private::ForApi(
isolate, toV8StringInternalized(isolate, "V8Console#InspectedContext"));
}
class ConsoleHelper {
public:
explicit ConsoleHelper(const v8::FunctionCallbackInfo<v8::Value>& info)
: m_info(info),
m_isolate(info.GetIsolate()),
m_context(info.GetIsolate()->GetCurrentContext()),
m_contextId(InspectedContext::contextId(m_context)) {
m_inspector = static_cast<V8InspectorImpl*>(
m_info.Data().As<v8::External>()->Value());
m_groupId = m_inspector->contextGroupId(m_contextId);
}
m_inspectedContext(nullptr),
m_inspectorClient(nullptr) {}
V8InspectorImpl* inspector() { return m_inspector; }
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;
}
int contextId() const { return m_contextId; }
int groupId() const { return m_groupId; }
InspectedContext* ensureInspectedContext() {
if (m_inspectedContext) return m_inspectedContext;
v8::Local<v8::Object> console = ensureConsole();
InjectedScript* injectedScript() {
InspectedContext* context = m_inspector->getContext(m_groupId, m_contextId);
if (!context) return nullptr;
return context->getInjectedScript();
v8::Local<v8::Private> key = inspectedContextPrivateKey(m_isolate);
v8::Local<v8::Value> inspectedContextValue;
if (!console->GetPrivate(m_context, key).ToLocal(&inspectedContextValue))
return nullptr;
DCHECK(inspectedContextValue->IsExternal());
m_inspectedContext = static_cast<InspectedContext*>(
inspectedContextValue.As<v8::External>()->Value());
return m_inspectedContext;
}
V8ConsoleMessageStorage* consoleMessageStorage() {
return inspector()->ensureConsoleMessageStorage(m_groupId);
V8InspectorClient* ensureDebuggerClient() {
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) {
......@@ -73,19 +91,20 @@ class ConsoleHelper {
void reportCall(ConsoleAPIType type,
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 =
V8ConsoleMessage::createForConsoleAPI(
m_context, m_contextId, m_groupId, m_inspector,
m_inspector->client()->currentTimeMS(), type, arguments,
m_inspector->debugger()->captureStackTrace(false));
consoleMessageStorage()->addMessage(std::move(message));
inspector->client()->currentTimeMS(), type, arguments,
inspector->debugger()->captureStackTrace(false), inspectedContext);
inspector->ensureConsoleMessageStorage(contextGroupId)
->addMessage(std::move(message));
}
void reportDeprecatedCall(const char* id, const String16& message) {
if (!consoleMessageStorage()->shouldReportDeprecationMessage(m_contextId,
id)) {
return;
}
if (checkAndSetPrivateFlagOnConsole(id, false)) return;
std::vector<v8::Local<v8::Value>> arguments(1,
toV8String(m_isolate, message));
reportCall(ConsoleAPIType::kWarning, arguments);
......@@ -126,6 +145,56 @@ class ConsoleHelper {
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() {
if (V8InspectorSessionImpl* session = currentSession()) {
if (session && session->profilerAgent()->enabled())
......@@ -143,7 +212,10 @@ class ConsoleHelper {
}
V8InspectorSessionImpl* currentSession() {
return m_inspector->sessionForContextGroup(m_groupId);
InspectedContext* inspectedContext = ensureInspectedContext();
if (!inspectedContext) return nullptr;
return inspectedContext->inspector()->sessionForContextGroup(
inspectedContext->contextGroupId());
}
private:
......@@ -151,9 +223,26 @@ class ConsoleHelper {
v8::Isolate* m_isolate;
v8::Local<v8::Context> m_context;
v8::Local<v8::Object> m_console;
V8InspectorImpl* m_inspector = nullptr;
int m_contextId;
int m_groupId;
InspectedContext* m_inspectedContext;
V8InspectorClient* m_inspectorClient;
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);
};
......@@ -164,13 +253,13 @@ void returnDataCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
void createBoundFunctionProperty(v8::Local<v8::Context> context,
v8::Local<v8::Object> console,
v8::Local<v8::Value> data, const char* name,
const char* name,
v8::FunctionCallback callback,
const char* description = nullptr) {
v8::Local<v8::String> funcName =
toV8StringInternalized(context->GetIsolate(), name);
v8::Local<v8::Function> func;
if (!v8::Function::New(context, callback, data, 0,
if (!v8::Function::New(context, callback, console, 0,
v8::ConstructorBehavior::kThrow)
.ToLocal(&func))
return;
......@@ -248,13 +337,18 @@ void V8Console::groupEndCallback(
void V8Console::clearCallback(const v8::FunctionCallbackInfo<v8::Value>& 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,
String16("console.clear"));
}
void V8Console::countCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
ConsoleHelper helper(info);
String16 title = helper.firstArgToString(String16());
String16 identifier;
if (title.isEmpty()) {
......@@ -268,8 +362,10 @@ void V8Console::countCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
identifier = title + "@";
}
int count =
helper.consoleMessageStorage()->count(helper.contextId(), identifier);
v8::Local<v8::Map> countMap;
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);
helper.reportCallWithArgument(
ConsoleAPIType::kCount,
......@@ -319,25 +415,33 @@ void V8Console::profileEndCallback(
static void timeFunction(const v8::FunctionCallbackInfo<v8::Value>& info,
bool timelinePrefix) {
ConsoleHelper helper(info);
V8InspectorClient* client = helper.inspector()->client();
if (V8InspectorClient* client = helper.ensureDebuggerClient()) {
String16 protocolTitle = helper.firstArgToString("default");
if (timelinePrefix) protocolTitle = "Timeline '" + 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,
bool timelinePrefix) {
ConsoleHelper helper(info);
V8InspectorClient* client = helper.inspector()->client();
if (V8InspectorClient* client = helper.ensureDebuggerClient()) {
String16 protocolTitle = helper.firstArgToString("default");
if (timelinePrefix) protocolTitle = "Timeline '" + protocolTitle + "'";
client->consoleTimeEnd(toStringView(protocolTitle));
double elapsed = helper.consoleMessageStorage()->timeEnd(helper.contextId(),
protocolTitle);
v8::Local<v8::Map> timeMap;
if (!helper.privateMap("V8Console#timeMap").ToLocal(&timeMap)) return;
double elapsed = client->currentTimeMS() -
helper.getDoubleFromMap(timeMap, protocolTitle, 0.0);
String16 message =
protocolTitle + ": " + String16::fromDouble(elapsed) + "ms";
helper.reportCallWithArgument(ConsoleAPIType::kTimeEnd, message);
}
}
void V8Console::timelineCallback(
......@@ -369,13 +473,15 @@ void V8Console::timeEndCallback(
void V8Console::timeStampCallback(
const v8::FunctionCallbackInfo<v8::Value>& info) {
ConsoleHelper helper(info);
if (V8InspectorClient* client = helper.ensureDebuggerClient()) {
String16 title = helper.firstArgToString(String16());
helper.inspector()->client()->consoleTimeStamp(toStringView(title));
client->consoleTimeStamp(toStringView(title));
}
}
void V8Console::memoryGetterCallback(
const v8::FunctionCallbackInfo<v8::Value>& info) {
V8InspectorClient* client = ConsoleHelper(info).inspector()->client();
if (V8InspectorClient* client = ConsoleHelper(info).ensureDebuggerClient()) {
v8::Local<v8::Value> memoryValue;
if (!client
->memoryInfo(info.GetIsolate(),
......@@ -383,6 +489,7 @@ void V8Console::memoryGetterCallback(
.ToLocal(&memoryValue))
return;
info.GetReturnValue().Set(memoryValue);
}
}
void V8Console::memorySetterCallback(
......@@ -503,8 +610,9 @@ void V8Console::unmonitorFunctionCallback(
void V8Console::lastEvaluationResultCallback(
const v8::FunctionCallbackInfo<v8::Value>& info) {
ConsoleHelper helper(info);
InjectedScript* injectedScript = helper.injectedScript();
if (!injectedScript) return;
InspectedContext* context = helper.ensureInspectedContext();
if (!context) return;
if (InjectedScript* injectedScript = context->getInjectedScript())
info.GetReturnValue().Set(injectedScript->lastEvaluationResult());
}
......@@ -514,7 +622,9 @@ static void inspectImpl(const v8::FunctionCallbackInfo<v8::Value>& info,
if (!copyToClipboard) info.GetReturnValue().Set(info[0]);
ConsoleHelper helper(info);
InjectedScript* injectedScript = helper.injectedScript();
InspectedContext* context = helper.ensureInspectedContext();
if (!context) return;
InjectedScript* injectedScript = context->getInjectedScript();
if (!injectedScript) return;
std::unique_ptr<protocol::Runtime::RemoteObject> wrappedObject;
protocol::Response response =
......@@ -525,10 +635,9 @@ static void inspectImpl(const v8::FunctionCallbackInfo<v8::Value>& info,
std::unique_ptr<protocol::DictionaryValue> hints =
protocol::DictionaryValue::create();
if (copyToClipboard) hints->setBoolean("copyToClipboard", true);
if (V8InspectorSessionImpl* session = helper.currentSession()) {
if (V8InspectorSessionImpl* session = helper.currentSession())
session->runtimeAgent()->inspect(std::move(wrappedObject),
std::move(hints));
}
}
void V8Console::inspectCallback(
......@@ -568,53 +677,49 @@ v8::Local<v8::Object> V8Console::createConsole(
DCHECK(success);
USE(success);
v8::Local<v8::External> data =
v8::External::New(isolate, inspectedContext->inspector());
createBoundFunctionProperty(context, console, data, "debug",
createBoundFunctionProperty(context, console, "debug",
V8Console::debugCallback);
createBoundFunctionProperty(context, console, data, "error",
createBoundFunctionProperty(context, console, "error",
V8Console::errorCallback);
createBoundFunctionProperty(context, console, data, "info",
createBoundFunctionProperty(context, console, "info",
V8Console::infoCallback);
createBoundFunctionProperty(context, console, data, "log",
V8Console::logCallback);
createBoundFunctionProperty(context, console, data, "warn",
createBoundFunctionProperty(context, console, "log", V8Console::logCallback);
createBoundFunctionProperty(context, console, "warn",
V8Console::warnCallback);
createBoundFunctionProperty(context, console, data, "dir",
V8Console::dirCallback);
createBoundFunctionProperty(context, console, data, "dirxml",
createBoundFunctionProperty(context, console, "dir", V8Console::dirCallback);
createBoundFunctionProperty(context, console, "dirxml",
V8Console::dirxmlCallback);
createBoundFunctionProperty(context, console, data, "table",
createBoundFunctionProperty(context, console, "table",
V8Console::tableCallback);
createBoundFunctionProperty(context, console, data, "trace",
createBoundFunctionProperty(context, console, "trace",
V8Console::traceCallback);
createBoundFunctionProperty(context, console, data, "group",
createBoundFunctionProperty(context, console, "group",
V8Console::groupCallback);
createBoundFunctionProperty(context, console, data, "groupCollapsed",
createBoundFunctionProperty(context, console, "groupCollapsed",
V8Console::groupCollapsedCallback);
createBoundFunctionProperty(context, console, data, "groupEnd",
createBoundFunctionProperty(context, console, "groupEnd",
V8Console::groupEndCallback);
createBoundFunctionProperty(context, console, data, "clear",
createBoundFunctionProperty(context, console, "clear",
V8Console::clearCallback);
createBoundFunctionProperty(context, console, data, "count",
createBoundFunctionProperty(context, console, "count",
V8Console::countCallback);
createBoundFunctionProperty(context, console, data, "assert",
createBoundFunctionProperty(context, console, "assert",
V8Console::assertCallback);
createBoundFunctionProperty(context, console, data, "markTimeline",
createBoundFunctionProperty(context, console, "markTimeline",
V8Console::markTimelineCallback);
createBoundFunctionProperty(context, console, data, "profile",
createBoundFunctionProperty(context, console, "profile",
V8Console::profileCallback);
createBoundFunctionProperty(context, console, data, "profileEnd",
createBoundFunctionProperty(context, console, "profileEnd",
V8Console::profileEndCallback);
createBoundFunctionProperty(context, console, data, "timeline",
createBoundFunctionProperty(context, console, "timeline",
V8Console::timelineCallback);
createBoundFunctionProperty(context, console, data, "timelineEnd",
createBoundFunctionProperty(context, console, "timelineEnd",
V8Console::timelineEndCallback);
createBoundFunctionProperty(context, console, data, "time",
createBoundFunctionProperty(context, console, "time",
V8Console::timeCallback);
createBoundFunctionProperty(context, console, data, "timeEnd",
createBoundFunctionProperty(context, console, "timeEnd",
V8Console::timeEndCallback);
createBoundFunctionProperty(context, console, data, "timeStamp",
createBoundFunctionProperty(context, console, "timeStamp",
V8Console::timeStampCallback);
const char* jsConsoleAssert =
......@@ -642,21 +747,30 @@ v8::Local<v8::Object> V8Console::createConsole(
->Call(context, console, 0, nullptr);
}
if (hasMemoryAttribute) {
if (hasMemoryAttribute)
console->SetAccessorProperty(
toV8StringInternalized(isolate, "memory"),
v8::Function::New(context, V8Console::memoryGetterCallback, data, 0,
v8::Function::New(context, V8Console::memoryGetterCallback, console, 0,
v8::ConstructorBehavior::kThrow)
.ToLocalChecked(),
v8::Function::New(context, V8Console::memorySetterCallback, data, 0,
v8::Function::New(context, V8Console::memorySetterCallback,
v8::Local<v8::Value>(), 0,
v8::ConstructorBehavior::kThrow)
.ToLocalChecked(),
static_cast<v8::PropertyAttribute>(v8::None), v8::DEFAULT);
}
console->SetPrivate(context, inspectedContextPrivateKey(isolate),
v8::External::New(isolate, inspectedContext));
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(
InspectedContext* inspectedContext) {
v8::Local<v8::Context> context = inspectedContext->context();
......@@ -670,70 +784,68 @@ v8::Local<v8::Object> V8Console::createCommandLineAPI(
DCHECK(success);
USE(success);
v8::Local<v8::External> data =
v8::External::New(isolate, inspectedContext->inspector());
createBoundFunctionProperty(context, commandLineAPI, data, "dir",
createBoundFunctionProperty(context, commandLineAPI, "dir",
V8Console::dirCallback,
"function dir(value) { [Command Line API] }");
createBoundFunctionProperty(context, commandLineAPI, data, "dirxml",
createBoundFunctionProperty(context, commandLineAPI, "dirxml",
V8Console::dirxmlCallback,
"function dirxml(value) { [Command Line API] }");
createBoundFunctionProperty(context, commandLineAPI, data, "profile",
createBoundFunctionProperty(context, commandLineAPI, "profile",
V8Console::profileCallback,
"function profile(title) { [Command Line API] }");
createBoundFunctionProperty(
context, commandLineAPI, data, "profileEnd",
V8Console::profileEndCallback,
context, commandLineAPI, "profileEnd", V8Console::profileEndCallback,
"function profileEnd(title) { [Command Line API] }");
createBoundFunctionProperty(context, commandLineAPI, data, "clear",
createBoundFunctionProperty(context, commandLineAPI, "clear",
V8Console::clearCallback,
"function clear() { [Command Line API] }");
createBoundFunctionProperty(
context, commandLineAPI, data, "table", V8Console::tableCallback,
context, commandLineAPI, "table", V8Console::tableCallback,
"function table(data, [columns]) { [Command Line API] }");
createBoundFunctionProperty(context, commandLineAPI, data, "keys",
createBoundFunctionProperty(context, commandLineAPI, "keys",
V8Console::keysCallback,
"function keys(object) { [Command Line API] }");
createBoundFunctionProperty(context, commandLineAPI, data, "values",
createBoundFunctionProperty(context, commandLineAPI, "values",
V8Console::valuesCallback,
"function values(object) { [Command Line API] }");
createBoundFunctionProperty(
context, commandLineAPI, data, "debug", V8Console::debugFunctionCallback,
context, commandLineAPI, "debug", V8Console::debugFunctionCallback,
"function debug(function) { [Command Line API] }");
createBoundFunctionProperty(
context, commandLineAPI, data, "undebug",
V8Console::undebugFunctionCallback,
context, commandLineAPI, "undebug", V8Console::undebugFunctionCallback,
"function undebug(function) { [Command Line API] }");
createBoundFunctionProperty(
context, commandLineAPI, data, "monitor",
V8Console::monitorFunctionCallback,
context, commandLineAPI, "monitor", V8Console::monitorFunctionCallback,
"function monitor(function) { [Command Line API] }");
createBoundFunctionProperty(
context, commandLineAPI, data, "unmonitor",
context, commandLineAPI, "unmonitor",
V8Console::unmonitorFunctionCallback,
"function unmonitor(function) { [Command Line API] }");
createBoundFunctionProperty(
context, commandLineAPI, data, "inspect", V8Console::inspectCallback,
context, commandLineAPI, "inspect", V8Console::inspectCallback,
"function inspect(object) { [Command Line API] }");
createBoundFunctionProperty(context, commandLineAPI, data, "copy",
createBoundFunctionProperty(context, commandLineAPI, "copy",
V8Console::copyCallback,
"function copy(value) { [Command Line API] }");
createBoundFunctionProperty(context, commandLineAPI, data, "$_",
createBoundFunctionProperty(context, commandLineAPI, "$_",
V8Console::lastEvaluationResultCallback);
createBoundFunctionProperty(context, commandLineAPI, data, "$0",
createBoundFunctionProperty(context, commandLineAPI, "$0",
V8Console::inspectedObject0);
createBoundFunctionProperty(context, commandLineAPI, data, "$1",
createBoundFunctionProperty(context, commandLineAPI, "$1",
V8Console::inspectedObject1);
createBoundFunctionProperty(context, commandLineAPI, data, "$2",
createBoundFunctionProperty(context, commandLineAPI, "$2",
V8Console::inspectedObject2);
createBoundFunctionProperty(context, commandLineAPI, data, "$3",
createBoundFunctionProperty(context, commandLineAPI, "$3",
V8Console::inspectedObject3);
createBoundFunctionProperty(context, commandLineAPI, data, "$4",
createBoundFunctionProperty(context, commandLineAPI, "$4",
V8Console::inspectedObject4);
inspectedContext->inspector()->client()->installAdditionalCommandLineAPI(
context, commandLineAPI);
commandLineAPI->SetPrivate(context, inspectedContextPrivateKey(isolate),
v8::External::New(isolate, inspectedContext));
return commandLineAPI;
}
......
......@@ -19,6 +19,8 @@ class V8Console {
public:
static v8::Local<v8::Object> createConsole(InspectedContext*,
bool hasMemoryAttribute);
static void clearInspectedContextIfNeeded(v8::Local<v8::Context>,
v8::Local<v8::Object> console);
static v8::Local<v8::Object> createCommandLineAPI(InspectedContext*);
class CommandLineAPIScope {
......
Tests checks that console.memory property can be set in strict mode (crbug.com/468611).
{
id : <messageId>
result : {
result : {
type : undefined
}
}
}
\ No newline at end of file
// 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.log("Tests checks that console.memory property can be set in strict mode (crbug.com/468611).")
Protocol.Runtime.evaluate({ expression: "\"use strict\"\nconsole.memory = {};undefined" }).then(dumpResult);
function dumpResult(result)
{
InspectorTest.logMessage(result);
InspectorTest.completeTest();
}
......@@ -174,10 +174,8 @@ void InspectorClientImpl::connect(v8::Local<v8::Context> context) {
sessions_[context_group_id] =
inspector_->connect(context_group_id, channel_.get(), state);
context->SetAlignedPointerInEmbedderData(kInspectorClientIndex, this);
v8_inspector::V8ContextInfo info(context, context_group_id,
v8_inspector::StringView());
info.hasMemoryOnConsole = true;
inspector_->contextCreated(info);
inspector_->contextCreated(v8_inspector::V8ContextInfo(
context, context_group_id, v8_inspector::StringView()));
} else {
for (const auto& it : states_) {
int context_group_id = it.first;
......@@ -187,10 +185,8 @@ void InspectorClientImpl::connect(v8::Local<v8::Context> context) {
sessions_[context_group_id] =
inspector_->connect(context_group_id, channel_.get(), state);
context->SetAlignedPointerInEmbedderData(kInspectorClientIndex, this);
v8_inspector::V8ContextInfo info(context, context_group_id,
v8_inspector::StringView());
info.hasMemoryOnConsole = true;
inspector_->contextCreated(info);
inspector_->contextCreated(v8_inspector::V8ContextInfo(
context, context_group_id, v8_inspector::StringView()));
}
}
states_.clear();
......@@ -260,17 +256,6 @@ double InspectorClientImpl::currentTimeMS() {
return v8::base::OS::TimeCurrentMillis();
}
void InspectorClientImpl::setMemoryInfoForTest(
v8::Local<v8::Value> memory_info) {
memory_info_.Reset(isolate_, memory_info);
}
v8::MaybeLocal<v8::Value> InspectorClientImpl::memoryInfo(
v8::Isolate* isolate, v8::Local<v8::Context>) {
if (memory_info_.IsEmpty()) return v8::MaybeLocal<v8::Value>();
return memory_info_.Get(isolate);
}
void InspectorClientImpl::runMessageLoopOnPause(int) {
task_runner_->RunMessageLoop(true);
}
......
......@@ -39,7 +39,6 @@ class InspectorClientImpl : public v8_inspector::V8InspectorClient {
v8_inspector::V8InspectorSession* session(int context_group_id = 0);
void setCurrentTimeMSForTest(double time);
void setMemoryInfoForTest(v8::Local<v8::Value> memory_info);
private:
// V8InspectorClient implementation.
......@@ -47,8 +46,6 @@ class InspectorClientImpl : public v8_inspector::V8InspectorClient {
v8::Local<v8::Context> ensureDefaultContextInGroup(
int context_group_id) override;
double currentTimeMS() override;
v8::MaybeLocal<v8::Value> memoryInfo(v8::Isolate* isolate,
v8::Local<v8::Context>) override;
void runMessageLoopOnPause(int context_group_id) override;
void quitMessageLoopOnPause() override;
......@@ -68,7 +65,6 @@ class InspectorClientImpl : public v8_inspector::V8InspectorClient {
std::map<int, std::unique_ptr<v8_inspector::StringBuffer>> states_;
v8::Isolate* isolate_;
v8::Global<v8::Value> memory_info_;
TaskRunner* task_runner_;
FrontendChannel* frontend_channel_;
......
......@@ -57,7 +57,6 @@ class UtilsExtension : public v8::Extension {
"native function load();"
"native function compileAndRunWithOrigin();"
"native function setCurrentTimeMSForTest();"
"native function setMemoryInfoForTest();"
"native function schedulePauseOnNextStatement();"
"native function cancelPauseOnNextStatement();"
"native function reconnect();"
......@@ -108,13 +107,6 @@ class UtilsExtension : public v8::Extension {
.FromJust()) {
return v8::FunctionTemplate::New(isolate,
UtilsExtension::SetCurrentTimeMSForTest);
} else if (name->Equals(context, v8::String::NewFromUtf8(
isolate, "setMemoryInfoForTest",
v8::NewStringType::kNormal)
.ToLocalChecked())
.FromJust()) {
return v8::FunctionTemplate::New(isolate,
UtilsExtension::SetMemoryInfoForTest);
} else if (name->Equals(context,
v8::String::NewFromUtf8(
isolate, "schedulePauseOnNextStatement",
......@@ -274,15 +266,6 @@ class UtilsExtension : public v8::Extension {
args[0].As<v8::Number>()->Value());
}
static void SetMemoryInfoForTest(
const v8::FunctionCallbackInfo<v8::Value>& args) {
if (args.Length() != 1) {
fprintf(stderr, "Internal error: setMemoryInfoForTest(value).");
Exit();
}
inspector_client_->setMemoryInfoForTest(args[0]);
}
static void SchedulePauseOnNextStatement(
const v8::FunctionCallbackInfo<v8::Value>& args) {
if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString()) {
......
......@@ -49,8 +49,6 @@ var utils = {};
this.setlocale = null;
utils.setCurrentTimeMSForTest = setCurrentTimeMSForTest;
this.setCurrentTimeMSForTest = null;
utils.setMemoryInfoForTest = setMemoryInfoForTest;
this.setMemoryInfoForTest = null;
utils.schedulePauseOnNextStatement = schedulePauseOnNextStatement;
this.schedulePauseOnNextStatement = null;
utils.cancelPauseOnNextStatement = cancelPauseOnNextStatement;
......@@ -77,8 +75,6 @@ InspectorTest.logMessage = function(originalMessage)
for (var key in object) {
if (nonStableFields.has(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")
objects.push(object[key]);
}
......
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
}
}
// 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();
}
]);
Checks console.memory
Running test: testWithoutMemory
{
id : <messageId>
result : {
result : {
type : undefined
}
}
}
Running test: testSetterInStrictMode
{
id : <messageId>
result : {
result : {
type : undefined
}
}
}
Running test: testWithMemory
{
id : <messageId>
result : {
result : {
description : 239
type : number
value : 239
}
}
}
Running test: testSetterDoesntOverride
{
id : <messageId>
result : {
result : {
description : 42
type : number
value : 42
}
}
}
// 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 console.memory');
InspectorTest.runAsyncTestSuite([
async function testWithoutMemory() {
InspectorTest.logMessage(
await Protocol.Runtime.evaluate({expression: 'console.memory'}));
},
async function testSetterInStrictMode() {
// crbug.com/468611
InspectorTest.logMessage(
await Protocol.Runtime.evaluate({
expression: '"use strict"\nconsole.memory = {};undefined' }));
},
async function testWithMemory() {
utils.setMemoryInfoForTest(239);
InspectorTest.logMessage(
await Protocol.Runtime.evaluate({expression: 'console.memory'}));
},
async function testSetterDoesntOverride() {
utils.setMemoryInfoForTest(42);
await Protocol.Runtime.evaluate({expression: 'console.memory = 0'});
InspectorTest.logMessage(
await Protocol.Runtime.evaluate({expression: 'console.memory'}));
}
]);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment