OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "platform/v8_inspector/V8Console.h" | 5 #include "platform/v8_inspector/V8Console.h" |
6 | 6 |
7 #include "platform/inspector_protocol/Platform.h" | 7 #include "platform/inspector_protocol/Platform.h" |
8 #include "platform/inspector_protocol/String16.h" | 8 #include "platform/inspector_protocol/String16.h" |
9 #include "platform/v8_inspector/InjectedScript.h" | 9 #include "platform/v8_inspector/InjectedScript.h" |
10 #include "platform/v8_inspector/InspectedContext.h" | 10 #include "platform/v8_inspector/InspectedContext.h" |
11 #include "platform/v8_inspector/V8Compat.h" | 11 #include "platform/v8_inspector/V8Compat.h" |
12 #include "platform/v8_inspector/V8ConsoleMessage.h" | 12 #include "platform/v8_inspector/V8ConsoleMessage.h" |
13 #include "platform/v8_inspector/V8DebuggerAgentImpl.h" | 13 #include "platform/v8_inspector/V8DebuggerAgentImpl.h" |
14 #include "platform/v8_inspector/V8DebuggerImpl.h" | 14 #include "platform/v8_inspector/V8InspectorImpl.h" |
15 #include "platform/v8_inspector/V8InspectorSessionImpl.h" | 15 #include "platform/v8_inspector/V8InspectorSessionImpl.h" |
16 #include "platform/v8_inspector/V8ProfilerAgentImpl.h" | 16 #include "platform/v8_inspector/V8ProfilerAgentImpl.h" |
17 #include "platform/v8_inspector/V8RuntimeAgentImpl.h" | 17 #include "platform/v8_inspector/V8RuntimeAgentImpl.h" |
18 #include "platform/v8_inspector/V8StackTraceImpl.h" | 18 #include "platform/v8_inspector/V8StackTraceImpl.h" |
19 #include "platform/v8_inspector/V8StringUtil.h" | 19 #include "platform/v8_inspector/V8StringUtil.h" |
20 #include "platform/v8_inspector/public/V8DebuggerClient.h" | 20 #include "platform/v8_inspector/public/V8InspectorClient.h" |
21 | 21 |
22 namespace blink { | 22 namespace blink { |
23 | 23 |
24 namespace { | 24 namespace { |
25 | 25 |
26 v8::Local<v8::Private> inspectedContextPrivateKey(v8::Isolate* isolate) | 26 v8::Local<v8::Private> inspectedContextPrivateKey(v8::Isolate* isolate) |
27 { | 27 { |
28 return v8::Private::ForApi(isolate, toV8StringInternalized(isolate, "V8Conso
le#InspectedContext")); | 28 return v8::Private::ForApi(isolate, toV8StringInternalized(isolate, "V8Conso
le#InspectedContext")); |
29 } | 29 } |
30 | 30 |
31 class ConsoleHelper { | 31 class ConsoleHelper { |
32 PROTOCOL_DISALLOW_COPY(ConsoleHelper); | 32 PROTOCOL_DISALLOW_COPY(ConsoleHelper); |
33 public: | 33 public: |
34 ConsoleHelper(const v8::FunctionCallbackInfo<v8::Value>& info) | 34 ConsoleHelper(const v8::FunctionCallbackInfo<v8::Value>& info) |
35 : m_info(info) | 35 : m_info(info) |
36 , m_isolate(info.GetIsolate()) | 36 , m_isolate(info.GetIsolate()) |
37 , m_context(info.GetIsolate()->GetCurrentContext()) | 37 , m_context(info.GetIsolate()->GetCurrentContext()) |
38 , m_inspectedContext(nullptr) | 38 , m_inspectedContext(nullptr) |
39 , m_debuggerClient(nullptr) | 39 , m_inspectorClient(nullptr) |
40 { | 40 { |
41 } | 41 } |
42 | 42 |
43 v8::Local<v8::Object> ensureConsole() | 43 v8::Local<v8::Object> ensureConsole() |
44 { | 44 { |
45 if (m_console.IsEmpty()) { | 45 if (m_console.IsEmpty()) { |
46 DCHECK(!m_info.Data().IsEmpty()); | 46 DCHECK(!m_info.Data().IsEmpty()); |
47 DCHECK(!m_info.Data()->IsUndefined()); | 47 DCHECK(!m_info.Data()->IsUndefined()); |
48 m_console = m_info.Data().As<v8::Object>(); | 48 m_console = m_info.Data().As<v8::Object>(); |
49 } | 49 } |
50 return m_console; | 50 return m_console; |
51 } | 51 } |
52 | 52 |
53 InspectedContext* ensureInspectedContext() | 53 InspectedContext* ensureInspectedContext() |
54 { | 54 { |
55 if (m_inspectedContext) | 55 if (m_inspectedContext) |
56 return m_inspectedContext; | 56 return m_inspectedContext; |
57 v8::Local<v8::Object> console = ensureConsole(); | 57 v8::Local<v8::Object> console = ensureConsole(); |
58 | 58 |
59 v8::Local<v8::Private> key = inspectedContextPrivateKey(m_isolate); | 59 v8::Local<v8::Private> key = inspectedContextPrivateKey(m_isolate); |
60 v8::Local<v8::Value> inspectedContextValue; | 60 v8::Local<v8::Value> inspectedContextValue; |
61 if (!console->GetPrivate(m_context, key).ToLocal(&inspectedContextValue)
) | 61 if (!console->GetPrivate(m_context, key).ToLocal(&inspectedContextValue)
) |
62 return nullptr; | 62 return nullptr; |
63 DCHECK(inspectedContextValue->IsExternal()); | 63 DCHECK(inspectedContextValue->IsExternal()); |
64 m_inspectedContext = static_cast<InspectedContext*>(inspectedContextValu
e.As<v8::External>()->Value()); | 64 m_inspectedContext = static_cast<InspectedContext*>(inspectedContextValu
e.As<v8::External>()->Value()); |
65 return m_inspectedContext; | 65 return m_inspectedContext; |
66 } | 66 } |
67 | 67 |
68 V8DebuggerClient* ensureDebuggerClient() | 68 V8InspectorClient* ensureDebuggerClient() |
69 { | 69 { |
70 if (m_debuggerClient) | 70 if (m_inspectorClient) |
71 return m_debuggerClient; | 71 return m_inspectorClient; |
72 InspectedContext* inspectedContext = ensureInspectedContext(); | 72 InspectedContext* inspectedContext = ensureInspectedContext(); |
73 if (!inspectedContext) | 73 if (!inspectedContext) |
74 return nullptr; | 74 return nullptr; |
75 m_debuggerClient = inspectedContext->debugger()->client(); | 75 m_inspectorClient = inspectedContext->inspector()->client(); |
76 return m_debuggerClient; | 76 return m_inspectorClient; |
77 } | 77 } |
78 | 78 |
79 void reportCall(ConsoleAPIType type) | 79 void reportCall(ConsoleAPIType type) |
80 { | 80 { |
81 if (!m_info.Length()) | 81 if (!m_info.Length()) |
82 return; | 82 return; |
83 std::vector<v8::Local<v8::Value>> arguments; | 83 std::vector<v8::Local<v8::Value>> arguments; |
84 for (int i = 0; i < m_info.Length(); ++i) | 84 for (int i = 0; i < m_info.Length(); ++i) |
85 arguments.push_back(m_info[i]); | 85 arguments.push_back(m_info[i]); |
86 reportCall(type, arguments); | 86 reportCall(type, arguments); |
(...skipping 13 matching lines...) Expand all Loading... |
100 { | 100 { |
101 std::vector<v8::Local<v8::Value>> arguments(1, toV8String(m_isolate, mes
sage)); | 101 std::vector<v8::Local<v8::Value>> arguments(1, toV8String(m_isolate, mes
sage)); |
102 reportCall(type, arguments); | 102 reportCall(type, arguments); |
103 } | 103 } |
104 | 104 |
105 void reportCall(ConsoleAPIType type, const std::vector<v8::Local<v8::Value>>
& arguments) | 105 void reportCall(ConsoleAPIType type, const std::vector<v8::Local<v8::Value>>
& arguments) |
106 { | 106 { |
107 InspectedContext* inspectedContext = ensureInspectedContext(); | 107 InspectedContext* inspectedContext = ensureInspectedContext(); |
108 if (!inspectedContext) | 108 if (!inspectedContext) |
109 return; | 109 return; |
110 V8DebuggerImpl* debugger = inspectedContext->debugger(); | 110 V8InspectorImpl* inspector = inspectedContext->inspector(); |
111 std::unique_ptr<V8ConsoleMessage> message = V8ConsoleMessage::createForC
onsoleAPI(debugger->client()->currentTimeMS(), type, arguments, debugger->captur
eStackTraceImpl(false), inspectedContext); | 111 std::unique_ptr<V8ConsoleMessage> message = V8ConsoleMessage::createForC
onsoleAPI(inspector->client()->currentTimeMS(), type, arguments, inspector->capt
ureStackTraceImpl(false), inspectedContext); |
112 debugger->ensureConsoleMessageStorage(inspectedContext->contextGroupId()
)->addMessage(std::move(message)); | 112 inspector->ensureConsoleMessageStorage(inspectedContext->contextGroupId(
))->addMessage(std::move(message)); |
113 } | 113 } |
114 | 114 |
115 void reportDeprecatedCall(const char* id, const String16& message) | 115 void reportDeprecatedCall(const char* id, const String16& message) |
116 { | 116 { |
117 if (checkAndSetPrivateFlagOnConsole(id, false)) | 117 if (checkAndSetPrivateFlagOnConsole(id, false)) |
118 return; | 118 return; |
119 std::vector<v8::Local<v8::Value>> arguments(1, toV8String(m_isolate, mes
sage)); | 119 std::vector<v8::Local<v8::Value>> arguments(1, toV8String(m_isolate, mes
sage)); |
120 reportCall(ConsoleAPIType::kWarning, arguments); | 120 reportCall(ConsoleAPIType::kWarning, arguments); |
121 } | 121 } |
122 | 122 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 return session->debuggerAgent(); | 226 return session->debuggerAgent(); |
227 } | 227 } |
228 return nullptr; | 228 return nullptr; |
229 } | 229 } |
230 | 230 |
231 V8InspectorSessionImpl* currentSession() | 231 V8InspectorSessionImpl* currentSession() |
232 { | 232 { |
233 InspectedContext* inspectedContext = ensureInspectedContext(); | 233 InspectedContext* inspectedContext = ensureInspectedContext(); |
234 if (!inspectedContext) | 234 if (!inspectedContext) |
235 return nullptr; | 235 return nullptr; |
236 return inspectedContext->debugger()->sessionForContextGroup(inspectedCon
text->contextGroupId()); | 236 return inspectedContext->inspector()->sessionForContextGroup(inspectedCo
ntext->contextGroupId()); |
237 } | 237 } |
238 | 238 |
239 private: | 239 private: |
240 const v8::FunctionCallbackInfo<v8::Value>& m_info; | 240 const v8::FunctionCallbackInfo<v8::Value>& m_info; |
241 v8::Isolate* m_isolate; | 241 v8::Isolate* m_isolate; |
242 v8::Local<v8::Context> m_context; | 242 v8::Local<v8::Context> m_context; |
243 v8::Local<v8::Object> m_console; | 243 v8::Local<v8::Object> m_console; |
244 InspectedContext* m_inspectedContext; | 244 InspectedContext* m_inspectedContext; |
245 V8DebuggerClient* m_debuggerClient; | 245 V8InspectorClient* m_inspectorClient; |
246 | 246 |
247 bool checkAndSetPrivateFlagOnConsole(const char* name, bool defaultValue) | 247 bool checkAndSetPrivateFlagOnConsole(const char* name, bool defaultValue) |
248 { | 248 { |
249 v8::Local<v8::Object> console = ensureConsole(); | 249 v8::Local<v8::Object> console = ensureConsole(); |
250 v8::Local<v8::Private> key = v8::Private::ForApi(m_isolate, toV8StringIn
ternalized(m_isolate, name)); | 250 v8::Local<v8::Private> key = v8::Private::ForApi(m_isolate, toV8StringIn
ternalized(m_isolate, name)); |
251 v8::Local<v8::Value> flagValue; | 251 v8::Local<v8::Value> flagValue; |
252 if (!console->GetPrivate(m_context, key).ToLocal(&flagValue)) | 252 if (!console->GetPrivate(m_context, key).ToLocal(&flagValue)) |
253 return defaultValue; | 253 return defaultValue; |
254 DCHECK(flagValue->IsUndefined() || flagValue->IsBoolean()); | 254 DCHECK(flagValue->IsUndefined() || flagValue->IsBoolean()); |
255 if (flagValue->IsBoolean()) { | 255 if (flagValue->IsBoolean()) { |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 void V8Console::profileEndCallback(const v8::FunctionCallbackInfo<v8::Value>& in
fo) | 406 void V8Console::profileEndCallback(const v8::FunctionCallbackInfo<v8::Value>& in
fo) |
407 { | 407 { |
408 ConsoleHelper helper(info); | 408 ConsoleHelper helper(info); |
409 if (V8ProfilerAgentImpl* profilerAgent = helper.profilerAgent()) | 409 if (V8ProfilerAgentImpl* profilerAgent = helper.profilerAgent()) |
410 profilerAgent->consoleProfileEnd(helper.firstArgToString(String16())); | 410 profilerAgent->consoleProfileEnd(helper.firstArgToString(String16())); |
411 } | 411 } |
412 | 412 |
413 static void timeFunction(const v8::FunctionCallbackInfo<v8::Value>& info, bool t
imelinePrefix) | 413 static void timeFunction(const v8::FunctionCallbackInfo<v8::Value>& info, bool t
imelinePrefix) |
414 { | 414 { |
415 ConsoleHelper helper(info); | 415 ConsoleHelper helper(info); |
416 if (V8DebuggerClient* client = helper.ensureDebuggerClient()) { | 416 if (V8InspectorClient* client = helper.ensureDebuggerClient()) { |
417 String16 protocolTitle = helper.firstArgToString("default"); | 417 String16 protocolTitle = helper.firstArgToString("default"); |
418 if (timelinePrefix) | 418 if (timelinePrefix) |
419 protocolTitle = "Timeline '" + protocolTitle + "'"; | 419 protocolTitle = "Timeline '" + protocolTitle + "'"; |
420 client->consoleTime(protocolTitle); | 420 client->consoleTime(protocolTitle); |
421 | 421 |
422 v8::Local<v8::Map> timeMap; | 422 v8::Local<v8::Map> timeMap; |
423 if (!helper.privateMap("V8Console#timeMap").ToLocal(&timeMap)) | 423 if (!helper.privateMap("V8Console#timeMap").ToLocal(&timeMap)) |
424 return; | 424 return; |
425 helper.setDoubleOnMap(timeMap, protocolTitle, client->currentTimeMS()); | 425 helper.setDoubleOnMap(timeMap, protocolTitle, client->currentTimeMS()); |
426 } | 426 } |
427 } | 427 } |
428 | 428 |
429 static void timeEndFunction(const v8::FunctionCallbackInfo<v8::Value>& info, boo
l timelinePrefix) | 429 static void timeEndFunction(const v8::FunctionCallbackInfo<v8::Value>& info, boo
l timelinePrefix) |
430 { | 430 { |
431 ConsoleHelper helper(info); | 431 ConsoleHelper helper(info); |
432 if (V8DebuggerClient* client = helper.ensureDebuggerClient()) { | 432 if (V8InspectorClient* client = helper.ensureDebuggerClient()) { |
433 String16 protocolTitle = helper.firstArgToString("default"); | 433 String16 protocolTitle = helper.firstArgToString("default"); |
434 if (timelinePrefix) | 434 if (timelinePrefix) |
435 protocolTitle = "Timeline '" + protocolTitle + "'"; | 435 protocolTitle = "Timeline '" + protocolTitle + "'"; |
436 client->consoleTimeEnd(protocolTitle); | 436 client->consoleTimeEnd(protocolTitle); |
437 | 437 |
438 v8::Local<v8::Map> timeMap; | 438 v8::Local<v8::Map> timeMap; |
439 if (!helper.privateMap("V8Console#timeMap").ToLocal(&timeMap)) | 439 if (!helper.privateMap("V8Console#timeMap").ToLocal(&timeMap)) |
440 return; | 440 return; |
441 double elapsed = client->currentTimeMS() - helper.getDoubleFromMap(timeM
ap, protocolTitle, 0.0); | 441 double elapsed = client->currentTimeMS() - helper.getDoubleFromMap(timeM
ap, protocolTitle, 0.0); |
442 String16 message = protocolTitle + ": " + String16::fromDoubleFixedPreci
sion(elapsed, 3) + "ms"; | 442 String16 message = protocolTitle + ": " + String16::fromDoubleFixedPreci
sion(elapsed, 3) + "ms"; |
(...skipping 19 matching lines...) Expand all Loading... |
462 } | 462 } |
463 | 463 |
464 void V8Console::timeEndCallback(const v8::FunctionCallbackInfo<v8::Value>& info) | 464 void V8Console::timeEndCallback(const v8::FunctionCallbackInfo<v8::Value>& info) |
465 { | 465 { |
466 timeEndFunction(info, false); | 466 timeEndFunction(info, false); |
467 } | 467 } |
468 | 468 |
469 void V8Console::timeStampCallback(const v8::FunctionCallbackInfo<v8::Value>& inf
o) | 469 void V8Console::timeStampCallback(const v8::FunctionCallbackInfo<v8::Value>& inf
o) |
470 { | 470 { |
471 ConsoleHelper helper(info); | 471 ConsoleHelper helper(info); |
472 if (V8DebuggerClient* client = helper.ensureDebuggerClient()) | 472 if (V8InspectorClient* client = helper.ensureDebuggerClient()) |
473 client->consoleTimeStamp(helper.firstArgToString(String16())); | 473 client->consoleTimeStamp(helper.firstArgToString(String16())); |
474 } | 474 } |
475 | 475 |
476 void V8Console::memoryGetterCallback(const v8::FunctionCallbackInfo<v8::Value>&
info) | 476 void V8Console::memoryGetterCallback(const v8::FunctionCallbackInfo<v8::Value>&
info) |
477 { | 477 { |
478 if (V8DebuggerClient* client = ConsoleHelper(info).ensureDebuggerClient()) { | 478 if (V8InspectorClient* client = ConsoleHelper(info).ensureDebuggerClient())
{ |
479 v8::Local<v8::Value> memoryValue; | 479 v8::Local<v8::Value> memoryValue; |
480 if (!client->memoryInfo(info.GetIsolate(), info.GetIsolate()->GetCurrent
Context()).ToLocal(&memoryValue)) | 480 if (!client->memoryInfo(info.GetIsolate(), info.GetIsolate()->GetCurrent
Context()).ToLocal(&memoryValue)) |
481 return; | 481 return; |
482 info.GetReturnValue().Set(memoryValue); | 482 info.GetReturnValue().Set(memoryValue); |
483 } | 483 } |
484 } | 484 } |
485 | 485 |
486 void V8Console::memorySetterCallback(const v8::FunctionCallbackInfo<v8::Value>&
info) | 486 void V8Console::memorySetterCallback(const v8::FunctionCallbackInfo<v8::Value>&
info) |
487 { | 487 { |
488 // We can't make the attribute readonly as it breaks existing code that reli
es on being able to assign to console.memory in strict mode. Instead, the setter
just ignores the passed value. http://crbug.com/468611 | 488 // We can't make the attribute readonly as it breaks existing code that reli
es on being able to assign to console.memory in strict mode. Instead, the setter
just ignores the passed value. http://crbug.com/468611 |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 createBoundFunctionProperty(context, commandLineAPI, "unmonitor", V8Console:
:unmonitorFunctionCallback, "function unmonitor(function) { [Command Line API] }
"); | 724 createBoundFunctionProperty(context, commandLineAPI, "unmonitor", V8Console:
:unmonitorFunctionCallback, "function unmonitor(function) { [Command Line API] }
"); |
725 createBoundFunctionProperty(context, commandLineAPI, "inspect", V8Console::i
nspectCallback, "function inspect(object) { [Command Line API] }"); | 725 createBoundFunctionProperty(context, commandLineAPI, "inspect", V8Console::i
nspectCallback, "function inspect(object) { [Command Line API] }"); |
726 createBoundFunctionProperty(context, commandLineAPI, "copy", V8Console::copy
Callback, "function copy(value) { [Command Line API] }"); | 726 createBoundFunctionProperty(context, commandLineAPI, "copy", V8Console::copy
Callback, "function copy(value) { [Command Line API] }"); |
727 createBoundFunctionProperty(context, commandLineAPI, "$_", V8Console::lastEv
aluationResultCallback); | 727 createBoundFunctionProperty(context, commandLineAPI, "$_", V8Console::lastEv
aluationResultCallback); |
728 createBoundFunctionProperty(context, commandLineAPI, "$0", V8Console::inspec
tedObject0); | 728 createBoundFunctionProperty(context, commandLineAPI, "$0", V8Console::inspec
tedObject0); |
729 createBoundFunctionProperty(context, commandLineAPI, "$1", V8Console::inspec
tedObject1); | 729 createBoundFunctionProperty(context, commandLineAPI, "$1", V8Console::inspec
tedObject1); |
730 createBoundFunctionProperty(context, commandLineAPI, "$2", V8Console::inspec
tedObject2); | 730 createBoundFunctionProperty(context, commandLineAPI, "$2", V8Console::inspec
tedObject2); |
731 createBoundFunctionProperty(context, commandLineAPI, "$3", V8Console::inspec
tedObject3); | 731 createBoundFunctionProperty(context, commandLineAPI, "$3", V8Console::inspec
tedObject3); |
732 createBoundFunctionProperty(context, commandLineAPI, "$4", V8Console::inspec
tedObject4); | 732 createBoundFunctionProperty(context, commandLineAPI, "$4", V8Console::inspec
tedObject4); |
733 | 733 |
734 inspectedContext->debugger()->client()->installAdditionalCommandLineAPI(cont
ext, commandLineAPI); | 734 inspectedContext->inspector()->client()->installAdditionalCommandLineAPI(con
text, commandLineAPI); |
735 | 735 |
736 commandLineAPI->SetPrivate(context, inspectedContextPrivateKey(isolate), v8:
:External::New(isolate, inspectedContext)); | 736 commandLineAPI->SetPrivate(context, inspectedContextPrivateKey(isolate), v8:
:External::New(isolate, inspectedContext)); |
737 return commandLineAPI; | 737 return commandLineAPI; |
738 } | 738 } |
739 | 739 |
740 static bool isCommandLineAPIGetter(const String16& name) | 740 static bool isCommandLineAPIGetter(const String16& name) |
741 { | 741 { |
742 if (name.length() != 2) | 742 if (name.length() != 2) |
743 return false; | 743 return false; |
744 // $0 ... $4, $_ | 744 // $0 ... $4, $_ |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 continue; | 822 continue; |
823 if (name->IsString()) { | 823 if (name->IsString()) { |
824 v8::Local<v8::Value> descriptor; | 824 v8::Local<v8::Value> descriptor; |
825 bool success = m_global->GetOwnPropertyDescriptor(m_context, v8::Loc
al<v8::String>::Cast(name)).ToLocal(&descriptor); | 825 bool success = m_global->GetOwnPropertyDescriptor(m_context, v8::Loc
al<v8::String>::Cast(name)).ToLocal(&descriptor); |
826 DCHECK(success); | 826 DCHECK(success); |
827 } | 827 } |
828 } | 828 } |
829 } | 829 } |
830 | 830 |
831 } // namespace blink | 831 } // namespace blink |
OLD | NEW |