Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Side by Side Diff: resources/inspector/debugger_agent.js

Issue 853002: Updating the Chromium reference build for Windows. The continuous... (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/reference_builds/chrome/
Patch Set: Added the symbol files back. Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « resources/inspector/csvparser.js ('k') | resources/inspector/devtools.css » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 /**
6 * @fileoverview Provides communication interface to remote v8 debugger. See
7 * protocol decription at http://code.google.com/p/v8/wiki/DebuggerProtocol
8 */
9 goog.provide('devtools.DebuggerAgent');
10
11
12 /**
13 * @constructor
14 */
15 devtools.DebuggerAgent = function() {
16 RemoteDebuggerAgent.DebuggerOutput =
17 goog.bind(this.handleDebuggerOutput_, this);
18 RemoteDebuggerAgent.SetContextId =
19 goog.bind(this.setContextId_, this);
20 RemoteDebuggerAgent.DidGetActiveProfilerModules =
21 goog.bind(this.didGetActiveProfilerModules_, this);
22 RemoteDebuggerAgent.DidGetNextLogLines =
23 goog.bind(this.didGetNextLogLines_, this);
24
25 /**
26 * Id of the inspected page global context. It is used for filtering scripts.
27 * @type {number}
28 */
29 this.contextId_ = null;
30
31 /**
32 * Mapping from script id to script info.
33 * @type {Object}
34 */
35 this.parsedScripts_ = null;
36
37 /**
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
40 * 'setbreakpoint' responses to learn their ids in the v8 debugger.
41 * @see #handleSetBreakpointResponse_
42 * @type {Object}
43 */
44 this.requestNumberToBreakpointInfo_ = null;
45
46 /**
47 * Information on current stack frames.
48 * @type {Array.<devtools.CallFrame>}
49 */
50 this.callFrames_ = [];
51
52 /**
53 * Whether to stop in the debugger on the exceptions.
54 * @type {boolean}
55 */
56 this.pauseOnExceptions_ = true;
57
58 /**
59 * Mapping: request sequence number->callback.
60 * @type {Object}
61 */
62 this.requestSeqToCallback_ = null;
63
64 /**
65 * Whether the scripts list has been requested.
66 * @type {boolean}
67 */
68 this.scriptsCacheInitialized_ = false;
69
70 /**
71 * Whether the scripts list should be requested next time when context id is
72 * set.
73 * @type {boolean}
74 */
75 this.requestScriptsWhenContextIdSet_ = false;
76
77 /**
78 * Active profiler modules flags.
79 * @type {number}
80 */
81 this.activeProfilerModules_ =
82 devtools.DebuggerAgent.ProfilerModules.PROFILER_MODULE_NONE;
83
84 /**
85 * Profiler processor instance.
86 * @type {devtools.profiler.Processor}
87 */
88 this.profilerProcessor_ = new devtools.profiler.Processor();
89
90 /**
91 * Container of all breakpoints set using resource URL. These breakpoints
92 * survive page reload. Breakpoints set by script id(for scripts that don't
93 * have URLs) are stored in ScriptInfo objects.
94 * @type {Object}
95 */
96 this.urlToBreakpoints_ = {};
97
98
99 /**
100 * Exception message that is shown to user while on exception break.
101 * @type {WebInspector.ConsoleMessage}
102 */
103 this.currentExceptionMessage_ = null;
104 };
105
106
107 /**
108 * A copy of the scope types from v8/src/mirror-delay.js
109 * @enum {number}
110 */
111 devtools.DebuggerAgent.ScopeType = {
112 Global: 0,
113 Local: 1,
114 With: 2,
115 Closure: 3,
116 Catch: 4
117 };
118
119
120 /**
121 * A copy of enum from include/v8.h
122 * @enum {number}
123 */
124 devtools.DebuggerAgent.ProfilerModules = {
125 PROFILER_MODULE_NONE: 0,
126 PROFILER_MODULE_CPU: 1,
127 PROFILER_MODULE_HEAP_STATS: 1 << 1,
128 PROFILER_MODULE_JS_CONSTRUCTORS: 1 << 2,
129 PROFILER_MODULE_HEAP_SNAPSHOT: 1 << 16
130 };
131
132
133 /**
134 * Resets debugger agent to its initial state.
135 */
136 devtools.DebuggerAgent.prototype.reset = function() {
137 this.contextId_ = null;
138 // No need to request scripts since they all will be pushed in AfterCompile
139 // events.
140 this.requestScriptsWhenContextIdSet_ = false;
141 this.parsedScripts_ = {};
142 this.requestNumberToBreakpointInfo_ = {};
143 this.callFrames_ = [];
144 this.requestSeqToCallback_ = {};
145
146 // Profiler isn't reset because it contains no data that is
147 // specific for a particular V8 instance. All such data is
148 // managed by an agent on the Render's side.
149 };
150
151
152 /**
153 * Initializes scripts UI. This method is called every time Scripts panel
154 * is shown. It will send request for context id if it's not set yet.
155 */
156 devtools.DebuggerAgent.prototype.initUI = function() {
157 // Initialize scripts cache when Scripts panel is shown first time.
158 if (this.scriptsCacheInitialized_) {
159 return;
160 }
161 this.scriptsCacheInitialized_ = true;
162 if (this.contextId_) {
163 // We already have context id. This means that we are here from the
164 // very beginning of the page load cycle and hence will get all scripts
165 // via after-compile events. No need to request scripts for this session.
166 return;
167 }
168 // Script list should be requested only when current context id is known.
169 RemoteDebuggerAgent.GetContextId();
170 this.requestScriptsWhenContextIdSet_ = true;
171 };
172
173
174 /**
175 * Asynchronously requests the debugger for the script source.
176 * @param {number} scriptId Id of the script whose source should be resolved.
177 * @param {function(source:?string):void} callback Function that will be called
178 * when the source resolution is completed. 'source' parameter will be null
179 * if the resolution fails.
180 */
181 devtools.DebuggerAgent.prototype.resolveScriptSource = function(
182 scriptId, callback) {
183 var script = this.parsedScripts_[scriptId];
184 if (!script || script.isUnresolved()) {
185 callback(null);
186 return;
187 }
188
189 var cmd = new devtools.DebugCommand('scripts', {
190 'ids': [scriptId],
191 'includeSource': true
192 });
193 devtools.DebuggerAgent.sendCommand_(cmd);
194 // Force v8 execution so that it gets to processing the requested command.
195 RemoteToolsAgent.ExecuteVoidJavaScript();
196
197 this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) {
198 if (msg.isSuccess()) {
199 var scriptJson = msg.getBody()[0];
200 callback(scriptJson.source);
201 } else {
202 callback(null);
203 }
204 };
205 };
206
207
208 /**
209 * Tells the v8 debugger to stop on as soon as possible.
210 */
211 devtools.DebuggerAgent.prototype.pauseExecution = function() {
212 RemoteDebuggerAgent.DebugBreak();
213 };
214
215
216 /**
217 * @param {number} sourceId Id of the script fot the breakpoint.
218 * @param {number} line Number of the line for the breakpoint.
219 * @param {?string} condition The breakpoint condition.
220 */
221 devtools.DebuggerAgent.prototype.addBreakpoint = function(
222 sourceId, line, condition) {
223 var script = this.parsedScripts_[sourceId];
224 if (!script) {
225 return;
226 }
227
228 line = devtools.DebuggerAgent.webkitToV8LineNumber_(line);
229
230 var commandArguments;
231 if (script.getUrl()) {
232 var breakpoints = this.urlToBreakpoints_[script.getUrl()];
233 if (breakpoints && breakpoints[line]) {
234 return;
235 }
236 if (!breakpoints) {
237 breakpoints = {};
238 this.urlToBreakpoints_[script.getUrl()] = breakpoints;
239 }
240
241 var breakpointInfo = new devtools.BreakpointInfo(line);
242 breakpoints[line] = breakpointInfo;
243
244 commandArguments = {
245 'groupId': this.contextId_,
246 'type': 'script',
247 'target': script.getUrl(),
248 'line': line,
249 'condition': condition
250 };
251 } else {
252 var breakpointInfo = script.getBreakpointInfo(line);
253 if (breakpointInfo) {
254 return;
255 }
256
257 breakpointInfo = new devtools.BreakpointInfo(line);
258 script.addBreakpointInfo(breakpointInfo);
259
260 commandArguments = {
261 'groupId': this.contextId_,
262 'type': 'scriptId',
263 'target': sourceId,
264 'line': line,
265 'condition': condition
266 };
267 }
268
269 var cmd = new devtools.DebugCommand('setbreakpoint', commandArguments);
270
271 this.requestNumberToBreakpointInfo_[cmd.getSequenceNumber()] = breakpointInfo;
272
273 devtools.DebuggerAgent.sendCommand_(cmd);
274 // Force v8 execution so that it gets to processing the requested command.
275 // It is necessary for being able to change a breakpoint just after it
276 // has been created (since we need an existing breakpoint id for that).
277 RemoteToolsAgent.ExecuteVoidJavaScript();
278 };
279
280
281 /**
282 * @param {number} sourceId Id of the script for the breakpoint.
283 * @param {number} line Number of the line for the breakpoint.
284 */
285 devtools.DebuggerAgent.prototype.removeBreakpoint = function(sourceId, line) {
286 var script = this.parsedScripts_[sourceId];
287 if (!script) {
288 return;
289 }
290
291 line = devtools.DebuggerAgent.webkitToV8LineNumber_(line);
292
293 var breakpointInfo;
294 if (script.getUrl()) {
295 var breakpoints = this.urlToBreakpoints_[script.getUrl()];
296 breakpointInfo = breakpoints[line];
297 delete breakpoints[line];
298 } else {
299 breakpointInfo = script.getBreakpointInfo(line);
300 if (breakpointInfo) {
301 script.removeBreakpointInfo(breakpointInfo);
302 }
303 }
304
305 if (!breakpointInfo) {
306 return;
307 }
308
309 breakpointInfo.markAsRemoved();
310
311 var id = breakpointInfo.getV8Id();
312
313 // If we don't know id of this breakpoint in the v8 debugger we cannot send
314 // 'clearbreakpoint' request. In that case it will be removed in
315 // 'setbreakpoint' response handler when we learn the id.
316 if (id != -1) {
317 this.requestClearBreakpoint_(id);
318 }
319 };
320
321
322 /**
323 * @param {number} sourceId Id of the script for the breakpoint.
324 * @param {number} line Number of the line for the breakpoint.
325 * @param {?string} condition New breakpoint condition.
326 */
327 devtools.DebuggerAgent.prototype.updateBreakpoint = function(
328 sourceId, line, condition) {
329 var script = this.parsedScripts_[sourceId];
330 if (!script) {
331 return;
332 }
333
334 line = devtools.DebuggerAgent.webkitToV8LineNumber_(line);
335
336 var breakpointInfo;
337 if (script.getUrl()) {
338 var breakpoints = this.urlToBreakpoints_[script.getUrl()];
339 breakpointInfo = breakpoints[line];
340 } else {
341 breakpointInfo = script.getBreakpointInfo(line);
342 }
343
344 var id = breakpointInfo.getV8Id();
345
346 // If we don't know id of this breakpoint in the v8 debugger we cannot send
347 // the 'changebreakpoint' request.
348 if (id != -1) {
349 // TODO(apavlov): make use of the real values for 'enabled' and
350 // 'ignoreCount' when appropriate.
351 this.requestChangeBreakpoint_(id, true, condition, null);
352 }
353 };
354
355
356 /**
357 * Tells the v8 debugger to step into the next statement.
358 */
359 devtools.DebuggerAgent.prototype.stepIntoStatement = function() {
360 this.stepCommand_('in');
361 };
362
363
364 /**
365 * Tells the v8 debugger to step out of current function.
366 */
367 devtools.DebuggerAgent.prototype.stepOutOfFunction = function() {
368 this.stepCommand_('out');
369 };
370
371
372 /**
373 * Tells the v8 debugger to step over the next statement.
374 */
375 devtools.DebuggerAgent.prototype.stepOverStatement = function() {
376 this.stepCommand_('next');
377 };
378
379
380 /**
381 * Tells the v8 debugger to continue execution after it has been stopped on a
382 * breakpoint or an exception.
383 */
384 devtools.DebuggerAgent.prototype.resumeExecution = function() {
385 this.clearExceptionMessage_();
386 var cmd = new devtools.DebugCommand('continue');
387 devtools.DebuggerAgent.sendCommand_(cmd);
388 };
389
390
391 /**
392 * Creates exception message and schedules it for addition to the resource upon
393 * backtrace availability.
394 * @param {string} url Resource url.
395 * @param {number} line Resource line number.
396 * @param {string} message Exception text.
397 */
398 devtools.DebuggerAgent.prototype.createExceptionMessage_ = function(
399 url, line, message) {
400 this.currentExceptionMessage_ = new WebInspector.ConsoleMessage(
401 WebInspector.ConsoleMessage.MessageSource.JS,
402 WebInspector.ConsoleMessage.MessageType.Log,
403 WebInspector.ConsoleMessage.MessageLevel.Error,
404 line,
405 url,
406 0 /* group level */,
407 1 /* repeat count */,
408 '[Exception] ' + message);
409 };
410
411
412 /**
413 * Shows pending exception message that is created with createExceptionMessage_
414 * earlier.
415 */
416 devtools.DebuggerAgent.prototype.showPendingExceptionMessage_ = function() {
417 if (!this.currentExceptionMessage_) {
418 return;
419 }
420 var msg = this.currentExceptionMessage_;
421 var resource = WebInspector.resourceURLMap[msg.url];
422 if (resource) {
423 msg.resource = resource;
424 WebInspector.panels.resources.addMessageToResource(resource, msg);
425 } else {
426 this.currentExceptionMessage_ = null;
427 }
428 };
429
430
431 /**
432 * Clears exception message from the resource.
433 */
434 devtools.DebuggerAgent.prototype.clearExceptionMessage_ = function() {
435 if (this.currentExceptionMessage_) {
436 var messageElement =
437 this.currentExceptionMessage_._resourceMessageLineElement;
438 var bubble = messageElement.parentElement;
439 bubble.removeChild(messageElement);
440 if (!bubble.firstChild) {
441 // Last message in bubble removed.
442 bubble.parentElement.removeChild(bubble);
443 }
444 this.currentExceptionMessage_ = null;
445 }
446 };
447
448
449 /**
450 * @return {boolean} True iff the debugger will pause execution on the
451 * exceptions.
452 */
453 devtools.DebuggerAgent.prototype.pauseOnExceptions = function() {
454 return this.pauseOnExceptions_;
455 };
456
457
458 /**
459 * Tells whether to pause in the debugger on the exceptions or not.
460 * @param {boolean} value True iff execution should be stopped in the debugger
461 * on the exceptions.
462 */
463 devtools.DebuggerAgent.prototype.setPauseOnExceptions = function(value) {
464 this.pauseOnExceptions_ = value;
465 };
466
467
468 /**
469 * Sends 'evaluate' request to the debugger.
470 * @param {Object} arguments Request arguments map.
471 * @param {function(devtools.DebuggerMessage)} callback Callback to be called
472 * when response is received.
473 */
474 devtools.DebuggerAgent.prototype.requestEvaluate = function(
475 arguments, callback) {
476 var cmd = new devtools.DebugCommand('evaluate', arguments);
477 devtools.DebuggerAgent.sendCommand_(cmd);
478 this.requestSeqToCallback_[cmd.getSequenceNumber()] = callback;
479 };
480
481
482 /**
483 * Sends 'lookup' request for each unresolved property of the object. When
484 * response is received the properties will be changed with their resolved
485 * values.
486 * @param {Object} object Object whose properties should be resolved.
487 * @param {function(devtools.DebuggerMessage)} Callback to be called when all
488 * children are resolved.
489 * @param {boolean} noIntrinsic Whether intrinsic properties should be included.
490 */
491 devtools.DebuggerAgent.prototype.resolveChildren = function(object, callback,
492 noIntrinsic) {
493 if ('handle' in object) {
494 var result = [];
495 devtools.DebuggerAgent.formatObjectProperties_(object, result,
496 noIntrinsic);
497 callback(result);
498 } else {
499 this.requestLookup_([object.ref], function(msg) {
500 var result = [];
501 if (msg.isSuccess()) {
502 var handleToObject = msg.getBody();
503 var resolved = handleToObject[object.ref];
504 devtools.DebuggerAgent.formatObjectProperties_(resolved, result,
505 noIntrinsic);
506 callback(result);
507 } else {
508 callback([]);
509 }
510 });
511 }
512 };
513
514
515 /**
516 * Sends 'scope' request for the scope object to resolve its variables.
517 * @param {Object} scope Scope to be resolved.
518 * @param {function(Array.<WebInspector.ObjectPropertyProxy>)} callback
519 * Callback to be called when all scope variables are resolved.
520 */
521 devtools.DebuggerAgent.prototype.resolveScope = function(scope, callback) {
522 var cmd = new devtools.DebugCommand('scope', {
523 'frameNumber': scope.frameNumber,
524 'number': scope.index,
525 'compactFormat': true
526 });
527 devtools.DebuggerAgent.sendCommand_(cmd);
528 this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) {
529 var result = [];
530 if (msg.isSuccess()) {
531 var scopeObjectJson = msg.getBody().object;
532 devtools.DebuggerAgent.formatObjectProperties_(scopeObjectJson, result,
533 true /* no intrinsic */);
534 }
535 callback(result);
536 };
537 };
538
539
540 /**
541 * Sends 'scopes' request for the frame object to resolve all variables
542 * available in the frame.
543 * @param {number} callFrameId Id of call frame whose variables need to
544 * be resolved.
545 * @param {function(Object)} callback Callback to be called when all frame
546 * variables are resolved.
547 */
548 devtools.DebuggerAgent.prototype.resolveFrameVariables_ = function(
549 callFrameId, callback) {
550 var result = {};
551
552 var frame = this.callFrames_[callFrameId];
553 if (!frame) {
554 callback(result);
555 return;
556 }
557
558 var waitingResponses = 0;
559 function scopeResponseHandler(msg) {
560 waitingResponses--;
561
562 if (msg.isSuccess()) {
563 var properties = msg.getBody().object.properties;
564 for (var j = 0; j < properties.length; j++) {
565 result[properties[j].name] = true;
566 }
567 }
568
569 // When all scopes are resolved invoke the callback.
570 if (waitingResponses == 0) {
571 callback(result);
572 }
573 };
574
575 for (var i = 0; i < frame.scopeChain.length; i++) {
576 var scope = frame.scopeChain[i].objectId;
577 if (scope.type == devtools.DebuggerAgent.ScopeType.Global) {
578 // Do not resolve global scope since it takes for too long.
579 // TODO(yurys): allow to send only property names in the response.
580 continue;
581 }
582 var cmd = new devtools.DebugCommand('scope', {
583 'frameNumber': scope.frameNumber,
584 'number': scope.index,
585 'compactFormat': true
586 });
587 devtools.DebuggerAgent.sendCommand_(cmd);
588 this.requestSeqToCallback_[cmd.getSequenceNumber()] =
589 scopeResponseHandler;
590 waitingResponses++;
591 }
592 };
593
594 /**
595 * Evaluates the expressionString to an object in the call frame and reports
596 * all its properties.
597 * @param{string} expressionString Expression whose properties should be
598 * collected.
599 * @param{number} callFrameId The frame id.
600 * @param{function(Object result,bool isException)} reportCompletions Callback
601 * function.
602 */
603 devtools.DebuggerAgent.prototype.resolveCompletionsOnFrame = function(
604 expressionString, callFrameId, reportCompletions) {
605 if (expressionString) {
606 expressionString = 'var obj = ' + expressionString +
607 '; var names = {}; for (var n in obj) { names[n] = true; };' +
608 'names;';
609 this.evaluateInCallFrame(
610 callFrameId,
611 expressionString,
612 function(result) {
613 var names = {};
614 if (!result.isException) {
615 var props = result.value.objectId.properties;
616 // Put all object properties into the map.
617 for (var i = 0; i < props.length; i++) {
618 names[props[i].name] = true;
619 }
620 }
621 reportCompletions(names, result.isException);
622 });
623 } else {
624 this.resolveFrameVariables_(callFrameId,
625 function(result) {
626 reportCompletions(result, false /* isException */);
627 });
628 }
629 };
630
631
632 /**
633 * Sets up callbacks that deal with profiles processing.
634 */
635 devtools.DebuggerAgent.prototype.setupProfilerProcessorCallbacks = function() {
636 // A temporary icon indicating that the profile is being processed.
637 var processingIcon = new WebInspector.SidebarTreeElement(
638 'profile-sidebar-tree-item',
639 WebInspector.UIString('Processing...'),
640 '', null, false);
641 var profilesSidebar = WebInspector.panels.profiles.getProfileType(
642 WebInspector.CPUProfileType.TypeId).treeElement;
643
644 this.profilerProcessor_.setCallbacks(
645 function onProfileProcessingStarted() {
646 // Set visually empty string. Subtitle hiding is done via styles
647 // manipulation which doesn't play well with dynamic append / removal.
648 processingIcon.subtitle = ' ';
649 profilesSidebar.appendChild(processingIcon);
650 },
651 function onProfileProcessingStatus(ticksCount) {
652 processingIcon.subtitle =
653 WebInspector.UIString('%d ticks processed', ticksCount);
654 },
655 function onProfileProcessingFinished(profile) {
656 profilesSidebar.removeChild(processingIcon);
657 WebInspector.addProfile(profile);
658 // If no profile is currently shown, show the new one.
659 var profilesPanel = WebInspector.panels.profiles;
660 if (!profilesPanel.visibleView) {
661 profilesPanel.showProfile(profile);
662 }
663 }
664 );
665 };
666
667
668 /**
669 * Initializes profiling state.
670 */
671 devtools.DebuggerAgent.prototype.initializeProfiling = function() {
672 this.setupProfilerProcessorCallbacks();
673 RemoteDebuggerAgent.GetActiveProfilerModules();
674 };
675
676
677 /**
678 * Starts profiling.
679 * @param {number} modules List of modules to enable.
680 */
681 devtools.DebuggerAgent.prototype.startProfiling = function(modules) {
682 RemoteDebuggerAgent.StartProfiling(modules);
683 if (modules &
684 devtools.DebuggerAgent.ProfilerModules.PROFILER_MODULE_HEAP_SNAPSHOT) {
685 // Active modules will not change, instead, a snapshot will be logged.
686 RemoteDebuggerAgent.GetNextLogLines();
687 } else {
688 RemoteDebuggerAgent.GetActiveProfilerModules();
689 }
690 };
691
692
693 /**
694 * Stops profiling.
695 */
696 devtools.DebuggerAgent.prototype.stopProfiling = function(modules) {
697 RemoteDebuggerAgent.StopProfiling(modules);
698 };
699
700
701 /**
702 * @param{number} scriptId
703 * @return {string} Type of the context of the script with specified id.
704 */
705 devtools.DebuggerAgent.prototype.getScriptContextType = function(scriptId) {
706 return this.parsedScripts_[scriptId].getContextType();
707 };
708
709
710 /**
711 * Removes specified breakpoint from the v8 debugger.
712 * @param {number} breakpointId Id of the breakpoint in the v8 debugger.
713 */
714 devtools.DebuggerAgent.prototype.requestClearBreakpoint_ = function(
715 breakpointId) {
716 var cmd = new devtools.DebugCommand('clearbreakpoint', {
717 'breakpoint': breakpointId
718 });
719 devtools.DebuggerAgent.sendCommand_(cmd);
720 };
721
722
723 /**
724 * Changes breakpoint parameters in the v8 debugger.
725 * @param {number} breakpointId Id of the breakpoint in the v8 debugger.
726 * @param {boolean} enabled Whether to enable the breakpoint.
727 * @param {?string} condition New breakpoint condition.
728 * @param {number} ignoreCount New ignore count for the breakpoint.
729 */
730 devtools.DebuggerAgent.prototype.requestChangeBreakpoint_ = function(
731 breakpointId, enabled, condition, ignoreCount) {
732 var cmd = new devtools.DebugCommand('changebreakpoint', {
733 'breakpoint': breakpointId,
734 'enabled': enabled,
735 'condition': condition,
736 'ignoreCount': ignoreCount
737 });
738 devtools.DebuggerAgent.sendCommand_(cmd);
739 };
740
741
742 /**
743 * Sends 'backtrace' request to v8.
744 */
745 devtools.DebuggerAgent.prototype.requestBacktrace_ = function() {
746 var cmd = new devtools.DebugCommand('backtrace', {
747 'compactFormat':true
748 });
749 devtools.DebuggerAgent.sendCommand_(cmd);
750 };
751
752
753 /**
754 * Sends command to v8 debugger.
755 * @param {devtools.DebugCommand} cmd Command to execute.
756 */
757 devtools.DebuggerAgent.sendCommand_ = function(cmd) {
758 RemoteDebuggerCommandExecutor.DebuggerCommand(cmd.toJSONProtocol());
759 };
760
761
762 /**
763 * Tells the v8 debugger to make the next execution step.
764 * @param {string} action 'in', 'out' or 'next' action.
765 */
766 devtools.DebuggerAgent.prototype.stepCommand_ = function(action) {
767 this.clearExceptionMessage_();
768 var cmd = new devtools.DebugCommand('continue', {
769 'stepaction': action,
770 'stepcount': 1
771 });
772 devtools.DebuggerAgent.sendCommand_(cmd);
773 };
774
775
776 /**
777 * Sends 'lookup' request to v8.
778 * @param {number} handle Handle to the object to lookup.
779 */
780 devtools.DebuggerAgent.prototype.requestLookup_ = function(handles, callback) {
781 var cmd = new devtools.DebugCommand('lookup', {
782 'compactFormat':true,
783 'handles': handles
784 });
785 devtools.DebuggerAgent.sendCommand_(cmd);
786 this.requestSeqToCallback_[cmd.getSequenceNumber()] = callback;
787 };
788
789
790 /**
791 * Sets debugger context id for scripts filtering.
792 * @param {number} contextId Id of the inspected page global context.
793 */
794 devtools.DebuggerAgent.prototype.setContextId_ = function(contextId) {
795 this.contextId_ = contextId;
796
797 // If it's the first time context id is set request scripts list.
798 if (this.requestScriptsWhenContextIdSet_) {
799 this.requestScriptsWhenContextIdSet_ = false;
800 var cmd = new devtools.DebugCommand('scripts', {
801 'includeSource': false
802 });
803 devtools.DebuggerAgent.sendCommand_(cmd);
804 // Force v8 execution so that it gets to processing the requested command.
805 RemoteToolsAgent.ExecuteVoidJavaScript();
806
807 var debuggerAgent = this;
808 this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) {
809 // Handle the response iff the context id hasn't changed since the request
810 // was issued. Otherwise if the context id did change all up-to-date
811 // scripts will be pushed in after compile events and there is no need to
812 // handle the response.
813 if (contextId == debuggerAgent.contextId_) {
814 debuggerAgent.handleScriptsResponse_(msg);
815 }
816 };
817 }
818 };
819
820
821 /**
822 * Handles output sent by v8 debugger. The output is either asynchronous event
823 * or response to a previously sent request. See protocol definitioun for more
824 * details on the output format.
825 * @param {string} output
826 */
827 devtools.DebuggerAgent.prototype.handleDebuggerOutput_ = function(output) {
828 var msg;
829 try {
830 msg = new devtools.DebuggerMessage(output);
831 } catch(e) {
832 debugPrint('Failed to handle debugger reponse:\n' + e);
833 throw e;
834 }
835
836 if (msg.getType() == 'event') {
837 if (msg.getEvent() == 'break') {
838 this.handleBreakEvent_(msg);
839 } else if (msg.getEvent() == 'exception') {
840 this.handleExceptionEvent_(msg);
841 } else if (msg.getEvent() == 'afterCompile') {
842 this.handleAfterCompileEvent_(msg);
843 }
844 } else if (msg.getType() == 'response') {
845 if (msg.getCommand() == 'scripts') {
846 this.invokeCallbackForResponse_(msg);
847 } else if (msg.getCommand() == 'setbreakpoint') {
848 this.handleSetBreakpointResponse_(msg);
849 } else if (msg.getCommand() == 'clearbreakpoint') {
850 this.handleClearBreakpointResponse_(msg);
851 } else if (msg.getCommand() == 'backtrace') {
852 this.handleBacktraceResponse_(msg);
853 } else if (msg.getCommand() == 'lookup') {
854 this.invokeCallbackForResponse_(msg);
855 } else if (msg.getCommand() == 'evaluate') {
856 this.invokeCallbackForResponse_(msg);
857 } else if (msg.getCommand() == 'scope') {
858 this.invokeCallbackForResponse_(msg);
859 }
860 }
861 };
862
863
864 /**
865 * @param {devtools.DebuggerMessage} msg
866 */
867 devtools.DebuggerAgent.prototype.handleBreakEvent_ = function(msg) {
868 // Force scrips panel to be shown first.
869 WebInspector.currentPanel = WebInspector.panels.scripts;
870
871 var body = msg.getBody();
872
873 var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine);
874 this.requestBacktrace_();
875 };
876
877
878 /**
879 * @param {devtools.DebuggerMessage} msg
880 */
881 devtools.DebuggerAgent.prototype.handleExceptionEvent_ = function(msg) {
882 // Force scrips panel to be shown first.
883 WebInspector.currentPanel = WebInspector.panels.scripts;
884
885 var body = msg.getBody();
886 // No script field in the body means that v8 failed to parse the script. We
887 // resume execution on parser errors automatically.
888 if (this.pauseOnExceptions_ && body.script) {
889 var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine);
890 this.createExceptionMessage_(body.script.name, line, body.exception.text);
891 this.requestBacktrace_();
892 } else {
893 this.resumeExecution();
894 }
895 };
896
897
898 /**
899 * @param {devtools.DebuggerMessage} msg
900 */
901 devtools.DebuggerAgent.prototype.handleScriptsResponse_ = function(msg) {
902 var scripts = msg.getBody();
903 for (var i = 0; i < scripts.length; i++) {
904 var script = scripts[i];
905
906 // Skip scripts from other tabs.
907 if (!this.isScriptFromInspectedContext_(script, msg)) {
908 continue;
909 }
910
911 // We may already have received the info in an afterCompile event.
912 if (script.id in this.parsedScripts_) {
913 continue;
914 }
915 this.addScriptInfo_(script, msg);
916 }
917 };
918
919
920 /**
921 * @param {Object} script Json object representing script.
922 * @param {devtools.DebuggerMessage} msg Debugger response.
923 */
924 devtools.DebuggerAgent.prototype.isScriptFromInspectedContext_ = function(
925 script, msg) {
926 if (!script.context) {
927 // Always ignore scripts from the utility context.
928 return false;
929 }
930 var context = msg.lookup(script.context.ref);
931 var scriptContextId = context.data;
932 if (!goog.isDef(scriptContextId)) {
933 return false; // Always ignore scripts from the utility context.
934 }
935 if (this.contextId_ === null) {
936 return true;
937 }
938 return (scriptContextId.value == this.contextId_);
939 };
940
941
942 /**
943 * @param {devtools.DebuggerMessage} msg
944 */
945 devtools.DebuggerAgent.prototype.handleSetBreakpointResponse_ = function(msg) {
946 var requestSeq = msg.getRequestSeq();
947 var breakpointInfo = this.requestNumberToBreakpointInfo_[requestSeq];
948 if (!breakpointInfo) {
949 // TODO(yurys): handle this case
950 return;
951 }
952 delete this.requestNumberToBreakpointInfo_[requestSeq];
953 if (!msg.isSuccess()) {
954 // TODO(yurys): handle this case
955 return;
956 }
957 var idInV8 = msg.getBody().breakpoint;
958 breakpointInfo.setV8Id(idInV8);
959
960 if (breakpointInfo.isRemoved()) {
961 this.requestClearBreakpoint_(idInV8);
962 }
963 };
964
965
966 /**
967 * @param {devtools.DebuggerMessage} msg
968 */
969 devtools.DebuggerAgent.prototype.handleAfterCompileEvent_ = function(msg) {
970 if (!this.contextId_) {
971 // Ignore scripts delta if main request has not been issued yet.
972 return;
973 }
974 var script = msg.getBody().script;
975
976 // Ignore scripts from other tabs.
977 if (!this.isScriptFromInspectedContext_(script, msg)) {
978 return;
979 }
980 this.addScriptInfo_(script, msg);
981 };
982
983
984 /**
985 * Handles current profiler status.
986 * @param {number} modules List of active (started) modules.
987 */
988 devtools.DebuggerAgent.prototype.didGetActiveProfilerModules_ = function(
989 modules) {
990 var profModules = devtools.DebuggerAgent.ProfilerModules;
991 var profModuleNone = profModules.PROFILER_MODULE_NONE;
992 if (modules != profModuleNone &&
993 this.activeProfilerModules_ == profModuleNone) {
994 // Start to query log data.
995 RemoteDebuggerAgent.GetNextLogLines();
996 }
997 this.activeProfilerModules_ = modules;
998 // Update buttons.
999 WebInspector.setRecordingProfile(modules & profModules.PROFILER_MODULE_CPU);
1000 if (modules != profModuleNone) {
1001 // Monitor profiler state. It can stop itself on buffer fill-up.
1002 setTimeout(
1003 function() { RemoteDebuggerAgent.GetActiveProfilerModules(); }, 1000);
1004 }
1005 };
1006
1007
1008 /**
1009 * Handles a portion of a profiler log retrieved by GetNextLogLines call.
1010 * @param {string} log A portion of profiler log.
1011 */
1012 devtools.DebuggerAgent.prototype.didGetNextLogLines_ = function(log) {
1013 if (log.length > 0) {
1014 this.profilerProcessor_.processLogChunk(log);
1015 } else if (this.activeProfilerModules_ ==
1016 devtools.DebuggerAgent.ProfilerModules.PROFILER_MODULE_NONE) {
1017 // No new data and profiling is stopped---suspend log reading.
1018 return;
1019 }
1020 setTimeout(function() { RemoteDebuggerAgent.GetNextLogLines(); }, 500);
1021 };
1022
1023
1024 /**
1025 * Adds the script info to the local cache. This method assumes that the script
1026 * is not in the cache yet.
1027 * @param {Object} script Script json object from the debugger message.
1028 * @param {devtools.DebuggerMessage} msg Debugger message containing the script
1029 * data.
1030 */
1031 devtools.DebuggerAgent.prototype.addScriptInfo_ = function(script, msg) {
1032 var context = msg.lookup(script.context.ref);
1033 var contextType = context.data.type;
1034 this.parsedScripts_[script.id] = new devtools.ScriptInfo(
1035 script.id, script.name, script.lineOffset, contextType);
1036 if (WebInspector.panels.scripts.element.parentElement) {
1037 // Only report script as parsed after scripts panel has been shown.
1038 WebInspector.parsedScriptSource(
1039 script.id, script.name, script.source, script.lineOffset);
1040 }
1041 };
1042
1043
1044 /**
1045 * @param {devtools.DebuggerMessage} msg
1046 */
1047 devtools.DebuggerAgent.prototype.handleClearBreakpointResponse_ = function(
1048 msg) {
1049 // Do nothing.
1050 };
1051
1052
1053 /**
1054 * Handles response to 'backtrace' command.
1055 * @param {devtools.DebuggerMessage} msg
1056 */
1057 devtools.DebuggerAgent.prototype.handleBacktraceResponse_ = function(msg) {
1058 var frames = msg.getBody().frames;
1059 this.callFrames_ = [];
1060 for (var i = 0; i < frames.length; ++i) {
1061 this.callFrames_.push(this.formatCallFrame_(frames[i]));
1062 }
1063 WebInspector.pausedScript(this.callFrames_);
1064 this.showPendingExceptionMessage_();
1065 DevToolsHost.activateWindow();
1066 };
1067
1068
1069 /**
1070 * Evaluates code on given callframe.
1071 */
1072 devtools.DebuggerAgent.prototype.evaluateInCallFrame = function(
1073 callFrameId, code, callback) {
1074 var callFrame = this.callFrames_[callFrameId];
1075 callFrame.evaluate_(code, callback);
1076 };
1077
1078
1079 /**
1080 * Handles response to a command by invoking its callback (if any).
1081 * @param {devtools.DebuggerMessage} msg
1082 * @return {boolean} Whether a callback for the given message was found and
1083 * excuted.
1084 */
1085 devtools.DebuggerAgent.prototype.invokeCallbackForResponse_ = function(msg) {
1086 var callback = this.requestSeqToCallback_[msg.getRequestSeq()];
1087 if (!callback) {
1088 // It may happend if reset was called.
1089 return false;
1090 }
1091 delete this.requestSeqToCallback_[msg.getRequestSeq()];
1092 callback(msg);
1093 return true;
1094 };
1095
1096
1097 /**
1098 * @param {Object} stackFrame Frame json object from 'backtrace' response.
1099 * @return {!devtools.CallFrame} Object containing information related to the
1100 * call frame in the format expected by ScriptsPanel and its panes.
1101 */
1102 devtools.DebuggerAgent.prototype.formatCallFrame_ = function(stackFrame) {
1103 var func = stackFrame.func;
1104 var sourceId = func.scriptId;
1105
1106 // Add service script if it does not exist.
1107 var existingScript = this.parsedScripts_[sourceId];
1108 if (!existingScript) {
1109 this.parsedScripts_[sourceId] = new devtools.ScriptInfo(
1110 sourceId, null /* name */, 0 /* line */, 'unknown' /* type */,
1111 true /* unresolved */);
1112 WebInspector.parsedScriptSource(sourceId, null, null, 0);
1113 }
1114
1115 var funcName = func.name || func.inferredName || '(anonymous function)';
1116 var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(stackFrame.line);
1117
1118 // Add basic scope chain info with scope variables.
1119 var scopeChain = [];
1120 var ScopeType = devtools.DebuggerAgent.ScopeType;
1121 for (var i = 0; i < stackFrame.scopes.length; i++) {
1122 var scope = stackFrame.scopes[i];
1123 scope.frameNumber = stackFrame.index;
1124 var scopeObjectProxy = new WebInspector.ObjectProxy(scope, [], 0, '', true);
1125 scopeObjectProxy.isScope = true;
1126 switch(scope.type) {
1127 case ScopeType.Global:
1128 scopeObjectProxy.isDocument = true;
1129 break;
1130 case ScopeType.Local:
1131 scopeObjectProxy.isLocal = true;
1132 scopeObjectProxy.thisObject =
1133 devtools.DebuggerAgent.formatObjectProxy_(stackFrame.receiver);
1134 break;
1135 case ScopeType.With:
1136 // Catch scope is treated as a regular with scope by WebKit so we
1137 // also treat it this way.
1138 case ScopeType.Catch:
1139 scopeObjectProxy.isWithBlock = true;
1140 break;
1141 case ScopeType.Closure:
1142 scopeObjectProxy.isClosure = true;
1143 break;
1144 }
1145 scopeChain.push(scopeObjectProxy);
1146 }
1147 return new devtools.CallFrame(stackFrame.index, 'function', funcName,
1148 sourceId, line, scopeChain);
1149 };
1150
1151
1152 /**
1153 * Collects properties for an object from the debugger response.
1154 * @param {Object} object An object from the debugger protocol response.
1155 * @param {Array.<WebInspector.ObjectPropertyProxy>} result An array to put the
1156 * properties into.
1157 * @param {boolean} noIntrinsic Whether intrinsic properties should be
1158 * included.
1159 */
1160 devtools.DebuggerAgent.formatObjectProperties_ = function(object, result,
1161 noIntrinsic) {
1162 devtools.DebuggerAgent.propertiesToProxies_(object.properties, result);
1163 if (noIntrinsic) {
1164 return;
1165 }
1166
1167 result.push(new WebInspector.ObjectPropertyProxy('__proto__',
1168 devtools.DebuggerAgent.formatObjectProxy_(object.protoObject)));
1169 result.push(new WebInspector.ObjectPropertyProxy('constructor',
1170 devtools.DebuggerAgent.formatObjectProxy_(object.constructorFunction)));
1171 // Don't add 'prototype' property since it is one of the regualar properties.
1172 };
1173
1174
1175 /**
1176 * For each property in 'properties' creates its proxy representative.
1177 * @param {Array.<Object>} properties Receiver properties or locals array from
1178 * 'backtrace' response.
1179 * @param {Array.<WebInspector.ObjectPropertyProxy>} Results holder.
1180 */
1181 devtools.DebuggerAgent.propertiesToProxies_ = function(properties, result) {
1182 var map = {};
1183 for (var i = 0; i < properties.length; ++i) {
1184 var property = properties[i];
1185 var name = String(property.name);
1186 if (name in map) {
1187 continue;
1188 }
1189 map[name] = true;
1190 var value = devtools.DebuggerAgent.formatObjectProxy_(property.value);
1191 var propertyProxy = new WebInspector.ObjectPropertyProxy(name, value);
1192 result.push(propertyProxy);
1193 }
1194 };
1195
1196
1197 /**
1198 * @param {Object} v An object reference from the debugger response.
1199 * @return {*} The value representation expected by ScriptsPanel.
1200 */
1201 devtools.DebuggerAgent.formatObjectProxy_ = function(v) {
1202 var description;
1203 var hasChildren = false;
1204 if (v.type == 'object') {
1205 description = v.className;
1206 hasChildren = true;
1207 } else if (v.type == 'function') {
1208 if (v.source) {
1209 description = v.source;
1210 } else {
1211 description = 'function ' + v.name + '()';
1212 }
1213 hasChildren = true;
1214 } else if (v.type == 'undefined') {
1215 description = 'undefined';
1216 } else if (v.type == 'null') {
1217 description = 'null';
1218 } else if (goog.isDef(v.value)) {
1219 // Check for undefined and null types before checking the value, otherwise
1220 // null/undefined may have blank value.
1221 description = v.value;
1222 } else {
1223 description = '<unresolved ref: ' + v.ref + ', type: ' + v.type + '>';
1224 }
1225 var proxy = new WebInspector.ObjectProxy(v, [], 0, description, hasChildren);
1226 proxy.type = v.type;
1227 proxy.isV8Ref = true;
1228 return proxy;
1229 };
1230
1231
1232 /**
1233 * Converts line number from Web Inspector UI(1-based) to v8(0-based).
1234 * @param {number} line Resource line number in Web Inspector UI.
1235 * @return {number} The line number in v8.
1236 */
1237 devtools.DebuggerAgent.webkitToV8LineNumber_ = function(line) {
1238 return line - 1;
1239 };
1240
1241
1242 /**
1243 * Converts line number from v8(0-based) to Web Inspector UI(1-based).
1244 * @param {number} line Resource line number in v8.
1245 * @return {number} The line number in Web Inspector.
1246 */
1247 devtools.DebuggerAgent.v8ToWwebkitLineNumber_ = function(line) {
1248 return line + 1;
1249 };
1250
1251
1252 /**
1253 * @param {number} scriptId Id of the script.
1254 * @param {?string} url Script resource URL if any.
1255 * @param {number} lineOffset First line 0-based offset in the containing
1256 * document.
1257 * @param {string} contextType Type of the script's context:
1258 * "page" - regular script from html page
1259 * "injected" - extension content script
1260 * @param {bool} opt_isUnresolved If true, script will not be resolved.
1261 * @constructor
1262 */
1263 devtools.ScriptInfo = function(
1264 scriptId, url, lineOffset, contextType, opt_isUnresolved) {
1265 this.scriptId_ = scriptId;
1266 this.lineOffset_ = lineOffset;
1267 this.contextType_ = contextType;
1268 this.url_ = url;
1269 this.isUnresolved_ = opt_isUnresolved;
1270
1271 this.lineToBreakpointInfo_ = {};
1272 };
1273
1274
1275 /**
1276 * @return {number}
1277 */
1278 devtools.ScriptInfo.prototype.getLineOffset = function() {
1279 return this.lineOffset_;
1280 };
1281
1282
1283 /**
1284 * @return {string}
1285 */
1286 devtools.ScriptInfo.prototype.getContextType = function() {
1287 return this.contextType_;
1288 };
1289
1290
1291 /**
1292 * @return {?string}
1293 */
1294 devtools.ScriptInfo.prototype.getUrl = function() {
1295 return this.url_;
1296 };
1297
1298
1299 /**
1300 * @return {?bool}
1301 */
1302 devtools.ScriptInfo.prototype.isUnresolved = function() {
1303 return this.isUnresolved_;
1304 };
1305
1306
1307 /**
1308 * @param {number} line 0-based line number in the script.
1309 * @return {?devtools.BreakpointInfo} Information on a breakpoint at the
1310 * specified line in the script or undefined if there is no breakpoint at
1311 * that line.
1312 */
1313 devtools.ScriptInfo.prototype.getBreakpointInfo = function(line) {
1314 return this.lineToBreakpointInfo_[line];
1315 };
1316
1317
1318 /**
1319 * Adds breakpoint info to the script.
1320 * @param {devtools.BreakpointInfo} breakpoint
1321 */
1322 devtools.ScriptInfo.prototype.addBreakpointInfo = function(breakpoint) {
1323 this.lineToBreakpointInfo_[breakpoint.getLine()] = breakpoint;
1324 };
1325
1326
1327 /**
1328 * @param {devtools.BreakpointInfo} breakpoint Breakpoint info to be removed.
1329 */
1330 devtools.ScriptInfo.prototype.removeBreakpointInfo = function(breakpoint) {
1331 var line = breakpoint.getLine();
1332 delete this.lineToBreakpointInfo_[line];
1333 };
1334
1335
1336
1337 /**
1338 * @param {number} line Breakpoint 0-based line number in the containing script.
1339 * @constructor
1340 */
1341 devtools.BreakpointInfo = function(line) {
1342 this.line_ = line;
1343 this.v8id_ = -1;
1344 this.removed_ = false;
1345 };
1346
1347
1348 /**
1349 * @return {number}
1350 */
1351 devtools.BreakpointInfo.prototype.getLine = function(n) {
1352 return this.line_;
1353 };
1354
1355
1356 /**
1357 * @return {number} Unique identifier of this breakpoint in the v8 debugger.
1358 */
1359 devtools.BreakpointInfo.prototype.getV8Id = function(n) {
1360 return this.v8id_;
1361 };
1362
1363
1364 /**
1365 * Sets id of this breakpoint in the v8 debugger.
1366 * @param {number} id
1367 */
1368 devtools.BreakpointInfo.prototype.setV8Id = function(id) {
1369 this.v8id_ = id;
1370 };
1371
1372
1373 /**
1374 * Marks this breakpoint as removed from the front-end.
1375 */
1376 devtools.BreakpointInfo.prototype.markAsRemoved = function() {
1377 this.removed_ = true;
1378 };
1379
1380
1381 /**
1382 * @return {boolean} Whether this breakpoint has been removed from the
1383 * front-end.
1384 */
1385 devtools.BreakpointInfo.prototype.isRemoved = function() {
1386 return this.removed_;
1387 };
1388
1389
1390 /**
1391 * Call stack frame data.
1392 * @param {string} id CallFrame id.
1393 * @param {string} type CallFrame type.
1394 * @param {string} functionName CallFrame type.
1395 * @param {string} sourceID Source id.
1396 * @param {number} line Source line.
1397 * @param {Array.<Object>} scopeChain Array of scoped objects.
1398 * @construnctor
1399 */
1400 devtools.CallFrame = function(id, type, functionName, sourceID, line,
1401 scopeChain) {
1402 this.id = id;
1403 this.type = type;
1404 this.functionName = functionName;
1405 this.sourceID = sourceID;
1406 this.line = line;
1407 this.scopeChain = scopeChain;
1408 };
1409
1410
1411 /**
1412 * This method issues asynchronous evaluate request, reports result to the
1413 * callback.
1414 * @param {string} expression An expression to be evaluated in the context of
1415 * this call frame.
1416 * @param {function(Object):undefined} callback Callback to report result to.
1417 */
1418 devtools.CallFrame.prototype.evaluate_ = function(expression, callback) {
1419 devtools.tools.getDebuggerAgent().requestEvaluate({
1420 'expression': expression,
1421 'frame': this.id,
1422 'global': false,
1423 'disable_break': false,
1424 'compactFormat': true
1425 },
1426 function(response) {
1427 var result = {};
1428 if (response.isSuccess()) {
1429 result.value = devtools.DebuggerAgent.formatObjectProxy_(
1430 response.getBody());
1431 } else {
1432 result.value = response.getMessage();
1433 result.isException = true;
1434 }
1435 callback(result);
1436 });
1437 };
1438
1439
1440 /**
1441 * JSON based commands sent to v8 debugger.
1442 * @param {string} command Name of the command to execute.
1443 * @param {Object} opt_arguments Command-specific arguments map.
1444 * @constructor
1445 */
1446 devtools.DebugCommand = function(command, opt_arguments) {
1447 this.command_ = command;
1448 this.type_ = 'request';
1449 this.seq_ = ++devtools.DebugCommand.nextSeq_;
1450 if (opt_arguments) {
1451 this.arguments_ = opt_arguments;
1452 }
1453 };
1454
1455
1456 /**
1457 * Next unique number to be used as debugger request sequence number.
1458 * @type {number}
1459 */
1460 devtools.DebugCommand.nextSeq_ = 1;
1461
1462
1463 /**
1464 * @return {number}
1465 */
1466 devtools.DebugCommand.prototype.getSequenceNumber = function() {
1467 return this.seq_;
1468 };
1469
1470
1471 /**
1472 * @return {string}
1473 */
1474 devtools.DebugCommand.prototype.toJSONProtocol = function() {
1475 var json = {
1476 'seq': this.seq_,
1477 'type': this.type_,
1478 'command': this.command_
1479 }
1480 if (this.arguments_) {
1481 json.arguments = this.arguments_;
1482 }
1483 return JSON.stringify(json);
1484 };
1485
1486
1487 /**
1488 * JSON messages sent from v8 debugger. See protocol definition for more
1489 * details: http://code.google.com/p/v8/wiki/DebuggerProtocol
1490 * @param {string} msg Raw protocol packet as JSON string.
1491 * @constructor
1492 */
1493 devtools.DebuggerMessage = function(msg) {
1494 this.packet_ = JSON.parse(msg);
1495 this.refs_ = [];
1496 if (this.packet_.refs) {
1497 for (var i = 0; i < this.packet_.refs.length; i++) {
1498 this.refs_[this.packet_.refs[i].handle] = this.packet_.refs[i];
1499 }
1500 }
1501 };
1502
1503
1504 /**
1505 * @return {string} The packet type.
1506 */
1507 devtools.DebuggerMessage.prototype.getType = function() {
1508 return this.packet_.type;
1509 };
1510
1511
1512 /**
1513 * @return {?string} The packet event if the message is an event.
1514 */
1515 devtools.DebuggerMessage.prototype.getEvent = function() {
1516 return this.packet_.event;
1517 };
1518
1519
1520 /**
1521 * @return {?string} The packet command if the message is a response to a
1522 * command.
1523 */
1524 devtools.DebuggerMessage.prototype.getCommand = function() {
1525 return this.packet_.command;
1526 };
1527
1528
1529 /**
1530 * @return {number} The packet request sequence.
1531 */
1532 devtools.DebuggerMessage.prototype.getRequestSeq = function() {
1533 return this.packet_.request_seq;
1534 };
1535
1536
1537 /**
1538 * @return {number} Whether the v8 is running after processing the request.
1539 */
1540 devtools.DebuggerMessage.prototype.isRunning = function() {
1541 return this.packet_.running ? true : false;
1542 };
1543
1544
1545 /**
1546 * @return {boolean} Whether the request succeeded.
1547 */
1548 devtools.DebuggerMessage.prototype.isSuccess = function() {
1549 return this.packet_.success ? true : false;
1550 };
1551
1552
1553 /**
1554 * @return {string}
1555 */
1556 devtools.DebuggerMessage.prototype.getMessage = function() {
1557 return this.packet_.message;
1558 };
1559
1560
1561 /**
1562 * @return {Object} Parsed message body json.
1563 */
1564 devtools.DebuggerMessage.prototype.getBody = function() {
1565 return this.packet_.body;
1566 };
1567
1568
1569 /**
1570 * @param {number} handle Object handle.
1571 * @return {?Object} Returns the object with the handle if it was sent in this
1572 * message(some objects referenced by handles may be missing in the message).
1573 */
1574 devtools.DebuggerMessage.prototype.lookup = function(handle) {
1575 return this.refs_[handle];
1576 };
OLDNEW
« no previous file with comments | « resources/inspector/csvparser.js ('k') | resources/inspector/devtools.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698