WebKit/chromium/src/js/DebuggerScript.js
changeset 0 4f2f89ce4247
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebKit/chromium/src/js/DebuggerScript.js	Fri Sep 17 09:02:29 2010 +0300
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+(function () {
+
+var DebuggerScript = {};
+DebuggerScript._breakpoints = {};
+
+DebuggerScript.PauseOnExceptionsState = {
+    DontPauseOnExceptions : 0,
+    PauseOnAllExceptions : 1,
+    PauseOnUncaughtExceptions: 2
+};
+
+DebuggerScript.ScriptWorldType = {
+    MainWorld : 0,
+    ExtensionsWorld : 1
+};
+
+DebuggerScript._pauseOnExceptionsState = DebuggerScript.PauseOnExceptionsState.DontPauseOnExceptions;
+Debug.clearBreakOnException();
+Debug.clearBreakOnUncaughtException();
+
+DebuggerScript.getAfterCompileScript = function(eventData)
+{
+    return DebuggerScript._formatScript(eventData.script_.script_);
+}
+
+DebuggerScript.getScripts = function(contextData)
+{
+    var result = [];
+
+    if (!contextData)
+        return result;
+    var comma = contextData.indexOf(",");
+    if (comma === -1)
+        return result;
+    // Context data is a string in the following format:
+    // ("page"|"injected")","<page id>
+    var idSuffix = contextData.substring(comma); // including the comma
+
+    var scripts = Debug.scripts();
+    for (var i = 0; i < scripts.length; ++i) {
+        var script = scripts[i];
+        if (script.context_data && script.context_data.lastIndexOf(idSuffix) != -1)
+            result.push(DebuggerScript._formatScript(script));
+    }
+    return result;
+}
+
+DebuggerScript._formatScript = function(script)
+{
+    var scriptWorldType = DebuggerScript.ScriptWorldType.MainWorld;
+    if (script.context_data && script.context_data.indexOf("injected") == 0)
+        scriptWorldType = DebuggerScript.ScriptWorldType.ExtensionsWorld;
+    return {
+        id: script.id,
+        name: script.name,
+        source: script.source,
+        lineOffset: DebuggerScript._v8ToWebkitLineNumber(script.line_offset),
+        lineCount: script.lineCount(),
+        scriptWorldType: scriptWorldType
+    };
+}
+
+DebuggerScript.setBreakpoint = function(execState, args)
+{
+    args.lineNumber = DebuggerScript._webkitToV8LineNumber(args.lineNumber);
+    var breakId = Debug.setScriptBreakPointById(args.scriptId, args.lineNumber, 0 /* column */, args.condition);
+    if (!args.enabled)
+        Debug.disableScriptBreakPoint(breakId);
+
+    var locations = Debug.findBreakPointActualLocations(breakId);
+    var actualLineNumber = locations.length ? locations[0].line : args.lineNumber;
+
+    var key = args.scriptId + ":" + actualLineNumber;
+    if (key in DebuggerScript._breakpoints) {
+        // Remove old breakpoint.
+        Debug.findBreakPoint(DebuggerScript._breakpoints[key], true);
+    }
+    DebuggerScript._breakpoints[key] = breakId;
+    return DebuggerScript._v8ToWebkitLineNumber(actualLineNumber);
+}
+
+DebuggerScript.removeBreakpoint = function(execState, args)
+{
+    args.lineNumber = DebuggerScript._webkitToV8LineNumber(args.lineNumber);
+    var key = args.scriptId + ":" + args.lineNumber;
+    var breakId = DebuggerScript._breakpoints[key];
+    if (breakId)
+        Debug.findBreakPoint(breakId, true);
+    delete DebuggerScript._breakpoints[key];
+}
+
+DebuggerScript.pauseOnExceptionsState = function()
+{
+    return DebuggerScript._pauseOnExceptionsState;
+}
+
+DebuggerScript.setPauseOnExceptionsState = function(newState)
+{
+    DebuggerScript._pauseOnExceptionsState = newState;
+
+    if (DebuggerScript.PauseOnExceptionsState.PauseOnAllExceptions === newState)
+        Debug.setBreakOnException();
+    else
+        Debug.clearBreakOnException();
+
+    if (DebuggerScript.PauseOnExceptionsState.PauseOnUncaughtExceptions === newState)
+        Debug.setBreakOnUncaughtException();
+    else
+        Debug.clearBreakOnUncaughtException();
+}
+
+DebuggerScript.currentCallFrame = function(execState, args)
+{
+    var frameCount = execState.frameCount();
+    if (frameCount === 0)
+        return undefined;
+    
+    var topFrame;
+    for (var i = frameCount - 1; i >= 0; i--) {
+        var frameMirror = execState.frame(i);
+        topFrame = DebuggerScript._frameMirrorToJSCallFrame(frameMirror, topFrame);
+    }
+    return topFrame;
+}
+
+DebuggerScript.stepIntoStatement = function(execState)
+{
+    execState.prepareStep(Debug.StepAction.StepIn, 1);
+}
+
+DebuggerScript.stepOverStatement = function(execState)
+{
+    execState.prepareStep(Debug.StepAction.StepNext, 1);
+}
+
+DebuggerScript.stepOutOfFunction = function(execState)
+{
+    execState.prepareStep(Debug.StepAction.StepOut, 1);
+}
+
+DebuggerScript.editScriptSource = function(scriptId, newSource)
+{
+    var scripts = Debug.scripts();
+    var scriptToEdit = null;
+    for (var i = 0; i < scripts.length; i++) {
+        if (scripts[i].id == scriptId) {
+            scriptToEdit = scripts[i];
+            break;
+        }
+    }
+    if (!scriptToEdit)
+        throw("Script not found");
+
+    var changeLog = [];
+    Debug.LiveEdit.SetScriptSource(scriptToEdit, newSource, false, changeLog);
+    return scriptToEdit.source;
+}
+
+DebuggerScript.clearBreakpoints = function(execState, args)
+{
+    for (var key in DebuggerScript._breakpoints) {
+        var breakId = DebuggerScript._breakpoints[key];
+        Debug.findBreakPoint(breakId, true);
+    }
+    DebuggerScript._breakpoints = {};
+}
+
+DebuggerScript.setBreakpointsActivated = function(execState, args)
+{
+    for (var key in DebuggerScript._breakpoints) {
+        var breakId = DebuggerScript._breakpoints[key];
+        if (args.enabled)
+            Debug.enableScriptBreakPoint(breakId);
+        else
+            Debug.disableScriptBreakPoint(breakId);
+    }
+}
+
+DebuggerScript._frameMirrorToJSCallFrame = function(frameMirror, callerFrame)
+{
+    // Get function name.
+    var func;
+    try {
+        func = frameMirror.func();
+    } catch(e) {
+    }
+    var functionName;
+    if (func)
+        functionName = func.name() || func.inferredName();
+        
+    // Get script ID.
+    var script = func.script();
+    var sourceID = script && script.id();
+    
+    // Get line number.
+    var line = DebuggerScript._v8ToWebkitLineNumber(frameMirror.sourceLine());
+    
+    // Get this object.
+    var thisObject = frameMirror.details_.receiver();
+
+    // Get scope chain array in format: [<scope type>, <scope object>, <scope type>, <scope object>,...]
+    var scopeChain = [];
+    var scopeType = [];
+    for (var i = 0; i < frameMirror.scopeCount(); i++) {
+        var scopeMirror = frameMirror.scope(i);
+        var scopeObjectMirror = scopeMirror.scopeObject();
+        var properties = scopeObjectMirror.properties();
+        var scopeObject = {};
+        for (var j = 0; j < properties.length; j++)
+            scopeObject[properties[j].name()] = properties[j].value_;
+        // Reset scope object prototype to null so that the proto properties
+        // don't appear in th local scope section.
+        scopeObject.__proto__ = null;
+        scopeType.push(scopeMirror.scopeType());
+        scopeChain.push(scopeObject);
+    }
+    
+    function evaluate(expression) {
+        return frameMirror.evaluate(expression, false).value();
+    }
+    
+    return {
+        "sourceID": sourceID,
+        "line": line,
+        "functionName": functionName,
+        "type": "function",
+        "thisObject": thisObject,
+        "scopeChain": scopeChain,
+        "scopeType": scopeType,
+        "evaluate": evaluate,
+        "caller": callerFrame
+    };
+}
+
+DebuggerScript._webkitToV8LineNumber = function(line)
+{
+    return line - 1;
+};
+
+DebuggerScript._v8ToWebkitLineNumber = function(line)
+{
+    return line + 1;
+};
+
+return DebuggerScript;
+
+})();