Commit 12d60aab authored by timothy@apple.com's avatar timothy@apple.com

Implements more debugger APIs on JavaScriptDebugServer and reduces

the number of callbacks to JavaScriptDebugListeners. These changes
will better facilitate debugger optimizations when SquirrelFish merges.

Reviewed by Kevin McCullough.

* page/InspectorController.cpp:
(WebCore::InspectorController::didParseSource): Removed the ExecState.
(WebCore::InspectorController::failedToParseSource): Ditto.
(WebCore::InspectorController::didPause): Added.
* page/InspectorController.h: Changed the JavaScriptDebugListener functions.
* page/JavaScriptDebugListener.h: Removed some callbacks and added didPause.
* page/JavaScriptDebugServer.cpp:
(WebCore::JavaScriptDebugServer::JavaScriptDebugServer): Initialize new data members.
(WebCore::JavaScriptDebugServer::~JavaScriptDebugServer): Delete all values of m_breakpoints.
(WebCore::JavaScriptDebugServer::removeListener): Call resume if the last listener was removed.
(WebCore::JavaScriptDebugServer::hasListenersInterestedInPage): Returns true if there are any
global listeners or a listener for the page.
(WebCore::JavaScriptDebugServer::addBreakpoint): Adds and entry to m_breakpoints.
(WebCore::JavaScriptDebugServer::removeBreakpoint): Removes a entry in m_breakpoints.
(WebCore::JavaScriptDebugServer::hasBreakpoint):  Checks if there is a breakpoint for the
sourceID and line.
(WebCore::JavaScriptDebugServer::clearBreakpoints): Removed all breakpoints.
(WebCore::JavaScriptDebugServer::pauseOnNextStatement): Sets m_pauseOnNextStatement to true.
(WebCore::JavaScriptDebugServer::resume): Sets m_paused to false.
(WebCore::JavaScriptDebugServer::stepIntoStatement): Calls resume and sets
m_pauseOnNextStatement to true.
(WebCore::JavaScriptDebugServer::stepOverStatement): Calls resume and sets m_pauseOnExecState to
the current call frame's ExecState.
(WebCore::JavaScriptDebugServer::stepOutOfFunction): Calls resume and sets m_pauseOnExecState to
the current call frame's caller ExecState.
(WebCore::JavaScriptDebugServer::currentCallFrame): Returns m_currentCallFrame if paused.
(WebCore::dispatchDidParseSource): Removed the ExecState argument.
(WebCore::dispatchFailedToParseSource): Ditto.
(WebCore::JavaScriptDebugServer::sourceParsed): Doesn't pass the ExecState to dispatchDidParseSource
or dispatchFailedToParseSource.
(WebCore::dispatchFunctionToListeners):
(WebCore::JavaScriptDebugServer::dispatchFunctionToListeners): Removes all the arguments passed
to the callback.
(WebCore::JavaScriptDebugServer::setJavaScriptPaused): Various overloaded functions
to pause parts of WebCore to prevent JavaScript execution while paused.
(WebCore::JavaScriptDebugServer::pauseIfNeeded): Decides if the debugger should pause based
on the passed in ExecState, source ID and line number. This checks for breakpoints, stepping, etc.
Calls didPause on all the listeners and spins a EventLoop until resume is called.
(WebCore::JavaScriptDebugServer::callEvent): Call pauseIfNeeded.
(WebCore::JavaScriptDebugServer::atStatement): Ditto.
(WebCore::JavaScriptDebugServer::returnEvent): Ditto.
(WebCore::JavaScriptDebugServer::exception): Ditto.
* page/JavaScriptDebugServer.h: Added new functions.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@33404 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 8906ca0d
......@@ -221,6 +221,7 @@ __ZN3WTF16callOnMainThreadEPFvPvES0_
__ZN3WTF16fastZeroedMallocEm
__ZN3WTF19initializeThreadingEv
__ZN3WTF23waitForThreadCompletionEjPPv
__ZN3WTF28setMainThreadCallbacksPausedEb
__ZN3WTF32atomicallyInitializedStaticMutexE
__ZN3WTF5Mutex4lockEv
__ZN3WTF5Mutex6unlockEv
......
2008-05-13 Timothy Hatcher <timothy@apple.com>
Implements more debugger APIs on JavaScriptDebugServer and reduces
the number of callbacks to JavaScriptDebugListeners. These changes
will better facilitate debugger optimizations when SquirrelFish merges.
Reviewed by Kevin McCullough.
* page/InspectorController.cpp:
(WebCore::InspectorController::didParseSource): Removed the ExecState.
(WebCore::InspectorController::failedToParseSource): Ditto.
(WebCore::InspectorController::didPause): Added.
* page/InspectorController.h: Changed the JavaScriptDebugListener functions.
* page/JavaScriptDebugListener.h: Removed some callbacks and added didPause.
* page/JavaScriptDebugServer.cpp:
(WebCore::JavaScriptDebugServer::JavaScriptDebugServer): Initialize new data members.
(WebCore::JavaScriptDebugServer::~JavaScriptDebugServer): Delete all values of m_breakpoints.
(WebCore::JavaScriptDebugServer::removeListener): Call resume if the last listener was removed.
(WebCore::JavaScriptDebugServer::hasListenersInterestedInPage): Returns true if there are any
global listeners or a listener for the page.
(WebCore::JavaScriptDebugServer::addBreakpoint): Adds and entry to m_breakpoints.
(WebCore::JavaScriptDebugServer::removeBreakpoint): Removes a entry in m_breakpoints.
(WebCore::JavaScriptDebugServer::hasBreakpoint): Checks if there is a breakpoint for the
sourceID and line.
(WebCore::JavaScriptDebugServer::clearBreakpoints): Removed all breakpoints.
(WebCore::JavaScriptDebugServer::pauseOnNextStatement): Sets m_pauseOnNextStatement to true.
(WebCore::JavaScriptDebugServer::resume): Sets m_paused to false.
(WebCore::JavaScriptDebugServer::stepIntoStatement): Calls resume and sets
m_pauseOnNextStatement to true.
(WebCore::JavaScriptDebugServer::stepOverStatement): Calls resume and sets m_pauseOnExecState to
the current call frame's ExecState.
(WebCore::JavaScriptDebugServer::stepOutOfFunction): Calls resume and sets m_pauseOnExecState to
the current call frame's caller ExecState.
(WebCore::JavaScriptDebugServer::currentCallFrame): Returns m_currentCallFrame if paused.
(WebCore::dispatchDidParseSource): Removed the ExecState argument.
(WebCore::dispatchFailedToParseSource): Ditto.
(WebCore::JavaScriptDebugServer::sourceParsed): Doesn't pass the ExecState to dispatchDidParseSource
or dispatchFailedToParseSource.
(WebCore::dispatchFunctionToListeners):
(WebCore::JavaScriptDebugServer::dispatchFunctionToListeners): Removes all the arguments passed
to the callback.
(WebCore::JavaScriptDebugServer::setJavaScriptPaused): Various overloaded functions
to pause parts of WebCore to prevent JavaScript execution while paused.
(WebCore::JavaScriptDebugServer::pauseIfNeeded): Decides if the debugger should pause based
on the passed in ExecState, source ID and line number. This checks for breakpoints, stepping, etc.
Calls didPause on all the listeners and spins a EventLoop until resume is called.
(WebCore::JavaScriptDebugServer::callEvent): Call pauseIfNeeded.
(WebCore::JavaScriptDebugServer::atStatement): Ditto.
(WebCore::JavaScriptDebugServer::returnEvent): Ditto.
(WebCore::JavaScriptDebugServer::exception): Ditto.
* page/JavaScriptDebugServer.h: Added new functions.
2008-05-13 Timothy Hatcher <timothy@apple.com>
Change View.show to call detach if the parentNode dosen't
......@@ -2002,27 +2002,15 @@ bool InspectorController::handleException(JSContextRef context, JSValueRef excep
#pragma mark -
#pragma mark JavaScriptDebugListener functions
void InspectorController::didParseSource(ExecState*, const UString& /*source*/, int /*startingLineNumber*/, const UString& /*sourceURL*/, int /*sourceID*/)
void InspectorController::didParseSource(const UString& /*source*/, int /*startingLineNumber*/, const UString& /*sourceURL*/, int /*sourceID*/)
{
}
void InspectorController::failedToParseSource(ExecState*, const UString& /*source*/, int /*startingLineNumber*/, const UString& /*sourceURL*/, int /*errorLine*/, const UString& /*errorMessage*/)
void InspectorController::failedToParseSource(const UString& /*source*/, int /*startingLineNumber*/, const UString& /*sourceURL*/, int /*errorLine*/, const UString& /*errorMessage*/)
{
}
void InspectorController::didEnterCallFrame(ExecState*, int /*sourceID*/, int /*lineNumber*/)
{
}
void InspectorController::willExecuteStatement(ExecState*, int /*sourceID*/, int /*lineNumber*/)
{
}
void InspectorController::willLeaveCallFrame(ExecState*, int /*sourceID*/, int /*lineNumber*/)
{
}
void InspectorController::exceptionWasRaised(ExecState*, int /*sourceID*/, int /*lineNumber*/)
void InspectorController::didPause()
{
}
......
......@@ -171,12 +171,9 @@ private:
void showWindow();
void closeWindow();
virtual void didParseSource(KJS::ExecState*, const KJS::UString& source, int startingLineNumber, const KJS::UString& sourceURL, int sourceID);
virtual void failedToParseSource(KJS::ExecState*, const KJS::UString& source, int startingLineNumber, const KJS::UString& sourceURL, int errorLine, const KJS::UString& errorMessage);
virtual void didEnterCallFrame(KJS::ExecState*, int sourceID, int lineNumber);
virtual void willExecuteStatement(KJS::ExecState*, int sourceID, int lineNumber);
virtual void willLeaveCallFrame(KJS::ExecState*, int sourceID, int lineNumber);
virtual void exceptionWasRaised(KJS::ExecState*, int sourceID, int lineNumber);
virtual void didParseSource(const KJS::UString& source, int startingLineNumber, const KJS::UString& sourceURL, int sourceID);
virtual void failedToParseSource(const KJS::UString& source, int startingLineNumber, const KJS::UString& sourceURL, int errorLine, const KJS::UString& errorMessage);
virtual void didPause();
Page* m_inspectedPage;
InspectorClient* m_client;
......
......@@ -43,12 +43,9 @@ namespace WebCore {
public:
virtual ~JavaScriptDebugListener() { }
virtual void didParseSource(KJS::ExecState*, const KJS::UString& source, int startingLineNumber, const KJS::UString& sourceURL, int sourceID) = 0;
virtual void failedToParseSource(KJS::ExecState*, const KJS::UString& source, int startingLineNumber, const KJS::UString& sourceURL, int errorLine, const KJS::UString& errorMessage) = 0;
virtual void didEnterCallFrame(KJS::ExecState*, int sourceID, int lineNumber) = 0;
virtual void willExecuteStatement(KJS::ExecState*, int sourceID, int lineNumber) = 0;
virtual void willLeaveCallFrame(KJS::ExecState*, int sourceID, int lineNumber) = 0;
virtual void exceptionWasRaised(KJS::ExecState*, int sourceID, int lineNumber) = 0;
virtual void didParseSource(const KJS::UString& source, int startingLineNumber, const KJS::UString& sourceURL, int sourceID) = 0;
virtual void failedToParseSource(const KJS::UString& source, int startingLineNumber, const KJS::UString& sourceURL, int errorLine, const KJS::UString& errorMessage) = 0;
virtual void didPause() = 0;
};
} // namespace WebCore
......
......@@ -30,10 +30,20 @@
#include "JavaScriptDebugServer.h"
#include "DOMWindow.h"
#include "EventLoop.h"
#include "Frame.h"
#include "FrameTree.h"
#include "FrameView.h"
#include "JSDOMWindow.h"
#include "JavaScriptCallFrame.h"
#include "JavaScriptDebugListener.h"
#include "kjs_proxy.h"
#include "Page.h"
#include "PageGroup.h"
#include "PluginView.h"
#include "ScrollView.h"
#include "Widget.h"
#include <wtf/MainThread.h>
using namespace KJS;
......@@ -49,12 +59,16 @@ JavaScriptDebugServer& JavaScriptDebugServer::shared()
JavaScriptDebugServer::JavaScriptDebugServer()
: m_callingListeners(false)
, m_pauseOnNextStatement(false)
, m_paused(false)
, m_pauseOnExecState(0)
{
}
JavaScriptDebugServer::~JavaScriptDebugServer()
{
deleteAllValues(m_pageListenersMap);
deleteAllValues(m_breakpoints);
}
void JavaScriptDebugServer::addListener(JavaScriptDebugListener* listener)
......@@ -68,8 +82,10 @@ void JavaScriptDebugServer::addListener(JavaScriptDebugListener* listener)
void JavaScriptDebugServer::removeListener(JavaScriptDebugListener* listener)
{
m_listeners.remove(listener);
if (!hasListeners())
if (!hasListeners()) {
Page::setDebuggerForAllPages(0);
resume();
}
}
void JavaScriptDebugServer::addListener(JavaScriptDebugListener* listener, Page* page)
......@@ -104,8 +120,10 @@ void JavaScriptDebugServer::removeListener(JavaScriptDebugListener* listener, Pa
delete listeners;
}
if (!hasListeners())
if (!hasListeners()) {
Page::setDebuggerForAllPages(0);
resume();
}
}
void JavaScriptDebugServer::pageCreated(Page* page)
......@@ -116,20 +134,123 @@ void JavaScriptDebugServer::pageCreated(Page* page)
page->setDebugger(this);
}
static void dispatchDidParseSource(const ListenerSet& listeners, ExecState* exec, const UString& source, int startingLineNumber, const UString& sourceURL, int sourceID)
bool JavaScriptDebugServer::hasListenersInterestedInPage(Page* page)
{
ASSERT_ARG(page, page);
if (!m_listeners.isEmpty())
return true;
return m_pageListenersMap.contains(page);
}
void JavaScriptDebugServer::addBreakpoint(int sourceID, unsigned lineNumber)
{
HashSet<unsigned>* lines = m_breakpoints.get(sourceID);
if (!lines) {
lines = new HashSet<unsigned>;
m_breakpoints.set(sourceID, lines);
}
lines->add(lineNumber);
}
void JavaScriptDebugServer::removeBreakpoint(int sourceID, unsigned lineNumber)
{
HashSet<unsigned>* lines = m_breakpoints.get(sourceID);
if (!lines)
return;
lines->remove(lineNumber);
if (!lines->isEmpty())
return;
m_breakpoints.remove(sourceID);
delete lines;
}
bool JavaScriptDebugServer::hasBreakpoint(int sourceID, unsigned lineNumber) const
{
HashSet<unsigned>* lines = m_breakpoints.get(sourceID);
if (!lines)
return false;
return lines->contains(lineNumber);
}
void JavaScriptDebugServer::clearBreakpoints()
{
deleteAllValues(m_breakpoints);
m_breakpoints.clear();
}
void JavaScriptDebugServer::pauseOnNextStatement()
{
m_pauseOnNextStatement = true;
}
void JavaScriptDebugServer::resume()
{
m_paused = false;
}
void JavaScriptDebugServer::stepIntoStatement()
{
if (!m_paused)
return;
resume();
m_pauseOnNextStatement = true;
}
void JavaScriptDebugServer::stepOverStatement()
{
if (!m_paused)
return;
resume();
if (m_currentCallFrame)
m_pauseOnExecState = m_currentCallFrame->execState();
else
m_pauseOnExecState = 0;
}
void JavaScriptDebugServer::stepOutOfFunction()
{
if (!m_paused)
return;
resume();
if (m_currentCallFrame && m_currentCallFrame->caller())
m_pauseOnExecState = m_currentCallFrame->caller()->execState();
else
m_pauseOnExecState = 0;
}
JavaScriptCallFrame* JavaScriptDebugServer::currentCallFrame()
{
if (!m_paused)
return 0;
return m_currentCallFrame.get();
}
static void dispatchDidParseSource(const ListenerSet& listeners, const UString& source, int startingLineNumber, const UString& sourceURL, int sourceID)
{
Vector<JavaScriptDebugListener*> copy;
copyToVector(listeners, copy);
for (size_t i = 0; i < copy.size(); ++i)
copy[i]->didParseSource(exec, source, startingLineNumber, sourceURL, sourceID);
copy[i]->didParseSource(source, startingLineNumber, sourceURL, sourceID);
}
static void dispatchFailedToParseSource(const ListenerSet& listeners, ExecState* exec, const UString& source, int startingLineNumber, const UString& sourceURL, int errorLine, const UString& errorMessage)
static void dispatchFailedToParseSource(const ListenerSet& listeners, const UString& source, int startingLineNumber, const UString& sourceURL, int errorLine, const UString& errorMessage)
{
Vector<JavaScriptDebugListener*> copy;
copyToVector(listeners, copy);
for (size_t i = 0; i < copy.size(); ++i)
copy[i]->failedToParseSource(exec, source, startingLineNumber, sourceURL, errorLine, errorMessage);
copy[i]->failedToParseSource(source, startingLineNumber, sourceURL, errorLine, errorMessage);
}
static Page* toPage(ExecState* exec)
......@@ -159,32 +280,32 @@ bool JavaScriptDebugServer::sourceParsed(ExecState* exec, int sourceID, const US
if (!m_listeners.isEmpty()) {
if (isError)
dispatchFailedToParseSource(m_listeners, exec, source, startingLineNumber, sourceURL, errorLine, errorMessage);
dispatchFailedToParseSource(m_listeners, source, startingLineNumber, sourceURL, errorLine, errorMessage);
else
dispatchDidParseSource(m_listeners, exec, source, startingLineNumber, sourceURL, sourceID);
dispatchDidParseSource(m_listeners, source, startingLineNumber, sourceURL, sourceID);
}
if (ListenerSet* pageListeners = m_pageListenersMap.get(page)) {
ASSERT(!pageListeners->isEmpty());
if (isError)
dispatchFailedToParseSource(*pageListeners, exec, source, startingLineNumber, sourceURL, errorLine, errorMessage);
dispatchFailedToParseSource(*pageListeners, source, startingLineNumber, sourceURL, errorLine, errorMessage);
else
dispatchDidParseSource(*pageListeners, exec, source, startingLineNumber, sourceURL, sourceID);
dispatchDidParseSource(*pageListeners, source, startingLineNumber, sourceURL, sourceID);
}
m_callingListeners = false;
return true;
}
static void dispatchFunctionToListeners(const ListenerSet& listeners, JavaScriptDebugServer::JavaScriptExecutionCallback callback, ExecState* exec, int sourceID, int lineNumber)
static void dispatchFunctionToListeners(const ListenerSet& listeners, JavaScriptDebugServer::JavaScriptExecutionCallback callback)
{
Vector<JavaScriptDebugListener*> copy;
copyToVector(listeners, copy);
for (size_t i = 0; i < copy.size(); ++i)
(copy[i]->*callback)(exec, sourceID, lineNumber);
(copy[i]->*callback)();
}
void JavaScriptDebugServer::dispatchFunctionToListeners(JavaScriptExecutionCallback callback, ExecState* exec, int sourceID, int lineNumber)
void JavaScriptDebugServer::dispatchFunctionToListeners(JavaScriptExecutionCallback callback, ExecState* exec)
{
if (m_callingListeners)
return;
......@@ -197,36 +318,156 @@ void JavaScriptDebugServer::dispatchFunctionToListeners(JavaScriptExecutionCallb
ASSERT(hasListeners());
WebCore::dispatchFunctionToListeners(m_listeners, callback, exec, sourceID, lineNumber);
WebCore::dispatchFunctionToListeners(m_listeners, callback);
if (ListenerSet* pageListeners = m_pageListenersMap.get(page)) {
ASSERT(!pageListeners->isEmpty());
WebCore::dispatchFunctionToListeners(*pageListeners, callback, exec, sourceID, lineNumber);
WebCore::dispatchFunctionToListeners(*pageListeners, callback);
}
m_callingListeners = false;
}
void JavaScriptDebugServer::setJavaScriptPaused(const PageGroup& pageGroup, bool paused)
{
setMainThreadCallbacksPaused(paused);
const HashSet<Page*>& pages = pageGroup.pages();
HashSet<Page*>::const_iterator end = pages.end();
for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it)
setJavaScriptPaused(*it, false);
}
void JavaScriptDebugServer::setJavaScriptPaused(Page* page, bool paused)
{
ASSERT_ARG(page, page);
page->setDefersLoading(paused);
for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext())
setJavaScriptPaused(frame, paused);
}
void JavaScriptDebugServer::setJavaScriptPaused(Frame* frame, bool paused)
{
ASSERT_ARG(frame, frame);
if (!frame->scriptProxy()->isEnabled())
return;
frame->scriptProxy()->setPaused(paused);
if (JSDOMWindow* window = toJSDOMWindow(frame)) {
if (paused)
m_pausedTimeouts.set(frame, window->pauseTimeouts());
else
window->resumeTimeouts(m_pausedTimeouts.take(frame));
}
setJavaScriptPaused(frame->view(), paused);
}
void JavaScriptDebugServer::setJavaScriptPaused(FrameView* view, bool paused)
{
#if !PLATFORM(MAC)
if (!view)
return;
HashSet<Widget*>* children = static_cast<ScrollView*>(view)->children();
ASSERT(children);
HashSet<Widget*>::iterator end = children->end();
for (HashSet<Widget*>::iterator it = children->begin(); it != end; ++it) {
Widget* widget = *it;
if (!widget->isPluginView())
continue;
static_cast<PluginView*>(widget)->setJavaScriptPaused(paused);
}
#endif
}
void JavaScriptDebugServer::pauseIfNeeded(ExecState* exec, int sourceID, int lineNumber)
{
if (m_paused)
return;
Page* page = toPage(exec);
if (!page || !hasListenersInterestedInPage(page))
return;
bool pauseNow = m_pauseOnNextStatement;
if (!pauseNow && m_pauseOnExecState)
pauseNow = (m_pauseOnExecState == exec);
if (!pauseNow && lineNumber > 0)
pauseNow = hasBreakpoint(sourceID, lineNumber);
if (!pauseNow)
return;
m_pauseOnExecState = 0;
m_pauseOnNextStatement = false;
m_paused = true;
dispatchFunctionToListeners(&JavaScriptDebugListener::didPause, exec);
setJavaScriptPaused(page->group(), true);
EventLoop loop;
while (m_paused && !loop.ended())
loop.cycle();
setJavaScriptPaused(page->group(), false);
m_paused = false;
}
bool JavaScriptDebugServer::callEvent(ExecState* exec, int sourceID, int lineNumber, JSObject*, const List&)
{
dispatchFunctionToListeners(&JavaScriptDebugListener::didEnterCallFrame, exec, sourceID, lineNumber);
if (m_paused)
return true;
if (m_currentCallFrame && m_currentCallFrame->execState() != exec->callingExecState()) {
m_currentCallFrame->invalidate();
m_currentCallFrame = 0;
}
m_currentCallFrame = JavaScriptCallFrame::create(exec, m_currentCallFrame, sourceID, lineNumber);
pauseIfNeeded(exec, sourceID, lineNumber);
return true;
}
bool JavaScriptDebugServer::atStatement(ExecState* exec, int sourceID, int firstLine, int)
{
dispatchFunctionToListeners(&JavaScriptDebugListener::willExecuteStatement, exec, sourceID, firstLine);
if (m_paused)
return true;
if (m_currentCallFrame)
m_currentCallFrame->setLine(firstLine);
else
m_currentCallFrame = JavaScriptCallFrame::create(exec, 0, sourceID, firstLine);
pauseIfNeeded(exec, sourceID, firstLine);
return true;
}
bool JavaScriptDebugServer::returnEvent(ExecState* exec, int sourceID, int lineNumber, JSObject*)
{
dispatchFunctionToListeners(&JavaScriptDebugListener::willLeaveCallFrame, exec, sourceID, lineNumber);
if (m_paused)
return true;
m_currentCallFrame->invalidate();
m_currentCallFrame = m_currentCallFrame->caller();
pauseIfNeeded(exec, sourceID, lineNumber);
return true;
}
bool JavaScriptDebugServer::exception(ExecState* exec, int sourceID, int lineNumber, JSValue*)
{
dispatchFunctionToListeners(&JavaScriptDebugListener::exceptionWasRaised, exec, sourceID, lineNumber);
if (m_paused)
return true;
if (m_currentCallFrame)
m_currentCallFrame->setLine(lineNumber);
else
m_currentCallFrame = JavaScriptCallFrame::create(exec, 0, sourceID, lineNumber);
// FIXME: ideally this should only pause if a "pause on exception" flag is set,
// not m_pauseOnNextStatement, etc.
pauseIfNeeded(exec, sourceID, lineNumber);
return true;
}
......
......@@ -33,11 +33,16 @@
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/RefPtr.h>
namespace WebCore {
class Frame;
class FrameView;
class Page;
class PageGroup;
class PausedTimeouts;
class JavaScriptCallFrame;
class JavaScriptDebugListener;
class JavaScriptDebugServer : KJS::Debugger {
......@@ -50,18 +55,39 @@ namespace WebCore {
void addListener(JavaScriptDebugListener*, Page*);
void removeListener(JavaScriptDebugListener*, Page*);
void addBreakpoint(int sourceID, unsigned lineNumber);
void removeBreakpoint(int sourceID, unsigned lineNumber);
bool hasBreakpoint(int sourceID, unsigned lineNumber) const;
void clearBreakpoints();
void pauseOnNextStatement();
void resume();
void stepIntoStatement();
void stepOverStatement();
void stepOutOfFunction();
JavaScriptCallFrame* currentCallFrame();
void pageCreated(Page*);
typedef HashSet<JavaScriptDebugListener*> ListenerSet;
typedef void (JavaScriptDebugListener::*JavaScriptExecutionCallback)(KJS::ExecState*, int sourceID, int lineNumber);
typedef void (JavaScriptDebugListener::*JavaScriptExecutionCallback)();
private:
JavaScriptDebugServer();
~JavaScriptDebugServer();
bool hasListeners() const { return !m_listeners.isEmpty() || !m_pageListenersMap.isEmpty(); }
bool hasListenersInterestedInPage(Page*);
void setJavaScriptPaused(const PageGroup&, bool paused);
void setJavaScriptPaused(Page*, bool paused);
void setJavaScriptPaused(Frame*, bool paused);
void setJavaScriptPaused(FrameView*, bool paused);
void dispatchFunctionToListeners(JavaScriptExecutionCallback, KJS::ExecState*, int sourceID, int lineNumber);
void dispatchFunctionToListeners(JavaScriptExecutionCallback, KJS::ExecState*);
void pauseIfNeeded(KJS::ExecState* exec, int sourceID, int lineNumber);
virtual bool sourceParsed(KJS::ExecState*, int sourceID, const KJS::UString& sourceURL, const KJS::UString& source, int startingLineNumber, int errorLine, const KJS::UString& errorMsg);
virtual bool callEvent(KJS::ExecState*, int sourceID, int lineNumber, KJS::JSObject* function, const KJS::List& args);
......@@ -73,6 +99,12 @@ namespace WebCore {
PageListenersMap m_pageListenersMap;
ListenerSet m_listeners;
bool m_callingListeners;
bool m_pauseOnNextStatement;
bool m_paused;
KJS::ExecState* m_pauseOnExecState;
RefPtr<JavaScriptCallFrame> m_currentCallFrame;
HashMap<RefPtr<Frame>, PausedTimeouts*> m_pausedTimeouts;
HashMap<int, HashSet<unsigned>*> m_breakpoints;
};
} // namespace WebCore
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment