Changeset 85035 in webkit


Ignore:
Timestamp:
Apr 27, 2011 1:55:09 AM (13 years ago)
Author:
yurys@chromium.org
Message:

2011-04-26 Yury Semikhatsky <yurys@chromium.org>

Reviewed by Pavel Feldman.

Web Inspector: [protocol] Paused event should expose exception value that caused it
https://bugs.webkit.org/show_bug.cgi?id=58996

Debug.pause event now contains an optional reference to the exception
object in case script execution is paused on a JavaScript exception.

Also JavaScript call frames are passed directly into the injected script when
we need to wrap them for passing to the front-end. This change breaks cyclic
dependency ScriptDebugServer->InspectorDebuggerAgent->InjectedScript->InjectedScriptHost->ScriptDebugServer

  • bindings/js/JSInjectedScriptHostCustom.cpp:
  • bindings/js/ScriptDebugServer.cpp: (WebCore::ScriptDebugServer::dispatchDidPause):
  • bindings/js/ScriptDebugServer.h:
  • bindings/v8/ScriptDebugServer.cpp: (WebCore::ScriptDebugServer::breakProgram): (WebCore::ScriptDebugServer::editScriptSource): (WebCore::ScriptDebugServer::breakProgramCallback): (WebCore::ScriptDebugServer::handleV8DebugEvent):
  • bindings/v8/ScriptDebugServer.h:
  • bindings/v8/custom/V8InjectedScriptHostCustom.cpp:
  • inspector/InjectedScript.cpp: (WebCore::InjectedScript::evaluateOnCallFrame): (WebCore::InjectedScript::wrapCallFrames):
  • inspector/InjectedScript.h:
  • inspector/InjectedScriptHost.cpp:
  • inspector/InjectedScriptHost.h: (WebCore::InjectedScriptHost::init):
  • inspector/InjectedScriptHost.idl:
  • inspector/InjectedScriptSource.js: (.):
  • inspector/Inspector.json:
  • inspector/InspectorAgent.cpp: (WebCore::InspectorAgent::InspectorAgent):
  • inspector/InspectorDebuggerAgent.cpp: (WebCore::InspectorDebuggerAgent::evaluateOnCallFrame): (WebCore::InspectorDebuggerAgent::currentCallFrames): (WebCore::InspectorDebuggerAgent::wrapCallFrames): (WebCore::InspectorDebuggerAgent::didPause): (WebCore::InspectorDebuggerAgent::didContinue): (WebCore::InspectorDebuggerAgent::clear):
  • inspector/InspectorDebuggerAgent.h:
  • inspector/ScriptDebugListener.h:
  • inspector/WorkerInspectorController.cpp: (WebCore::WorkerInspectorController::WorkerInspectorController):
