WebKit/chromium/src/js/DebuggerScript.js
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2010 Google Inc. All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions are
       
     6  * met:
       
     7  *
       
     8  *     * Redistributions of source code must retain the above copyright
       
     9  * notice, this list of conditions and the following disclaimer.
       
    10  *     * Redistributions in binary form must reproduce the above
       
    11  * copyright notice, this list of conditions and the following disclaimer
       
    12  * in the documentation and/or other materials provided with the
       
    13  * distribution.
       
    14  *     * Neither the name of Google Inc. nor the names of its
       
    15  * contributors may be used to endorse or promote products derived from
       
    16  * this software without specific prior written permission.
       
    17  *
       
    18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
    19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
    20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
    21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
    22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    29  */
       
    30 
       
    31 (function () {
       
    32 
       
    33 var DebuggerScript = {};
       
    34 DebuggerScript._breakpoints = {};
       
    35 
       
    36 DebuggerScript.PauseOnExceptionsState = {
       
    37     DontPauseOnExceptions : 0,
       
    38     PauseOnAllExceptions : 1,
       
    39     PauseOnUncaughtExceptions: 2
       
    40 };
       
    41 
       
    42 DebuggerScript.ScriptWorldType = {
       
    43     MainWorld : 0,
       
    44     ExtensionsWorld : 1
       
    45 };
       
    46 
       
    47 DebuggerScript._pauseOnExceptionsState = DebuggerScript.PauseOnExceptionsState.DontPauseOnExceptions;
       
    48 Debug.clearBreakOnException();
       
    49 Debug.clearBreakOnUncaughtException();
       
    50 
       
    51 DebuggerScript.getAfterCompileScript = function(eventData)
       
    52 {
       
    53     return DebuggerScript._formatScript(eventData.script_.script_);
       
    54 }
       
    55 
       
    56 DebuggerScript.getScripts = function(contextData)
       
    57 {
       
    58     var result = [];
       
    59 
       
    60     if (!contextData)
       
    61         return result;
       
    62     var comma = contextData.indexOf(",");
       
    63     if (comma === -1)
       
    64         return result;
       
    65     // Context data is a string in the following format:
       
    66     // ("page"|"injected")","<page id>
       
    67     var idSuffix = contextData.substring(comma); // including the comma
       
    68 
       
    69     var scripts = Debug.scripts();
       
    70     for (var i = 0; i < scripts.length; ++i) {
       
    71         var script = scripts[i];
       
    72         if (script.context_data && script.context_data.lastIndexOf(idSuffix) != -1)
       
    73             result.push(DebuggerScript._formatScript(script));
       
    74     }
       
    75     return result;
       
    76 }
       
    77 
       
    78 DebuggerScript._formatScript = function(script)
       
    79 {
       
    80     var scriptWorldType = DebuggerScript.ScriptWorldType.MainWorld;
       
    81     if (script.context_data && script.context_data.indexOf("injected") == 0)
       
    82         scriptWorldType = DebuggerScript.ScriptWorldType.ExtensionsWorld;
       
    83     return {
       
    84         id: script.id,
       
    85         name: script.name,
       
    86         source: script.source,
       
    87         lineOffset: DebuggerScript._v8ToWebkitLineNumber(script.line_offset),
       
    88         lineCount: script.lineCount(),
       
    89         scriptWorldType: scriptWorldType
       
    90     };
       
    91 }
       
    92 
       
    93 DebuggerScript.setBreakpoint = function(execState, args)
       
    94 {
       
    95     args.lineNumber = DebuggerScript._webkitToV8LineNumber(args.lineNumber);
       
    96     var breakId = Debug.setScriptBreakPointById(args.scriptId, args.lineNumber, 0 /* column */, args.condition);
       
    97     if (!args.enabled)
       
    98         Debug.disableScriptBreakPoint(breakId);
       
    99 
       
   100     var locations = Debug.findBreakPointActualLocations(breakId);
       
   101     var actualLineNumber = locations.length ? locations[0].line : args.lineNumber;
       
   102 
       
   103     var key = args.scriptId + ":" + actualLineNumber;
       
   104     if (key in DebuggerScript._breakpoints) {
       
   105         // Remove old breakpoint.
       
   106         Debug.findBreakPoint(DebuggerScript._breakpoints[key], true);
       
   107     }
       
   108     DebuggerScript._breakpoints[key] = breakId;
       
   109     return DebuggerScript._v8ToWebkitLineNumber(actualLineNumber);
       
   110 }
       
   111 
       
   112 DebuggerScript.removeBreakpoint = function(execState, args)
       
   113 {
       
   114     args.lineNumber = DebuggerScript._webkitToV8LineNumber(args.lineNumber);
       
   115     var key = args.scriptId + ":" + args.lineNumber;
       
   116     var breakId = DebuggerScript._breakpoints[key];
       
   117     if (breakId)
       
   118         Debug.findBreakPoint(breakId, true);
       
   119     delete DebuggerScript._breakpoints[key];
       
   120 }
       
   121 
       
   122 DebuggerScript.pauseOnExceptionsState = function()
       
   123 {
       
   124     return DebuggerScript._pauseOnExceptionsState;
       
   125 }
       
   126 
       
   127 DebuggerScript.setPauseOnExceptionsState = function(newState)
       
   128 {
       
   129     DebuggerScript._pauseOnExceptionsState = newState;
       
   130 
       
   131     if (DebuggerScript.PauseOnExceptionsState.PauseOnAllExceptions === newState)
       
   132         Debug.setBreakOnException();
       
   133     else
       
   134         Debug.clearBreakOnException();
       
   135 
       
   136     if (DebuggerScript.PauseOnExceptionsState.PauseOnUncaughtExceptions === newState)
       
   137         Debug.setBreakOnUncaughtException();
       
   138     else
       
   139         Debug.clearBreakOnUncaughtException();
       
   140 }
       
   141 
       
   142 DebuggerScript.currentCallFrame = function(execState, args)
       
   143 {
       
   144     var frameCount = execState.frameCount();
       
   145     if (frameCount === 0)
       
   146         return undefined;
       
   147     
       
   148     var topFrame;
       
   149     for (var i = frameCount - 1; i >= 0; i--) {
       
   150         var frameMirror = execState.frame(i);
       
   151         topFrame = DebuggerScript._frameMirrorToJSCallFrame(frameMirror, topFrame);
       
   152     }
       
   153     return topFrame;
       
   154 }
       
   155 
       
   156 DebuggerScript.stepIntoStatement = function(execState)
       
   157 {
       
   158     execState.prepareStep(Debug.StepAction.StepIn, 1);
       
   159 }
       
   160 
       
   161 DebuggerScript.stepOverStatement = function(execState)
       
   162 {
       
   163     execState.prepareStep(Debug.StepAction.StepNext, 1);
       
   164 }
       
   165 
       
   166 DebuggerScript.stepOutOfFunction = function(execState)
       
   167 {
       
   168     execState.prepareStep(Debug.StepAction.StepOut, 1);
       
   169 }
       
   170 
       
   171 DebuggerScript.editScriptSource = function(scriptId, newSource)
       
   172 {
       
   173     var scripts = Debug.scripts();
       
   174     var scriptToEdit = null;
       
   175     for (var i = 0; i < scripts.length; i++) {
       
   176         if (scripts[i].id == scriptId) {
       
   177             scriptToEdit = scripts[i];
       
   178             break;
       
   179         }
       
   180     }
       
   181     if (!scriptToEdit)
       
   182         throw("Script not found");
       
   183 
       
   184     var changeLog = [];
       
   185     Debug.LiveEdit.SetScriptSource(scriptToEdit, newSource, false, changeLog);
       
   186     return scriptToEdit.source;
       
   187 }
       
   188 
       
   189 DebuggerScript.clearBreakpoints = function(execState, args)
       
   190 {
       
   191     for (var key in DebuggerScript._breakpoints) {
       
   192         var breakId = DebuggerScript._breakpoints[key];
       
   193         Debug.findBreakPoint(breakId, true);
       
   194     }
       
   195     DebuggerScript._breakpoints = {};
       
   196 }
       
   197 
       
   198 DebuggerScript.setBreakpointsActivated = function(execState, args)
       
   199 {
       
   200     for (var key in DebuggerScript._breakpoints) {
       
   201         var breakId = DebuggerScript._breakpoints[key];
       
   202         if (args.enabled)
       
   203             Debug.enableScriptBreakPoint(breakId);
       
   204         else
       
   205             Debug.disableScriptBreakPoint(breakId);
       
   206     }
       
   207 }
       
   208 
       
   209 DebuggerScript._frameMirrorToJSCallFrame = function(frameMirror, callerFrame)
       
   210 {
       
   211     // Get function name.
       
   212     var func;
       
   213     try {
       
   214         func = frameMirror.func();
       
   215     } catch(e) {
       
   216     }
       
   217     var functionName;
       
   218     if (func)
       
   219         functionName = func.name() || func.inferredName();
       
   220         
       
   221     // Get script ID.
       
   222     var script = func.script();
       
   223     var sourceID = script && script.id();
       
   224     
       
   225     // Get line number.
       
   226     var line = DebuggerScript._v8ToWebkitLineNumber(frameMirror.sourceLine());
       
   227     
       
   228     // Get this object.
       
   229     var thisObject = frameMirror.details_.receiver();
       
   230 
       
   231     // Get scope chain array in format: [<scope type>, <scope object>, <scope type>, <scope object>,...]
       
   232     var scopeChain = [];
       
   233     var scopeType = [];
       
   234     for (var i = 0; i < frameMirror.scopeCount(); i++) {
       
   235         var scopeMirror = frameMirror.scope(i);
       
   236         var scopeObjectMirror = scopeMirror.scopeObject();
       
   237         var properties = scopeObjectMirror.properties();
       
   238         var scopeObject = {};
       
   239         for (var j = 0; j < properties.length; j++)
       
   240             scopeObject[properties[j].name()] = properties[j].value_;
       
   241         // Reset scope object prototype to null so that the proto properties
       
   242         // don't appear in th local scope section.
       
   243         scopeObject.__proto__ = null;
       
   244         scopeType.push(scopeMirror.scopeType());
       
   245         scopeChain.push(scopeObject);
       
   246     }
       
   247     
       
   248     function evaluate(expression) {
       
   249         return frameMirror.evaluate(expression, false).value();
       
   250     }
       
   251     
       
   252     return {
       
   253         "sourceID": sourceID,
       
   254         "line": line,
       
   255         "functionName": functionName,
       
   256         "type": "function",
       
   257         "thisObject": thisObject,
       
   258         "scopeChain": scopeChain,
       
   259         "scopeType": scopeType,
       
   260         "evaluate": evaluate,
       
   261         "caller": callerFrame
       
   262     };
       
   263 }
       
   264 
       
   265 DebuggerScript._webkitToV8LineNumber = function(line)
       
   266 {
       
   267     return line - 1;
       
   268 };
       
   269 
       
   270 DebuggerScript._v8ToWebkitLineNumber = function(line)
       
   271 {
       
   272     return line + 1;
       
   273 };
       
   274 
       
   275 return DebuggerScript;
       
   276 
       
   277 })();