Changeset 57812 in webkit


Ignore:
Timestamp:
Apr 19, 2010 10:01:39 AM (14 years ago)
Author:
yurys@chromium.org
Message:

2010-04-19 Yury Semikhatsky <yurys@chromium.org>

Reviewed by Pavel Feldman.

Web Inspector: implement JavaScriptCallFrame that works for v8.
Implementing this binding for v8 allows to make evaluations on
call frames and protects access to the debugger context from
inspected context.

https://bugs.webkit.org/show_bug.cgi?id=37755

  • WebCore.gyp/WebCore.gyp:
  • WebCore.gypi:
  • bindings/js/JSJavaScriptCallFrameCustom.cpp: (WebCore::JSJavaScriptCallFrame::scopeType):
  • bindings/v8/JavaScriptCallFrame.cpp: Added. (WebCore::JavaScriptCallFrame::JavaScriptCallFrame): (WebCore::JavaScriptCallFrame::~JavaScriptCallFrame): (WebCore::JavaScriptCallFrame::caller): (WebCore::JavaScriptCallFrame::sourceID): (WebCore::JavaScriptCallFrame::line): (WebCore::JavaScriptCallFrame::functionName): (WebCore::JavaScriptCallFrame::scopeChain): (WebCore::JavaScriptCallFrame::scopeType): (WebCore::JavaScriptCallFrame::thisObject): (WebCore::JavaScriptCallFrame::evaluate):
  • bindings/v8/JavaScriptCallFrame.h: Added. (WebCore::JavaScriptCallFrame::create):
  • bindings/v8/ScriptDebugServer.cpp: (WebCore::ScriptDebugServer::currentCallFrame):
  • bindings/v8/ScriptDebugServer.h:
  • bindings/v8/custom/V8InjectedScriptHostCustom.cpp: (WebCore::V8InjectedScriptHost::currentCallFrameCallback):
  • bindings/v8/custom/V8JavaScriptCallFrameCustom.cpp: Added. (WebCore::V8JavaScriptCallFrame::evaluateCallback): (WebCore::V8JavaScriptCallFrame::scopeChainAccessorGetter): (WebCore::V8JavaScriptCallFrame::scopeTypeCallback): (WebCore::V8JavaScriptCallFrame::thisObjectAccessorGetter): (WebCore::V8JavaScriptCallFrame::typeAccessorGetter):
  • inspector/JavaScriptCallFrame.idl:
  • inspector/front-end/InjectedScript.js: (injectedScriptConstructor.):
Location:
trunk
Files:
3 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r57810 r57812  
     12010-04-19  Yury Semikhatsky  <yurys@chromium.org>
     2
     3        Reviewed by Pavel Feldman.
     4
     5        Web Inspector: implement JavaScriptCallFrame that works for v8.
     6        Implementing this binding for v8 allows to make evaluations on
     7        call frames and protects access to the debugger context from
     8        inspected context.
     9
     10        https://bugs.webkit.org/show_bug.cgi?id=37755
     11
     12        * WebCore.gyp/WebCore.gyp:
     13        * WebCore.gypi:
     14        * bindings/js/JSJavaScriptCallFrameCustom.cpp:
     15        (WebCore::JSJavaScriptCallFrame::scopeType):
     16        * bindings/v8/JavaScriptCallFrame.cpp: Added.
     17        (WebCore::JavaScriptCallFrame::JavaScriptCallFrame):
     18        (WebCore::JavaScriptCallFrame::~JavaScriptCallFrame):
     19        (WebCore::JavaScriptCallFrame::caller):
     20        (WebCore::JavaScriptCallFrame::sourceID):
     21        (WebCore::JavaScriptCallFrame::line):
     22        (WebCore::JavaScriptCallFrame::functionName):
     23        (WebCore::JavaScriptCallFrame::scopeChain):
     24        (WebCore::JavaScriptCallFrame::scopeType):
     25        (WebCore::JavaScriptCallFrame::thisObject):
     26        (WebCore::JavaScriptCallFrame::evaluate):
     27        * bindings/v8/JavaScriptCallFrame.h: Added.
     28        (WebCore::JavaScriptCallFrame::create):
     29        * bindings/v8/ScriptDebugServer.cpp:
     30        (WebCore::ScriptDebugServer::currentCallFrame):
     31        * bindings/v8/ScriptDebugServer.h:
     32        * bindings/v8/custom/V8InjectedScriptHostCustom.cpp:
     33        (WebCore::V8InjectedScriptHost::currentCallFrameCallback):
     34        * bindings/v8/custom/V8JavaScriptCallFrameCustom.cpp: Added.
     35        (WebCore::V8JavaScriptCallFrame::evaluateCallback):
     36        (WebCore::V8JavaScriptCallFrame::scopeChainAccessorGetter):
     37        (WebCore::V8JavaScriptCallFrame::scopeTypeCallback):
     38        (WebCore::V8JavaScriptCallFrame::thisObjectAccessorGetter):
     39        (WebCore::V8JavaScriptCallFrame::typeAccessorGetter):
     40        * inspector/JavaScriptCallFrame.idl:
     41        * inspector/front-end/InjectedScript.js:
     42        (injectedScriptConstructor.):
     43
    1442010-04-19  Jessie Berlin  <jberlin@webkit.org>
    245
  • trunk/WebCore/WebCore.gyp/WebCore.gyp

    r57162 r57812  
    180180      '../dom/EventTarget.idl',
    181181      '../html/VoidCallback.idl',
    182 
    183       # JSC-only.
    184       '../inspector/JavaScriptCallFrame.idl',
    185182
    186183      # Bindings with custom Objective-C implementations.
  • trunk/WebCore/WebCore.gypi

    r57784 r57812  
    759759            'bindings/v8/custom/V8InjectedScriptHostCustom.cpp',
    760760            'bindings/v8/custom/V8InspectorFrontendHostCustom.cpp',
     761            'bindings/v8/custom/V8JavaScriptCallFrameCustom.cpp',
    761762            'bindings/v8/custom/V8LocationCustom.cpp',
    762763            'bindings/v8/custom/V8MessageChannelConstructor.cpp',
     
    805806            'bindings/v8/IsolatedWorld.cpp',
    806807            'bindings/v8/IsolatedWorld.h',
     808            'bindings/v8/JavaScriptCallFrame.cpp',
     809            'bindings/v8/JavaScriptCallFrame.h',
    807810            'bindings/v8/MainThreadDOMData.cpp',
    808811            'bindings/v8/MainThreadDOMData.h',
  • trunk/WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp

    r53371 r57812  
    8686}
    8787
     88JSValue JSJavaScriptCallFrame::scopeType(ExecState*, const ArgList&)
     89{
     90    // FIXME(37663): implement this method the way it's done in the InjectedScipt.js
     91    return jsNull();
     92}
     93
    8894} // namespace WebCore
    8995
  • trunk/WebCore/bindings/v8/ScriptDebugServer.cpp

    r57701 r57812  
    3535
    3636#include "Frame.h"
     37#include "JavaScriptCallFrame.h"
    3738#include "Page.h"
    3839#include "ScriptDebugListener.h"
     
    7475    if (!m_listenersMap.size()) {
    7576        ensureDebuggerScriptCompiled();
    76         ASSERT(!m_debuggerScript->IsUndefined());
     77        ASSERT(!m_debuggerScript.get()->IsUndefined());
    7778        v8::Debug::SetMessageHandler2(&ScriptDebugServer::onV8DebugMessage);
    7879        v8::Debug::SetHostDispatchHandler(&ScriptDebugServer::onV8DebugHostDispatch, 100 /* ms */);
     
    8485    m_contextDataMap.set(listener, contextData);
    8586
    86     v8::Handle<v8::Function> getScriptsFunction = v8::Local<v8::Function>::Cast(m_debuggerScript->Get(v8::String::New("getScripts")));
     87    v8::Handle<v8::Function> getScriptsFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("getScripts")));
    8788    v8::Handle<v8::Value> value = v8::Debug::Call(getScriptsFunction);
    8889    if (value.IsEmpty())
     
    126127    args->Set(v8::String::New("enabled"), v8::Boolean::New(breakpoint.enabled));
    127128
    128     v8::Handle<v8::Function> setBreakpointFunction = v8::Local<v8::Function>::Cast(m_debuggerScript->Get(v8::String::New("setBreakpoint")));
     129    v8::Handle<v8::Function> setBreakpointFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("setBreakpoint")));
    129130    v8::Debug::Call(setBreakpointFunction, args);
    130131#endif
     
    142143    args->Set(v8::String::New("lineNumber"), v8::Integer::New(lineNumber));
    143144
    144     v8::Handle<v8::Function> removeBreakpointFunction = v8::Local<v8::Function>::Cast(m_debuggerScript->Get(v8::String::New("removeBreakpoint")));
     145    v8::Handle<v8::Function> removeBreakpointFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("removeBreakpoint")));
    145146    v8::Debug::Call(removeBreakpointFunction, args);
    146147#endif
     
    155156    v8::Context::Scope contextScope(debuggerContext);
    156157
    157     v8::Handle<v8::Function> setBreakpointsActivated = v8::Local<v8::Function>::Cast(m_debuggerScript->Get(v8::String::New("clearBreakpoints")));
     158    v8::Handle<v8::Function> setBreakpointsActivated = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("clearBreakpoints")));
    158159    v8::Debug::Call(setBreakpointsActivated);
    159160#endif
     
    170171    v8::Local<v8::Object> args = v8::Object::New();
    171172    args->Set(v8::String::New("enabled"), v8::Boolean::New(enabled));
    172     v8::Handle<v8::Function> setBreakpointsActivated = v8::Local<v8::Function>::Cast(m_debuggerScript->Get(v8::String::New("setBreakpointsActivated")));
     173    v8::Handle<v8::Function> setBreakpointsActivated = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("setBreakpointsActivated")));
    173174    v8::Debug::Call(setBreakpointsActivated, args);
    174175#endif
     
    219220{
    220221#if ENABLE(V8_SCRIPT_DEBUG_SERVER)
    221     if (!m_currentCallFrame.IsEmpty())
    222         return m_currentCallFrame;
     222    if (!m_currentCallFrame.get().IsEmpty())
     223        return m_currentCallFrame.get();
    223224
    224225    // Check on a bp.
    225     v8::Handle<v8::Function> currentCallFrameFunction = v8::Local<v8::Function>::Cast(m_debuggerScript->Get(v8::String::New("currentCallFrame")));
    226     v8::Handle<v8::Value> argv[] = { m_executionState };
    227     v8::Handle<v8::Value> result = currentCallFrameFunction->Call(m_debuggerScript, 1, argv);
    228     m_currentCallFrame = v8::Persistent<v8::Value>::New(result);
     226    v8::Handle<v8::Function> currentCallFrameFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("currentCallFrame")));
     227    v8::Handle<v8::Value> argv[] = { m_executionState.get() };
     228    v8::Handle<v8::Value> result = currentCallFrameFunction->Call(m_debuggerScript.get(), 1, argv);
     229    m_currentCallFrame.set(result);
    229230    return result;
    230231#else
    231232    return v8::Handle<v8::Value>();
    232233#endif
     234}
     235
     236PassRefPtr<JavaScriptCallFrame> ScriptDebugServer::currentCallFrame()
     237{
     238    return JavaScriptCallFrame::create(v8::Debug::GetDebugContext(), v8::Handle<v8::Object>::Cast(currentCallFrameV8()));
    233239}
    234240
     
    289295                v8::Local<v8::Object> args = v8::Object::New();
    290296                args->Set(v8::String::New("eventData"), message.GetEventData());
    291                 v8::Handle<v8::Function> onAfterCompileFunction = v8::Local<v8::Function>::Cast(m_debuggerScript->Get(v8::String::New("getAfterCompileScript")));
     297                v8::Handle<v8::Function> onAfterCompileFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("getAfterCompileScript")));
    292298                v8::Handle<v8::Value> argv[] = { message.GetExecutionState(), args };
    293                 v8::Handle<v8::Value> value = onAfterCompileFunction->Call(m_debuggerScript, 2, argv);
     299                v8::Handle<v8::Value> value = onAfterCompileFunction->Call(m_debuggerScript.get(), 2, argv);
    294300                ASSERT(value->IsObject());
    295301                v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value);
    296302                dispatchDidParseSource(listener, object);
    297303            } else if (message.GetEvent() == v8::Break) {
    298                 m_executionState = v8::Persistent<v8::Object>::New(message.GetExecutionState());
     304                m_executionState.set(message.GetExecutionState());
    299305                m_currentCallFrameState = mainWorldScriptState(frame);
    300306                listener->didPause();
     
    320326void ScriptDebugServer::ensureDebuggerScriptCompiled()
    321327{
    322     if (m_debuggerScript.IsEmpty()) {
     328    if (m_debuggerScript.get().IsEmpty()) {
    323329        v8::HandleScope scope;
    324330        v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
    325331        v8::Context::Scope contextScope(debuggerContext);
    326         m_debuggerScript = v8::Persistent<v8::Object>::New(v8::Handle<v8::Object>::Cast(v8::Script::Compile(v8String(m_debuggerScriptSource))->Run()));
     332        m_debuggerScript.set(v8::Handle<v8::Object>::Cast(v8::Script::Compile(v8String(m_debuggerScriptSource))->Run()));
    327333    }
    328334}
     
    330336void ScriptDebugServer::didResume()
    331337{
    332     if (!m_currentCallFrame.IsEmpty()) {
    333         m_currentCallFrame.Dispose();
    334         m_currentCallFrame.Clear();
    335     }
    336     if (!m_executionState.IsEmpty()) {
    337         m_executionState.Dispose();
    338         m_executionState.Clear();
    339     }
     338    m_currentCallFrame.clear();
     339    m_executionState.clear();
    340340}
    341341
  • trunk/WebCore/bindings/v8/ScriptDebugServer.h

    r57701 r57812  
    3434#if ENABLE(JAVASCRIPT_DEBUGGER)
    3535
     36#include "OwnHandle.h"
    3637#include "PlatformString.h"
    3738#include "ScriptBreakpoint.h"
     
    4546namespace WebCore {
    4647
     48class JavaScriptCallFrame;
    4749class Page;
    4850class ScriptDebugListener;
     
    9799
    98100    v8::Handle<v8::Value> currentCallFrameV8();
     101    PassRefPtr<JavaScriptCallFrame> currentCallFrame();
    99102
    100103private:
     
    132135    String m_debuggerScriptSource;
    133136    PauseOnExceptionsState m_pauseOnExceptionsState;
    134     v8::Persistent<v8::Object> m_debuggerScript;
     137    OwnHandle<v8::Object> m_debuggerScript;
    135138    ScriptState* m_currentCallFrameState;
    136     v8::Persistent<v8::Value> m_currentCallFrame;
    137     v8::Persistent<v8::Object> m_executionState;
     139    OwnHandle<v8::Value> m_currentCallFrame;
     140    OwnHandle<v8::Object> m_executionState;
    138141
    139142    static MessageLoopDispatchHandler s_messageLoopDispatchHandler;
  • trunk/WebCore/bindings/v8/custom/V8InjectedScriptHostCustom.cpp

    r57701 r57812  
    4747#include "V8DOMWindow.h"
    4848#include "V8Database.h"
     49#include "V8JavaScriptCallFrame.h"
    4950#include "V8Node.h"
    5051#include "V8Proxy.h"
     
    159160{
    160161    INC_STATS("InjectedScriptHost.currentCallFrame()");
    161     return ScriptDebugServer::shared().currentCallFrameV8();
     162    return toV8(ScriptDebugServer::shared().currentCallFrame());
    162163}
    163164
  • trunk/WebCore/inspector/JavaScriptCallFrame.idl

    r52534 r57812  
    2727
    2828    interface [Conditional=JAVASCRIPT_DEBUGGER, OmitConstructor] JavaScriptCallFrame {
     29
     30        // Scope type
     31        const unsigned short GLOBAL_SCOPE = 0;
     32        const unsigned short LOCAL_SCOPE = 1;
     33        const unsigned short WITH_SCOPE = 2;
     34        const unsigned short CLOSURE_SCOPE = 3;
     35        const unsigned short CATCH_SCOPE = 4;
     36
    2937        [Custom] void evaluate(in DOMString script);
    3038
     
    3341        readonly attribute long line;
    3442        readonly attribute [CustomGetter] Array scopeChain;
     43        [Custom] unsigned short scopeType(in int scopeIndex);
    3544        readonly attribute [CustomGetter] Object thisObject;
    3645        readonly attribute DOMString functionName;
  • trunk/WebCore/inspector/front-end/InjectedScript.js

    r57701 r57812  
    846846
    847847InjectedScript.CallFrameProxy.prototype = {
     848    _wrapScopeChain: function(callFrame)
     849    {
     850        const GLOBAL_SCOPE = 0;
     851        const LOCAL_SCOPE = 1;
     852        const WITH_SCOPE = 2;
     853        const CLOSURE_SCOPE = 3;
     854        const CATCH_SCOPE = 4;
    848855   
    849 
    850     _wrapScopeChain: function(callFrame)
    851     {
    852         var ScopeType = { Global: 0,
    853                           Local: 1,
    854                           With: 2,
    855                           Closure: 3,
    856                           Catch: 4 };
    857856        var scopeChain = callFrame.scopeChain;
    858857        var scopeChainProxy = [];
    859         for (var i = 0; i < scopeChain.length; i += 2) {
    860             var scopeType = scopeChain[i];
    861             var scopeObject = scopeChain[i + 1];
    862             var scopeObjectProxy = InjectedScript.createProxyObject(scopeObject, { callFrame: this.id, chainIndex: (i + 1) }, true);
     858        for (var i = 0; i < scopeChain.length; i++) {
     859            var scopeType = callFrame.scopeType(i);
     860            var scopeObject = scopeChain[i];
     861            var scopeObjectProxy = InjectedScript.createProxyObject(scopeObject, { callFrame: this.id, chainIndex: i }, true);
    863862
    864863            var foundLocalScope = false;
    865864            switch(scopeType) {
    866                 case ScopeType.Local: {
     865                case LOCAL_SCOPE: {
    867866                    foundLocalScope = true;
    868867                    scopeObjectProxy.isLocal = true;
     
    870869                    break;
    871870                }
    872                 case ScopeType.Closure: {
     871                case CLOSURE_SCOPE: {
    873872                    scopeObjectProxy.isClosure = true;
    874873                    break;
    875874                }
    876                 case ScopeType.With: {
     875                case WITH_SCOPE:
     876                case CATCH_SCOPE: {
    877877                    scopeObjectProxy.isWithBlock = true;
    878878                    break;
  • trunk/WebKit/chromium/src/js/DebuggerScript.js

    r57701 r57812  
    168168    // Get scope chain array in format: [<scope type>, <scope object>, <scope type>, <scope object>,...]
    169169    var scopeChain = [];
     170    var scopeType = [];
    170171    for (var i = 0; i < frameMirror.scopeCount(); i++) {
    171172        var scopeMirror = frameMirror.scope(i);
     
    175176        for (var j = 0; j < properties.length; j++)
    176177            scopeObject[properties[j].name()] = properties[j].value_;
    177         scopeChain.push(scopeMirror.scopeType());
     178        scopeType.push(scopeMirror.scopeType());
    178179        scopeChain.push(scopeObject);
     180    }
     181   
     182    function evaluate(expression) {
     183        return frameMirror.evaluate(expression, false).value();
    179184    }
    180185   
     
    186191        "thisObject": thisObject,
    187192        "scopeChain": scopeChain,
     193        "scopeType": scopeType,
     194        "evaluate": evaluate,
    188195        "caller": callerFrame
    189196    };
Note: See TracChangeset for help on using the changeset viewer.