2 * Copyright (C) 2010 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 var DebuggerScript = {};
35 DebuggerScript.PauseOnExceptionsState = {
36 DontPauseOnExceptions : 0,
37 PauseOnAllExceptions : 1,
38 PauseOnUncaughtExceptions: 2
41 DebuggerScript._pauseOnExceptionsState = DebuggerScript.PauseOnExceptionsState.DontPauseOnExceptions;
42 Debug.clearBreakOnException();
43 Debug.clearBreakOnUncaughtException();
45 DebuggerScript.getAfterCompileScript = function(eventData)
47 return DebuggerScript._formatScript(eventData.script_.script_);
50 DebuggerScript.getWorkerScripts = function()
53 var scripts = Debug.scripts();
54 for (var i = 0; i < scripts.length; ++i) {
55 var script = scripts[i];
56 // Workers don't share same V8 heap now so there is no need to complicate stuff with
57 // the context id like we do to discriminate between scripts from different pages.
58 // However we need to filter out v8 native scripts.
59 if (script.context_data && script.context_data === "worker")
60 result.push(DebuggerScript._formatScript(script));
65 DebuggerScript.getScripts = function(contextData)
71 var comma = contextData.indexOf(",");
74 // Context data is a string in the following format:
75 // ("page"|"injected")","<page id>
76 var idSuffix = contextData.substring(comma); // including the comma
78 var scripts = Debug.scripts();
79 for (var i = 0; i < scripts.length; ++i) {
80 var script = scripts[i];
81 if (script.context_data && script.context_data.lastIndexOf(idSuffix) != -1)
82 result.push(DebuggerScript._formatScript(script));
87 DebuggerScript._formatScript = function(script)
89 var lineEnds = script.line_ends;
90 var lineCount = lineEnds.length;
91 var endLine = script.line_offset + lineCount - 1;
94 endColumn = script.source.length + script.column_offset;
96 endColumn = script.source.length - (script.line_ends[lineCount - 2] + 1);
100 name: script.nameOrSourceURL(),
101 source: script.source,
102 startLine: script.line_offset,
103 startColumn: script.column_offset,
105 endColumn: endColumn,
106 isContentScript: !!script.context_data && script.context_data.indexOf("injected") == 0
110 DebuggerScript.setBreakpoint = function(execState, args)
112 var breakId = Debug.setScriptBreakPointById(args.sourceID, args.lineNumber, args.columnNumber, args.condition);
114 var locations = Debug.findBreakPointActualLocations(breakId);
115 if (!locations.length)
117 args.lineNumber = locations[0].line;
118 args.columnNumber = locations[0].column;
119 return breakId.toString();
122 DebuggerScript.removeBreakpoint = function(execState, args)
124 Debug.findBreakPoint(args.breakpointId, true);
127 DebuggerScript.pauseOnExceptionsState = function()
129 return DebuggerScript._pauseOnExceptionsState;
132 DebuggerScript.setPauseOnExceptionsState = function(newState)
134 DebuggerScript._pauseOnExceptionsState = newState;
136 if (DebuggerScript.PauseOnExceptionsState.PauseOnAllExceptions === newState)
137 Debug.setBreakOnException();
139 Debug.clearBreakOnException();
141 if (DebuggerScript.PauseOnExceptionsState.PauseOnUncaughtExceptions === newState)
142 Debug.setBreakOnUncaughtException();
144 Debug.clearBreakOnUncaughtException();
147 DebuggerScript.currentCallFrame = function(execState, args)
149 var frameCount = execState.frameCount();
150 if (frameCount === 0)
154 for (var i = frameCount - 1; i >= 0; i--) {
155 var frameMirror = execState.frame(i);
156 topFrame = DebuggerScript._frameMirrorToJSCallFrame(frameMirror, topFrame);
161 DebuggerScript.stepIntoStatement = function(execState)
163 execState.prepareStep(Debug.StepAction.StepIn, 1);
166 DebuggerScript.stepOverStatement = function(execState)
168 execState.prepareStep(Debug.StepAction.StepNext, 1);
171 DebuggerScript.stepOutOfFunction = function(execState)
173 execState.prepareStep(Debug.StepAction.StepOut, 1);
176 DebuggerScript.setScriptSource = function(scriptId, newSource, preview)
178 var scripts = Debug.scripts();
179 var scriptToEdit = null;
180 for (var i = 0; i < scripts.length; i++) {
181 if (scripts[i].id == scriptId) {
182 scriptToEdit = scripts[i];
187 throw("Script not found");
190 return Debug.LiveEdit.SetScriptSource(scriptToEdit, newSource, preview, changeLog);
193 DebuggerScript.clearBreakpoints = function(execState, args)
195 Debug.clearAllBreakPoints();
198 DebuggerScript.setBreakpointsActivated = function(execState, args)
200 Debug.debuggerFlags().breakPointsActive.setValue(args.enabled);
203 DebuggerScript._frameMirrorToJSCallFrame = function(frameMirror, callerFrame)
205 // Get function name.
208 func = frameMirror.func();
213 functionName = func.name() || func.inferredName();
216 var script = func.script();
217 var sourceID = script && script.id();
220 var location = frameMirror.sourceLocation();
223 var thisObject = frameMirror.details_.receiver();
225 // Get scope chain array in format: [<scope type>, <scope object>, <scope type>, <scope object>,...]
228 for (var i = 0; i < frameMirror.scopeCount(); i++) {
229 var scopeMirror = frameMirror.scope(i);
230 var scopeObjectMirror = scopeMirror.scopeObject();
233 switch (scopeMirror.scopeType()) {
234 case ScopeType.Local:
235 case ScopeType.Closure:
236 // For transient objects we create a "persistent" copy that contains
237 // the same properties.
239 // Reset scope object prototype to null so that the proto properties
240 // don't appear in the local scope section.
241 scopeObject.__proto__ = null;
242 var properties = scopeObjectMirror.properties();
243 for (var j = 0; j < properties.length; j++) {
244 var name = properties[j].name();
245 if (name.charAt(0) === ".")
246 continue; // Skip internal variables like ".arguments"
247 scopeObject[name] = properties[j].value_;
250 case ScopeType.Global:
252 case ScopeType.Catch:
253 scopeObject = scopeMirror.details_.object();
257 scopeType.push(scopeMirror.scopeType());
258 scopeChain.push(scopeObject);
261 function evaluate(expression) {
262 return frameMirror.evaluate(expression, false).value();
266 "sourceID": sourceID,
267 "line": location ? location.line : 0,
268 "column": location ? location.column : 0,
269 "functionName": functionName,
270 "thisObject": thisObject,
271 "scopeChain": scopeChain,
272 "scopeType": scopeType,
273 "evaluate": evaluate,
274 "caller": callerFrame
278 return DebuggerScript;