OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 /** | 5 /** |
6 * @fileoverview Provides communication interface to remote v8 debugger. See | 6 * @fileoverview Provides communication interface to remote v8 debugger. See |
7 * protocol decription at http://code.google.com/p/v8/wiki/DebuggerProtocol | 7 * protocol decription at http://code.google.com/p/v8/wiki/DebuggerProtocol |
8 */ | 8 */ |
9 goog.provide('devtools.DebuggerAgent'); | 9 goog.provide('devtools.DebuggerAgent'); |
10 | 10 |
11 | 11 |
12 /** | 12 /** |
13 * @constructor | 13 * @constructor |
14 */ | 14 */ |
15 devtools.DebuggerAgent = function() { | 15 devtools.DebuggerAgent = function() { |
16 RemoteDebuggerAgent.DebuggerOutput = | 16 RemoteDebuggerAgent.DebuggerOutput = |
17 goog.bind(this.handleDebuggerOutput_, this); | 17 goog.bind(this.handleDebuggerOutput_, this); |
18 RemoteDebuggerAgent.DidGetContextId = | 18 RemoteDebuggerAgent.SetContextId = |
19 goog.bind(this.didGetContextId_, this); | 19 goog.bind(this.setContextId_, this); |
20 RemoteDebuggerAgent.DidIsProfilingStarted = | 20 RemoteDebuggerAgent.DidGetActiveProfilerModules = |
21 goog.bind(this.didIsProfilingStarted_, this); | 21 goog.bind(this.didGetActiveProfilerModules_, this); |
22 RemoteDebuggerAgent.DidGetLogLines = | 22 RemoteDebuggerAgent.DidGetNextLogLines = |
23 goog.bind(this.didGetLogLines_, this); | 23 goog.bind(this.didGetNextLogLines_, this); |
24 | 24 |
25 /** | 25 /** |
26 * Id of the inspected page global context. It is used for filtering scripts. | 26 * Id of the inspected page global context. It is used for filtering scripts. |
27 * @type {number} | 27 * @type {number} |
28 */ | 28 */ |
29 this.contextId_ = null; | 29 this.contextId_ = null; |
30 | 30 |
31 /** | 31 /** |
32 * Mapping from script id to script info. | 32 * Mapping from script id to script info. |
33 * @type {Object} | 33 * @type {Object} |
34 */ | 34 */ |
35 this.parsedScripts_ = null; | 35 this.parsedScripts_ = null; |
36 | 36 |
37 /** | 37 /** |
38 * Mapping from the request id to the devtools.BreakpointInfo for the | 38 * Mapping from the request id to the devtools.BreakpointInfo for the |
39 * breakpoints whose v8 ids are not set yet. These breakpoints are waiting for | 39 * breakpoints whose v8 ids are not set yet. These breakpoints are waiting for |
40 * 'setbreakpoint' responses to learn their ids in the v8 debugger. | 40 * 'setbreakpoint' responses to learn their ids in the v8 debugger. |
41 * @see #handleSetBreakpointResponse_ | 41 * @see #handleSetBreakpointResponse_ |
42 * @type {Object} | 42 * @type {Object} |
43 */ | 43 */ |
44 this.requestNumberToBreakpointInfo_ = null; | 44 this.requestNumberToBreakpointInfo_ = null; |
45 | 45 |
46 /** | 46 /** |
47 * Information on current stack top frame. | 47 * Information on current stack frames. |
48 * See JavaScriptCallFrame.idl. | 48 * @type {Array.<devtools.CallFrame>} |
49 * @type {?devtools.CallFrame} | |
50 */ | 49 */ |
51 this.currentCallFrame_ = null; | 50 this.callFrames_ = []; |
52 | 51 |
53 /** | 52 /** |
54 * Whether to stop in the debugger on the exceptions. | 53 * Whether to stop in the debugger on the exceptions. |
55 * @type {boolean} | 54 * @type {boolean} |
56 */ | 55 */ |
57 this.pauseOnExceptions_ = true; | 56 this.pauseOnExceptions_ = true; |
58 | 57 |
59 /** | 58 /** |
60 * Mapping: request sequence number->callback. | 59 * Mapping: request sequence number->callback. |
61 * @type {Object} | 60 * @type {Object} |
62 */ | 61 */ |
63 this.requestSeqToCallback_ = null; | 62 this.requestSeqToCallback_ = null; |
64 | 63 |
65 /** | 64 /** |
66 * Whether the scripts list has been requested. | 65 * Whether the scripts list has been requested. |
67 * @type {boolean} | 66 * @type {boolean} |
68 */ | 67 */ |
69 this.scriptsCacheInitialized_ = false; | 68 this.scriptsCacheInitialized_ = false; |
70 | 69 |
71 /** | 70 /** |
72 * Whether user has stopped profiling and we are retrieving the rest of | 71 * Active profiler modules flags. |
73 * profiler's log. | |
74 * @type {boolean} | |
75 */ | |
76 this.isProcessingProfile_ = false; | |
77 | |
78 /** | |
79 * The position in log file to read from. | |
80 * @type {number} | 72 * @type {number} |
81 */ | 73 */ |
82 this.lastProfileLogPosition_ = 0; | 74 this.activeProfilerModules_ = |
| 75 devtools.DebuggerAgent.ProfilerModules.PROFILER_MODULE_NONE; |
83 | 76 |
84 /** | 77 /** |
85 * Profiler processor instance. | 78 * Profiler processor instance. |
86 * @type {devtools.profiler.Processor} | 79 * @type {devtools.profiler.Processor} |
87 */ | 80 */ |
88 this.profilerProcessor_ = new devtools.profiler.Processor(); | 81 this.profilerProcessor_ = new devtools.profiler.Processor(); |
| 82 |
| 83 /** |
| 84 * Container of all breakpoints set using resource URL. These breakpoints |
| 85 * survive page reload. Breakpoints set by script id(for scripts that don't |
| 86 * have URLs) are stored in ScriptInfo objects. |
| 87 * @type {Object} |
| 88 */ |
| 89 this.urlToBreakpoints_ = {}; |
| 90 |
| 91 |
| 92 /** |
| 93 * Exception message that is shown to user while on exception break. |
| 94 * @type {WebInspector.ConsoleMessage} |
| 95 */ |
| 96 this.currentExceptionMessage_ = null; |
89 }; | 97 }; |
90 | 98 |
91 | 99 |
| 100 /** |
| 101 * A copy of the scope types from v8/src/mirror-delay.js |
| 102 * @enum {number} |
| 103 */ |
| 104 devtools.DebuggerAgent.ScopeType = { |
| 105 Global: 0, |
| 106 Local: 1, |
| 107 With: 2, |
| 108 Closure: 3 |
| 109 }; |
| 110 |
| 111 |
| 112 /** |
| 113 * A no-op JS expression that is sent to the inspected page in order to force v8 |
| 114 * execution. |
| 115 */ |
| 116 devtools.DebuggerAgent.VOID_SCRIPT = 'javascript:void(0)'; |
| 117 |
| 118 |
| 119 /** |
| 120 * A copy of enum from include/v8.h |
| 121 * @enum {number} |
| 122 */ |
| 123 devtools.DebuggerAgent.ProfilerModules = { |
| 124 PROFILER_MODULE_NONE: 0, |
| 125 PROFILER_MODULE_CPU: 1, |
| 126 PROFILER_MODULE_HEAP_STATS: 1 << 1, |
| 127 PROFILER_MODULE_JS_CONSTRUCTORS: 1 << 2, |
| 128 PROFILER_MODULE_HEAP_SNAPSHOT: 1 << 16 |
| 129 }; |
| 130 |
| 131 |
92 /** | 132 /** |
93 * Resets debugger agent to its initial state. | 133 * Resets debugger agent to its initial state. |
94 */ | 134 */ |
95 devtools.DebuggerAgent.prototype.reset = function() { | 135 devtools.DebuggerAgent.prototype.reset = function() { |
96 this.scriptsCacheInitialized_ = false; | |
97 this.contextId_ = null; | 136 this.contextId_ = null; |
98 this.parsedScripts_ = {}; | 137 this.parsedScripts_ = {}; |
99 this.requestNumberToBreakpointInfo_ = {}; | 138 this.requestNumberToBreakpointInfo_ = {}; |
100 this.currentCallFrame_ = null; | 139 this.callFrames_ = []; |
101 this.requestSeqToCallback_ = {}; | 140 this.requestSeqToCallback_ = {}; |
| 141 |
| 142 // Profiler isn't reset because it contains no data that is |
| 143 // specific for a particular V8 instance. All such data is |
| 144 // managed by an agent on the Render's side. |
102 }; | 145 }; |
103 | 146 |
104 | 147 |
105 /** | 148 /** |
106 * Requests scripts list if it has not been requested yet. | 149 * Initializes scripts UI. Asynchronously requests for all parsed scripts |
| 150 * if necessary. Response will be processed in handleScriptsResponse_. |
107 */ | 151 */ |
108 devtools.DebuggerAgent.prototype.initializeScriptsCache = function() { | 152 devtools.DebuggerAgent.prototype.initUI = function() { |
109 if (!this.scriptsCacheInitialized_) { | 153 // There can be a number of scripts from after-compile events that are |
110 this.scriptsCacheInitialized_ = true; | 154 // pending addition into the UI. |
111 this.requestScripts(); | 155 for (var scriptId in this.parsedScripts_) { |
| 156 var script = this.parsedScripts_[scriptId]; |
| 157 WebInspector.parsedScriptSource(scriptId, script.getUrl(), |
| 158 undefined /* script source */, script.getLineOffset()); |
112 } | 159 } |
113 }; | |
114 | 160 |
115 | 161 if (this.contextId_) { |
116 /** | 162 // We already have context id. This means that we are here from the |
117 * Asynchronously requests for all parsed script sources. Response will be | 163 // very beginning of the page load cycle and hence will get all scripts |
118 * processed in handleScriptsResponse_. | 164 // via after-compile events. No need to request scripts for this session. |
119 */ | |
120 devtools.DebuggerAgent.prototype.requestScripts = function() { | |
121 if (this.contextId_ === null) { | |
122 // Update context id first to filter the scripts. | |
123 RemoteDebuggerAgent.GetContextId(); | |
124 return; | 165 return; |
125 } | 166 } |
| 167 |
| 168 RemoteDebuggerAgent.GetContextId(); |
126 var cmd = new devtools.DebugCommand('scripts', { | 169 var cmd = new devtools.DebugCommand('scripts', { |
127 'includeSource': false | 170 'includeSource': false |
128 }); | 171 }); |
129 devtools.DebuggerAgent.sendCommand_(cmd); | 172 devtools.DebuggerAgent.sendCommand_(cmd); |
130 // Force v8 execution so that it gets to processing the requested command. | 173 // Force v8 execution so that it gets to processing the requested command. |
131 devtools.tools.evaluateJavaScript('javascript:void(0)'); | 174 devtools.tools.evaluateJavaScript(devtools.DebuggerAgent.VOID_SCRIPT); |
132 }; | 175 }; |
133 | 176 |
134 | 177 |
135 /** | 178 /** |
136 * Asynchronously requests the debugger for the script source. | 179 * Asynchronously requests the debugger for the script source. |
137 * @param {number} scriptId Id of the script whose source should be resolved. | 180 * @param {number} scriptId Id of the script whose source should be resolved. |
138 * @param {function(source:?string):void} callback Function that will be called | 181 * @param {function(source:?string):void} callback Function that will be called |
139 * when the source resolution is completed. 'source' parameter will be null | 182 * when the source resolution is completed. 'source' parameter will be null |
140 * if the resolution fails. | 183 * if the resolution fails. |
141 */ | 184 */ |
142 devtools.DebuggerAgent.prototype.resolveScriptSource = function( | 185 devtools.DebuggerAgent.prototype.resolveScriptSource = function( |
143 scriptId, callback) { | 186 scriptId, callback) { |
144 var script = this.parsedScripts_[scriptId]; | 187 var script = this.parsedScripts_[scriptId]; |
145 if (!script) { | 188 if (!script || script.isUnresolved()) { |
146 callback(null); | 189 callback(null); |
147 return; | 190 return; |
148 } | 191 } |
149 | 192 |
150 var cmd = new devtools.DebugCommand('scripts', { | 193 var cmd = new devtools.DebugCommand('scripts', { |
151 'ids': [scriptId], | 194 'ids': [scriptId], |
152 'includeSource': true | 195 'includeSource': true |
153 }); | 196 }); |
154 devtools.DebuggerAgent.sendCommand_(cmd); | 197 devtools.DebuggerAgent.sendCommand_(cmd); |
155 // Force v8 execution so that it gets to processing the requested command. | 198 // Force v8 execution so that it gets to processing the requested command. |
156 devtools.tools.evaluateJavaScript('javascript:void(0)'); | 199 devtools.tools.evaluateJavaScript(devtools.DebuggerAgent.VOID_SCRIPT); |
157 | 200 |
158 this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) { | 201 this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) { |
159 if (msg.isSuccess()) { | 202 if (msg.isSuccess()) { |
160 var scriptJson = msg.getBody()[0]; | 203 var scriptJson = msg.getBody()[0]; |
161 callback(scriptJson.source); | 204 callback(scriptJson.source); |
162 } else { | 205 } else { |
163 callback(null); | 206 callback(null); |
164 } | 207 } |
165 }; | 208 }; |
166 }; | 209 }; |
(...skipping 12 matching lines...) Expand all Loading... |
179 * @param {number} line Number of the line for the breakpoint. | 222 * @param {number} line Number of the line for the breakpoint. |
180 */ | 223 */ |
181 devtools.DebuggerAgent.prototype.addBreakpoint = function(sourceId, line) { | 224 devtools.DebuggerAgent.prototype.addBreakpoint = function(sourceId, line) { |
182 var script = this.parsedScripts_[sourceId]; | 225 var script = this.parsedScripts_[sourceId]; |
183 if (!script) { | 226 if (!script) { |
184 return; | 227 return; |
185 } | 228 } |
186 | 229 |
187 line = devtools.DebuggerAgent.webkitToV8LineNumber_(line); | 230 line = devtools.DebuggerAgent.webkitToV8LineNumber_(line); |
188 | 231 |
189 var breakpointInfo = script.getBreakpointInfo(line); | 232 var commandArguments; |
190 if (breakpointInfo) { | 233 if (script.getUrl()) { |
191 return; | 234 var breakpoints = this.urlToBreakpoints_[script.getUrl()]; |
| 235 if (breakpoints && breakpoints[line]) { |
| 236 return; |
| 237 } |
| 238 if (!breakpoints) { |
| 239 breakpoints = {}; |
| 240 this.urlToBreakpoints_[script.getUrl()] = breakpoints; |
| 241 } |
| 242 |
| 243 var breakpointInfo = new devtools.BreakpointInfo(line); |
| 244 breakpoints[line] = breakpointInfo; |
| 245 |
| 246 commandArguments = { |
| 247 'groupId': this.contextId_, |
| 248 'type': 'script', |
| 249 'target': script.getUrl(), |
| 250 'line': line |
| 251 }; |
| 252 } else { |
| 253 var breakpointInfo = script.getBreakpointInfo(line); |
| 254 if (breakpointInfo) { |
| 255 return; |
| 256 } |
| 257 |
| 258 breakpointInfo = new devtools.BreakpointInfo(line); |
| 259 script.addBreakpointInfo(breakpointInfo); |
| 260 |
| 261 commandArguments = { |
| 262 'groupId': this.contextId_, |
| 263 'type': 'scriptId', |
| 264 'target': sourceId, |
| 265 'line': line |
| 266 }; |
192 } | 267 } |
193 | 268 |
194 breakpointInfo = new devtools.BreakpointInfo(sourceId, line); | 269 var cmd = new devtools.DebugCommand('setbreakpoint', commandArguments); |
195 script.addBreakpointInfo(breakpointInfo); | |
196 | |
197 var cmd = new devtools.DebugCommand('setbreakpoint', { | |
198 'type': 'scriptId', | |
199 'target': sourceId, | |
200 'line': line | |
201 }); | |
202 | 270 |
203 this.requestNumberToBreakpointInfo_[cmd.getSequenceNumber()] = breakpointInfo; | 271 this.requestNumberToBreakpointInfo_[cmd.getSequenceNumber()] = breakpointInfo; |
204 | 272 |
205 devtools.DebuggerAgent.sendCommand_(cmd); | 273 devtools.DebuggerAgent.sendCommand_(cmd); |
206 }; | 274 }; |
207 | 275 |
208 | 276 |
209 /** | 277 /** |
210 * @param {number} sourceId Id of the script fot the breakpoint. | 278 * @param {number} sourceId Id of the script fot the breakpoint. |
211 * @param {number} line Number of the line for the breakpoint. | 279 * @param {number} line Number of the line for the breakpoint. |
212 */ | 280 */ |
213 devtools.DebuggerAgent.prototype.removeBreakpoint = function(sourceId, line) { | 281 devtools.DebuggerAgent.prototype.removeBreakpoint = function(sourceId, line) { |
214 var script = this.parsedScripts_[sourceId]; | 282 var script = this.parsedScripts_[sourceId]; |
215 if (!script) { | 283 if (!script) { |
216 return; | 284 return; |
217 } | 285 } |
218 | 286 |
219 line = devtools.DebuggerAgent.webkitToV8LineNumber_(line); | 287 line = devtools.DebuggerAgent.webkitToV8LineNumber_(line); |
220 | 288 |
221 var breakpointInfo = script.getBreakpointInfo(line); | 289 var breakpointInfo; |
222 script.removeBreakpointInfo(breakpointInfo); | 290 if (script.getUrl()) { |
| 291 var breakpoints = this.urlToBreakpoints_[script.getUrl()]; |
| 292 breakpointInfo = breakpoints[line]; |
| 293 delete breakpoints[line]; |
| 294 } else { |
| 295 breakpointInfo = script.getBreakpointInfo(line); |
| 296 if (breakpointInfo) { |
| 297 script.removeBreakpointInfo(breakpointInfo); |
| 298 } |
| 299 } |
| 300 |
| 301 if (!breakpointInfo) { |
| 302 return; |
| 303 } |
| 304 |
223 breakpointInfo.markAsRemoved(); | 305 breakpointInfo.markAsRemoved(); |
224 | 306 |
225 var id = breakpointInfo.getV8Id(); | 307 var id = breakpointInfo.getV8Id(); |
226 | 308 |
227 // If we don't know id of this breakpoint in the v8 debugger we cannot send | 309 // If we don't know id of this breakpoint in the v8 debugger we cannot send |
228 // 'clearbreakpoint' request. In that case it will be removed in | 310 // 'clearbreakpoint' request. In that case it will be removed in |
229 // 'setbreakpoint' response handler when we learn the id. | 311 // 'setbreakpoint' response handler when we learn the id. |
230 if (id != -1) { | 312 if (id != -1) { |
231 this.requestClearBreakpoint_(id); | 313 this.requestClearBreakpoint_(id); |
232 } | 314 } |
(...skipping 22 matching lines...) Expand all Loading... |
255 devtools.DebuggerAgent.prototype.stepOverStatement = function() { | 337 devtools.DebuggerAgent.prototype.stepOverStatement = function() { |
256 this.stepCommand_('next'); | 338 this.stepCommand_('next'); |
257 }; | 339 }; |
258 | 340 |
259 | 341 |
260 /** | 342 /** |
261 * Tells the v8 debugger to continue execution after it has been stopped on a | 343 * Tells the v8 debugger to continue execution after it has been stopped on a |
262 * breakpoint or an exception. | 344 * breakpoint or an exception. |
263 */ | 345 */ |
264 devtools.DebuggerAgent.prototype.resumeExecution = function() { | 346 devtools.DebuggerAgent.prototype.resumeExecution = function() { |
| 347 this.clearExceptionMessage_(); |
265 var cmd = new devtools.DebugCommand('continue'); | 348 var cmd = new devtools.DebugCommand('continue'); |
266 devtools.DebuggerAgent.sendCommand_(cmd); | 349 devtools.DebuggerAgent.sendCommand_(cmd); |
267 }; | 350 }; |
268 | 351 |
269 | 352 |
270 /** | 353 /** |
| 354 * Creates exception message and schedules it for addition to the resource upon |
| 355 * backtrace availability. |
| 356 * @param {string} url Resource url. |
| 357 * @param {number} line Resource line number. |
| 358 * @param {string} message Exception text. |
| 359 */ |
| 360 devtools.DebuggerAgent.prototype.createExceptionMessage_ = function( |
| 361 url, line, message) { |
| 362 this.currentExceptionMessage_ = new WebInspector.ConsoleMessage( |
| 363 WebInspector.ConsoleMessage.MessageSource.JS, |
| 364 WebInspector.ConsoleMessage.MessageType.Log, |
| 365 WebInspector.ConsoleMessage.MessageLevel.Error, |
| 366 line, |
| 367 url, |
| 368 0 /* group level */, |
| 369 1 /* repeat count */, |
| 370 '[Exception] ' + message); |
| 371 }; |
| 372 |
| 373 |
| 374 /** |
| 375 * Shows pending exception message that is created with createExceptionMessage_ |
| 376 * earlier. |
| 377 */ |
| 378 devtools.DebuggerAgent.prototype.showPendingExceptionMessage_ = function() { |
| 379 if (!this.currentExceptionMessage_) { |
| 380 return; |
| 381 } |
| 382 var msg = this.currentExceptionMessage_; |
| 383 var resource = WebInspector.resourceURLMap[msg.url]; |
| 384 if (resource) { |
| 385 msg.resource = resource; |
| 386 WebInspector.panels.resources.addMessageToResource(resource, msg); |
| 387 } else { |
| 388 this.currentExceptionMessage_ = null; |
| 389 } |
| 390 }; |
| 391 |
| 392 |
| 393 /** |
| 394 * Clears exception message from the resource. |
| 395 */ |
| 396 devtools.DebuggerAgent.prototype.clearExceptionMessage_ = function() { |
| 397 if (this.currentExceptionMessage_) { |
| 398 var messageElement = |
| 399 this.currentExceptionMessage_._resourceMessageLineElement; |
| 400 var bubble = messageElement.parentElement; |
| 401 bubble.removeChild(messageElement); |
| 402 if (!bubble.firstChild) { |
| 403 // Last message in bubble removed. |
| 404 bubble.parentElement.removeChild(bubble); |
| 405 } |
| 406 this.currentExceptionMessage_ = null; |
| 407 } |
| 408 }; |
| 409 |
| 410 |
| 411 /** |
271 * @return {boolean} True iff the debugger will pause execution on the | 412 * @return {boolean} True iff the debugger will pause execution on the |
272 * exceptions. | 413 * exceptions. |
273 */ | 414 */ |
274 devtools.DebuggerAgent.prototype.pauseOnExceptions = function() { | 415 devtools.DebuggerAgent.prototype.pauseOnExceptions = function() { |
275 return this.pauseOnExceptions_; | 416 return this.pauseOnExceptions_; |
276 }; | 417 }; |
277 | 418 |
278 | 419 |
279 /** | 420 /** |
280 * Tells whether to pause in the debugger on the exceptions or not. | 421 * Tells whether to pause in the debugger on the exceptions or not. |
281 * @param {boolean} value True iff execution should be stopped in the debugger | 422 * @param {boolean} value True iff execution should be stopped in the debugger |
282 * on the exceptions. | 423 * on the exceptions. |
283 */ | 424 */ |
284 devtools.DebuggerAgent.prototype.setPauseOnExceptions = function(value) { | 425 devtools.DebuggerAgent.prototype.setPauseOnExceptions = function(value) { |
285 this.pauseOnExceptions_ = value; | 426 this.pauseOnExceptions_ = value; |
286 }; | 427 }; |
287 | 428 |
288 | 429 |
289 /** | 430 /** |
290 * Current stack top frame. | |
291 * @return {devtools.CallFrame} | |
292 */ | |
293 devtools.DebuggerAgent.prototype.getCurrentCallFrame = function() { | |
294 return this.currentCallFrame_; | |
295 }; | |
296 | |
297 | |
298 /** | |
299 * Sends 'evaluate' request to the debugger. | 431 * Sends 'evaluate' request to the debugger. |
300 * @param {Object} arguments Request arguments map. | 432 * @param {Object} arguments Request arguments map. |
301 * @param {function(devtools.DebuggerMessage)} callback Callback to be called | 433 * @param {function(devtools.DebuggerMessage)} callback Callback to be called |
302 * when response is received. | 434 * when response is received. |
303 */ | 435 */ |
304 devtools.DebuggerAgent.prototype.requestEvaluate = function( | 436 devtools.DebuggerAgent.prototype.requestEvaluate = function( |
305 arguments, callback) { | 437 arguments, callback) { |
306 var cmd = new devtools.DebugCommand('evaluate', arguments); | 438 var cmd = new devtools.DebugCommand('evaluate', arguments); |
307 devtools.DebuggerAgent.sendCommand_(cmd); | 439 devtools.DebuggerAgent.sendCommand_(cmd); |
308 this.requestSeqToCallback_[cmd.getSequenceNumber()] = callback; | 440 this.requestSeqToCallback_[cmd.getSequenceNumber()] = callback; |
309 }; | 441 }; |
310 | 442 |
311 | 443 |
312 /** | 444 /** |
313 * Sends 'lookup' request for each unresolved property of the object. When | 445 * Sends 'lookup' request for each unresolved property of the object. When |
314 * response is received the properties will be changed with their resolved | 446 * response is received the properties will be changed with their resolved |
315 * values. | 447 * values. |
316 * @param {Object} object Object whose properties should be resolved. | 448 * @param {Object} object Object whose properties should be resolved. |
317 * @param {function(devtools.DebuggerMessage)} Callback to be called when all | 449 * @param {function(devtools.DebuggerMessage)} Callback to be called when all |
318 * children are resolved. | 450 * children are resolved. |
| 451 * @param {boolean} noIntrinsic Whether intrinsic properties should be included. |
319 */ | 452 */ |
320 devtools.DebuggerAgent.prototype.resolveChildren = function(object, callback) { | 453 devtools.DebuggerAgent.prototype.resolveChildren = function(object, callback, |
321 if ('ref' in object) { | 454 noIntrinsic) { |
| 455 if ('handle' in object) { |
| 456 var result = []; |
| 457 devtools.DebuggerAgent.formatObjectProperties_(object, result, |
| 458 noIntrinsic); |
| 459 callback(result); |
| 460 } else { |
322 this.requestLookup_([object.ref], function(msg) { | 461 this.requestLookup_([object.ref], function(msg) { |
323 var result = {}; | 462 var result = []; |
324 if (msg.isSuccess()) { | 463 if (msg.isSuccess()) { |
325 var handleToObject = msg.getBody(); | 464 var handleToObject = msg.getBody(); |
326 var resolved = handleToObject[object.ref]; | 465 var resolved = handleToObject[object.ref]; |
327 devtools.DebuggerAgent.formatObjectProperties_(resolved, result); | 466 devtools.DebuggerAgent.formatObjectProperties_(resolved, result, |
| 467 noIntrinsic); |
| 468 callback(result); |
328 } else { | 469 } else { |
329 result.error = 'Failed to resolve children: ' + msg.getMessage(); | 470 callback([]); |
330 } | 471 } |
331 object.resolvedValue = result; | |
332 callback(object); | |
333 }); | 472 }); |
334 | |
335 return; | |
336 } else { | |
337 if (!object.resolvedValue) { | |
338 var message = 'Corrupted object: ' + JSON.stringify(object); | |
339 object.resolvedValue = {}; | |
340 object.resolvedValue.error = message; | |
341 } | |
342 callback(object); | |
343 } | 473 } |
344 }; | 474 }; |
345 | 475 |
346 | 476 |
347 /** | 477 /** |
348 * Starts (resumes) profiling. | 478 * Sends 'scope' request for the scope object to resolve its variables. |
| 479 * @param {Object} scope Scope to be resolved. |
| 480 * @param {function(Array.<WebInspector.ObjectPropertyProxy>)} callback |
| 481 * Callback to be called when all scope variables are resolved. |
349 */ | 482 */ |
350 devtools.DebuggerAgent.prototype.startProfiling = function() { | 483 devtools.DebuggerAgent.prototype.resolveScope = function(scope, callback) { |
351 if (this.isProcessingProfile_) { | 484 var cmd = new devtools.DebugCommand('scope', { |
352 return; | 485 'frameNumber': scope.frameNumber, |
353 } | 486 'number': scope.index, |
354 RemoteDebuggerAgent.StartProfiling(); | 487 'compactFormat': true |
355 // Query if profiling has been really started. | 488 }); |
356 RemoteDebuggerAgent.IsProfilingStarted(); | 489 devtools.DebuggerAgent.sendCommand_(cmd); |
| 490 this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) { |
| 491 var result = []; |
| 492 if (msg.isSuccess()) { |
| 493 var scopeObjectJson = msg.getBody().object; |
| 494 devtools.DebuggerAgent.formatObjectProperties_(scopeObjectJson, result, |
| 495 true /* no intrinsic */); |
| 496 } |
| 497 callback(result); |
| 498 }; |
357 }; | 499 }; |
358 | 500 |
359 | 501 |
360 /** | 502 /** |
361 * Stops (pauses) profiling. | 503 * Sets up callbacks that deal with profiles processing. |
362 */ | 504 */ |
363 devtools.DebuggerAgent.prototype.stopProfiling = function() { | 505 devtools.DebuggerAgent.prototype.setupProfilerProcessorCallbacks = function() { |
364 this.isProcessingProfile_ = true; | 506 // A temporary icon indicating that the profile is being processed. |
365 RemoteDebuggerAgent.StopProfiling(); | 507 var processingIcon = new WebInspector.SidebarTreeElement( |
| 508 'profile-sidebar-tree-item', |
| 509 WebInspector.UIString('Processing...'), |
| 510 '', null, false); |
| 511 var profilesSidebar = WebInspector.panels.profiles.sidebarTree; |
| 512 |
| 513 this.profilerProcessor_.setCallbacks( |
| 514 function onProfileProcessingStarted() { |
| 515 // Set visually empty string. Subtitle hiding is done via styles |
| 516 // manipulation which doesn't play well with dynamic append / removal. |
| 517 processingIcon.subtitle = ' '; |
| 518 profilesSidebar.appendChild(processingIcon); |
| 519 }, |
| 520 function onProfileProcessingStatus(ticksCount) { |
| 521 processingIcon.subtitle = |
| 522 WebInspector.UIString('%d ticks processed', ticksCount); |
| 523 }, |
| 524 function onProfileProcessingFinished(profile) { |
| 525 profilesSidebar.removeChild(processingIcon); |
| 526 WebInspector.addProfile(profile); |
| 527 // If no profile is currently shown, show the new one. |
| 528 var profilesPanel = WebInspector.panels.profiles; |
| 529 if (!profilesPanel.visibleView) { |
| 530 profilesPanel.showProfile(profile); |
| 531 } |
| 532 } |
| 533 ); |
366 }; | 534 }; |
367 | 535 |
368 | 536 |
| 537 /** |
| 538 * Initializes profiling state. |
| 539 */ |
| 540 devtools.DebuggerAgent.prototype.initializeProfiling = function() { |
| 541 this.setupProfilerProcessorCallbacks(); |
| 542 RemoteDebuggerAgent.GetActiveProfilerModules(); |
| 543 }; |
| 544 |
| 545 |
| 546 /** |
| 547 * Starts profiling. |
| 548 * @param {number} modules List of modules to enable. |
| 549 */ |
| 550 devtools.DebuggerAgent.prototype.startProfiling = function(modules) { |
| 551 RemoteDebuggerAgent.StartProfiling(modules); |
| 552 if (modules & |
| 553 devtools.DebuggerAgent.ProfilerModules.PROFILER_MODULE_HEAP_SNAPSHOT) { |
| 554 // Active modules will not change, instead, a snapshot will be logged. |
| 555 RemoteDebuggerAgent.GetNextLogLines(); |
| 556 } else { |
| 557 RemoteDebuggerAgent.GetActiveProfilerModules(); |
| 558 } |
| 559 }; |
| 560 |
| 561 |
| 562 /** |
| 563 * Stops profiling. |
| 564 */ |
| 565 devtools.DebuggerAgent.prototype.stopProfiling = function(modules) { |
| 566 RemoteDebuggerAgent.StopProfiling(modules); |
| 567 }; |
| 568 |
| 569 |
| 570 /** |
| 571 * @param{number} scriptId |
| 572 * @return {string} Type of the context of the script with specified id. |
| 573 */ |
| 574 devtools.DebuggerAgent.prototype.getScriptContextType = function(scriptId) { |
| 575 return this.parsedScripts_[scriptId].getContextType(); |
| 576 }; |
| 577 |
| 578 |
369 /** | 579 /** |
370 * Removes specified breakpoint from the v8 debugger. | 580 * Removes specified breakpoint from the v8 debugger. |
371 * @param {number} breakpointId Id of the breakpoint in the v8 debugger. | 581 * @param {number} breakpointId Id of the breakpoint in the v8 debugger. |
372 */ | 582 */ |
373 devtools.DebuggerAgent.prototype.requestClearBreakpoint_ = function( | 583 devtools.DebuggerAgent.prototype.requestClearBreakpoint_ = function( |
374 breakpointId) { | 584 breakpointId) { |
375 var cmd = new devtools.DebugCommand('clearbreakpoint', { | 585 var cmd = new devtools.DebugCommand('clearbreakpoint', { |
376 'breakpoint': breakpointId | 586 'breakpoint': breakpointId |
377 }); | 587 }); |
378 devtools.DebuggerAgent.sendCommand_(cmd); | 588 devtools.DebuggerAgent.sendCommand_(cmd); |
(...skipping 18 matching lines...) Expand all Loading... |
397 devtools.DebuggerAgent.sendCommand_ = function(cmd) { | 607 devtools.DebuggerAgent.sendCommand_ = function(cmd) { |
398 RemoteDebuggerCommandExecutor.DebuggerCommand(cmd.toJSONProtocol()); | 608 RemoteDebuggerCommandExecutor.DebuggerCommand(cmd.toJSONProtocol()); |
399 }; | 609 }; |
400 | 610 |
401 | 611 |
402 /** | 612 /** |
403 * Tells the v8 debugger to make the next execution step. | 613 * Tells the v8 debugger to make the next execution step. |
404 * @param {string} action 'in', 'out' or 'next' action. | 614 * @param {string} action 'in', 'out' or 'next' action. |
405 */ | 615 */ |
406 devtools.DebuggerAgent.prototype.stepCommand_ = function(action) { | 616 devtools.DebuggerAgent.prototype.stepCommand_ = function(action) { |
| 617 this.clearExceptionMessage_(); |
407 var cmd = new devtools.DebugCommand('continue', { | 618 var cmd = new devtools.DebugCommand('continue', { |
408 'stepaction': action, | 619 'stepaction': action, |
409 'stepcount': 1 | 620 'stepcount': 1 |
410 }); | 621 }); |
411 devtools.DebuggerAgent.sendCommand_(cmd); | 622 devtools.DebuggerAgent.sendCommand_(cmd); |
412 }; | 623 }; |
413 | 624 |
414 | 625 |
415 /** | 626 /** |
416 * Sends 'lookup' request to v8. | 627 * Sends 'lookup' request to v8. |
417 * @param {number} handle Handle to the object to lookup. | 628 * @param {number} handle Handle to the object to lookup. |
418 */ | 629 */ |
419 devtools.DebuggerAgent.prototype.requestLookup_ = function(handles, callback) { | 630 devtools.DebuggerAgent.prototype.requestLookup_ = function(handles, callback) { |
420 var cmd = new devtools.DebugCommand('lookup', { | 631 var cmd = new devtools.DebugCommand('lookup', { |
421 'compactFormat':true, | 632 'compactFormat':true, |
422 'handles': handles | 633 'handles': handles |
423 }); | 634 }); |
424 devtools.DebuggerAgent.sendCommand_(cmd); | 635 devtools.DebuggerAgent.sendCommand_(cmd); |
425 this.requestSeqToCallback_[cmd.getSequenceNumber()] = callback; | 636 this.requestSeqToCallback_[cmd.getSequenceNumber()] = callback; |
426 }; | 637 }; |
427 | 638 |
428 | 639 |
429 /** | 640 /** |
430 * Handles GetContextId response. | 641 * Sets debugger context id for scripts filtering. |
431 * @param {number} contextId Id of the inspected page global context. | 642 * @param {number} contextId Id of the inspected page global context. |
432 */ | 643 */ |
433 devtools.DebuggerAgent.prototype.didGetContextId_ = function(contextId) { | 644 devtools.DebuggerAgent.prototype.setContextId_ = function(contextId) { |
434 this.contextId_ = contextId; | 645 this.contextId_ = contextId; |
435 // Update scripts. | |
436 this.requestScripts(); | |
437 }; | 646 }; |
438 | 647 |
439 | 648 |
440 /** | 649 /** |
441 * Handles output sent by v8 debugger. The output is either asynchronous event | 650 * Handles output sent by v8 debugger. The output is either asynchronous event |
442 * or response to a previously sent request. See protocol definitioun for more | 651 * or response to a previously sent request. See protocol definitioun for more |
443 * details on the output format. | 652 * details on the output format. |
444 * @param {string} output | 653 * @param {string} output |
445 */ | 654 */ |
446 devtools.DebuggerAgent.prototype.handleDebuggerOutput_ = function(output) { | 655 devtools.DebuggerAgent.prototype.handleDebuggerOutput_ = function(output) { |
447 var msg; | 656 var msg; |
448 try { | 657 try { |
449 msg = new devtools.DebuggerMessage(output); | 658 msg = new devtools.DebuggerMessage(output); |
450 } catch(e) { | 659 } catch(e) { |
451 debugPrint('Failed to handle debugger reponse:\n' + e); | 660 debugPrint('Failed to handle debugger reponse:\n' + e); |
452 throw e; | 661 throw e; |
453 } | 662 } |
454 | 663 |
455 | |
456 if (msg.getType() == 'event') { | 664 if (msg.getType() == 'event') { |
457 if (msg.getEvent() == 'break') { | 665 if (msg.getEvent() == 'break') { |
458 this.handleBreakEvent_(msg); | 666 this.handleBreakEvent_(msg); |
459 } else if (msg.getEvent() == 'exception') { | 667 } else if (msg.getEvent() == 'exception') { |
460 this.handleExceptionEvent_(msg); | 668 this.handleExceptionEvent_(msg); |
461 } else if (msg.getEvent() == 'afterCompile') { | 669 } else if (msg.getEvent() == 'afterCompile') { |
462 this.handleAfterCompileEvent_(msg); | 670 this.handleAfterCompileEvent_(msg); |
463 } | 671 } |
464 } else if (msg.getType() == 'response') { | 672 } else if (msg.getType() == 'response') { |
465 if (msg.getCommand() == 'scripts') { | 673 if (msg.getCommand() == 'scripts') { |
466 this.handleScriptsResponse_(msg); | 674 this.handleScriptsResponse_(msg); |
467 } else if (msg.getCommand() == 'setbreakpoint') { | 675 } else if (msg.getCommand() == 'setbreakpoint') { |
468 this.handleSetBreakpointResponse_(msg); | 676 this.handleSetBreakpointResponse_(msg); |
469 } else if (msg.getCommand() == 'clearbreakpoint') { | 677 } else if (msg.getCommand() == 'clearbreakpoint') { |
470 this.handleClearBreakpointResponse_(msg); | 678 this.handleClearBreakpointResponse_(msg); |
471 } else if (msg.getCommand() == 'backtrace') { | 679 } else if (msg.getCommand() == 'backtrace') { |
472 this.handleBacktraceResponse_(msg); | 680 this.handleBacktraceResponse_(msg); |
473 } else if (msg.getCommand() == 'lookup') { | 681 } else if (msg.getCommand() == 'lookup') { |
474 this.invokeCallbackForResponse_(msg); | 682 this.invokeCallbackForResponse_(msg); |
475 } else if (msg.getCommand() == 'evaluate') { | 683 } else if (msg.getCommand() == 'evaluate') { |
476 this.invokeCallbackForResponse_(msg); | 684 this.invokeCallbackForResponse_(msg); |
| 685 } else if (msg.getCommand() == 'scope') { |
| 686 this.invokeCallbackForResponse_(msg); |
477 } | 687 } |
478 } | 688 } |
479 }; | 689 }; |
480 | 690 |
481 | 691 |
482 /** | 692 /** |
483 * @param {devtools.DebuggerMessage} msg | 693 * @param {devtools.DebuggerMessage} msg |
484 */ | 694 */ |
485 devtools.DebuggerAgent.prototype.handleBreakEvent_ = function(msg) { | 695 devtools.DebuggerAgent.prototype.handleBreakEvent_ = function(msg) { |
| 696 // Force scrips panel to be shown first. |
| 697 WebInspector.currentPanel = WebInspector.panels.scripts; |
| 698 |
486 var body = msg.getBody(); | 699 var body = msg.getBody(); |
487 | 700 |
488 var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine); | 701 var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine); |
489 this.currentCallFrame_ = new devtools.CallFrame(); | |
490 this.currentCallFrame_.sourceID = body.script.id; | |
491 this.currentCallFrame_.line = line; | |
492 this.currentCallFrame_.script = body.script; | |
493 this.requestBacktrace_(); | 702 this.requestBacktrace_(); |
494 }; | 703 }; |
495 | 704 |
496 | 705 |
497 /** | 706 /** |
498 * @param {devtools.DebuggerMessage} msg | 707 * @param {devtools.DebuggerMessage} msg |
499 */ | 708 */ |
500 devtools.DebuggerAgent.prototype.handleExceptionEvent_ = function(msg) { | 709 devtools.DebuggerAgent.prototype.handleExceptionEvent_ = function(msg) { |
| 710 // Force scrips panel to be shown first. |
| 711 WebInspector.currentPanel = WebInspector.panels.scripts; |
| 712 |
501 var body = msg.getBody(); | 713 var body = msg.getBody(); |
502 debugPrint('Uncaught exception in ' + body.script.name + ':' + | |
503 body.sourceLine + '\n' + body.sourceLineText); | |
504 if (this.pauseOnExceptions_) { | 714 if (this.pauseOnExceptions_) { |
505 var body = msg.getBody(); | 715 var body = msg.getBody(); |
506 | |
507 var sourceId = -1; | |
508 // The exception may happen in native code in which case there is no script. | |
509 if (body.script) { | |
510 sourceId = body.script.id; | |
511 } | |
512 | |
513 var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine); | 716 var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine); |
514 | 717 this.createExceptionMessage_(body.script.name, line, body.exception.text); |
515 this.currentCallFrame_ = new devtools.CallFrame(); | |
516 this.currentCallFrame_.sourceID = sourceId; | |
517 this.currentCallFrame_.line = line; | |
518 this.currentCallFrame_.script = body.script; | |
519 this.requestBacktrace_(); | 718 this.requestBacktrace_(); |
520 } else { | 719 } else { |
521 this.resumeExecution(); | 720 this.resumeExecution(); |
522 } | 721 } |
523 }; | 722 }; |
524 | 723 |
525 | 724 |
526 /** | 725 /** |
527 * @param {devtools.DebuggerMessage} msg | 726 * @param {devtools.DebuggerMessage} msg |
528 */ | 727 */ |
529 devtools.DebuggerAgent.prototype.handleScriptsResponse_ = function(msg) { | 728 devtools.DebuggerAgent.prototype.handleScriptsResponse_ = function(msg) { |
530 if (this.invokeCallbackForResponse_(msg)) { | 729 if (this.invokeCallbackForResponse_(msg)) { |
531 return; | 730 return; |
532 } | 731 } |
533 | 732 |
534 var scripts = msg.getBody(); | 733 var scripts = msg.getBody(); |
535 for (var i = 0; i < scripts.length; i++) { | 734 for (var i = 0; i < scripts.length; i++) { |
536 var script = scripts[i]; | 735 var script = scripts[i]; |
537 | 736 |
538 // Skip scripts from other tabs. | 737 // Skip scripts from other tabs. |
539 if (!this.isScriptFromInspectedContext_(script, msg)) { | 738 if (!this.isScriptFromInspectedContext_(script, msg)) { |
540 continue; | 739 continue; |
541 } | 740 } |
542 | 741 |
| 742 // There is no script source |
| 743 if (this.isVoidScript_(script)) { |
| 744 continue; |
| 745 } |
| 746 |
543 // We may already have received the info in an afterCompile event. | 747 // We may already have received the info in an afterCompile event. |
544 if (script.id in this.parsedScripts_) { | 748 if (script.id in this.parsedScripts_) { |
545 continue; | 749 continue; |
546 } | 750 } |
547 this.addScriptInfo_(script); | 751 this.addScriptInfo_(script, msg); |
548 } | 752 } |
549 }; | 753 }; |
550 | 754 |
551 | 755 |
552 /** | 756 /** |
553 * @param {Object} script Json object representing script. | 757 * @param {Object} script Json object representing script. |
554 * @param {devtools.DebuggerMessage} msg Debugger response. | 758 * @param {devtools.DebuggerMessage} msg Debugger response. |
555 */ | 759 */ |
556 devtools.DebuggerAgent.prototype.isScriptFromInspectedContext_ = function( | 760 devtools.DebuggerAgent.prototype.isScriptFromInspectedContext_ = function( |
557 script, msg) { | 761 script, msg) { |
558 if (!script.context) { | 762 if (!script.context) { |
559 // Always ignore scripts from the utility context. | 763 // Always ignore scripts from the utility context. |
560 return false; | 764 return false; |
561 } | 765 } |
562 var context = msg.lookup(script.context.ref); | 766 var context = msg.lookup(script.context.ref); |
563 var scriptContextId = context.data; | 767 var scriptContextId = context.data; |
564 if (!goog.isDef(scriptContextId)) { | 768 if (!goog.isDef(scriptContextId)) { |
565 return false; // Always ignore scripts from the utility context. | 769 return false; // Always ignore scripts from the utility context. |
566 } | 770 } |
567 if (this.contextId_ === null) { | 771 if (this.contextId_ === null) { |
568 return true; | 772 return true; |
569 } | 773 } |
570 return (scriptContextId == this.contextId_); | 774 return (scriptContextId.value == this.contextId_); |
571 }; | 775 }; |
572 | 776 |
573 | 777 |
574 /** | 778 /** |
575 * @param {devtools.DebuggerMessage} msg | 779 * @param {devtools.DebuggerMessage} msg |
576 */ | 780 */ |
577 devtools.DebuggerAgent.prototype.handleSetBreakpointResponse_ = function(msg) { | 781 devtools.DebuggerAgent.prototype.handleSetBreakpointResponse_ = function(msg) { |
578 var requestSeq = msg.getRequestSeq(); | 782 var requestSeq = msg.getRequestSeq(); |
579 var breakpointInfo = this.requestNumberToBreakpointInfo_[requestSeq]; | 783 var breakpointInfo = this.requestNumberToBreakpointInfo_[requestSeq]; |
580 if (!breakpointInfo) { | 784 if (!breakpointInfo) { |
(...skipping 11 matching lines...) Expand all Loading... |
592 if (breakpointInfo.isRemoved()) { | 796 if (breakpointInfo.isRemoved()) { |
593 this.requestClearBreakpoint_(idInV8); | 797 this.requestClearBreakpoint_(idInV8); |
594 } | 798 } |
595 }; | 799 }; |
596 | 800 |
597 | 801 |
598 /** | 802 /** |
599 * @param {devtools.DebuggerMessage} msg | 803 * @param {devtools.DebuggerMessage} msg |
600 */ | 804 */ |
601 devtools.DebuggerAgent.prototype.handleAfterCompileEvent_ = function(msg) { | 805 devtools.DebuggerAgent.prototype.handleAfterCompileEvent_ = function(msg) { |
| 806 if (!this.contextId_) { |
| 807 // Ignore scripts delta if main request has not been issued yet. |
| 808 return; |
| 809 } |
602 var script = msg.getBody().script; | 810 var script = msg.getBody().script; |
| 811 |
| 812 if (this.isVoidScript_(script)) { |
| 813 return; |
| 814 } |
| 815 |
603 // Ignore scripts from other tabs. | 816 // Ignore scripts from other tabs. |
604 if (!this.isScriptFromInspectedContext_(script, msg)) { | 817 if (!this.isScriptFromInspectedContext_(script, msg)) { |
605 return; | 818 return; |
606 } | 819 } |
607 this.addScriptInfo_(script); | 820 this.addScriptInfo_(script, msg); |
| 821 }; |
| 822 |
| 823 |
| 824 /** |
| 825 * @param {Object} script Parsed JSON object representing script. |
| 826 * @return {boolean} Whether the script is a result of the void script |
| 827 * evaluation and should not appear in the UI. |
| 828 */ |
| 829 devtools.DebuggerAgent.prototype.isVoidScript_ = function(script) { |
| 830 return !script.name && |
| 831 (script.sourceStart == devtools.DebuggerAgent.VOID_SCRIPT || |
| 832 script.source == devtools.DebuggerAgent.VOID_SCRIPT); |
608 }; | 833 }; |
609 | 834 |
610 | 835 |
611 /** | 836 /** |
612 * Handles current profiler status. | 837 * Handles current profiler status. |
| 838 * @param {number} modules List of active (started) modules. |
613 */ | 839 */ |
614 devtools.DebuggerAgent.prototype.didIsProfilingStarted_ = function( | 840 devtools.DebuggerAgent.prototype.didGetActiveProfilerModules_ = function( |
615 is_started) { | 841 modules) { |
616 if (is_started) { | 842 var profModules = devtools.DebuggerAgent.ProfilerModules; |
| 843 var profModuleNone = profModules.PROFILER_MODULE_NONE; |
| 844 if (modules != profModuleNone && |
| 845 this.activeProfilerModules_ == profModuleNone) { |
617 // Start to query log data. | 846 // Start to query log data. |
618 RemoteDebuggerAgent.GetLogLines(this.lastProfileLogPosition_); | 847 RemoteDebuggerAgent.GetNextLogLines(); |
619 } | 848 } |
620 WebInspector.setRecordingProfile(is_started); | 849 this.activeProfilerModules_ = modules; |
| 850 // Update buttons. |
| 851 WebInspector.setRecordingProfile(modules & profModules.PROFILER_MODULE_CPU); |
| 852 if (modules != profModuleNone) { |
| 853 // Monitor profiler state. It can stop itself on buffer fill-up. |
| 854 setTimeout( |
| 855 function() { RemoteDebuggerAgent.GetActiveProfilerModules(); }, 1000); |
| 856 } |
621 }; | 857 }; |
622 | 858 |
623 | 859 |
624 /** | 860 /** |
625 * Handles a portion of a profiler log retrieved by GetLogLines call. | 861 * Handles a portion of a profiler log retrieved by GetNextLogLines call. |
626 * @param {string} log A portion of profiler log. | 862 * @param {string} log A portion of profiler log. |
627 * @param {number} newPosition The position in log file to read from | |
628 * next time. | |
629 */ | 863 */ |
630 devtools.DebuggerAgent.prototype.didGetLogLines_ = function( | 864 devtools.DebuggerAgent.prototype.didGetNextLogLines_ = function(log) { |
631 log, newPosition) { | |
632 if (log.length > 0) { | 865 if (log.length > 0) { |
633 this.profilerProcessor_.processLogChunk(log); | 866 this.profilerProcessor_.processLogChunk(log); |
634 this.lastProfileLogPosition_ = newPosition; | 867 } else if (this.activeProfilerModules_ == |
635 } else if (this.isProcessingProfile_) { | 868 devtools.DebuggerAgent.ProfilerModules.PROFILER_MODULE_NONE) { |
636 this.isProcessingProfile_ = false; | 869 // No new data and profiling is stopped---suspend log reading. |
637 WebInspector.setRecordingProfile(false); | |
638 WebInspector.addProfile(this.profilerProcessor_.createProfileForView()); | |
639 return; | 870 return; |
640 } | 871 } |
641 setTimeout(function() { RemoteDebuggerAgent.GetLogLines(newPosition); }, | 872 setTimeout(function() { RemoteDebuggerAgent.GetNextLogLines(); }, 500); |
642 this.isProcessingProfile_ ? 100 : 1000); | |
643 }; | 873 }; |
644 | 874 |
645 | 875 |
646 /** | 876 /** |
647 * Adds the script info to the local cache. This method assumes that the script | 877 * Adds the script info to the local cache. This method assumes that the script |
648 * is not in the cache yet. | 878 * is not in the cache yet. |
649 * @param {Object} script Script json object from the debugger message. | 879 * @param {Object} script Script json object from the debugger message. |
| 880 * @param {devtools.DebuggerMessage} msg Debugger message containing the script |
| 881 * data. |
650 */ | 882 */ |
651 devtools.DebuggerAgent.prototype.addScriptInfo_ = function(script) { | 883 devtools.DebuggerAgent.prototype.addScriptInfo_ = function(script, msg) { |
| 884 var context = msg.lookup(script.context.ref); |
| 885 var contextType = context.data.type; |
652 this.parsedScripts_[script.id] = new devtools.ScriptInfo( | 886 this.parsedScripts_[script.id] = new devtools.ScriptInfo( |
653 script.id, script.lineOffset); | 887 script.id, script.name, script.lineOffset, contextType); |
654 WebInspector.parsedScriptSource( | 888 if (WebInspector.panels.scripts.element.parentElement) { |
655 script.id, script.name, script.source, script.lineOffset); | 889 // Only report script as parsed after scripts panel has been shown. |
| 890 WebInspector.parsedScriptSource( |
| 891 script.id, script.name, script.source, script.lineOffset); |
| 892 } |
656 }; | 893 }; |
657 | 894 |
658 | 895 |
659 /** | 896 /** |
660 * @param {devtools.DebuggerMessage} msg | 897 * @param {devtools.DebuggerMessage} msg |
661 */ | 898 */ |
662 devtools.DebuggerAgent.prototype.handleClearBreakpointResponse_ = function( | 899 devtools.DebuggerAgent.prototype.handleClearBreakpointResponse_ = function( |
663 msg) { | 900 msg) { |
664 // Do nothing. | 901 // Do nothing. |
665 }; | 902 }; |
666 | 903 |
667 | 904 |
668 /** | 905 /** |
669 * Handles response to 'backtrace' command. | 906 * Handles response to 'backtrace' command. |
670 * @param {devtools.DebuggerMessage} msg | 907 * @param {devtools.DebuggerMessage} msg |
671 */ | 908 */ |
672 devtools.DebuggerAgent.prototype.handleBacktraceResponse_ = function(msg) { | 909 devtools.DebuggerAgent.prototype.handleBacktraceResponse_ = function(msg) { |
673 if (!this.currentCallFrame_) { | 910 var frames = msg.getBody().frames; |
674 return; | 911 this.callFrames_ = []; |
| 912 for (var i = 0; i < frames.length; ++i) { |
| 913 this.callFrames_.push(this.formatCallFrame_(frames[i])); |
675 } | 914 } |
676 | 915 WebInspector.pausedScript(this.callFrames_); |
677 var script = this.currentCallFrame_.script; | 916 this.showPendingExceptionMessage_(); |
678 | |
679 var callerFrame = null; | |
680 var f = null; | |
681 var frames = msg.getBody().frames; | |
682 for (var i = frames.length - 1; i>=0; i--) { | |
683 var nextFrame = frames[i]; | |
684 var f = devtools.DebuggerAgent.formatCallFrame_(nextFrame, script, msg); | |
685 f.frameNumber = i; | |
686 f.caller = callerFrame; | |
687 callerFrame = f; | |
688 } | |
689 | |
690 this.currentCallFrame_ = f; | |
691 | |
692 WebInspector.pausedScript(); | |
693 DevToolsHost.activateWindow(); | 917 DevToolsHost.activateWindow(); |
694 }; | 918 }; |
695 | 919 |
696 | 920 |
| 921 /** |
| 922 * Returns current suspended stack. |
| 923 */ |
| 924 devtools.DebuggerAgent.prototype.getCallFrames = function(callback) { |
| 925 return this.callFrames_; |
| 926 }; |
| 927 |
| 928 |
| 929 /** |
| 930 * Evaluates code on given callframe. |
| 931 */ |
| 932 devtools.DebuggerAgent.prototype.evaluateInCallFrame = function( |
| 933 callFrameId, code, callback) { |
| 934 var callFrame = this.callFrames_[callFrameId]; |
| 935 callFrame.evaluate_(code, callback); |
| 936 }; |
| 937 |
| 938 |
697 /** | 939 /** |
698 * Handles response to a command by invoking its callback (if any). | 940 * Handles response to a command by invoking its callback (if any). |
699 * @param {devtools.DebuggerMessage} msg | 941 * @param {devtools.DebuggerMessage} msg |
700 * @return {boolean} Whether a callback for the given message was found and | 942 * @return {boolean} Whether a callback for the given message was found and |
701 * excuted. | 943 * excuted. |
702 */ | 944 */ |
703 devtools.DebuggerAgent.prototype.invokeCallbackForResponse_ = function(msg) { | 945 devtools.DebuggerAgent.prototype.invokeCallbackForResponse_ = function(msg) { |
704 var callback = this.requestSeqToCallback_[msg.getRequestSeq()]; | 946 var callback = this.requestSeqToCallback_[msg.getRequestSeq()]; |
705 if (!callback) { | 947 if (!callback) { |
706 // It may happend if reset was called. | 948 // It may happend if reset was called. |
707 return false; | 949 return false; |
708 } | 950 } |
709 delete this.requestSeqToCallback_[msg.getRequestSeq()]; | 951 delete this.requestSeqToCallback_[msg.getRequestSeq()]; |
710 callback(msg); | 952 callback(msg); |
711 return true; | 953 return true; |
712 }; | 954 }; |
713 | 955 |
714 | 956 |
715 devtools.DebuggerAgent.prototype.evaluateInCallFrame_ = function(expression) { | |
716 }; | |
717 | |
718 | |
719 /** | 957 /** |
720 * @param {Object} stackFrame Frame json object from 'backtrace' response. | 958 * @param {Object} stackFrame Frame json object from 'backtrace' response. |
721 * @param {Object} script Script json object from 'break' event. | |
722 * @param {devtools.DebuggerMessage} msg Parsed 'backtrace' response. | |
723 * @return {!devtools.CallFrame} Object containing information related to the | 959 * @return {!devtools.CallFrame} Object containing information related to the |
724 * call frame in the format expected by ScriptsPanel and its panes. | 960 * call frame in the format expected by ScriptsPanel and its panes. |
725 */ | 961 */ |
726 devtools.DebuggerAgent.formatCallFrame_ = function(stackFrame, script, msg) { | 962 devtools.DebuggerAgent.prototype.formatCallFrame_ = function(stackFrame) { |
727 var sourceId = script.id; | |
728 | |
729 var func = stackFrame.func; | 963 var func = stackFrame.func; |
730 var sourceId = func.scriptId; | 964 var sourceId = func.scriptId; |
| 965 |
| 966 // Add service script if it does not exist. |
| 967 var existingScript = this.parsedScripts_[sourceId]; |
| 968 if (!existingScript) { |
| 969 this.parsedScripts_[sourceId] = new devtools.ScriptInfo( |
| 970 sourceId, null /* name */, 0 /* line */, 'unknown' /* type */, |
| 971 true /* unresolved */); |
| 972 WebInspector.parsedScriptSource(sourceId, null, null, 0); |
| 973 } |
| 974 |
731 var funcName = func.name || func.inferredName || '(anonymous function)'; | 975 var funcName = func.name || func.inferredName || '(anonymous function)'; |
| 976 var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(stackFrame.line); |
732 | 977 |
733 var scope = {}; | 978 // Add basic scope chain info with scope variables. |
734 | 979 var scopeChain = []; |
735 // Add arguments. | 980 var ScopeType = devtools.DebuggerAgent.ScopeType; |
736 devtools.DebuggerAgent.argumentsArrayToMap_(stackFrame.arguments, scope); | 981 for (var i = 0; i < stackFrame.scopes.length; i++) { |
737 | 982 var scope = stackFrame.scopes[i]; |
738 // Add local variables. | 983 scope.frameNumber = stackFrame.index; |
739 devtools.DebuggerAgent.propertiesToMap_(stackFrame.locals, scope); | 984 var scopeObjectProxy = new WebInspector.ObjectProxy(scope, [], 0, '', true); |
740 | 985 scopeObjectProxy.isScope = true; |
741 var thisObject = devtools.DebuggerAgent.formatObjectReference_( | 986 scopeObjectProxy.properties = {}; // TODO(pfeldman): Fix autocomplete. |
742 stackFrame.receiver); | 987 switch(scope.type) { |
743 // Add variable with name 'this' to the scope. | 988 case ScopeType.Global: |
744 scope['this'] = thisObject; | 989 scopeObjectProxy.isDocument = true; |
745 | 990 break; |
746 var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(stackFrame.line); | 991 case ScopeType.Local: |
747 var result = new devtools.CallFrame(); | 992 scopeObjectProxy.isLocal = true; |
748 result.sourceID = sourceId; | 993 scopeObjectProxy.thisObject = |
749 result.line = line; | 994 devtools.DebuggerAgent.formatObjectProxy_(stackFrame.receiver); |
750 result.type = 'function'; | 995 break; |
751 result.functionName = funcName; | 996 case ScopeType.With: |
752 result.localScope = scope; | 997 scopeObjectProxy.isWithBlock = true; |
753 result.scopeChain = [scope]; | 998 break; |
754 result.thisObject = thisObject; | 999 case ScopeType.Closure: |
755 return result; | 1000 scopeObjectProxy.isClosure = true; |
| 1001 break; |
| 1002 } |
| 1003 scopeChain.push(scopeObjectProxy); |
| 1004 } |
| 1005 return new devtools.CallFrame(stackFrame.index, 'function', funcName, |
| 1006 sourceId, line, scopeChain); |
756 }; | 1007 }; |
757 | 1008 |
758 | 1009 |
759 /** | 1010 /** |
760 * Collects properties for an object from the debugger response. | 1011 * Collects properties for an object from the debugger response. |
761 * @param {Object} object An object from the debugger protocol response. | 1012 * @param {Object} object An object from the debugger protocol response. |
762 * @param {Object} result A map to put the properties in. | 1013 * @param {Array.<WebInspector.ObjectPropertyProxy>} result An array to put the |
| 1014 * properties into. |
| 1015 * @param {boolean} noIntrinsic Whether intrinsic properties should be |
| 1016 * included. |
763 */ | 1017 */ |
764 devtools.DebuggerAgent.formatObjectProperties_ = function(object, result) { | 1018 devtools.DebuggerAgent.formatObjectProperties_ = function(object, result, |
765 devtools.DebuggerAgent.propertiesToMap_(object.properties, result); | 1019 noIntrinsic) { |
766 result.protoObject = devtools.DebuggerAgent.formatObjectReference_( | 1020 devtools.DebuggerAgent.propertiesToProxies_(object.properties, result); |
767 object.protoObject); | 1021 if (noIntrinsic) { |
768 result.prototypeObject = devtools.DebuggerAgent.formatObjectReference_( | 1022 return; |
769 object.prototypeObject); | 1023 } |
770 result.constructorFunction = devtools.DebuggerAgent.formatObjectReference_( | 1024 |
771 object.constructorFunction); | 1025 result.push(new WebInspector.ObjectPropertyProxy('__proto__', |
| 1026 devtools.DebuggerAgent.formatObjectProxy_(object.protoObject))); |
| 1027 result.push(new WebInspector.ObjectPropertyProxy('prototype', |
| 1028 devtools.DebuggerAgent.formatObjectProxy_(object.prototypeObject))); |
| 1029 result.push(new WebInspector.ObjectPropertyProxy('constructor', |
| 1030 devtools.DebuggerAgent.formatObjectProxy_(object.constructorFunction))); |
772 }; | 1031 }; |
773 | 1032 |
774 | 1033 |
775 /** | 1034 /** |
776 * For each property in 'properties' puts its name and user-friendly value into | 1035 * For each property in 'properties' creates its proxy representative. |
777 * 'map'. | |
778 * @param {Array.<Object>} properties Receiver properties or locals array from | 1036 * @param {Array.<Object>} properties Receiver properties or locals array from |
779 * 'backtrace' response. | 1037 * 'backtrace' response. |
780 * @param {Object} map Result holder. | 1038 * @param {Array.<WebInspector.ObjectPropertyProxy>} Results holder. |
781 */ | 1039 */ |
782 devtools.DebuggerAgent.propertiesToMap_ = function(properties, map) { | 1040 devtools.DebuggerAgent.propertiesToProxies_ = function(properties, result) { |
783 for (var j = 0; j < properties.length; j++) { | 1041 var map = {}; |
784 var nextValue = properties[j]; | 1042 for (var i = 0; i < properties.length; ++i) { |
785 // Skip unnamed properties. They may appear e.g. when number of actual | 1043 var property = properties[i]; |
786 // parameters is greater the that of formal. In that case the superfluous | 1044 var name = String(property.name); |
787 // parameters will be present in the arguments list as elements without | 1045 if (name in map) { |
788 // names. | 1046 continue; |
789 if (nextValue.name) { | |
790 map[nextValue.name] = | |
791 devtools.DebuggerAgent.formatObjectReference_(nextValue.value); | |
792 } | 1047 } |
| 1048 map[name] = true; |
| 1049 var value = devtools.DebuggerAgent.formatObjectProxy_(property.value); |
| 1050 var propertyProxy = new WebInspector.ObjectPropertyProxy(name, value); |
| 1051 result.push(propertyProxy); |
793 } | 1052 } |
794 }; | 1053 }; |
795 | 1054 |
796 | |
797 /** | |
798 * Puts arguments from the protocol arguments array to the map assigning names | |
799 * to the anonymous arguments. | |
800 * @param {Array.<Object>} array Arguments array from 'backtrace' response. | |
801 * @param {Object} map Result holder. | |
802 */ | |
803 devtools.DebuggerAgent.argumentsArrayToMap_ = function(array, map) { | |
804 for (var j = 0; j < array.length; j++) { | |
805 var nextValue = array[j]; | |
806 // Skip unnamed properties. They may appear e.g. when number of actual | |
807 // parameters is greater the that of formal. In that case the superfluous | |
808 // parameters will be present in the arguments list as elements without | |
809 // names. | |
810 var name = nextValue.name ? nextValue.name : '<arg #' + j + '>'; | |
811 map[name] = devtools.DebuggerAgent.formatObjectReference_(nextValue.value); | |
812 } | |
813 }; | |
814 | |
815 | 1055 |
816 /** | 1056 /** |
817 * @param {Object} v An object reference from the debugger response. | 1057 * @param {Object} v An object reference from the debugger response. |
818 * @return {*} The value representation expected by ScriptsPanel. | 1058 * @return {*} The value representation expected by ScriptsPanel. |
819 */ | 1059 */ |
820 devtools.DebuggerAgent.formatObjectReference_ = function(v) { | 1060 devtools.DebuggerAgent.formatObjectProxy_ = function(v) { |
| 1061 var description; |
| 1062 var hasChildren = false; |
821 if (v.type == 'object') { | 1063 if (v.type == 'object') { |
822 return v; | 1064 description = v.className; |
| 1065 hasChildren = true; |
823 } else if (v.type == 'function') { | 1066 } else if (v.type == 'function') { |
824 var f = function() {}; | 1067 if (v.source) { |
825 f.ref = v.ref; | 1068 description = v.source; |
826 return f; | 1069 } else { |
| 1070 description = 'function ' + v.name + '()'; |
| 1071 } |
| 1072 hasChildren = true; |
827 } else if (goog.isDef(v.value)) { | 1073 } else if (goog.isDef(v.value)) { |
828 return v.value; | 1074 description = v.value; |
829 } else if (v.type == 'undefined') { | 1075 } else if (v.type == 'undefined') { |
830 return 'undefined'; | 1076 description = 'undefined'; |
831 } else if (v.type == 'null') { | 1077 } else if (v.type == 'null') { |
832 return 'null'; | 1078 description = 'null'; |
833 } else if (v.name) { | |
834 return v.name; | |
835 } else if (v.className) { | |
836 return v.className; | |
837 } else { | 1079 } else { |
838 return '<unresolved ref: ' + v.ref + ', type: ' + v.type + '>'; | 1080 description = '<unresolved ref: ' + v.ref + ', type: ' + v.type + '>'; |
839 } | 1081 } |
| 1082 var proxy = new WebInspector.ObjectProxy(v, [], 0, description, hasChildren); |
| 1083 proxy.type = v.type; |
| 1084 proxy.isV8Ref = true; |
| 1085 return proxy; |
840 }; | 1086 }; |
841 | 1087 |
842 | 1088 |
843 /** | 1089 /** |
844 * Converts line number from Web Inspector UI(1-based) to v8(0-based). | 1090 * Converts line number from Web Inspector UI(1-based) to v8(0-based). |
845 * @param {number} line Resource line number in Web Inspector UI. | 1091 * @param {number} line Resource line number in Web Inspector UI. |
846 * @return {number} The line number in v8. | 1092 * @return {number} The line number in v8. |
847 */ | 1093 */ |
848 devtools.DebuggerAgent.webkitToV8LineNumber_ = function(line) { | 1094 devtools.DebuggerAgent.webkitToV8LineNumber_ = function(line) { |
849 return line - 1; | 1095 return line - 1; |
850 }; | 1096 }; |
851 | 1097 |
852 | 1098 |
853 /** | 1099 /** |
854 * Converts line number from v8(0-based) to Web Inspector UI(1-based). | 1100 * Converts line number from v8(0-based) to Web Inspector UI(1-based). |
855 * @param {number} line Resource line number in v8. | 1101 * @param {number} line Resource line number in v8. |
856 * @return {number} The line number in Web Inspector. | 1102 * @return {number} The line number in Web Inspector. |
857 */ | 1103 */ |
858 devtools.DebuggerAgent.v8ToWwebkitLineNumber_ = function(line) { | 1104 devtools.DebuggerAgent.v8ToWwebkitLineNumber_ = function(line) { |
859 return line + 1; | 1105 return line + 1; |
860 }; | 1106 }; |
861 | 1107 |
862 | 1108 |
863 /** | 1109 /** |
864 * @param {number} scriptId Id of the script. | 1110 * @param {number} scriptId Id of the script. |
| 1111 * @param {?string} url Script resource URL if any. |
865 * @param {number} lineOffset First line 0-based offset in the containing | 1112 * @param {number} lineOffset First line 0-based offset in the containing |
866 * document. | 1113 * document. |
| 1114 * @param {string} contextType Type of the script's context: |
| 1115 * "page" - regular script from html page |
| 1116 * "injected" - extension content script |
| 1117 * @param {bool} opt_isUnresolved If true, script will not be resolved. |
867 * @constructor | 1118 * @constructor |
868 */ | 1119 */ |
869 devtools.ScriptInfo = function(scriptId, lineOffset) { | 1120 devtools.ScriptInfo = function( |
| 1121 scriptId, url, lineOffset, contextType, opt_isUnresolved) { |
870 this.scriptId_ = scriptId; | 1122 this.scriptId_ = scriptId; |
871 this.lineOffset_ = lineOffset; | 1123 this.lineOffset_ = lineOffset; |
| 1124 this.contextType_ = contextType; |
| 1125 this.url_ = url; |
| 1126 this.isUnresolved_ = opt_isUnresolved; |
872 | 1127 |
873 this.lineToBreakpointInfo_ = {}; | 1128 this.lineToBreakpointInfo_ = {}; |
874 }; | 1129 }; |
875 | 1130 |
876 | 1131 |
877 /** | 1132 /** |
878 * @return {number} | 1133 * @return {number} |
879 */ | 1134 */ |
880 devtools.ScriptInfo.prototype.getLineOffset = function() { | 1135 devtools.ScriptInfo.prototype.getLineOffset = function() { |
881 return this.lineOffset_; | 1136 return this.lineOffset_; |
882 }; | 1137 }; |
883 | 1138 |
884 | 1139 |
885 /** | 1140 /** |
| 1141 * @return {string} |
| 1142 */ |
| 1143 devtools.ScriptInfo.prototype.getContextType = function() { |
| 1144 return this.contextType_; |
| 1145 }; |
| 1146 |
| 1147 |
| 1148 /** |
| 1149 * @return {?string} |
| 1150 */ |
| 1151 devtools.ScriptInfo.prototype.getUrl = function() { |
| 1152 return this.url_; |
| 1153 }; |
| 1154 |
| 1155 |
| 1156 /** |
| 1157 * @return {?bool} |
| 1158 */ |
| 1159 devtools.ScriptInfo.prototype.isUnresolved = function() { |
| 1160 return this.isUnresolved_; |
| 1161 }; |
| 1162 |
| 1163 |
| 1164 /** |
886 * @param {number} line 0-based line number in the script. | 1165 * @param {number} line 0-based line number in the script. |
887 * @return {?devtools.BreakpointInfo} Information on a breakpoint at the | 1166 * @return {?devtools.BreakpointInfo} Information on a breakpoint at the |
888 * specified line in the script or undefined if there is no breakpoint at | 1167 * specified line in the script or undefined if there is no breakpoint at |
889 * that line. | 1168 * that line. |
890 */ | 1169 */ |
891 devtools.ScriptInfo.prototype.getBreakpointInfo = function(line) { | 1170 devtools.ScriptInfo.prototype.getBreakpointInfo = function(line) { |
892 return this.lineToBreakpointInfo_[line]; | 1171 return this.lineToBreakpointInfo_[line]; |
893 }; | 1172 }; |
894 | 1173 |
895 | 1174 |
(...skipping 10 matching lines...) Expand all Loading... |
906 * @param {devtools.BreakpointInfo} breakpoint Breakpoint info to be removed. | 1185 * @param {devtools.BreakpointInfo} breakpoint Breakpoint info to be removed. |
907 */ | 1186 */ |
908 devtools.ScriptInfo.prototype.removeBreakpointInfo = function(breakpoint) { | 1187 devtools.ScriptInfo.prototype.removeBreakpointInfo = function(breakpoint) { |
909 var line = breakpoint.getLine(); | 1188 var line = breakpoint.getLine(); |
910 delete this.lineToBreakpointInfo_[line]; | 1189 delete this.lineToBreakpointInfo_[line]; |
911 }; | 1190 }; |
912 | 1191 |
913 | 1192 |
914 | 1193 |
915 /** | 1194 /** |
916 * @param {number} scriptId Id of the owning script. | |
917 * @param {number} line Breakpoint 0-based line number in the containing script. | 1195 * @param {number} line Breakpoint 0-based line number in the containing script. |
918 * @constructor | 1196 * @constructor |
919 */ | 1197 */ |
920 devtools.BreakpointInfo = function(sourceId, line) { | 1198 devtools.BreakpointInfo = function(line) { |
921 this.sourceId_ = sourceId; | |
922 this.line_ = line; | 1199 this.line_ = line; |
923 this.v8id_ = -1; | 1200 this.v8id_ = -1; |
924 this.removed_ = false; | 1201 this.removed_ = false; |
925 }; | 1202 }; |
926 | 1203 |
927 | 1204 |
928 /** | 1205 /** |
929 * @return {number} | 1206 * @return {number} |
930 */ | 1207 */ |
931 devtools.BreakpointInfo.prototype.getSourceId = function(n) { | |
932 return this.sourceId_; | |
933 }; | |
934 | |
935 | |
936 /** | |
937 * @return {number} | |
938 */ | |
939 devtools.BreakpointInfo.prototype.getLine = function(n) { | 1208 devtools.BreakpointInfo.prototype.getLine = function(n) { |
940 return this.line_; | 1209 return this.line_; |
941 }; | 1210 }; |
942 | 1211 |
943 | 1212 |
944 /** | 1213 /** |
945 * @return {number} Unique identifier of this breakpoint in the v8 debugger. | 1214 * @return {number} Unique identifier of this breakpoint in the v8 debugger. |
946 */ | 1215 */ |
947 devtools.BreakpointInfo.prototype.getV8Id = function(n) { | 1216 devtools.BreakpointInfo.prototype.getV8Id = function(n) { |
948 return this.v8id_; | 1217 return this.v8id_; |
(...skipping 21 matching lines...) Expand all Loading... |
970 * @return {boolean} Whether this breakpoint has been removed from the | 1239 * @return {boolean} Whether this breakpoint has been removed from the |
971 * front-end. | 1240 * front-end. |
972 */ | 1241 */ |
973 devtools.BreakpointInfo.prototype.isRemoved = function() { | 1242 devtools.BreakpointInfo.prototype.isRemoved = function() { |
974 return this.removed_; | 1243 return this.removed_; |
975 }; | 1244 }; |
976 | 1245 |
977 | 1246 |
978 /** | 1247 /** |
979 * Call stack frame data. | 1248 * Call stack frame data. |
| 1249 * @param {string} id CallFrame id. |
| 1250 * @param {string} type CallFrame type. |
| 1251 * @param {string} functionName CallFrame type. |
| 1252 * @param {string} sourceID Source id. |
| 1253 * @param {number} line Source line. |
| 1254 * @param {Array.<Object>} scopeChain Array of scoped objects. |
980 * @construnctor | 1255 * @construnctor |
981 */ | 1256 */ |
982 devtools.CallFrame = function() { | 1257 devtools.CallFrame = function(id, type, functionName, sourceID, line, |
983 this.sourceID = null; | 1258 scopeChain) { |
984 this.line = null; | 1259 this.id = id; |
985 this.type = 'function'; | 1260 this.type = type; |
986 this.functionName = null; | 1261 this.functionName = functionName; |
987 this.caller = null; | 1262 this.sourceID = sourceID; |
988 this.localScope = null; | 1263 this.line = line; |
989 this.scopeChain = []; | 1264 this.scopeChain = scopeChain; |
990 this.thisObject = {}; | |
991 this.frameNumber = null; | |
992 }; | 1265 }; |
993 | 1266 |
994 | 1267 |
995 /** | 1268 /** |
996 * This method is called by | 1269 * This method issues asynchronous evaluate request, reports result to the |
997 * WebInspector.ScriptsPanel.evaluateInSelectedCallFrame. This method issues | 1270 * callback. |
998 * asynchronous evaluate request. | |
999 * @param {string} expression An expression to be evaluated in the context of | 1271 * @param {string} expression An expression to be evaluated in the context of |
1000 * this call frame. | 1272 * this call frame. |
1001 * @return {string} User message that the expression is being evaluated. | 1273 * @param {function(Object):undefined} callback Callback to report result to. |
1002 */ | 1274 */ |
1003 devtools.CallFrame.prototype.evaluate = function(expression) { | 1275 devtools.CallFrame.prototype.evaluate_ = function(expression, callback) { |
1004 devtools.tools.getDebuggerAgent().requestEvaluate({ | 1276 devtools.tools.getDebuggerAgent().requestEvaluate({ |
1005 'expression': expression, | 1277 'expression': expression, |
1006 'frame': this.frameNumber, | 1278 'frame': this.id, |
1007 'global': false, | 1279 'global': false, |
1008 'disable_break': false | 1280 'disable_break': false, |
1009 }, | 1281 'compactFormat': true |
1010 devtools.CallFrame.handleEvaluateResponse_); | 1282 }, |
1011 return 'evaluating...'; | 1283 function(response) { |
| 1284 var result = {}; |
| 1285 if (response.isSuccess()) { |
| 1286 result.value = devtools.DebuggerAgent.formatObjectProxy_( |
| 1287 response.getBody()); |
| 1288 } else { |
| 1289 result.value = response.getMessage(); |
| 1290 result.isException = true; |
| 1291 } |
| 1292 callback(result); |
| 1293 }); |
1012 }; | 1294 }; |
1013 | 1295 |
1014 | 1296 |
1015 /** | |
1016 * Handles 'evaluate' response for a call frame | |
1017 * @param {devtools.DebuggerMessage} response | |
1018 */ | |
1019 devtools.CallFrame.handleEvaluateResponse_ = function(response) { | |
1020 var body = response.getBody(); | |
1021 var value = devtools.DebuggerAgent.formatObjectReference_(body); | |
1022 WebInspector.addMessageToConsole(new WebInspector.ConsoleCommandResult( | |
1023 value, false /* exception */, null /* commandMessage */)); | |
1024 }; | |
1025 | |
1026 | |
1027 /** | 1297 /** |
1028 * JSON based commands sent to v8 debugger. | 1298 * JSON based commands sent to v8 debugger. |
1029 * @param {string} command Name of the command to execute. | 1299 * @param {string} command Name of the command to execute. |
1030 * @param {Object} opt_arguments Command-specific arguments map. | 1300 * @param {Object} opt_arguments Command-specific arguments map. |
1031 * @constructor | 1301 * @constructor |
1032 */ | 1302 */ |
1033 devtools.DebugCommand = function(command, opt_arguments) { | 1303 devtools.DebugCommand = function(command, opt_arguments) { |
1034 this.command_ = command; | 1304 this.command_ = command; |
1035 this.type_ = 'request'; | 1305 this.type_ = 'request'; |
1036 this.seq_ = ++devtools.DebugCommand.nextSeq_; | 1306 this.seq_ = ++devtools.DebugCommand.nextSeq_; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1071 }; | 1341 }; |
1072 | 1342 |
1073 | 1343 |
1074 /** | 1344 /** |
1075 * JSON messages sent from v8 debugger. See protocol definition for more | 1345 * JSON messages sent from v8 debugger. See protocol definition for more |
1076 * details: http://code.google.com/p/v8/wiki/DebuggerProtocol | 1346 * details: http://code.google.com/p/v8/wiki/DebuggerProtocol |
1077 * @param {string} msg Raw protocol packet as JSON string. | 1347 * @param {string} msg Raw protocol packet as JSON string. |
1078 * @constructor | 1348 * @constructor |
1079 */ | 1349 */ |
1080 devtools.DebuggerMessage = function(msg) { | 1350 devtools.DebuggerMessage = function(msg) { |
1081 var jsExpression = '[' + msg + '][0]'; | 1351 this.packet_ = JSON.parse(msg); |
1082 this.packet_ = eval(jsExpression); | |
1083 this.refs_ = []; | 1352 this.refs_ = []; |
1084 if (this.packet_.refs) { | 1353 if (this.packet_.refs) { |
1085 for (var i = 0; i < this.packet_.refs.length; i++) { | 1354 for (var i = 0; i < this.packet_.refs.length; i++) { |
1086 this.refs_[this.packet_.refs[i].handle] = this.packet_.refs[i]; | 1355 this.refs_[this.packet_.refs[i].handle] = this.packet_.refs[i]; |
1087 } | 1356 } |
1088 } | 1357 } |
1089 }; | 1358 }; |
1090 | 1359 |
1091 | 1360 |
1092 /** | 1361 /** |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 | 1424 |
1156 | 1425 |
1157 /** | 1426 /** |
1158 * @param {number} handle Object handle. | 1427 * @param {number} handle Object handle. |
1159 * @return {?Object} Returns the object with the handle if it was sent in this | 1428 * @return {?Object} Returns the object with the handle if it was sent in this |
1160 * message(some objects referenced by handles may be missing in the message). | 1429 * message(some objects referenced by handles may be missing in the message). |
1161 */ | 1430 */ |
1162 devtools.DebuggerMessage.prototype.lookup = function(handle) { | 1431 devtools.DebuggerMessage.prototype.lookup = function(handle) { |
1163 return this.refs_[handle]; | 1432 return this.refs_[handle]; |
1164 }; | 1433 }; |
OLD | NEW |