OLD | NEW |
1 /* | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 * Copyright (c) 2010-2011 Google Inc. All rights reserved. | 2 // Use of this source code is governed by a BSD-style license that can be |
3 * | 3 // found in the LICENSE file. |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 */ | |
30 | 4 |
31 #include "platform/v8_inspector/V8InspectorImpl.h" | 5 #include "platform/v8_inspector/V8Debugger.h" |
32 | 6 |
33 #include "platform/inspector_protocol/Values.h" | |
34 #include "platform/v8_inspector/Atomics.h" | |
35 #include "platform/v8_inspector/DebuggerScript.h" | 7 #include "platform/v8_inspector/DebuggerScript.h" |
36 #include "platform/v8_inspector/InspectedContext.h" | |
37 #include "platform/v8_inspector/ScriptBreakpoint.h" | 8 #include "platform/v8_inspector/ScriptBreakpoint.h" |
38 #include "platform/v8_inspector/V8Compat.h" | 9 #include "platform/v8_inspector/V8Compat.h" |
39 #include "platform/v8_inspector/V8ConsoleAgentImpl.h" | |
40 #include "platform/v8_inspector/V8ConsoleMessage.h" | |
41 #include "platform/v8_inspector/V8DebuggerAgentImpl.h" | 10 #include "platform/v8_inspector/V8DebuggerAgentImpl.h" |
42 #include "platform/v8_inspector/V8InjectedScriptHost.h" | 11 #include "platform/v8_inspector/V8InspectorImpl.h" |
43 #include "platform/v8_inspector/V8InspectorSessionImpl.h" | |
44 #include "platform/v8_inspector/V8InternalValueType.h" | 12 #include "platform/v8_inspector/V8InternalValueType.h" |
45 #include "platform/v8_inspector/V8RuntimeAgentImpl.h" | |
46 #include "platform/v8_inspector/V8StackTraceImpl.h" | 13 #include "platform/v8_inspector/V8StackTraceImpl.h" |
47 #include "platform/v8_inspector/V8StringUtil.h" | 14 #include "platform/v8_inspector/V8StringUtil.h" |
48 #include "platform/v8_inspector/public/V8InspectorClient.h" | 15 #include "platform/v8_inspector/public/V8InspectorClient.h" |
49 #include <v8-profiler.h> | |
50 | 16 |
51 namespace blink { | 17 namespace blink { |
52 | 18 |
53 namespace { | 19 namespace { |
54 const char stepIntoV8MethodName[] = "stepIntoStatement"; | 20 const char stepIntoV8MethodName[] = "stepIntoStatement"; |
55 const char stepOutV8MethodName[] = "stepOutOfFunction"; | 21 const char stepOutV8MethodName[] = "stepOutOfFunction"; |
56 volatile int s_lastContextId = 0; | |
57 static const char v8AsyncTaskEventEnqueue[] = "enqueue"; | 22 static const char v8AsyncTaskEventEnqueue[] = "enqueue"; |
58 static const char v8AsyncTaskEventWillHandle[] = "willHandle"; | 23 static const char v8AsyncTaskEventWillHandle[] = "willHandle"; |
59 static const char v8AsyncTaskEventDidHandle[] = "didHandle"; | 24 static const char v8AsyncTaskEventDidHandle[] = "didHandle"; |
60 | 25 |
61 inline v8::Local<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate) | 26 inline v8::Local<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate) |
62 { | 27 { |
63 return value ? v8::True(isolate) : v8::False(isolate); | 28 return value ? v8::True(isolate) : v8::False(isolate); |
64 } | 29 } |
65 | 30 |
66 } | 31 } |
67 | 32 |
68 static bool inLiveEditScope = false; | 33 static bool inLiveEditScope = false; |
69 | 34 |
70 v8::MaybeLocal<v8::Value> V8InspectorImpl::callDebuggerMethod(const char* functi
onName, int argc, v8::Local<v8::Value> argv[]) | 35 v8::MaybeLocal<v8::Value> V8Debugger::callDebuggerMethod(const char* functionNam
e, int argc, v8::Local<v8::Value> argv[]) |
71 { | 36 { |
72 v8::MicrotasksScope microtasks(m_isolate, v8::MicrotasksScope::kDoNotRunMicr
otasks); | 37 v8::MicrotasksScope microtasks(m_isolate, v8::MicrotasksScope::kDoNotRunMicr
otasks); |
73 v8::Local<v8::Object> debuggerScript = m_debuggerScript.Get(m_isolate); | 38 v8::Local<v8::Object> debuggerScript = m_debuggerScript.Get(m_isolate); |
74 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(debuggerScr
ipt->Get(v8InternalizedString(functionName))); | 39 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(debuggerScr
ipt->Get(toV8StringInternalized(m_isolate, functionName))); |
75 DCHECK(m_isolate->InContext()); | 40 DCHECK(m_isolate->InContext()); |
76 return function->Call(m_isolate->GetCurrentContext(), debuggerScript, argc,
argv); | 41 return function->Call(m_isolate->GetCurrentContext(), debuggerScript, argc,
argv); |
77 } | 42 } |
78 | 43 |
79 std::unique_ptr<V8Inspector> V8Inspector::create(v8::Isolate* isolate, V8Inspect
orClient* client) | 44 V8Debugger::V8Debugger(v8::Isolate* isolate, V8InspectorImpl* inspector) |
80 { | |
81 return wrapUnique(new V8InspectorImpl(isolate, client)); | |
82 } | |
83 | |
84 V8InspectorImpl::V8InspectorImpl(v8::Isolate* isolate, V8InspectorClient* client
) | |
85 : m_isolate(isolate) | 45 : m_isolate(isolate) |
86 , m_client(client) | 46 , m_inspector(inspector) |
87 , m_capturingStackTracesCount(0) | 47 , m_lastContextId(0) |
88 , m_lastExceptionId(0) | 48 , m_enableCount(0) |
89 , m_enabledAgentsCount(0) | |
90 , m_breakpointsActivated(true) | 49 , m_breakpointsActivated(true) |
91 , m_runningNestedMessageLoop(false) | 50 , m_runningNestedMessageLoop(false) |
92 , m_maxAsyncCallStackDepth(0) | 51 , m_maxAsyncCallStackDepth(0) |
93 { | 52 { |
94 } | 53 } |
95 | 54 |
96 V8InspectorImpl::~V8InspectorImpl() | 55 V8Debugger::~V8Debugger() |
97 { | 56 { |
98 } | 57 } |
99 | 58 |
100 void V8InspectorImpl::enable() | 59 void V8Debugger::enable() |
101 { | 60 { |
| 61 if (m_enableCount++) |
| 62 return; |
102 DCHECK(!enabled()); | 63 DCHECK(!enabled()); |
103 v8::HandleScope scope(m_isolate); | 64 v8::HandleScope scope(m_isolate); |
104 v8::Debug::SetDebugEventListener(m_isolate, &V8InspectorImpl::v8DebugEventCa
llback, v8::External::New(m_isolate, this)); | 65 v8::Debug::SetDebugEventListener(m_isolate, &V8Debugger::v8DebugEventCallbac
k, v8::External::New(m_isolate, this)); |
105 m_debuggerContext.Reset(m_isolate, v8::Debug::GetDebugContext(m_isolate)); | 66 m_debuggerContext.Reset(m_isolate, v8::Debug::GetDebugContext(m_isolate)); |
106 compileDebuggerScript(); | 67 compileDebuggerScript(); |
107 } | 68 } |
108 | 69 |
109 void V8InspectorImpl::disable() | 70 void V8Debugger::disable() |
110 { | 71 { |
| 72 if (--m_enableCount) |
| 73 return; |
111 DCHECK(enabled()); | 74 DCHECK(enabled()); |
112 clearBreakpoints(); | 75 clearBreakpoints(); |
113 m_debuggerScript.Reset(); | 76 m_debuggerScript.Reset(); |
114 m_debuggerContext.Reset(); | 77 m_debuggerContext.Reset(); |
115 allAsyncTasksCanceled(); | 78 allAsyncTasksCanceled(); |
116 v8::Debug::SetDebugEventListener(m_isolate, nullptr); | 79 v8::Debug::SetDebugEventListener(m_isolate, nullptr); |
117 } | 80 } |
118 | 81 |
119 bool V8InspectorImpl::enabled() const | 82 bool V8Debugger::enabled() const |
120 { | 83 { |
121 return !m_debuggerScript.IsEmpty(); | 84 return !m_debuggerScript.IsEmpty(); |
122 } | 85 } |
123 | 86 |
124 // static | 87 // static |
125 int V8InspectorImpl::contextId(v8::Local<v8::Context> context) | 88 int V8Debugger::contextId(v8::Local<v8::Context> context) |
126 { | 89 { |
127 v8::Local<v8::Value> data = context->GetEmbedderData(static_cast<int>(v8::Co
ntext::kDebugIdIndex)); | 90 v8::Local<v8::Value> data = context->GetEmbedderData(static_cast<int>(v8::Co
ntext::kDebugIdIndex)); |
128 if (data.IsEmpty() || !data->IsString()) | 91 if (data.IsEmpty() || !data->IsString()) |
129 return 0; | 92 return 0; |
130 String16 dataString = toProtocolString(data.As<v8::String>()); | 93 String16 dataString = toProtocolString(data.As<v8::String>()); |
131 if (dataString.isEmpty()) | 94 if (dataString.isEmpty()) |
132 return 0; | 95 return 0; |
133 size_t commaPos = dataString.find(","); | 96 size_t commaPos = dataString.find(","); |
134 if (commaPos == kNotFound) | 97 if (commaPos == kNotFound) |
135 return 0; | 98 return 0; |
136 size_t commaPos2 = dataString.find(",", commaPos + 1); | 99 size_t commaPos2 = dataString.find(",", commaPos + 1); |
137 if (commaPos2 == kNotFound) | 100 if (commaPos2 == kNotFound) |
138 return 0; | 101 return 0; |
139 return dataString.substring(commaPos + 1, commaPos2 - commaPos - 1).toInt(); | 102 return dataString.substring(commaPos + 1, commaPos2 - commaPos - 1).toInt(); |
140 } | 103 } |
141 | 104 |
142 // static | 105 // static |
143 int V8InspectorImpl::getGroupId(v8::Local<v8::Context> context) | 106 int V8Debugger::getGroupId(v8::Local<v8::Context> context) |
144 { | 107 { |
145 v8::Local<v8::Value> data = context->GetEmbedderData(static_cast<int>(v8::Co
ntext::kDebugIdIndex)); | 108 v8::Local<v8::Value> data = context->GetEmbedderData(static_cast<int>(v8::Co
ntext::kDebugIdIndex)); |
146 if (data.IsEmpty() || !data->IsString()) | 109 if (data.IsEmpty() || !data->IsString()) |
147 return 0; | 110 return 0; |
148 String16 dataString = toProtocolString(data.As<v8::String>()); | 111 String16 dataString = toProtocolString(data.As<v8::String>()); |
149 if (dataString.isEmpty()) | 112 if (dataString.isEmpty()) |
150 return 0; | 113 return 0; |
151 size_t commaPos = dataString.find(","); | 114 size_t commaPos = dataString.find(","); |
152 if (commaPos == kNotFound) | 115 if (commaPos == kNotFound) |
153 return 0; | 116 return 0; |
154 return dataString.substring(0, commaPos).toInt(); | 117 return dataString.substring(0, commaPos).toInt(); |
155 } | 118 } |
156 | 119 |
157 void V8InspectorImpl::debuggerAgentEnabled() | 120 void V8Debugger::getCompiledScripts(int contextGroupId, std::vector<std::unique_
ptr<V8DebuggerScript>>& result) |
158 { | |
159 if (!m_enabledAgentsCount++) | |
160 enable(); | |
161 } | |
162 | |
163 void V8InspectorImpl::debuggerAgentDisabled() | |
164 { | |
165 if (!--m_enabledAgentsCount) | |
166 disable(); | |
167 } | |
168 | |
169 V8DebuggerAgentImpl* V8InspectorImpl::findEnabledDebuggerAgent(int contextGroupI
d) | |
170 { | |
171 if (!contextGroupId) | |
172 return nullptr; | |
173 SessionMap::iterator it = m_sessions.find(contextGroupId); | |
174 if (it == m_sessions.end()) | |
175 return nullptr; | |
176 V8DebuggerAgentImpl* agent = it->second->debuggerAgent(); | |
177 if (!agent->enabled()) | |
178 return nullptr; | |
179 return agent; | |
180 } | |
181 | |
182 V8DebuggerAgentImpl* V8InspectorImpl::findEnabledDebuggerAgent(v8::Local<v8::Con
text> context) | |
183 { | |
184 return findEnabledDebuggerAgent(getGroupId(context)); | |
185 } | |
186 | |
187 void V8InspectorImpl::getCompiledScripts(int contextGroupId, std::vector<std::un
ique_ptr<V8DebuggerScript>>& result) | |
188 { | 121 { |
189 v8::HandleScope scope(m_isolate); | 122 v8::HandleScope scope(m_isolate); |
190 v8::MicrotasksScope microtasks(m_isolate, v8::MicrotasksScope::kDoNotRunMicr
otasks); | 123 v8::MicrotasksScope microtasks(m_isolate, v8::MicrotasksScope::kDoNotRunMicr
otasks); |
191 v8::Local<v8::Object> debuggerScript = m_debuggerScript.Get(m_isolate); | 124 v8::Local<v8::Object> debuggerScript = m_debuggerScript.Get(m_isolate); |
192 DCHECK(!debuggerScript->IsUndefined()); | 125 DCHECK(!debuggerScript->IsUndefined()); |
193 v8::Local<v8::Function> getScriptsFunction = v8::Local<v8::Function>::Cast(d
ebuggerScript->Get(v8InternalizedString("getScripts"))); | 126 v8::Local<v8::Function> getScriptsFunction = v8::Local<v8::Function>::Cast(d
ebuggerScript->Get(toV8StringInternalized(m_isolate, "getScripts"))); |
194 v8::Local<v8::Value> argv[] = { v8::Integer::New(m_isolate, contextGroupId)
}; | 127 v8::Local<v8::Value> argv[] = { v8::Integer::New(m_isolate, contextGroupId)
}; |
195 v8::Local<v8::Value> value; | 128 v8::Local<v8::Value> value; |
196 if (!getScriptsFunction->Call(debuggerContext(), debuggerScript, PROTOCOL_AR
RAY_LENGTH(argv), argv).ToLocal(&value)) | 129 if (!getScriptsFunction->Call(debuggerContext(), debuggerScript, PROTOCOL_AR
RAY_LENGTH(argv), argv).ToLocal(&value)) |
197 return; | 130 return; |
198 DCHECK(value->IsArray()); | 131 DCHECK(value->IsArray()); |
199 v8::Local<v8::Array> scriptsArray = v8::Local<v8::Array>::Cast(value); | 132 v8::Local<v8::Array> scriptsArray = v8::Local<v8::Array>::Cast(value); |
200 result.reserve(scriptsArray->Length()); | 133 result.reserve(scriptsArray->Length()); |
201 for (unsigned i = 0; i < scriptsArray->Length(); ++i) { | 134 for (unsigned i = 0; i < scriptsArray->Length(); ++i) { |
202 v8::Local<v8::Object> scriptObject = v8::Local<v8::Object>::Cast(scripts
Array->Get(v8::Integer::New(m_isolate, i))); | 135 v8::Local<v8::Object> scriptObject = v8::Local<v8::Object>::Cast(scripts
Array->Get(v8::Integer::New(m_isolate, i))); |
203 result.push_back(wrapUnique(new V8DebuggerScript(m_isolate, scriptObject
, inLiveEditScope))); | 136 result.push_back(wrapUnique(new V8DebuggerScript(m_isolate, scriptObject
, inLiveEditScope))); |
204 } | 137 } |
205 } | 138 } |
206 | 139 |
207 String16 V8InspectorImpl::setBreakpoint(const String16& sourceID, const ScriptBr
eakpoint& scriptBreakpoint, int* actualLineNumber, int* actualColumnNumber, bool
interstatementLocation) | 140 String16 V8Debugger::setBreakpoint(const String16& sourceID, const ScriptBreakpo
int& scriptBreakpoint, int* actualLineNumber, int* actualColumnNumber, bool inte
rstatementLocation) |
208 { | 141 { |
209 v8::HandleScope scope(m_isolate); | 142 v8::HandleScope scope(m_isolate); |
210 v8::Context::Scope contextScope(debuggerContext()); | 143 v8::Context::Scope contextScope(debuggerContext()); |
211 | 144 |
212 v8::Local<v8::Object> info = v8::Object::New(m_isolate); | 145 v8::Local<v8::Object> info = v8::Object::New(m_isolate); |
213 info->Set(v8InternalizedString("sourceID"), toV8String(m_isolate, sourceID))
; | 146 info->Set(toV8StringInternalized(m_isolate, "sourceID"), toV8String(m_isolat
e, sourceID)); |
214 info->Set(v8InternalizedString("lineNumber"), v8::Integer::New(m_isolate, sc
riptBreakpoint.lineNumber)); | 147 info->Set(toV8StringInternalized(m_isolate, "lineNumber"), v8::Integer::New(
m_isolate, scriptBreakpoint.lineNumber)); |
215 info->Set(v8InternalizedString("columnNumber"), v8::Integer::New(m_isolate,
scriptBreakpoint.columnNumber)); | 148 info->Set(toV8StringInternalized(m_isolate, "columnNumber"), v8::Integer::Ne
w(m_isolate, scriptBreakpoint.columnNumber)); |
216 info->Set(v8InternalizedString("interstatementLocation"), v8Boolean(intersta
tementLocation, m_isolate)); | 149 info->Set(toV8StringInternalized(m_isolate, "interstatementLocation"), v8Boo
lean(interstatementLocation, m_isolate)); |
217 info->Set(v8InternalizedString("condition"), toV8String(m_isolate, scriptBre
akpoint.condition)); | 150 info->Set(toV8StringInternalized(m_isolate, "condition"), toV8String(m_isola
te, scriptBreakpoint.condition)); |
218 | 151 |
219 v8::Local<v8::Function> setBreakpointFunction = v8::Local<v8::Function>::Cas
t(m_debuggerScript.Get(m_isolate)->Get(v8InternalizedString("setBreakpoint"))); | 152 v8::Local<v8::Function> setBreakpointFunction = v8::Local<v8::Function>::Cas
t(m_debuggerScript.Get(m_isolate)->Get(toV8StringInternalized(m_isolate, "setBre
akpoint"))); |
220 v8::Local<v8::Value> breakpointId = v8::Debug::Call(debuggerContext(), setBr
eakpointFunction, info).ToLocalChecked(); | 153 v8::Local<v8::Value> breakpointId = v8::Debug::Call(debuggerContext(), setBr
eakpointFunction, info).ToLocalChecked(); |
221 if (!breakpointId->IsString()) | 154 if (!breakpointId->IsString()) |
222 return ""; | 155 return ""; |
223 *actualLineNumber = info->Get(v8InternalizedString("lineNumber"))->Int32Valu
e(); | 156 *actualLineNumber = info->Get(toV8StringInternalized(m_isolate, "lineNumber"
))->Int32Value(); |
224 *actualColumnNumber = info->Get(v8InternalizedString("columnNumber"))->Int32
Value(); | 157 *actualColumnNumber = info->Get(toV8StringInternalized(m_isolate, "columnNum
ber"))->Int32Value(); |
225 return toProtocolString(breakpointId.As<v8::String>()); | 158 return toProtocolString(breakpointId.As<v8::String>()); |
226 } | 159 } |
227 | 160 |
228 void V8InspectorImpl::removeBreakpoint(const String16& breakpointId) | 161 void V8Debugger::removeBreakpoint(const String16& breakpointId) |
229 { | 162 { |
230 v8::HandleScope scope(m_isolate); | 163 v8::HandleScope scope(m_isolate); |
231 v8::Context::Scope contextScope(debuggerContext()); | 164 v8::Context::Scope contextScope(debuggerContext()); |
232 | 165 |
233 v8::Local<v8::Object> info = v8::Object::New(m_isolate); | 166 v8::Local<v8::Object> info = v8::Object::New(m_isolate); |
234 info->Set(v8InternalizedString("breakpointId"), toV8String(m_isolate, breakp
ointId)); | 167 info->Set(toV8StringInternalized(m_isolate, "breakpointId"), toV8String(m_is
olate, breakpointId)); |
235 | 168 |
236 v8::Local<v8::Function> removeBreakpointFunction = v8::Local<v8::Function>::
Cast(m_debuggerScript.Get(m_isolate)->Get(v8InternalizedString("removeBreakpoint
"))); | 169 v8::Local<v8::Function> removeBreakpointFunction = v8::Local<v8::Function>::
Cast(m_debuggerScript.Get(m_isolate)->Get(toV8StringInternalized(m_isolate, "rem
oveBreakpoint"))); |
237 v8::Debug::Call(debuggerContext(), removeBreakpointFunction, info).ToLocalCh
ecked(); | 170 v8::Debug::Call(debuggerContext(), removeBreakpointFunction, info).ToLocalCh
ecked(); |
238 } | 171 } |
239 | 172 |
240 void V8InspectorImpl::clearBreakpoints() | 173 void V8Debugger::clearBreakpoints() |
241 { | 174 { |
242 v8::HandleScope scope(m_isolate); | 175 v8::HandleScope scope(m_isolate); |
243 v8::Context::Scope contextScope(debuggerContext()); | 176 v8::Context::Scope contextScope(debuggerContext()); |
244 | 177 |
245 v8::Local<v8::Function> clearBreakpoints = v8::Local<v8::Function>::Cast(m_d
ebuggerScript.Get(m_isolate)->Get(v8InternalizedString("clearBreakpoints"))); | 178 v8::Local<v8::Function> clearBreakpoints = v8::Local<v8::Function>::Cast(m_d
ebuggerScript.Get(m_isolate)->Get(toV8StringInternalized(m_isolate, "clearBreakp
oints"))); |
246 v8::Debug::Call(debuggerContext(), clearBreakpoints).ToLocalChecked(); | 179 v8::Debug::Call(debuggerContext(), clearBreakpoints).ToLocalChecked(); |
247 } | 180 } |
248 | 181 |
249 void V8InspectorImpl::setBreakpointsActivated(bool activated) | 182 void V8Debugger::setBreakpointsActivated(bool activated) |
250 { | 183 { |
251 if (!enabled()) { | 184 if (!enabled()) { |
252 NOTREACHED(); | 185 NOTREACHED(); |
253 return; | 186 return; |
254 } | 187 } |
255 v8::HandleScope scope(m_isolate); | 188 v8::HandleScope scope(m_isolate); |
256 v8::Context::Scope contextScope(debuggerContext()); | 189 v8::Context::Scope contextScope(debuggerContext()); |
257 | 190 |
258 v8::Local<v8::Object> info = v8::Object::New(m_isolate); | 191 v8::Local<v8::Object> info = v8::Object::New(m_isolate); |
259 info->Set(v8InternalizedString("enabled"), v8::Boolean::New(m_isolate, activ
ated)); | 192 info->Set(toV8StringInternalized(m_isolate, "enabled"), v8::Boolean::New(m_i
solate, activated)); |
260 v8::Local<v8::Function> setBreakpointsActivated = v8::Local<v8::Function>::C
ast(m_debuggerScript.Get(m_isolate)->Get(v8InternalizedString("setBreakpointsAct
ivated"))); | 193 v8::Local<v8::Function> setBreakpointsActivated = v8::Local<v8::Function>::C
ast(m_debuggerScript.Get(m_isolate)->Get(toV8StringInternalized(m_isolate, "setB
reakpointsActivated"))); |
261 v8::Debug::Call(debuggerContext(), setBreakpointsActivated, info).ToLocalChe
cked(); | 194 v8::Debug::Call(debuggerContext(), setBreakpointsActivated, info).ToLocalChe
cked(); |
262 | 195 |
263 m_breakpointsActivated = activated; | 196 m_breakpointsActivated = activated; |
264 } | 197 } |
265 | 198 |
266 V8InspectorImpl::PauseOnExceptionsState V8InspectorImpl::getPauseOnExceptionsSta
te() | 199 V8Debugger::PauseOnExceptionsState V8Debugger::getPauseOnExceptionsState() |
267 { | 200 { |
268 DCHECK(enabled()); | 201 DCHECK(enabled()); |
269 v8::HandleScope scope(m_isolate); | 202 v8::HandleScope scope(m_isolate); |
270 v8::Context::Scope contextScope(debuggerContext()); | 203 v8::Context::Scope contextScope(debuggerContext()); |
271 | 204 |
272 v8::Local<v8::Value> argv[] = { v8::Undefined(m_isolate) }; | 205 v8::Local<v8::Value> argv[] = { v8::Undefined(m_isolate) }; |
273 v8::Local<v8::Value> result = callDebuggerMethod("pauseOnExceptionsState", 0
, argv).ToLocalChecked(); | 206 v8::Local<v8::Value> result = callDebuggerMethod("pauseOnExceptionsState", 0
, argv).ToLocalChecked(); |
274 return static_cast<V8InspectorImpl::PauseOnExceptionsState>(result->Int32Val
ue()); | 207 return static_cast<V8Debugger::PauseOnExceptionsState>(result->Int32Value())
; |
275 } | 208 } |
276 | 209 |
277 void V8InspectorImpl::setPauseOnExceptionsState(PauseOnExceptionsState pauseOnEx
ceptionsState) | 210 void V8Debugger::setPauseOnExceptionsState(PauseOnExceptionsState pauseOnExcepti
onsState) |
278 { | 211 { |
279 DCHECK(enabled()); | 212 DCHECK(enabled()); |
280 v8::HandleScope scope(m_isolate); | 213 v8::HandleScope scope(m_isolate); |
281 v8::Context::Scope contextScope(debuggerContext()); | 214 v8::Context::Scope contextScope(debuggerContext()); |
282 | 215 |
283 v8::Local<v8::Value> argv[] = { v8::Int32::New(m_isolate, pauseOnExceptionsS
tate) }; | 216 v8::Local<v8::Value> argv[] = { v8::Int32::New(m_isolate, pauseOnExceptionsS
tate) }; |
284 callDebuggerMethod("setPauseOnExceptionsState", 1, argv); | 217 callDebuggerMethod("setPauseOnExceptionsState", 1, argv); |
285 } | 218 } |
286 | 219 |
287 void V8InspectorImpl::setPauseOnNextStatement(bool pause) | 220 void V8Debugger::setPauseOnNextStatement(bool pause) |
288 { | 221 { |
289 if (m_runningNestedMessageLoop) | 222 if (m_runningNestedMessageLoop) |
290 return; | 223 return; |
291 if (pause) | 224 if (pause) |
292 v8::Debug::DebugBreak(m_isolate); | 225 v8::Debug::DebugBreak(m_isolate); |
293 else | 226 else |
294 v8::Debug::CancelDebugBreak(m_isolate); | 227 v8::Debug::CancelDebugBreak(m_isolate); |
295 } | 228 } |
296 | 229 |
297 bool V8InspectorImpl::canBreakProgram() | 230 bool V8Debugger::canBreakProgram() |
298 { | 231 { |
299 if (!m_breakpointsActivated) | 232 if (!m_breakpointsActivated) |
300 return false; | 233 return false; |
301 return m_isolate->InContext(); | 234 return m_isolate->InContext(); |
302 } | 235 } |
303 | 236 |
304 void V8InspectorImpl::breakProgram() | 237 void V8Debugger::breakProgram() |
305 { | 238 { |
306 if (isPaused()) { | 239 if (isPaused()) { |
307 DCHECK(!m_runningNestedMessageLoop); | 240 DCHECK(!m_runningNestedMessageLoop); |
308 v8::Local<v8::Value> exception; | 241 v8::Local<v8::Value> exception; |
309 v8::Local<v8::Array> hitBreakpoints; | 242 v8::Local<v8::Array> hitBreakpoints; |
310 handleProgramBreak(m_pausedContext, m_executionState, exception, hitBrea
kpoints); | 243 handleProgramBreak(m_pausedContext, m_executionState, exception, hitBrea
kpoints); |
311 return; | 244 return; |
312 } | 245 } |
313 | 246 |
314 if (!canBreakProgram()) | 247 if (!canBreakProgram()) |
315 return; | 248 return; |
316 | 249 |
317 v8::HandleScope scope(m_isolate); | 250 v8::HandleScope scope(m_isolate); |
318 v8::Local<v8::Function> breakFunction; | 251 v8::Local<v8::Function> breakFunction; |
319 if (!v8::Function::New(m_isolate->GetCurrentContext(), &V8InspectorImpl::bre
akProgramCallback, v8::External::New(m_isolate, this), 0, v8::ConstructorBehavio
r::kThrow).ToLocal(&breakFunction)) | 252 if (!v8::Function::New(m_isolate->GetCurrentContext(), &V8Debugger::breakPro
gramCallback, v8::External::New(m_isolate, this), 0, v8::ConstructorBehavior::kT
hrow).ToLocal(&breakFunction)) |
320 return; | 253 return; |
321 v8::Debug::Call(debuggerContext(), breakFunction).ToLocalChecked(); | 254 v8::Debug::Call(debuggerContext(), breakFunction).ToLocalChecked(); |
322 } | 255 } |
323 | 256 |
324 void V8InspectorImpl::continueProgram() | 257 void V8Debugger::continueProgram() |
325 { | 258 { |
326 if (isPaused()) | 259 if (isPaused()) |
327 m_client->quitMessageLoopOnPause(); | 260 m_inspector->client()->quitMessageLoopOnPause(); |
328 m_pausedContext.Clear(); | 261 m_pausedContext.Clear(); |
329 m_executionState.Clear(); | 262 m_executionState.Clear(); |
330 } | 263 } |
331 | 264 |
332 void V8InspectorImpl::stepIntoStatement() | 265 void V8Debugger::stepIntoStatement() |
333 { | 266 { |
334 DCHECK(isPaused()); | 267 DCHECK(isPaused()); |
335 DCHECK(!m_executionState.IsEmpty()); | 268 DCHECK(!m_executionState.IsEmpty()); |
336 v8::HandleScope handleScope(m_isolate); | 269 v8::HandleScope handleScope(m_isolate); |
337 v8::Local<v8::Value> argv[] = { m_executionState }; | 270 v8::Local<v8::Value> argv[] = { m_executionState }; |
338 callDebuggerMethod(stepIntoV8MethodName, 1, argv); | 271 callDebuggerMethod(stepIntoV8MethodName, 1, argv); |
339 continueProgram(); | 272 continueProgram(); |
340 } | 273 } |
341 | 274 |
342 void V8InspectorImpl::stepOverStatement() | 275 void V8Debugger::stepOverStatement() |
343 { | 276 { |
344 DCHECK(isPaused()); | 277 DCHECK(isPaused()); |
345 DCHECK(!m_executionState.IsEmpty()); | 278 DCHECK(!m_executionState.IsEmpty()); |
346 v8::HandleScope handleScope(m_isolate); | 279 v8::HandleScope handleScope(m_isolate); |
347 v8::Local<v8::Value> argv[] = { m_executionState }; | 280 v8::Local<v8::Value> argv[] = { m_executionState }; |
348 callDebuggerMethod("stepOverStatement", 1, argv); | 281 callDebuggerMethod("stepOverStatement", 1, argv); |
349 continueProgram(); | 282 continueProgram(); |
350 } | 283 } |
351 | 284 |
352 void V8InspectorImpl::stepOutOfFunction() | 285 void V8Debugger::stepOutOfFunction() |
353 { | 286 { |
354 DCHECK(isPaused()); | 287 DCHECK(isPaused()); |
355 DCHECK(!m_executionState.IsEmpty()); | 288 DCHECK(!m_executionState.IsEmpty()); |
356 v8::HandleScope handleScope(m_isolate); | 289 v8::HandleScope handleScope(m_isolate); |
357 v8::Local<v8::Value> argv[] = { m_executionState }; | 290 v8::Local<v8::Value> argv[] = { m_executionState }; |
358 callDebuggerMethod(stepOutV8MethodName, 1, argv); | 291 callDebuggerMethod(stepOutV8MethodName, 1, argv); |
359 continueProgram(); | 292 continueProgram(); |
360 } | 293 } |
361 | 294 |
362 void V8InspectorImpl::clearStepping() | 295 void V8Debugger::clearStepping() |
363 { | 296 { |
364 DCHECK(enabled()); | 297 DCHECK(enabled()); |
365 v8::HandleScope scope(m_isolate); | 298 v8::HandleScope scope(m_isolate); |
366 v8::Context::Scope contextScope(debuggerContext()); | 299 v8::Context::Scope contextScope(debuggerContext()); |
367 | 300 |
368 v8::Local<v8::Value> argv[] = { v8::Undefined(m_isolate) }; | 301 v8::Local<v8::Value> argv[] = { v8::Undefined(m_isolate) }; |
369 callDebuggerMethod("clearStepping", 0, argv); | 302 callDebuggerMethod("clearStepping", 0, argv); |
370 } | 303 } |
371 | 304 |
372 bool V8InspectorImpl::setScriptSource(const String16& sourceID, v8::Local<v8::St
ring> newSource, bool preview, ErrorString* error, Maybe<protocol::Runtime::Exce
ptionDetails>* exceptionDetails, JavaScriptCallFrames* newCallFrames, Maybe<bool
>* stackChanged) | 305 bool V8Debugger::setScriptSource(const String16& sourceID, v8::Local<v8::String>
newSource, bool preview, ErrorString* error, Maybe<protocol::Runtime::Exception
Details>* exceptionDetails, JavaScriptCallFrames* newCallFrames, Maybe<bool>* st
ackChanged) |
373 { | 306 { |
374 class EnableLiveEditScope { | 307 class EnableLiveEditScope { |
375 public: | 308 public: |
376 explicit EnableLiveEditScope(v8::Isolate* isolate) : m_isolate(isolate) | 309 explicit EnableLiveEditScope(v8::Isolate* isolate) : m_isolate(isolate) |
377 { | 310 { |
378 v8::Debug::SetLiveEditEnabled(m_isolate, true); | 311 v8::Debug::SetLiveEditEnabled(m_isolate, true); |
379 inLiveEditScope = true; | 312 inLiveEditScope = true; |
380 } | 313 } |
381 ~EnableLiveEditScope() | 314 ~EnableLiveEditScope() |
382 { | 315 { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 .setScriptId(String16("0")) | 367 .setScriptId(String16("0")) |
435 .setLineNumber(resultTuple->Get(3)->ToInteger(m_isolate)->Value(
) - 1) | 368 .setLineNumber(resultTuple->Get(3)->ToInteger(m_isolate)->Value(
) - 1) |
436 .setColumnNumber(resultTuple->Get(4)->ToInteger(m_isolate)->Valu
e() - 1).build(); | 369 .setColumnNumber(resultTuple->Get(4)->ToInteger(m_isolate)->Valu
e() - 1).build(); |
437 return false; | 370 return false; |
438 } | 371 } |
439 } | 372 } |
440 *error = "Unknown error."; | 373 *error = "Unknown error."; |
441 return false; | 374 return false; |
442 } | 375 } |
443 | 376 |
444 JavaScriptCallFrames V8InspectorImpl::currentCallFrames(int limit) | 377 JavaScriptCallFrames V8Debugger::currentCallFrames(int limit) |
445 { | 378 { |
446 if (!m_isolate->InContext()) | 379 if (!m_isolate->InContext()) |
447 return JavaScriptCallFrames(); | 380 return JavaScriptCallFrames(); |
448 v8::Local<v8::Value> currentCallFramesV8; | 381 v8::Local<v8::Value> currentCallFramesV8; |
449 if (m_executionState.IsEmpty()) { | 382 if (m_executionState.IsEmpty()) { |
450 v8::Local<v8::Function> currentCallFramesFunction = v8::Local<v8::Functi
on>::Cast(m_debuggerScript.Get(m_isolate)->Get(v8InternalizedString("currentCall
Frames"))); | 383 v8::Local<v8::Function> currentCallFramesFunction = v8::Local<v8::Functi
on>::Cast(m_debuggerScript.Get(m_isolate)->Get(toV8StringInternalized(m_isolate,
"currentCallFrames"))); |
451 currentCallFramesV8 = v8::Debug::Call(debuggerContext(), currentCallFram
esFunction, v8::Integer::New(m_isolate, limit)).ToLocalChecked(); | 384 currentCallFramesV8 = v8::Debug::Call(debuggerContext(), currentCallFram
esFunction, v8::Integer::New(m_isolate, limit)).ToLocalChecked(); |
452 } else { | 385 } else { |
453 v8::Local<v8::Value> argv[] = { m_executionState, v8::Integer::New(m_iso
late, limit) }; | 386 v8::Local<v8::Value> argv[] = { m_executionState, v8::Integer::New(m_iso
late, limit) }; |
454 currentCallFramesV8 = callDebuggerMethod("currentCallFrames", PROTOCOL_A
RRAY_LENGTH(argv), argv).ToLocalChecked(); | 387 currentCallFramesV8 = callDebuggerMethod("currentCallFrames", PROTOCOL_A
RRAY_LENGTH(argv), argv).ToLocalChecked(); |
455 } | 388 } |
456 DCHECK(!currentCallFramesV8.IsEmpty()); | 389 DCHECK(!currentCallFramesV8.IsEmpty()); |
457 if (!currentCallFramesV8->IsArray()) | 390 if (!currentCallFramesV8->IsArray()) |
458 return JavaScriptCallFrames(); | 391 return JavaScriptCallFrames(); |
459 v8::Local<v8::Array> callFramesArray = currentCallFramesV8.As<v8::Array>(); | 392 v8::Local<v8::Array> callFramesArray = currentCallFramesV8.As<v8::Array>(); |
460 JavaScriptCallFrames callFrames; | 393 JavaScriptCallFrames callFrames; |
461 for (size_t i = 0; i < callFramesArray->Length(); ++i) { | 394 for (size_t i = 0; i < callFramesArray->Length(); ++i) { |
462 v8::Local<v8::Value> callFrameValue; | 395 v8::Local<v8::Value> callFrameValue; |
463 if (!callFramesArray->Get(debuggerContext(), i).ToLocal(&callFrameValue)
) | 396 if (!callFramesArray->Get(debuggerContext(), i).ToLocal(&callFrameValue)
) |
464 return JavaScriptCallFrames(); | 397 return JavaScriptCallFrames(); |
465 if (!callFrameValue->IsObject()) | 398 if (!callFrameValue->IsObject()) |
466 return JavaScriptCallFrames(); | 399 return JavaScriptCallFrames(); |
467 v8::Local<v8::Object> callFrameObject = callFrameValue.As<v8::Object>(); | 400 v8::Local<v8::Object> callFrameObject = callFrameValue.As<v8::Object>(); |
468 callFrames.push_back(JavaScriptCallFrame::create(debuggerContext(), v8::
Local<v8::Object>::Cast(callFrameObject))); | 401 callFrames.push_back(JavaScriptCallFrame::create(debuggerContext(), v8::
Local<v8::Object>::Cast(callFrameObject))); |
469 } | 402 } |
470 return callFrames; | 403 return callFrames; |
471 } | 404 } |
472 | 405 |
473 static V8InspectorImpl* toV8InspectorImpl(v8::Local<v8::Value> data) | 406 static V8Debugger* toV8Debugger(v8::Local<v8::Value> data) |
474 { | 407 { |
475 void* p = v8::Local<v8::External>::Cast(data)->Value(); | 408 void* p = v8::Local<v8::External>::Cast(data)->Value(); |
476 return static_cast<V8InspectorImpl*>(p); | 409 return static_cast<V8Debugger*>(p); |
477 } | 410 } |
478 | 411 |
479 void V8InspectorImpl::breakProgramCallback(const v8::FunctionCallbackInfo<v8::Va
lue>& info) | 412 void V8Debugger::breakProgramCallback(const v8::FunctionCallbackInfo<v8::Value>&
info) |
480 { | 413 { |
481 DCHECK_EQ(info.Length(), 2); | 414 DCHECK_EQ(info.Length(), 2); |
482 V8InspectorImpl* thisPtr = toV8InspectorImpl(info.Data()); | 415 V8Debugger* thisPtr = toV8Debugger(info.Data()); |
483 if (!thisPtr->enabled()) | 416 if (!thisPtr->enabled()) |
484 return; | 417 return; |
485 v8::Local<v8::Context> pausedContext = thisPtr->m_isolate->GetCurrentContext
(); | 418 v8::Local<v8::Context> pausedContext = thisPtr->m_isolate->GetCurrentContext
(); |
486 v8::Local<v8::Value> exception; | 419 v8::Local<v8::Value> exception; |
487 v8::Local<v8::Array> hitBreakpoints; | 420 v8::Local<v8::Array> hitBreakpoints; |
488 thisPtr->handleProgramBreak(pausedContext, v8::Local<v8::Object>::Cast(info[
0]), exception, hitBreakpoints); | 421 thisPtr->handleProgramBreak(pausedContext, v8::Local<v8::Object>::Cast(info[
0]), exception, hitBreakpoints); |
489 } | 422 } |
490 | 423 |
491 void V8InspectorImpl::handleProgramBreak(v8::Local<v8::Context> pausedContext, v
8::Local<v8::Object> executionState, v8::Local<v8::Value> exception, v8::Local<v
8::Array> hitBreakpointNumbers, bool isPromiseRejection) | 424 void V8Debugger::handleProgramBreak(v8::Local<v8::Context> pausedContext, v8::Lo
cal<v8::Object> executionState, v8::Local<v8::Value> exception, v8::Local<v8::Ar
ray> hitBreakpointNumbers, bool isPromiseRejection) |
492 { | 425 { |
493 // Don't allow nested breaks. | 426 // Don't allow nested breaks. |
494 if (m_runningNestedMessageLoop) | 427 if (m_runningNestedMessageLoop) |
495 return; | 428 return; |
496 | 429 |
497 V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(pausedContext); | 430 V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup(getGr
oupId(pausedContext)); |
498 if (!agent) | 431 if (!agent) |
499 return; | 432 return; |
500 | 433 |
501 std::vector<String16> breakpointIds; | 434 std::vector<String16> breakpointIds; |
502 if (!hitBreakpointNumbers.IsEmpty()) { | 435 if (!hitBreakpointNumbers.IsEmpty()) { |
503 breakpointIds.reserve(hitBreakpointNumbers->Length()); | 436 breakpointIds.reserve(hitBreakpointNumbers->Length()); |
504 for (size_t i = 0; i < hitBreakpointNumbers->Length(); i++) { | 437 for (size_t i = 0; i < hitBreakpointNumbers->Length(); i++) { |
505 v8::Local<v8::Value> hitBreakpointNumber = hitBreakpointNumbers->Get
(i); | 438 v8::Local<v8::Value> hitBreakpointNumber = hitBreakpointNumbers->Get
(i); |
506 DCHECK(!hitBreakpointNumber.IsEmpty() && hitBreakpointNumber->IsInt3
2()); | 439 DCHECK(!hitBreakpointNumber.IsEmpty() && hitBreakpointNumber->IsInt3
2()); |
507 breakpointIds.push_back(String16::fromInteger(hitBreakpointNumber->I
nt32Value())); | 440 breakpointIds.push_back(String16::fromInteger(hitBreakpointNumber->I
nt32Value())); |
508 } | 441 } |
509 } | 442 } |
510 | 443 |
511 m_pausedContext = pausedContext; | 444 m_pausedContext = pausedContext; |
512 m_executionState = executionState; | 445 m_executionState = executionState; |
513 V8DebuggerAgentImpl::SkipPauseRequest result = agent->didPause(pausedContext
, exception, breakpointIds, isPromiseRejection); | 446 V8DebuggerAgentImpl::SkipPauseRequest result = agent->didPause(pausedContext
, exception, breakpointIds, isPromiseRejection); |
514 if (result == V8DebuggerAgentImpl::RequestNoSkip) { | 447 if (result == V8DebuggerAgentImpl::RequestNoSkip) { |
515 m_runningNestedMessageLoop = true; | 448 m_runningNestedMessageLoop = true; |
516 int groupId = getGroupId(pausedContext); | 449 int groupId = getGroupId(pausedContext); |
517 DCHECK(groupId); | 450 DCHECK(groupId); |
518 m_client->runMessageLoopOnPause(groupId); | 451 m_inspector->client()->runMessageLoopOnPause(groupId); |
519 // The agent may have been removed in the nested loop. | 452 // The agent may have been removed in the nested loop. |
520 agent = findEnabledDebuggerAgent(pausedContext); | 453 agent = m_inspector->enabledDebuggerAgentForGroup(getGroupId(pausedConte
xt)); |
521 if (agent) | 454 if (agent) |
522 agent->didContinue(); | 455 agent->didContinue(); |
523 m_runningNestedMessageLoop = false; | 456 m_runningNestedMessageLoop = false; |
524 } | 457 } |
525 m_pausedContext.Clear(); | 458 m_pausedContext.Clear(); |
526 m_executionState.Clear(); | 459 m_executionState.Clear(); |
527 | 460 |
528 if (result == V8DebuggerAgentImpl::RequestStepFrame) { | 461 if (result == V8DebuggerAgentImpl::RequestStepFrame) { |
529 v8::Local<v8::Value> argv[] = { executionState }; | 462 v8::Local<v8::Value> argv[] = { executionState }; |
530 callDebuggerMethod("stepFrameStatement", 1, argv); | 463 callDebuggerMethod("stepFrameStatement", 1, argv); |
531 } else if (result == V8DebuggerAgentImpl::RequestStepInto) { | 464 } else if (result == V8DebuggerAgentImpl::RequestStepInto) { |
532 v8::Local<v8::Value> argv[] = { executionState }; | 465 v8::Local<v8::Value> argv[] = { executionState }; |
533 callDebuggerMethod(stepIntoV8MethodName, 1, argv); | 466 callDebuggerMethod(stepIntoV8MethodName, 1, argv); |
534 } else if (result == V8DebuggerAgentImpl::RequestStepOut) { | 467 } else if (result == V8DebuggerAgentImpl::RequestStepOut) { |
535 v8::Local<v8::Value> argv[] = { executionState }; | 468 v8::Local<v8::Value> argv[] = { executionState }; |
536 callDebuggerMethod(stepOutV8MethodName, 1, argv); | 469 callDebuggerMethod(stepOutV8MethodName, 1, argv); |
537 } | 470 } |
538 } | 471 } |
539 | 472 |
540 void V8InspectorImpl::v8DebugEventCallback(const v8::Debug::EventDetails& eventD
etails) | 473 void V8Debugger::v8DebugEventCallback(const v8::Debug::EventDetails& eventDetail
s) |
541 { | 474 { |
542 V8InspectorImpl* thisPtr = toV8InspectorImpl(eventDetails.GetCallbackData())
; | 475 V8Debugger* thisPtr = toV8Debugger(eventDetails.GetCallbackData()); |
543 thisPtr->handleV8DebugEvent(eventDetails); | 476 thisPtr->handleV8DebugEvent(eventDetails); |
544 } | 477 } |
545 | 478 |
546 v8::Local<v8::Value> V8InspectorImpl::callInternalGetterFunction(v8::Local<v8::O
bject> object, const char* functionName) | 479 v8::Local<v8::Value> V8Debugger::callInternalGetterFunction(v8::Local<v8::Object
> object, const char* functionName) |
547 { | 480 { |
548 v8::MicrotasksScope microtasks(m_isolate, v8::MicrotasksScope::kDoNotRunMicr
otasks); | 481 v8::MicrotasksScope microtasks(m_isolate, v8::MicrotasksScope::kDoNotRunMicr
otasks); |
549 v8::Local<v8::Value> getterValue = object->Get(v8InternalizedString(function
Name)); | 482 v8::Local<v8::Value> getterValue = object->Get(toV8StringInternalized(m_isol
ate, functionName)); |
550 DCHECK(!getterValue.IsEmpty() && getterValue->IsFunction()); | 483 DCHECK(!getterValue.IsEmpty() && getterValue->IsFunction()); |
551 return v8::Local<v8::Function>::Cast(getterValue)->Call(m_isolate->GetCurren
tContext(), object, 0, 0).ToLocalChecked(); | 484 return v8::Local<v8::Function>::Cast(getterValue)->Call(m_isolate->GetCurren
tContext(), object, 0, 0).ToLocalChecked(); |
552 } | 485 } |
553 | 486 |
554 void V8InspectorImpl::handleV8DebugEvent(const v8::Debug::EventDetails& eventDet
ails) | 487 void V8Debugger::handleV8DebugEvent(const v8::Debug::EventDetails& eventDetails) |
555 { | 488 { |
556 if (!enabled()) | 489 if (!enabled()) |
557 return; | 490 return; |
558 v8::DebugEvent event = eventDetails.GetEvent(); | 491 v8::DebugEvent event = eventDetails.GetEvent(); |
559 if (event != v8::AsyncTaskEvent && event != v8::Break && event != v8::Except
ion && event != v8::AfterCompile && event != v8::BeforeCompile && event != v8::C
ompileError) | 492 if (event != v8::AsyncTaskEvent && event != v8::Break && event != v8::Except
ion && event != v8::AfterCompile && event != v8::BeforeCompile && event != v8::C
ompileError) |
560 return; | 493 return; |
561 | 494 |
562 v8::Local<v8::Context> eventContext = eventDetails.GetEventContext(); | 495 v8::Local<v8::Context> eventContext = eventDetails.GetEventContext(); |
563 DCHECK(!eventContext.IsEmpty()); | 496 DCHECK(!eventContext.IsEmpty()); |
564 | 497 |
565 if (event == v8::AsyncTaskEvent) { | 498 if (event == v8::AsyncTaskEvent) { |
566 v8::HandleScope scope(m_isolate); | 499 v8::HandleScope scope(m_isolate); |
567 handleV8AsyncTaskEvent(eventContext, eventDetails.GetExecutionState(), e
ventDetails.GetEventData()); | 500 handleV8AsyncTaskEvent(eventContext, eventDetails.GetExecutionState(), e
ventDetails.GetEventData()); |
568 return; | 501 return; |
569 } | 502 } |
570 | 503 |
571 V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(eventContext); | 504 V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup(getGr
oupId(eventContext)); |
572 if (agent) { | 505 if (agent) { |
573 v8::HandleScope scope(m_isolate); | 506 v8::HandleScope scope(m_isolate); |
574 if (event == v8::AfterCompile || event == v8::CompileError) { | 507 if (event == v8::AfterCompile || event == v8::CompileError) { |
575 v8::Context::Scope contextScope(debuggerContext()); | 508 v8::Context::Scope contextScope(debuggerContext()); |
576 v8::Local<v8::Value> argv[] = { eventDetails.GetEventData() }; | 509 v8::Local<v8::Value> argv[] = { eventDetails.GetEventData() }; |
577 v8::Local<v8::Value> value = callDebuggerMethod("getAfterCompileScri
pt", 1, argv).ToLocalChecked(); | 510 v8::Local<v8::Value> value = callDebuggerMethod("getAfterCompileScri
pt", 1, argv).ToLocalChecked(); |
578 DCHECK(value->IsObject()); | 511 DCHECK(value->IsObject()); |
579 v8::Local<v8::Object> scriptObject = v8::Local<v8::Object>::Cast(val
ue); | 512 v8::Local<v8::Object> scriptObject = v8::Local<v8::Object>::Cast(val
ue); |
580 agent->didParseSource(wrapUnique(new V8DebuggerScript(m_isolate, scr
iptObject, inLiveEditScope)), event == v8::AfterCompile); | 513 agent->didParseSource(wrapUnique(new V8DebuggerScript(m_isolate, scr
iptObject, inLiveEditScope)), event == v8::AfterCompile); |
581 } else if (event == v8::Exception) { | 514 } else if (event == v8::Exception) { |
582 v8::Local<v8::Object> eventData = eventDetails.GetEventData(); | 515 v8::Local<v8::Object> eventData = eventDetails.GetEventData(); |
583 v8::Local<v8::Value> exception = callInternalGetterFunction(eventDat
a, "exception"); | 516 v8::Local<v8::Value> exception = callInternalGetterFunction(eventDat
a, "exception"); |
584 v8::Local<v8::Value> promise = callInternalGetterFunction(eventData,
"promise"); | 517 v8::Local<v8::Value> promise = callInternalGetterFunction(eventData,
"promise"); |
585 bool isPromiseRejection = !promise.IsEmpty() && promise->IsObject(); | 518 bool isPromiseRejection = !promise.IsEmpty() && promise->IsObject(); |
586 handleProgramBreak(eventContext, eventDetails.GetExecutionState(), e
xception, v8::Local<v8::Array>(), isPromiseRejection); | 519 handleProgramBreak(eventContext, eventDetails.GetExecutionState(), e
xception, v8::Local<v8::Array>(), isPromiseRejection); |
587 } else if (event == v8::Break) { | 520 } else if (event == v8::Break) { |
588 v8::Local<v8::Value> argv[] = { eventDetails.GetEventData() }; | 521 v8::Local<v8::Value> argv[] = { eventDetails.GetEventData() }; |
589 v8::Local<v8::Value> hitBreakpoints = callDebuggerMethod("getBreakpo
intNumbers", 1, argv).ToLocalChecked(); | 522 v8::Local<v8::Value> hitBreakpoints = callDebuggerMethod("getBreakpo
intNumbers", 1, argv).ToLocalChecked(); |
590 DCHECK(hitBreakpoints->IsArray()); | 523 DCHECK(hitBreakpoints->IsArray()); |
591 handleProgramBreak(eventContext, eventDetails.GetExecutionState(), v
8::Local<v8::Value>(), hitBreakpoints.As<v8::Array>()); | 524 handleProgramBreak(eventContext, eventDetails.GetExecutionState(), v
8::Local<v8::Value>(), hitBreakpoints.As<v8::Array>()); |
592 } | 525 } |
593 } | 526 } |
594 } | 527 } |
595 | 528 |
596 void V8InspectorImpl::handleV8AsyncTaskEvent(v8::Local<v8::Context> context, v8:
:Local<v8::Object> executionState, v8::Local<v8::Object> eventData) | 529 void V8Debugger::handleV8AsyncTaskEvent(v8::Local<v8::Context> context, v8::Loca
l<v8::Object> executionState, v8::Local<v8::Object> eventData) |
597 { | 530 { |
598 if (!m_maxAsyncCallStackDepth) | 531 if (!m_maxAsyncCallStackDepth) |
599 return; | 532 return; |
600 | 533 |
601 String16 type = toProtocolStringWithTypeCheck(callInternalGetterFunction(eve
ntData, "type")); | 534 String16 type = toProtocolStringWithTypeCheck(callInternalGetterFunction(eve
ntData, "type")); |
602 String16 name = toProtocolStringWithTypeCheck(callInternalGetterFunction(eve
ntData, "name")); | 535 String16 name = toProtocolStringWithTypeCheck(callInternalGetterFunction(eve
ntData, "name")); |
603 int id = callInternalGetterFunction(eventData, "id")->ToInteger(m_isolate)->
Value(); | 536 int id = callInternalGetterFunction(eventData, "id")->ToInteger(m_isolate)->
Value(); |
604 // The scopes for the ids are defined by the eventData.name namespaces. Ther
e are currently two namespaces: "Object." and "Promise.". | 537 // The scopes for the ids are defined by the eventData.name namespaces. Ther
e are currently two namespaces: "Object." and "Promise.". |
605 void* ptr = reinterpret_cast<void*>(id * 4 + (name[0] == 'P' ? 2 : 0) + 1); | 538 void* ptr = reinterpret_cast<void*>(id * 4 + (name[0] == 'P' ? 2 : 0) + 1); |
606 if (type == v8AsyncTaskEventEnqueue) | 539 if (type == v8AsyncTaskEventEnqueue) |
607 asyncTaskScheduled(name, ptr, false); | 540 asyncTaskScheduled(name, ptr, false); |
608 else if (type == v8AsyncTaskEventWillHandle) | 541 else if (type == v8AsyncTaskEventWillHandle) |
609 asyncTaskStarted(ptr); | 542 asyncTaskStarted(ptr); |
610 else if (type == v8AsyncTaskEventDidHandle) | 543 else if (type == v8AsyncTaskEventDidHandle) |
611 asyncTaskFinished(ptr); | 544 asyncTaskFinished(ptr); |
612 else | 545 else |
613 NOTREACHED(); | 546 NOTREACHED(); |
614 } | 547 } |
615 | 548 |
616 V8StackTraceImpl* V8InspectorImpl::currentAsyncCallChain() | 549 V8StackTraceImpl* V8Debugger::currentAsyncCallChain() |
617 { | 550 { |
618 if (!m_currentStacks.size()) | 551 if (!m_currentStacks.size()) |
619 return nullptr; | 552 return nullptr; |
620 return m_currentStacks.back().get(); | 553 return m_currentStacks.back().get(); |
621 } | 554 } |
622 | 555 |
623 void V8InspectorImpl::compileDebuggerScript() | 556 void V8Debugger::compileDebuggerScript() |
624 { | 557 { |
625 if (!m_debuggerScript.IsEmpty()) { | 558 if (!m_debuggerScript.IsEmpty()) { |
626 NOTREACHED(); | 559 NOTREACHED(); |
627 return; | 560 return; |
628 } | 561 } |
629 | 562 |
630 v8::HandleScope scope(m_isolate); | 563 v8::HandleScope scope(m_isolate); |
631 v8::Context::Scope contextScope(debuggerContext()); | 564 v8::Context::Scope contextScope(debuggerContext()); |
632 | 565 |
633 v8::Local<v8::String> scriptValue = v8::String::NewFromUtf8(m_isolate, Debug
gerScript_js, v8::NewStringType::kInternalized, sizeof(DebuggerScript_js)).ToLoc
alChecked(); | 566 v8::Local<v8::String> scriptValue = v8::String::NewFromUtf8(m_isolate, Debug
gerScript_js, v8::NewStringType::kInternalized, sizeof(DebuggerScript_js)).ToLoc
alChecked(); |
634 v8::Local<v8::Value> value; | 567 v8::Local<v8::Value> value; |
635 if (!compileAndRunInternalScript(debuggerContext(), scriptValue).ToLocal(&va
lue)) { | 568 if (!m_inspector->compileAndRunInternalScript(debuggerContext(), scriptValue
).ToLocal(&value)) { |
636 NOTREACHED(); | 569 NOTREACHED(); |
637 return; | 570 return; |
638 } | 571 } |
639 DCHECK(value->IsObject()); | 572 DCHECK(value->IsObject()); |
640 m_debuggerScript.Reset(m_isolate, value.As<v8::Object>()); | 573 m_debuggerScript.Reset(m_isolate, value.As<v8::Object>()); |
641 } | 574 } |
642 | 575 |
643 v8::Local<v8::Context> V8InspectorImpl::debuggerContext() const | 576 v8::Local<v8::Context> V8Debugger::debuggerContext() const |
644 { | 577 { |
645 DCHECK(!m_debuggerContext.IsEmpty()); | 578 DCHECK(!m_debuggerContext.IsEmpty()); |
646 return m_debuggerContext.Get(m_isolate); | 579 return m_debuggerContext.Get(m_isolate); |
647 } | 580 } |
648 | 581 |
649 v8::Local<v8::String> V8InspectorImpl::v8InternalizedString(const char* str) con
st | 582 v8::MaybeLocal<v8::Value> V8Debugger::functionScopes(v8::Local<v8::Function> fun
ction) |
650 { | |
651 return v8::String::NewFromUtf8(m_isolate, str, v8::NewStringType::kInternali
zed).ToLocalChecked(); | |
652 } | |
653 | |
654 v8::MaybeLocal<v8::Value> V8InspectorImpl::functionScopes(v8::Local<v8::Function
> function) | |
655 { | 583 { |
656 if (!enabled()) { | 584 if (!enabled()) { |
657 NOTREACHED(); | 585 NOTREACHED(); |
658 return v8::Local<v8::Value>::New(m_isolate, v8::Undefined(m_isolate)); | 586 return v8::Local<v8::Value>::New(m_isolate, v8::Undefined(m_isolate)); |
659 } | 587 } |
660 v8::Local<v8::Value> argv[] = { function }; | 588 v8::Local<v8::Value> argv[] = { function }; |
661 v8::Local<v8::Value> scopesValue; | 589 v8::Local<v8::Value> scopesValue; |
662 if (!callDebuggerMethod("getFunctionScopes", 1, argv).ToLocal(&scopesValue)
|| !scopesValue->IsArray()) | 590 if (!callDebuggerMethod("getFunctionScopes", 1, argv).ToLocal(&scopesValue)
|| !scopesValue->IsArray()) |
663 return v8::MaybeLocal<v8::Value>(); | 591 return v8::MaybeLocal<v8::Value>(); |
664 v8::Local<v8::Array> scopes = scopesValue.As<v8::Array>(); | 592 v8::Local<v8::Array> scopes = scopesValue.As<v8::Array>(); |
665 v8::Local<v8::Context> context = m_debuggerContext.Get(m_isolate); | 593 v8::Local<v8::Context> context = m_debuggerContext.Get(m_isolate); |
666 if (!markAsInternal(context, scopes, V8InternalValueType::kScopeList)) | 594 if (!markAsInternal(context, scopes, V8InternalValueType::kScopeList)) |
667 return v8::MaybeLocal<v8::Value>(); | 595 return v8::MaybeLocal<v8::Value>(); |
668 if (!markArrayEntriesAsInternal(context, scopes, V8InternalValueType::kScope
)) | 596 if (!markArrayEntriesAsInternal(context, scopes, V8InternalValueType::kScope
)) |
669 return v8::MaybeLocal<v8::Value>(); | 597 return v8::MaybeLocal<v8::Value>(); |
670 if (!scopes->SetPrototype(context, v8::Null(m_isolate)).FromMaybe(false)) | 598 if (!scopes->SetPrototype(context, v8::Null(m_isolate)).FromMaybe(false)) |
671 return v8::Undefined(m_isolate); | 599 return v8::Undefined(m_isolate); |
672 return scopes; | 600 return scopes; |
673 } | 601 } |
674 | 602 |
675 v8::MaybeLocal<v8::Array> V8InspectorImpl::internalProperties(v8::Local<v8::Cont
ext> context, v8::Local<v8::Value> value) | 603 v8::MaybeLocal<v8::Array> V8Debugger::internalProperties(v8::Local<v8::Context>
context, v8::Local<v8::Value> value) |
676 { | 604 { |
677 v8::Local<v8::Array> properties; | 605 v8::Local<v8::Array> properties; |
678 if (!v8::Debug::GetInternalProperties(m_isolate, value).ToLocal(&properties)
) | 606 if (!v8::Debug::GetInternalProperties(m_isolate, value).ToLocal(&properties)
) |
679 return v8::MaybeLocal<v8::Array>(); | 607 return v8::MaybeLocal<v8::Array>(); |
680 if (value->IsFunction()) { | 608 if (value->IsFunction()) { |
681 v8::Local<v8::Function> function = value.As<v8::Function>(); | 609 v8::Local<v8::Function> function = value.As<v8::Function>(); |
682 v8::Local<v8::Value> location = functionLocation(context, function); | 610 v8::Local<v8::Value> location = functionLocation(context, function); |
683 if (location->IsObject()) { | 611 if (location->IsObject()) { |
684 properties->Set(properties->Length(), v8InternalizedString("[[Functi
onLocation]]")); | 612 properties->Set(properties->Length(), toV8StringInternalized(m_isola
te, "[[FunctionLocation]]")); |
685 properties->Set(properties->Length(), location); | 613 properties->Set(properties->Length(), location); |
686 } | 614 } |
687 if (function->IsGeneratorFunction()) { | 615 if (function->IsGeneratorFunction()) { |
688 properties->Set(properties->Length(), v8InternalizedString("[[IsGene
rator]]")); | 616 properties->Set(properties->Length(), toV8StringInternalized(m_isola
te, "[[IsGenerator]]")); |
689 properties->Set(properties->Length(), v8::True(m_isolate)); | 617 properties->Set(properties->Length(), v8::True(m_isolate)); |
690 } | 618 } |
691 } | 619 } |
692 if (!enabled()) | 620 if (!enabled()) |
693 return properties; | 621 return properties; |
694 if (value->IsMap() || value->IsWeakMap() || value->IsSet() || value->IsWeakS
et() || value->IsSetIterator() || value->IsMapIterator()) { | 622 if (value->IsMap() || value->IsWeakMap() || value->IsSet() || value->IsWeakS
et() || value->IsSetIterator() || value->IsMapIterator()) { |
695 v8::Local<v8::Value> entries = collectionEntries(context, v8::Local<v8::
Object>::Cast(value)); | 623 v8::Local<v8::Value> entries = collectionEntries(context, v8::Local<v8::
Object>::Cast(value)); |
696 if (entries->IsArray()) { | 624 if (entries->IsArray()) { |
697 properties->Set(properties->Length(), v8InternalizedString("[[Entrie
s]]")); | 625 properties->Set(properties->Length(), toV8StringInternalized(m_isola
te, "[[Entries]]")); |
698 properties->Set(properties->Length(), entries); | 626 properties->Set(properties->Length(), entries); |
699 } | 627 } |
700 } | 628 } |
701 if (value->IsGeneratorObject()) { | 629 if (value->IsGeneratorObject()) { |
702 v8::Local<v8::Value> location = generatorObjectLocation(v8::Local<v8::Ob
ject>::Cast(value)); | 630 v8::Local<v8::Value> location = generatorObjectLocation(v8::Local<v8::Ob
ject>::Cast(value)); |
703 if (location->IsObject()) { | 631 if (location->IsObject()) { |
704 properties->Set(properties->Length(), v8InternalizedString("[[Genera
torLocation]]")); | 632 properties->Set(properties->Length(), toV8StringInternalized(m_isola
te, "[[GeneratorLocation]]")); |
705 properties->Set(properties->Length(), location); | 633 properties->Set(properties->Length(), location); |
706 } | 634 } |
707 } | 635 } |
708 if (value->IsFunction()) { | 636 if (value->IsFunction()) { |
709 v8::Local<v8::Function> function = value.As<v8::Function>(); | 637 v8::Local<v8::Function> function = value.As<v8::Function>(); |
710 v8::Local<v8::Value> boundFunction = function->GetBoundFunction(); | 638 v8::Local<v8::Value> boundFunction = function->GetBoundFunction(); |
711 v8::Local<v8::Value> scopes; | 639 v8::Local<v8::Value> scopes; |
712 if (boundFunction->IsUndefined() && functionScopes(function).ToLocal(&sc
opes)) { | 640 if (boundFunction->IsUndefined() && functionScopes(function).ToLocal(&sc
opes)) { |
713 properties->Set(properties->Length(), v8InternalizedString("[[Scopes
]]")); | 641 properties->Set(properties->Length(), toV8StringInternalized(m_isola
te, "[[Scopes]]")); |
714 properties->Set(properties->Length(), scopes); | 642 properties->Set(properties->Length(), scopes); |
715 } | 643 } |
716 } | 644 } |
717 return properties; | 645 return properties; |
718 } | 646 } |
719 | 647 |
720 v8::Local<v8::Value> V8InspectorImpl::collectionEntries(v8::Local<v8::Context> c
ontext, v8::Local<v8::Object> object) | 648 v8::Local<v8::Value> V8Debugger::collectionEntries(v8::Local<v8::Context> contex
t, v8::Local<v8::Object> object) |
721 { | 649 { |
722 if (!enabled()) { | 650 if (!enabled()) { |
723 NOTREACHED(); | 651 NOTREACHED(); |
724 return v8::Undefined(m_isolate); | 652 return v8::Undefined(m_isolate); |
725 } | 653 } |
726 v8::Local<v8::Value> argv[] = { object }; | 654 v8::Local<v8::Value> argv[] = { object }; |
727 v8::Local<v8::Value> entriesValue = callDebuggerMethod("getCollectionEntries
", 1, argv).ToLocalChecked(); | 655 v8::Local<v8::Value> entriesValue = callDebuggerMethod("getCollectionEntries
", 1, argv).ToLocalChecked(); |
728 if (!entriesValue->IsArray()) | 656 if (!entriesValue->IsArray()) |
729 return v8::Undefined(m_isolate); | 657 return v8::Undefined(m_isolate); |
730 v8::Local<v8::Array> entries = entriesValue.As<v8::Array>(); | 658 v8::Local<v8::Array> entries = entriesValue.As<v8::Array>(); |
731 if (!markArrayEntriesAsInternal(context, entries, V8InternalValueType::kEntr
y)) | 659 if (!markArrayEntriesAsInternal(context, entries, V8InternalValueType::kEntr
y)) |
732 return v8::Undefined(m_isolate); | 660 return v8::Undefined(m_isolate); |
733 if (!entries->SetPrototype(context, v8::Null(m_isolate)).FromMaybe(false)) | 661 if (!entries->SetPrototype(context, v8::Null(m_isolate)).FromMaybe(false)) |
734 return v8::Undefined(m_isolate); | 662 return v8::Undefined(m_isolate); |
735 return entries; | 663 return entries; |
736 } | 664 } |
737 | 665 |
738 v8::Local<v8::Value> V8InspectorImpl::generatorObjectLocation(v8::Local<v8::Obje
ct> object) | 666 v8::Local<v8::Value> V8Debugger::generatorObjectLocation(v8::Local<v8::Object> o
bject) |
739 { | 667 { |
740 if (!enabled()) { | 668 if (!enabled()) { |
741 NOTREACHED(); | 669 NOTREACHED(); |
742 return v8::Null(m_isolate); | 670 return v8::Null(m_isolate); |
743 } | 671 } |
744 v8::Local<v8::Value> argv[] = { object }; | 672 v8::Local<v8::Value> argv[] = { object }; |
745 v8::Local<v8::Value> location = callDebuggerMethod("getGeneratorObjectLocati
on", 1, argv).ToLocalChecked(); | 673 v8::Local<v8::Value> location = callDebuggerMethod("getGeneratorObjectLocati
on", 1, argv).ToLocalChecked(); |
746 if (!location->IsObject()) | 674 if (!location->IsObject()) |
747 return v8::Null(m_isolate); | 675 return v8::Null(m_isolate); |
748 v8::Local<v8::Context> context = m_debuggerContext.Get(m_isolate); | 676 v8::Local<v8::Context> context = m_debuggerContext.Get(m_isolate); |
749 if (!markAsInternal(context, v8::Local<v8::Object>::Cast(location), V8Intern
alValueType::kLocation)) | 677 if (!markAsInternal(context, v8::Local<v8::Object>::Cast(location), V8Intern
alValueType::kLocation)) |
750 return v8::Null(m_isolate); | 678 return v8::Null(m_isolate); |
751 return location; | 679 return location; |
752 } | 680 } |
753 | 681 |
754 v8::Local<v8::Value> V8InspectorImpl::functionLocation(v8::Local<v8::Context> co
ntext, v8::Local<v8::Function> function) | 682 v8::Local<v8::Value> V8Debugger::functionLocation(v8::Local<v8::Context> context
, v8::Local<v8::Function> function) |
755 { | 683 { |
756 int scriptId = function->ScriptId(); | 684 int scriptId = function->ScriptId(); |
757 if (scriptId == v8::UnboundScript::kNoScriptId) | 685 if (scriptId == v8::UnboundScript::kNoScriptId) |
758 return v8::Null(m_isolate); | 686 return v8::Null(m_isolate); |
759 int lineNumber = function->GetScriptLineNumber(); | 687 int lineNumber = function->GetScriptLineNumber(); |
760 int columnNumber = function->GetScriptColumnNumber(); | 688 int columnNumber = function->GetScriptColumnNumber(); |
761 if (lineNumber == v8::Function::kLineOffsetNotFound || columnNumber == v8::F
unction::kLineOffsetNotFound) | 689 if (lineNumber == v8::Function::kLineOffsetNotFound || columnNumber == v8::F
unction::kLineOffsetNotFound) |
762 return v8::Null(m_isolate); | 690 return v8::Null(m_isolate); |
763 v8::Local<v8::Object> location = v8::Object::New(m_isolate); | 691 v8::Local<v8::Object> location = v8::Object::New(m_isolate); |
764 if (!location->Set(context, v8InternalizedString("scriptId"), toV8String(m_i
solate, String16::fromInteger(scriptId))).FromMaybe(false)) | 692 if (!location->Set(context, toV8StringInternalized(m_isolate, "scriptId"), t
oV8String(m_isolate, String16::fromInteger(scriptId))).FromMaybe(false)) |
765 return v8::Null(m_isolate); | 693 return v8::Null(m_isolate); |
766 if (!location->Set(context, v8InternalizedString("lineNumber"), v8::Integer:
:New(m_isolate, lineNumber)).FromMaybe(false)) | 694 if (!location->Set(context, toV8StringInternalized(m_isolate, "lineNumber"),
v8::Integer::New(m_isolate, lineNumber)).FromMaybe(false)) |
767 return v8::Null(m_isolate); | 695 return v8::Null(m_isolate); |
768 if (!location->Set(context, v8InternalizedString("columnNumber"), v8::Intege
r::New(m_isolate, columnNumber)).FromMaybe(false)) | 696 if (!location->Set(context, toV8StringInternalized(m_isolate, "columnNumber"
), v8::Integer::New(m_isolate, columnNumber)).FromMaybe(false)) |
769 return v8::Null(m_isolate); | 697 return v8::Null(m_isolate); |
770 if (!markAsInternal(context, location, V8InternalValueType::kLocation)) | 698 if (!markAsInternal(context, location, V8InternalValueType::kLocation)) |
771 return v8::Null(m_isolate); | 699 return v8::Null(m_isolate); |
772 return location; | 700 return location; |
773 } | 701 } |
774 | 702 |
775 bool V8InspectorImpl::isPaused() | 703 bool V8Debugger::isPaused() |
776 { | 704 { |
777 return !m_pausedContext.IsEmpty(); | 705 return !m_pausedContext.IsEmpty(); |
778 } | 706 } |
779 | 707 |
780 v8::MaybeLocal<v8::Value> V8InspectorImpl::runCompiledScript(v8::Local<v8::Conte
xt> context, v8::Local<v8::Script> script) | 708 std::unique_ptr<V8StackTraceImpl> V8Debugger::createStackTrace(v8::Local<v8::Sta
ckTrace> stackTrace) |
781 { | |
782 // TODO(dgozman): get rid of this check. | |
783 if (!m_client->isExecutionAllowed()) | |
784 return v8::MaybeLocal<v8::Value>(); | |
785 | |
786 v8::MicrotasksScope microtasksScope(m_isolate, v8::MicrotasksScope::kRunMicr
otasks); | |
787 int groupId = getGroupId(context); | |
788 if (V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(groupId)) | |
789 agent->willExecuteScript(script->GetUnboundScript()->GetId()); | |
790 v8::MaybeLocal<v8::Value> result = script->Run(context); | |
791 // Get agent from the map again, since it could have detached during script
execution. | |
792 if (V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(groupId)) | |
793 agent->didExecuteScript(); | |
794 return result; | |
795 } | |
796 | |
797 v8::MaybeLocal<v8::Value> V8InspectorImpl::callFunction(v8::Local<v8::Function>
function, v8::Local<v8::Context> context, v8::Local<v8::Value> receiver, int arg
c, v8::Local<v8::Value> info[]) | |
798 { | |
799 // TODO(dgozman): get rid of this check. | |
800 if (!m_client->isExecutionAllowed()) | |
801 return v8::MaybeLocal<v8::Value>(); | |
802 | |
803 v8::MicrotasksScope microtasksScope(m_isolate, v8::MicrotasksScope::kRunMicr
otasks); | |
804 int groupId = getGroupId(context); | |
805 if (V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(groupId)) | |
806 agent->willExecuteScript(function->ScriptId()); | |
807 v8::MaybeLocal<v8::Value> result = function->Call(context, receiver, argc, i
nfo); | |
808 // Get agent from the map again, since it could have detached during script
execution. | |
809 if (V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(groupId)) | |
810 agent->didExecuteScript(); | |
811 return result; | |
812 } | |
813 | |
814 v8::MaybeLocal<v8::Value> V8InspectorImpl::compileAndRunInternalScript(v8::Local
<v8::Context> context, v8::Local<v8::String> source) | |
815 { | |
816 v8::Local<v8::Script> script = compileScript(context, source, String(), true
); | |
817 if (script.IsEmpty()) | |
818 return v8::MaybeLocal<v8::Value>(); | |
819 v8::MicrotasksScope microtasksScope(m_isolate, v8::MicrotasksScope::kDoNotRu
nMicrotasks); | |
820 return script->Run(context); | |
821 } | |
822 | |
823 v8::Local<v8::Script> V8InspectorImpl::compileScript(v8::Local<v8::Context> cont
ext, v8::Local<v8::String> code, const String16& fileName, bool markAsInternal) | |
824 { | |
825 v8::ScriptOrigin origin( | |
826 toV8String(m_isolate, fileName), | |
827 v8::Integer::New(m_isolate, 0), | |
828 v8::Integer::New(m_isolate, 0), | |
829 v8::False(m_isolate), // sharable | |
830 v8::Local<v8::Integer>(), | |
831 v8::Boolean::New(m_isolate, markAsInternal), // internal | |
832 toV8String(m_isolate, String16()), // sourceMap | |
833 v8::True(m_isolate)); // opaqueresource | |
834 v8::ScriptCompiler::Source source(code, origin); | |
835 v8::Local<v8::Script> script; | |
836 if (!v8::ScriptCompiler::Compile(context, &source, v8::ScriptCompiler::kNoCo
mpileOptions).ToLocal(&script)) | |
837 return v8::Local<v8::Script>(); | |
838 return script; | |
839 } | |
840 | |
841 void V8InspectorImpl::enableStackCapturingIfNeeded() | |
842 { | |
843 if (!m_capturingStackTracesCount) | |
844 V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(m_isolate, t
rue); | |
845 ++m_capturingStackTracesCount; | |
846 } | |
847 | |
848 void V8InspectorImpl::disableStackCapturingIfNeeded() | |
849 { | |
850 if (!(--m_capturingStackTracesCount)) | |
851 V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(m_isolate, f
alse); | |
852 } | |
853 | |
854 V8ConsoleMessageStorage* V8InspectorImpl::ensureConsoleMessageStorage(int contex
tGroupId) | |
855 { | |
856 ConsoleStorageMap::iterator storageIt = m_consoleStorageMap.find(contextGrou
pId); | |
857 if (storageIt == m_consoleStorageMap.end()) | |
858 storageIt = m_consoleStorageMap.insert(std::make_pair(contextGroupId, wr
apUnique(new V8ConsoleMessageStorage(this, contextGroupId)))).first; | |
859 return storageIt->second.get(); | |
860 } | |
861 | |
862 std::unique_ptr<V8StackTrace> V8InspectorImpl::createStackTrace(v8::Local<v8::St
ackTrace> stackTrace) | |
863 { | |
864 return createStackTraceImpl(stackTrace); | |
865 } | |
866 | |
867 std::unique_ptr<V8StackTraceImpl> V8InspectorImpl::createStackTraceImpl(v8::Loca
l<v8::StackTrace> stackTrace) | |
868 { | 709 { |
869 int contextGroupId = m_isolate->InContext() ? getGroupId(m_isolate->GetCurre
ntContext()) : 0; | 710 int contextGroupId = m_isolate->InContext() ? getGroupId(m_isolate->GetCurre
ntContext()) : 0; |
870 return V8StackTraceImpl::create(this, contextGroupId, stackTrace, V8StackTra
ceImpl::maxCallStackSizeToCapture); | 711 return V8StackTraceImpl::create(this, contextGroupId, stackTrace, V8StackTra
ceImpl::maxCallStackSizeToCapture); |
871 } | 712 } |
872 | 713 |
873 std::unique_ptr<V8InspectorSession> V8InspectorImpl::connect(int contextGroupId,
protocol::FrontendChannel* channel, V8InspectorSessionClient* client, const Str
ing16* state) | 714 int V8Debugger::markContext(const V8ContextInfo& info) |
874 { | 715 { |
875 DCHECK(m_sessions.find(contextGroupId) == m_sessions.cend()); | 716 DCHECK(info.context->GetIsolate() == m_isolate); |
876 std::unique_ptr<V8InspectorSessionImpl> session = | 717 int contextId = ++m_lastContextId; |
877 V8InspectorSessionImpl::create(this, contextGroupId, channel, client, st
ate); | 718 String16 debugData = String16::fromInteger(info.contextGroupId) + "," + Stri
ng16::fromInteger(contextId) + "," + (info.isDefault ? "default" : "nondefault")
; |
878 m_sessions[contextGroupId] = session.get(); | 719 v8::Context::Scope contextScope(info.context); |
879 return std::move(session); | 720 info.context->SetEmbedderData(static_cast<int>(v8::Context::kDebugIdIndex),
toV8String(m_isolate, debugData)); |
| 721 return contextId; |
880 } | 722 } |
881 | 723 |
882 void V8InspectorImpl::disconnect(V8InspectorSessionImpl* session) | 724 void V8Debugger::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) |
883 { | |
884 DCHECK(m_sessions.find(session->contextGroupId()) != m_sessions.end()); | |
885 m_sessions.erase(session->contextGroupId()); | |
886 } | |
887 | |
888 InspectedContext* V8InspectorImpl::getContext(int groupId, int contextId) const | |
889 { | |
890 ContextsByGroupMap::const_iterator contextGroupIt = m_contexts.find(groupId)
; | |
891 if (contextGroupIt == m_contexts.end()) | |
892 return nullptr; | |
893 | |
894 ContextByIdMap::iterator contextIt = contextGroupIt->second->find(contextId)
; | |
895 if (contextIt == contextGroupIt->second->end()) | |
896 return nullptr; | |
897 | |
898 return contextIt->second.get(); | |
899 } | |
900 | |
901 void V8InspectorImpl::contextCreated(const V8ContextInfo& info) | |
902 { | |
903 DCHECK(info.context->GetIsolate() == m_isolate); | |
904 // TODO(dgozman): make s_lastContextId non-static. | |
905 int contextId = atomicIncrement(&s_lastContextId); | |
906 String16 debugData = String16::fromInteger(info.contextGroupId) + "," + Stri
ng16::fromInteger(contextId) + "," + (info.isDefault ? "default" : "nondefault")
; | |
907 v8::HandleScope scope(m_isolate); | |
908 v8::Context::Scope contextScope(info.context); | |
909 info.context->SetEmbedderData(static_cast<int>(v8::Context::kDebugIdIndex),
toV8String(m_isolate, debugData)); | |
910 | |
911 ContextsByGroupMap::iterator contextIt = m_contexts.find(info.contextGroupId
); | |
912 if (contextIt == m_contexts.end()) | |
913 contextIt = m_contexts.insert(std::make_pair(info.contextGroupId, wrapUn
ique(new ContextByIdMap()))).first; | |
914 | |
915 const auto& contextById = contextIt->second; | |
916 | |
917 DCHECK(contextById->find(contextId) == contextById->cend()); | |
918 InspectedContext* context = new InspectedContext(this, info, contextId); | |
919 (*contextById)[contextId] = wrapUnique(context); | |
920 SessionMap::iterator sessionIt = m_sessions.find(info.contextGroupId); | |
921 if (sessionIt != m_sessions.end()) | |
922 sessionIt->second->runtimeAgent()->reportExecutionContextCreated(context
); | |
923 } | |
924 | |
925 void V8InspectorImpl::contextDestroyed(v8::Local<v8::Context> context) | |
926 { | |
927 int contextId = V8InspectorImpl::contextId(context); | |
928 int contextGroupId = getGroupId(context); | |
929 | |
930 ConsoleStorageMap::iterator storageIt = m_consoleStorageMap.find(contextGrou
pId); | |
931 if (storageIt != m_consoleStorageMap.end()) | |
932 storageIt->second->contextDestroyed(contextId); | |
933 | |
934 InspectedContext* inspectedContext = getContext(contextGroupId, contextId); | |
935 if (!inspectedContext) | |
936 return; | |
937 | |
938 SessionMap::iterator iter = m_sessions.find(contextGroupId); | |
939 if (iter != m_sessions.end()) | |
940 iter->second->runtimeAgent()->reportExecutionContextDestroyed(inspectedC
ontext); | |
941 discardInspectedContext(contextGroupId, contextId); | |
942 } | |
943 | |
944 void V8InspectorImpl::resetContextGroup(int contextGroupId) | |
945 { | |
946 m_consoleStorageMap.erase(contextGroupId); | |
947 SessionMap::iterator session = m_sessions.find(contextGroupId); | |
948 if (session != m_sessions.end()) | |
949 session->second->reset(); | |
950 m_contexts.erase(contextGroupId); | |
951 } | |
952 | |
953 void V8InspectorImpl::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int dep
th) | |
954 { | 725 { |
955 if (depth <= 0) | 726 if (depth <= 0) |
956 m_maxAsyncCallStackDepthMap.erase(agent); | 727 m_maxAsyncCallStackDepthMap.erase(agent); |
957 else | 728 else |
958 m_maxAsyncCallStackDepthMap[agent] = depth; | 729 m_maxAsyncCallStackDepthMap[agent] = depth; |
959 | 730 |
960 int maxAsyncCallStackDepth = 0; | 731 int maxAsyncCallStackDepth = 0; |
961 for (const auto& pair : m_maxAsyncCallStackDepthMap) { | 732 for (const auto& pair : m_maxAsyncCallStackDepthMap) { |
962 if (pair.second > maxAsyncCallStackDepth) | 733 if (pair.second > maxAsyncCallStackDepth) |
963 maxAsyncCallStackDepth = pair.second; | 734 maxAsyncCallStackDepth = pair.second; |
964 } | 735 } |
965 | 736 |
966 if (m_maxAsyncCallStackDepth == maxAsyncCallStackDepth) | 737 if (m_maxAsyncCallStackDepth == maxAsyncCallStackDepth) |
967 return; | 738 return; |
968 m_maxAsyncCallStackDepth = maxAsyncCallStackDepth; | 739 m_maxAsyncCallStackDepth = maxAsyncCallStackDepth; |
969 if (!maxAsyncCallStackDepth) | 740 if (!maxAsyncCallStackDepth) |
970 allAsyncTasksCanceled(); | 741 allAsyncTasksCanceled(); |
971 } | 742 } |
972 | 743 |
973 void V8InspectorImpl::asyncTaskScheduled(const String16& taskName, void* task, b
ool recurring) | 744 void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task, bool r
ecurring) |
974 { | 745 { |
975 if (!m_maxAsyncCallStackDepth) | 746 if (!m_maxAsyncCallStackDepth) |
976 return; | 747 return; |
977 v8::HandleScope scope(m_isolate); | 748 v8::HandleScope scope(m_isolate); |
978 int contextGroupId = m_isolate->InContext() ? getGroupId(m_isolate->GetCurre
ntContext()) : 0; | 749 int contextGroupId = m_isolate->InContext() ? getGroupId(m_isolate->GetCurre
ntContext()) : 0; |
979 std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture(this, co
ntextGroupId, V8StackTraceImpl::maxCallStackSizeToCapture, taskName); | 750 std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture(this, co
ntextGroupId, V8StackTraceImpl::maxCallStackSizeToCapture, taskName); |
980 if (chain) { | 751 if (chain) { |
981 m_asyncTaskStacks[task] = std::move(chain); | 752 m_asyncTaskStacks[task] = std::move(chain); |
982 if (recurring) | 753 if (recurring) |
983 m_recurringTasks.insert(task); | 754 m_recurringTasks.insert(task); |
984 } | 755 } |
985 } | 756 } |
986 | 757 |
987 void V8InspectorImpl::asyncTaskCanceled(void* task) | 758 void V8Debugger::asyncTaskCanceled(void* task) |
988 { | 759 { |
989 if (!m_maxAsyncCallStackDepth) | 760 if (!m_maxAsyncCallStackDepth) |
990 return; | 761 return; |
991 m_asyncTaskStacks.erase(task); | 762 m_asyncTaskStacks.erase(task); |
992 m_recurringTasks.erase(task); | 763 m_recurringTasks.erase(task); |
993 } | 764 } |
994 | 765 |
995 void V8InspectorImpl::asyncTaskStarted(void* task) | 766 void V8Debugger::asyncTaskStarted(void* task) |
996 { | 767 { |
997 if (!m_maxAsyncCallStackDepth) | 768 if (!m_maxAsyncCallStackDepth) |
998 return; | 769 return; |
999 m_currentTasks.push_back(task); | 770 m_currentTasks.push_back(task); |
1000 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find(task); | 771 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find(task); |
1001 // Needs to support following order of events: | 772 // Needs to support following order of events: |
1002 // - asyncTaskScheduled | 773 // - asyncTaskScheduled |
1003 // <-- attached here --> | 774 // <-- attached here --> |
1004 // - asyncTaskStarted | 775 // - asyncTaskStarted |
1005 // - asyncTaskCanceled <-- canceled before finished | 776 // - asyncTaskCanceled <-- canceled before finished |
1006 // <-- async stack requested here --> | 777 // <-- async stack requested here --> |
1007 // - asyncTaskFinished | 778 // - asyncTaskFinished |
1008 std::unique_ptr<V8StackTraceImpl> stack; | 779 std::unique_ptr<V8StackTraceImpl> stack; |
1009 if (stackIt != m_asyncTaskStacks.end() && stackIt->second) | 780 if (stackIt != m_asyncTaskStacks.end() && stackIt->second) |
1010 stack = stackIt->second->cloneImpl(); | 781 stack = stackIt->second->cloneImpl(); |
1011 m_currentStacks.push_back(std::move(stack)); | 782 m_currentStacks.push_back(std::move(stack)); |
1012 } | 783 } |
1013 | 784 |
1014 void V8InspectorImpl::asyncTaskFinished(void* task) | 785 void V8Debugger::asyncTaskFinished(void* task) |
1015 { | 786 { |
1016 if (!m_maxAsyncCallStackDepth) | 787 if (!m_maxAsyncCallStackDepth) |
1017 return; | 788 return; |
1018 // We could start instrumenting half way and the stack is empty. | 789 // We could start instrumenting half way and the stack is empty. |
1019 if (!m_currentStacks.size()) | 790 if (!m_currentStacks.size()) |
1020 return; | 791 return; |
1021 | 792 |
1022 DCHECK(m_currentTasks.back() == task); | 793 DCHECK(m_currentTasks.back() == task); |
1023 m_currentTasks.pop_back(); | 794 m_currentTasks.pop_back(); |
1024 | 795 |
1025 m_currentStacks.pop_back(); | 796 m_currentStacks.pop_back(); |
1026 if (m_recurringTasks.find(task) == m_recurringTasks.end()) | 797 if (m_recurringTasks.find(task) == m_recurringTasks.end()) |
1027 m_asyncTaskStacks.erase(task); | 798 m_asyncTaskStacks.erase(task); |
1028 } | 799 } |
1029 | 800 |
1030 void V8InspectorImpl::allAsyncTasksCanceled() | 801 void V8Debugger::allAsyncTasksCanceled() |
1031 { | 802 { |
1032 m_asyncTaskStacks.clear(); | 803 m_asyncTaskStacks.clear(); |
1033 m_recurringTasks.clear(); | 804 m_recurringTasks.clear(); |
1034 m_currentStacks.clear(); | 805 m_currentStacks.clear(); |
1035 m_currentTasks.clear(); | 806 m_currentTasks.clear(); |
1036 } | 807 } |
1037 | 808 |
1038 void V8InspectorImpl::willExecuteScript(v8::Local<v8::Context> context, int scri
ptId) | 809 std::unique_ptr<V8StackTraceImpl> V8Debugger::captureStackTrace(bool fullStack) |
1039 { | |
1040 if (V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(context)) | |
1041 agent->willExecuteScript(scriptId); | |
1042 } | |
1043 | |
1044 void V8InspectorImpl::didExecuteScript(v8::Local<v8::Context> context) | |
1045 { | |
1046 if (V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(context)) | |
1047 agent->didExecuteScript(); | |
1048 } | |
1049 | |
1050 void V8InspectorImpl::idleStarted() | |
1051 { | |
1052 m_isolate->GetCpuProfiler()->SetIdle(true); | |
1053 } | |
1054 | |
1055 void V8InspectorImpl::idleFinished() | |
1056 { | |
1057 m_isolate->GetCpuProfiler()->SetIdle(false); | |
1058 } | |
1059 | |
1060 unsigned V8InspectorImpl::exceptionThrown(v8::Local<v8::Context> context, const
String16& message, v8::Local<v8::Value> exception, const String16& detailedMessa
ge, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique
_ptr<V8StackTrace> stackTrace, int scriptId) | |
1061 { | |
1062 int contextGroupId = getGroupId(context); | |
1063 if (!contextGroupId) | |
1064 return 0; | |
1065 std::unique_ptr<V8StackTraceImpl> stackTraceImpl = wrapUnique(static_cast<V8
StackTraceImpl*>(stackTrace.release())); | |
1066 unsigned exceptionId = ++m_lastExceptionId; | |
1067 std::unique_ptr<V8ConsoleMessage> consoleMessage = V8ConsoleMessage::createF
orException(m_client->currentTimeMS(), detailedMessage, url, lineNumber, columnN
umber, std::move(stackTraceImpl), scriptId, m_isolate, message, contextId(contex
t), exception, exceptionId); | |
1068 ensureConsoleMessageStorage(contextGroupId)->addMessage(std::move(consoleMes
sage)); | |
1069 return exceptionId; | |
1070 } | |
1071 | |
1072 void V8InspectorImpl::exceptionRevoked(v8::Local<v8::Context> context, unsigned
exceptionId, const String16& message) | |
1073 { | |
1074 int contextGroupId = getGroupId(context); | |
1075 if (!contextGroupId) | |
1076 return; | |
1077 | |
1078 std::unique_ptr<V8ConsoleMessage> consoleMessage = V8ConsoleMessage::createF
orRevokedException(m_client->currentTimeMS(), message, exceptionId); | |
1079 ensureConsoleMessageStorage(contextGroupId)->addMessage(std::move(consoleMes
sage)); | |
1080 } | |
1081 | |
1082 std::unique_ptr<V8StackTrace> V8InspectorImpl::captureStackTrace(bool fullStack) | |
1083 { | |
1084 return captureStackTraceImpl(fullStack); | |
1085 } | |
1086 | |
1087 std::unique_ptr<V8StackTraceImpl> V8InspectorImpl::captureStackTraceImpl(bool fu
llStack) | |
1088 { | 810 { |
1089 if (!m_isolate->InContext()) | 811 if (!m_isolate->InContext()) |
1090 return nullptr; | 812 return nullptr; |
1091 | 813 |
1092 v8::HandleScope handles(m_isolate); | 814 v8::HandleScope handles(m_isolate); |
1093 int contextGroupId = getGroupId(m_isolate->GetCurrentContext()); | 815 int contextGroupId = getGroupId(m_isolate->GetCurrentContext()); |
1094 if (!contextGroupId) | 816 if (!contextGroupId) |
1095 return nullptr; | 817 return nullptr; |
1096 | 818 |
1097 size_t stackSize = fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture :
1; | 819 size_t stackSize = fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture :
1; |
1098 SessionMap::iterator sessionIt = m_sessions.find(contextGroupId); | 820 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) |
1099 if (sessionIt != m_sessions.end() && sessionIt->second->runtimeAgent()->enab
led()) | |
1100 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; | 821 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; |
1101 | 822 |
1102 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); | 823 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); |
1103 } | 824 } |
1104 | 825 |
1105 v8::Local<v8::Context> V8InspectorImpl::regexContext() | |
1106 { | |
1107 if (m_regexContext.IsEmpty()) | |
1108 m_regexContext.Reset(m_isolate, v8::Context::New(m_isolate)); | |
1109 return m_regexContext.Get(m_isolate); | |
1110 } | |
1111 | |
1112 void V8InspectorImpl::discardInspectedContext(int contextGroupId, int contextId) | |
1113 { | |
1114 if (!getContext(contextGroupId, contextId)) | |
1115 return; | |
1116 m_contexts[contextGroupId]->erase(contextId); | |
1117 if (m_contexts[contextGroupId]->empty()) | |
1118 m_contexts.erase(contextGroupId); | |
1119 } | |
1120 | |
1121 const V8InspectorImpl::ContextByIdMap* V8InspectorImpl::contextGroup(int context
GroupId) | |
1122 { | |
1123 ContextsByGroupMap::iterator iter = m_contexts.find(contextGroupId); | |
1124 return iter == m_contexts.end() ? nullptr : iter->second.get(); | |
1125 } | |
1126 | |
1127 V8InspectorSessionImpl* V8InspectorImpl::sessionForContextGroup(int contextGroup
Id) | |
1128 { | |
1129 if (!contextGroupId) | |
1130 return nullptr; | |
1131 SessionMap::iterator iter = m_sessions.find(contextGroupId); | |
1132 return iter == m_sessions.end() ? nullptr : iter->second; | |
1133 } | |
1134 | |
1135 } // namespace blink | 826 } // namespace blink |
OLD | NEW |