Location:
trunk/Source/WebCore
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r85034 r85035  
     12011-04-26  Yury Semikhatsky  <yurys@chromium.org>
     2
     3        Reviewed by Pavel Feldman.
     4
     5        Web Inspector: [protocol] Paused event should expose exception value that caused it
     6        https://bugs.webkit.org/show_bug.cgi?id=58996
     7
     8        Debug.pause event now contains an optional reference to the exception
     9        object in case script execution is paused on a JavaScript exception.
     10
     11        Also JavaScript call frames are passed directly into the injected script when
     12        we need to wrap them for passing to the front-end. This change breaks cyclic
     13        dependency ScriptDebugServer->InspectorDebuggerAgent->InjectedScript->InjectedScriptHost->ScriptDebugServer
     14
     15        * bindings/js/JSInjectedScriptHostCustom.cpp:
     16        * bindings/js/ScriptDebugServer.cpp:
     17        (WebCore::ScriptDebugServer::dispatchDidPause):
     18        * bindings/js/ScriptDebugServer.h:
     19        * bindings/v8/ScriptDebugServer.cpp:
     20        (WebCore::ScriptDebugServer::breakProgram):
     21        (WebCore::ScriptDebugServer::editScriptSource):
     22        (WebCore::ScriptDebugServer::breakProgramCallback):
     23        (WebCore::ScriptDebugServer::handleV8DebugEvent):
     24        * bindings/v8/ScriptDebugServer.h:
     25        * bindings/v8/custom/V8InjectedScriptHostCustom.cpp:
     26        * inspector/InjectedScript.cpp:
     27        (WebCore::InjectedScript::evaluateOnCallFrame):
     28        (WebCore::InjectedScript::wrapCallFrames):
     29        * inspector/InjectedScript.h:
     30        * inspector/InjectedScriptHost.cpp:
     31        * inspector/InjectedScriptHost.h:
     32        (WebCore::InjectedScriptHost::init):
     33        * inspector/InjectedScriptHost.idl:
     34        * inspector/InjectedScriptSource.js:
     35        (.):
     36        * inspector/Inspector.json:
     37        * inspector/InspectorAgent.cpp:
     38        (WebCore::InspectorAgent::InspectorAgent):
     39        * inspector/InspectorDebuggerAgent.cpp:
     40        (WebCore::InspectorDebuggerAgent::evaluateOnCallFrame):
     41        (WebCore::InspectorDebuggerAgent::currentCallFrames):
     42        (WebCore::InspectorDebuggerAgent::wrapCallFrames):
     43        (WebCore::InspectorDebuggerAgent::didPause):
     44        (WebCore::InspectorDebuggerAgent::didContinue):
     45        (WebCore::InspectorDebuggerAgent::clear):
     46        * inspector/InspectorDebuggerAgent.h:
     47        * inspector/ScriptDebugListener.h:
     48        * inspector/WorkerInspectorController.cpp:
     49        (WebCore::WorkerInspectorController::WorkerInspectorController):
     50
    1512011-04-27  Pavel Feldman  <pfeldman@google.com>
    252
  • trunk/Source/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp

    r84641 r85035  
    5252#include <runtime/JSLock.h>
    5353
    54 #if ENABLE(JAVASCRIPT_DEBUGGER)
    55 #include "JavaScriptCallFrame.h"
    56 #include "JSJavaScriptCallFrame.h"
    57 #include "ScriptDebugServer.h"
    58 #endif
    59 
    6054using namespace JSC;
    6155
     
    7367    JSLock lock(SilenceAssertionsOnly);
    7468    return ScriptValue(state->globalData(), toJS(state, deprecatedGlobalObjectForPrototype(state), node));
    75 }
    76 
    77 JSValue JSInjectedScriptHost::currentCallFrame(ExecState* exec)
    78 {
    79 #if ENABLE(JAVASCRIPT_DEBUGGER)
    80     JavaScriptCallFrame* callFrame = impl()->debuggerAgent()->scriptDebugServer().currentCallFrame();
    81     if (!callFrame || !callFrame->isValid())
    82         return jsUndefined();
    83 
    84     JSLock lock(SilenceAssertionsOnly);
    85     return toJS(exec, globalObject(), callFrame);
    86 #else
    87     UNUSED_PARAM(exec);
    88     return jsUndefined();
    89 #endif
    9069}
    9170
  • trunk/Source/WebCore/bindings/js/ScriptDebugServer.cpp

    r84371 r85035  
    3535#include "EventLoop.h"
    3636#include "Frame.h"
     37#include "JSJavaScriptCallFrame.h"
    3738#include "JavaScriptCallFrame.h"
    3839#include "ScriptBreakpoint.h"
     
    189190}
    190191
    191 bool ScriptDebugServer::editScriptSource(const String&, const String&, String*)
     192bool ScriptDebugServer::editScriptSource(const String&, const String&, String*, ScriptValue*)
    192193{
    193194    // FIXME(40300): implement this.
     
    195196}
    196197
    197 JavaScriptCallFrame* ScriptDebugServer::currentCallFrame()
    198 {
    199     if (!m_paused)
    200         return 0;
    201     return m_currentCallFrame.get();
    202 }
    203 
    204198void ScriptDebugServer::dispatchDidPause(ScriptDebugListener* listener)
    205199{
    206200    ASSERT(m_paused);
    207     ScriptState* state = m_currentCallFrame->scopeChain()->globalObject->globalExec();
    208     listener->didPause(state);
     201    JSGlobalObject* globalObject = m_currentCallFrame->scopeChain()->globalObject.get();
     202    ScriptState* state = globalObject->globalExec();
     203    JSValue jsCallFrame;
     204    {
     205        if (m_currentCallFrame->isValid() && globalObject->inherits(&JSDOMGlobalObject::s_info)) {
     206            JSDOMGlobalObject* domGlobalObject = static_cast<JSDOMGlobalObject*>(globalObject);
     207            JSLock lock(SilenceAssertionsOnly);
     208            jsCallFrame = toJS(state, domGlobalObject, m_currentCallFrame.get());
     209        } else
     210            jsCallFrame = jsUndefined();
     211    }
     212    listener->didPause(state, ScriptValue(state->globalData(), jsCallFrame), ScriptValue());
    209213}
    210214
  • trunk/Source/WebCore/bindings/js/ScriptDebugServer.h

    r83601 r85035  
    5151namespace WebCore {
    5252
     53class JavaScriptCallFrame;
    5354class ScriptDebugListener;
    54 class JavaScriptCallFrame;
     55class ScriptValue;
    5556
    5657class ScriptDebugServer : protected JSC::Debugger {
     
    7980    void stepOutOfFunction();
    8081
    81     bool editScriptSource(const String& sourceID, const String& newContent, String* error);
     82    bool editScriptSource(const String& sourceID, const String& newContent, String* error, ScriptValue* newCallFrames);
    8283
    8384    void recompileAllJSFunctionsSoon();
    8485    virtual void recompileAllJSFunctions(Timer<ScriptDebugServer>* = 0) = 0;
    85 
    86     JavaScriptCallFrame* currentCallFrame();
    8786
    8887protected:
  • trunk/Source/WebCore/bindings/v8/ScriptDebugServer.cpp

    r84890 r85035  
    3838#include "ScriptDebugListener.h"
    3939#include "V8Binding.h"
     40#include "V8JavaScriptCallFrame.h"
    4041#include <wtf/StdLibExtras.h>
    4142
     
    171172        return;
    172173
    173     m_pausedPageContext = *context;
     174    m_pausedContext = *context;
    174175    v8::Handle<v8::Function> breakProgramFunction = m_breakProgramCallbackTemplate.get()->GetFunction();
    175176    v8::Debug::Call(breakProgramFunction);
    176     m_pausedPageContext.Clear();
     177    m_pausedContext.Clear();
    177178}
    178179
     
    181182    if (isPaused())
    182183        quitMessageLoopOnPause();
    183     m_currentCallFrame.clear();
    184184    m_executionState.clear();
    185185}
     
    212212}
    213213
    214 bool ScriptDebugServer::editScriptSource(const String& sourceID, const String& newContent, String* error)
     214bool ScriptDebugServer::editScriptSource(const String& sourceID, const String& newContent, String* error, ScriptValue* newCallFrames)
    215215{
    216216    ensureDebuggerScriptCompiled();
     
    238238
    239239    // Call stack may have changed after if the edited function was on the stack.
    240     if (m_currentCallFrame)
    241         m_currentCallFrame.clear();
     240    if (isPaused())
     241        *newCallFrames = currentCallFrame();
    242242    return true;
    243243}
    244244
    245 PassRefPtr<JavaScriptCallFrame> ScriptDebugServer::currentCallFrame()
    246 {
    247     if (!m_currentCallFrame) {
    248         v8::Handle<v8::Function> currentCallFrameFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("currentCallFrame")));
    249         v8::Handle<v8::Value> argv[] = { m_executionState.get() };
    250         v8::Handle<v8::Value> currentCallFrameV8 = currentCallFrameFunction->Call(m_debuggerScript.get(), 1, argv);
    251         m_currentCallFrame = JavaScriptCallFrame::create(v8::Debug::GetDebugContext(), v8::Handle<v8::Object>::Cast(currentCallFrameV8));
    252     }
    253     return m_currentCallFrame;
     245ScriptValue ScriptDebugServer::currentCallFrame()
     246{
     247    ASSERT(isPaused());
     248    v8::Handle<v8::Function> currentCallFrameFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("currentCallFrame")));
     249    v8::Handle<v8::Value> argv[] = { m_executionState.get() };
     250    v8::Handle<v8::Value> currentCallFrameV8 = currentCallFrameFunction->Call(m_debuggerScript.get(), 1, argv);
     251    RefPtr<JavaScriptCallFrame> currentCallFrame = JavaScriptCallFrame::create(v8::Debug::GetDebugContext(), v8::Handle<v8::Object>::Cast(currentCallFrameV8));
     252    v8::Context::Scope contextScope(m_pausedContext);
     253    return ScriptValue(toV8(currentCallFrame.release()));
    254254}
    255255
     
    275275   
    276276    ScriptDebugServer* thisPtr = toScriptDebugServer(args.Data());
    277     thisPtr->breakProgram(v8::Handle<v8::Object>::Cast(args[0]));
     277    v8::Handle<v8::Value> exception;
     278    thisPtr->breakProgram(v8::Handle<v8::Object>::Cast(args[0]), exception);
    278279    return v8::Undefined();
    279280}
    280281
    281 void ScriptDebugServer::breakProgram(v8::Handle<v8::Object> executionState)
     282void ScriptDebugServer::breakProgram(v8::Handle<v8::Object> executionState, v8::Handle<v8::Value> exception)
    282283{
    283284    // Don't allow nested breaks.
     
    285286        return;
    286287
    287     ScriptDebugListener* listener = getDebugListenerForContext(m_pausedPageContext);
     288    ScriptDebugListener* listener = getDebugListenerForContext(m_pausedContext);
    288289    if (!listener)
    289290        return;
    290291
    291292    m_executionState.set(executionState);
    292     ScriptState* currentCallFrameState = ScriptState::forContext(m_pausedPageContext);
    293     listener->didPause(currentCallFrameState);
    294 
    295     runMessageLoopOnPause(m_pausedPageContext);
     293    ScriptState* currentCallFrameState = ScriptState::forContext(m_pausedContext);
     294    listener->didPause(currentCallFrameState, currentCallFrame(), ScriptValue(exception));
     295
     296    runMessageLoopOnPause(m_pausedContext);
    296297}
    297298
     
    330331            dispatchDidParseSource(listener, object);
    331332        } else if (event == v8::Break || event == v8::Exception) {
     333            v8::Handle<v8::Value> exception;
    332334            if (event == v8::Exception) {
    333335                v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(1);
     
    335337                if (!stackTrace->GetFrameCount())
    336338                    return;
     339                v8::Handle<v8::Object> eventData = eventDetails.GetEventData();
     340                v8::Handle<v8::Value> exceptionGetterValue = eventData->Get(v8::String::New("exception"));
     341                ASSERT(!exceptionGetterValue.IsEmpty() && exceptionGetterValue->IsFunction());
     342                v8::Handle<v8::Value> argv[] = { v8::Handle<v8::Value>() };
     343                exception = v8::Handle<v8::Function>::Cast(exceptionGetterValue)->Call(eventData, 0, argv);
    337344            }
    338345
    339             m_pausedPageContext = *eventContext;
    340             breakProgram(eventDetails.GetExecutionState());
    341             m_pausedPageContext.Clear();
     346            m_pausedContext = *eventContext;
     347            breakProgram(eventDetails.GetExecutionState(), exception);
     348            m_pausedContext.Clear();
    342349        }
    343350    }
  • trunk/Source/WebCore/bindings/v8/ScriptDebugServer.h

    r82590 r85035  
    3434#if ENABLE(JAVASCRIPT_DEBUGGER)
    3535
    36 #include "JavaScriptCallFrame.h"
     36#include "OwnHandle.h"
    3737#include "PlatformString.h"
    3838#include "ScriptBreakpoint.h"
     
    4747
    4848class ScriptDebugListener;
     49class ScriptValue;
    4950
    5051class ScriptDebugServer {
     
    7374    void stepOutOfFunction();
    7475
    75     bool editScriptSource(const String& sourceID, const String& newContent, String* error);
     76    bool editScriptSource(const String& sourceID, const String& newContent, String* error, ScriptValue* newCallFrames);
    7677
    7778    void recompileAllJSFunctionsSoon() { }
    7879    void recompileAllJSFunctions(Timer<ScriptDebugServer>* = 0) { }
    79 
    80     PassRefPtr<JavaScriptCallFrame> currentCallFrame();
    8180
    8281    class Task {
     
    9291    ~ScriptDebugServer() { }
    9392   
     93    ScriptValue currentCallFrame();
     94
    9495    virtual ScriptDebugListener* getDebugListenerForContext(v8::Handle<v8::Context>) = 0;
    9596    virtual void runMessageLoopOnPause(v8::Handle<v8::Context>) = 0;
     
    9798
    9899    static v8::Handle<v8::Value> breakProgramCallback(const v8::Arguments& args);
    99     void breakProgram(v8::Handle<v8::Object> executionState);
     100    void breakProgram(v8::Handle<v8::Object> executionState, v8::Handle<v8::Value> exception);
    100101
    101102    static void v8DebugEventCallback(const v8::Debug::EventDetails& eventDetails);
     
    110111    PauseOnExceptionsState m_pauseOnExceptionsState;
    111112    OwnHandle<v8::Object> m_debuggerScript;
    112     RefPtr<JavaScriptCallFrame> m_currentCallFrame;
    113113    OwnHandle<v8::Object> m_executionState;
    114     v8::Local<v8::Context> m_pausedPageContext;
     114    v8::Local<v8::Context> m_pausedContext;
    115115
    116116    bool m_breakpointsActivated;
  • trunk/Source/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp

    r82449 r85035  
    3535#include "InjectedScript.h"
    3636#include "InjectedScriptHost.h"
    37 #include "InspectorDebuggerAgent.h"
    3837#include "InspectorValues.h"
    39 #include "ScriptDebugServer.h"
    4038#include "ScriptValue.h"
    4139#include "V8Binding.h"
     
    4341#include "V8Database.h"
    4442#include "V8HiddenPropertyName.h"
    45 #include "V8JavaScriptCallFrame.h"
    4643#include "V8Node.h"
    4744#include "V8Proxy.h"
     
    107104}
    108105
    109 v8::Handle<v8::Value> V8InjectedScriptHost::currentCallFrameCallback(const v8::Arguments& args)
    110 {
    111 #if ENABLE(JAVASCRIPT_DEBUGGER)
    112     INC_STATS("InjectedScriptHost.currentCallFrame()");
    113     InjectedScriptHost* host = V8InjectedScriptHost::toNative(args.Holder());
    114     return toV8(host->debuggerAgent()->scriptDebugServer().currentCallFrame());
    115 #else
    116     UNUSED_PARAM(args);
    117     return v8::Undefined();
    118 #endif
    119 }
    120 
    121106v8::Handle<v8::Value> V8InjectedScriptHost::databaseIdCallback(const v8::Arguments& args)
    122107{
  • trunk/Source/WebCore/inspector/InjectedScript.cpp

    r82803 r85035  
    7272}
    7373
    74 void InjectedScript::evaluateOnCallFrame(ErrorString* errorString, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr<InspectorObject>* result)
     74void InjectedScript::evaluateOnCallFrame(ErrorString* errorString, const ScriptValue& callFrames, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr<InspectorObject>* result)
    7575{
    7676    ScriptFunctionCall function(m_injectedScriptObject, "evaluateOnCallFrame");
     77    function.appendArgument(callFrames);
    7778    function.appendArgument(callFrameId);
    7879    function.appendArgument(expression);
     
    132133
    133134#if ENABLE(JAVASCRIPT_DEBUGGER)
    134 PassRefPtr<InspectorArray> InjectedScript::callFrames()
    135 {
    136     ASSERT(!hasNoValue());
    137     ScriptFunctionCall function(m_injectedScriptObject, "callFrames");
     135PassRefPtr<InspectorArray> InjectedScript::wrapCallFrames(const ScriptValue& callFrames)
     136{
     137    ASSERT(!hasNoValue());
     138    ScriptFunctionCall function(m_injectedScriptObject, "wrapCallFrames");
     139    function.appendArgument(callFrames);
    138140    ScriptValue callFramesValue = function.call();
    139141    RefPtr<InspectorValue> result = callFramesValue.toInspectorValue(m_injectedScriptObject.scriptState());
  • trunk/Source/WebCore/inspector/InjectedScript.h

    r82803 r85035  
    5858    void evaluate(ErrorString*, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr<InspectorObject>* result);
    5959    void evaluateOn(ErrorString*, const String& objectId, const String& expression, RefPtr<InspectorObject>* result);
    60     void evaluateOnCallFrame(ErrorString*, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr<InspectorObject>* result);
     60    void evaluateOnCallFrame(ErrorString*, const ScriptValue& callFrames, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, RefPtr<InspectorObject>* result);
    6161    void getProperties(ErrorString*, const String& objectId, bool ignoreHasOwnProperty, RefPtr<InspectorArray>* result);
    6262    Node* nodeForObjectId(const String& objectId);
     
    6565
    6666#if ENABLE(JAVASCRIPT_DEBUGGER)
    67     PassRefPtr<InspectorArray> callFrames();
     67    PassRefPtr<InspectorArray> wrapCallFrames(const ScriptValue&);
    6868#endif
    6969
  • trunk/Source/WebCore/inspector/InjectedScriptHost.cpp

    r81572 r85035  
    4747#include "InspectorValues.h"
    4848#include "Pasteboard.h"
    49 
    50 #if ENABLE(JAVASCRIPT_DEBUGGER)
    51 #include "ScriptDebugServer.h"
    52 #endif
    5349
    5450#if ENABLE(DATABASE)
  • trunk/Source/WebCore/inspector/InjectedScriptHost.h

    r82449 r85035  
    4848class InspectorDOMStorageAgent;
    4949class InspectorDatabaseAgent;
    50 class InspectorDebuggerAgent;
    5150class InspectorFrontend;
    5251class InspectorObject;
     
    7069            , InspectorDOMStorageAgent* domStorageAgent
    7170#endif
    72 #if ENABLE(JAVASCRIPT_DEBUGGER)
    73             , InspectorDebuggerAgent* debuggerAgent
    74 #endif
    7571        )
    7672    {
     
    8278#if ENABLE(DOM_STORAGE)
    8379        m_domStorageAgent = domStorageAgent;
    84 #endif
    85 #if ENABLE(JAVASCRIPT_DEBUGGER)
    86         m_debuggerAgent = debuggerAgent;
    8780#endif
    8881    }
     
    113106    void didDestroyWorker(long id);
    114107#endif
    115 #if ENABLE(JAVASCRIPT_DEBUGGER)
    116     InspectorDebuggerAgent* debuggerAgent() { return m_debuggerAgent; }
    117 #endif
    118108
    119109private:
     
    128118    InspectorDOMStorageAgent* m_domStorageAgent;
    129119#endif
    130 #if ENABLE(JAVASCRIPT_DEBUGGER)
    131     InspectorDebuggerAgent* m_debuggerAgent;
    132 #endif
    133120    InspectorFrontend* m_frontend;
    134121    long m_lastWorkerId;
  • trunk/Source/WebCore/inspector/InjectedScriptHost.idl

    r81572 r85035  
    4040        [Custom] DOMObject internalConstructorName(in DOMObject object);
    4141
    42         [Custom] DOMObject currentCallFrame();
    4342        [Custom] int databaseId(in DOMObject database);
    4443        [Custom] int storageId(in DOMObject storage);
  • trunk/Source/WebCore/inspector/InjectedScriptSource.js

    r84351 r85035  
    294294    },
    295295
    296     callFrames: function()
    297     {
    298         var callFrame = InjectedScriptHost.currentCallFrame();
     296    wrapCallFrames: function(callFrame)
     297    {
    299298        if (!callFrame)
    300299            return false;
     
    309308    },
    310309
    311     evaluateOnCallFrame: function(callFrameId, expression, objectGroup, injectCommandLineAPI)
    312     {
    313         var callFrame = this._callFrameForId(callFrameId);
     310    evaluateOnCallFrame: function(topCallFrame, callFrameId, expression, objectGroup, injectCommandLineAPI)
     311    {
     312        var callFrame = this._callFrameForId(topCallFrame, callFrameId);
    314313        if (!callFrame)
    315314            return "Could not find call frame with given id";
     
    317316    },
    318317
    319     _callFrameForId: function(callFrameId)
     318    _callFrameForId: function(topCallFrame, callFrameId)
    320319    {
    321320        var parsedCallFrameId = eval("(" + callFrameId + ")");
    322321        var ordinal = parsedCallFrameId.ordinal;
    323         var callFrame = InjectedScriptHost.currentCallFrame();
     322        var callFrame = topCallFrame;
    324323        while (--ordinal >= 0 && callFrame)
    325324            callFrame = callFrame.caller;
  • trunk/Source/WebCore/inspector/Inspector.json

    r84905 r85035  
    15021502                        "type": "object",
    15031503                        "properties": [
    1504                             { "name": "callFrames", "type": "array", "items": { "$ref": "CallFrame" }, "description": "Call stack the virtual machine stopped on." }
     1504                            { "name": "callFrames", "type": "array", "items": { "$ref": "CallFrame" }, "description": "Call stack the virtual machine stopped on." },
     1505                            { "name": "exception", "$ref": "Runtime.RemoteObject", "optional": true, "description": "Current exception object if script execution is paused when an exception is being thrown." }
    15051506                        ],
    15061507                        "description": "Call stack information."
  • trunk/Source/WebCore/inspector/InspectorAgent.cpp

    r84905 r85035  
    153153        , m_domStorageAgent.get()
    154154#endif
    155 #if ENABLE(JAVASCRIPT_DEBUGGER)
    156         , m_debuggerAgent.get()
    157 #endif
    158155    );
    159156}
  • trunk/Source/WebCore/inspector/InspectorDebuggerAgent.cpp

    r83706 r85035  
    4040#include "PlatformString.h"
    4141#include "ScriptDebugServer.h"
     42#include "ScriptObject.h"
    4243#include <wtf/text/StringConcatenate.h>
    4344
     
    280281void InspectorDebuggerAgent::editScriptSource(ErrorString* error, const String& sourceID, const String& newContent, RefPtr<InspectorArray>* newCallFrames)
    281282{
    282     if (scriptDebugServer().editScriptSource(sourceID, newContent, error))
     283    if (scriptDebugServer().editScriptSource(sourceID, newContent, error, &m_currentCallStack))
    283284        *newCallFrames = currentCallFrames();
    284285}
     
    356357    InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(callFrameId);
    357358    if (!injectedScript.hasNoValue())
    358         injectedScript.evaluateOnCallFrame(errorString, callFrameId, expression, objectGroup ? *objectGroup : "", includeCommandLineAPI ? *includeCommandLineAPI : false, result);
     359        injectedScript.evaluateOnCallFrame(errorString, m_currentCallStack, callFrameId, expression, objectGroup ? *objectGroup : "", includeCommandLineAPI ? *includeCommandLineAPI : false, result);
    359360}
    360361
     
    368369        return InspectorArray::create();
    369370    }
    370     return injectedScript.callFrames();
     371    return injectedScript.wrapCallFrames(m_currentCallStack);
    371372}
    372373
     
    405406}
    406407
    407 void InspectorDebuggerAgent::didPause(ScriptState* scriptState)
     408void InspectorDebuggerAgent::didPause(ScriptState* scriptState, const ScriptValue& callFrames, const ScriptValue& exception)
    408409{
    409410    ASSERT(scriptState && !m_pausedScriptState);
    410411    m_pausedScriptState = scriptState;
     412    m_currentCallStack = callFrames;
    411413
    412414    if (!m_breakProgramDetails)
     
    414416    m_breakProgramDetails->setValue("callFrames", currentCallFrames());
    415417
     418    if (!exception.hasNoValue()) {
     419        InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState);
     420        if (!injectedScript.hasNoValue())
     421            m_breakProgramDetails->setValue("exception", injectedScript.wrapObject(exception, "backtrace"));
     422    }
     423
    416424    m_frontend->paused(m_breakProgramDetails);
    417425    m_javaScriptPauseScheduled = false;
     
    426434{
    427435    m_pausedScriptState = 0;
     436    m_currentCallStack = ScriptValue();
    428437    m_breakProgramDetails = 0;
    429438    m_frontend->resumed();
     
    441450{
    442451    m_pausedScriptState = 0;
     452    m_currentCallStack = ScriptValue();
    443453    m_scripts.clear();
    444454    m_breakpointIdToDebugServerBreakpointIds.clear();
  • trunk/Source/WebCore/inspector/InspectorDebuggerAgent.h

    r83706 r85035  
    5454class InstrumentingAgents;
    5555class ScriptDebugServer;
     56class ScriptValue;
    5657
    5758typedef String ErrorString;
     
    122123    virtual void didParseSource(const String& sourceID, const String& url, const String& data, int lineOffset, int columnOffset, bool isContentScript);
    123124    virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage);
    124     virtual void didPause(ScriptState*);
     125    virtual void didPause(ScriptState*, const ScriptValue& callFrames, const ScriptValue& exception);
    125126    virtual void didContinue();
    126127
     
    161162    InspectorFrontend::Debugger* m_frontend;
    162163    ScriptState* m_pausedScriptState;
     164    ScriptValue m_currentCallStack;
    163165    ScriptsMap m_scripts;
    164166    BreakpointIdToDebugServerBreakpointIdsMap m_breakpointIdToDebugServerBreakpointIds;
  • trunk/Source/WebCore/inspector/ScriptDebugListener.h

    r83601 r85035  
    3737
    3838namespace WebCore {
     39class ScriptValue;
    3940
    4041class ScriptDebugListener {
     
    4445    virtual void didParseSource(const String&  sourceID, const String& url, const String& data, int lineOffset, int columnOffset, bool isContentScript) = 0;
    4546    virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage) = 0;
    46     virtual void didPause(ScriptState*) = 0;
     47    virtual void didPause(ScriptState*, const ScriptValue& callFrames, const ScriptValue& exception) = 0;
    4748    virtual void didContinue() = 0;
    4849};
  • trunk/Source/WebCore/inspector/WorkerInspectorController.cpp

    r84892 r85035  
    8787        , 0
    8888#endif
    89 #if ENABLE(JAVASCRIPT_DEBUGGER)
    90         , m_debuggerAgent.get()
    91 #endif
    9289    );
    9390}
Note: See TracChangeset for help on using the changeset viewer.