12bde8e466a4451c7319e3a072d118917957d6554Steve Block/* 22bde8e466a4451c7319e3a072d118917957d6554Steve Block * Copyright (c) 2011 Google Inc. All rights reserved. 32bde8e466a4451c7319e3a072d118917957d6554Steve Block * 42bde8e466a4451c7319e3a072d118917957d6554Steve Block * Redistribution and use in source and binary forms, with or without 52bde8e466a4451c7319e3a072d118917957d6554Steve Block * modification, are permitted provided that the following conditions are 62bde8e466a4451c7319e3a072d118917957d6554Steve Block * met: 72bde8e466a4451c7319e3a072d118917957d6554Steve Block * 82bde8e466a4451c7319e3a072d118917957d6554Steve Block * * Redistributions of source code must retain the above copyright 92bde8e466a4451c7319e3a072d118917957d6554Steve Block * notice, this list of conditions and the following disclaimer. 102bde8e466a4451c7319e3a072d118917957d6554Steve Block * * Redistributions in binary form must reproduce the above 112bde8e466a4451c7319e3a072d118917957d6554Steve Block * copyright notice, this list of conditions and the following disclaimer 122bde8e466a4451c7319e3a072d118917957d6554Steve Block * in the documentation and/or other materials provided with the 132bde8e466a4451c7319e3a072d118917957d6554Steve Block * distribution. 142bde8e466a4451c7319e3a072d118917957d6554Steve Block * * Neither the name of Google Inc. nor the names of its 152bde8e466a4451c7319e3a072d118917957d6554Steve Block * contributors may be used to endorse or promote products derived from 162bde8e466a4451c7319e3a072d118917957d6554Steve Block * this software without specific prior written permission. 172bde8e466a4451c7319e3a072d118917957d6554Steve Block * 182bde8e466a4451c7319e3a072d118917957d6554Steve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 192bde8e466a4451c7319e3a072d118917957d6554Steve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 202bde8e466a4451c7319e3a072d118917957d6554Steve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 212bde8e466a4451c7319e3a072d118917957d6554Steve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 222bde8e466a4451c7319e3a072d118917957d6554Steve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 232bde8e466a4451c7319e3a072d118917957d6554Steve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 242bde8e466a4451c7319e3a072d118917957d6554Steve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 252bde8e466a4451c7319e3a072d118917957d6554Steve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 262bde8e466a4451c7319e3a072d118917957d6554Steve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 272bde8e466a4451c7319e3a072d118917957d6554Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 282bde8e466a4451c7319e3a072d118917957d6554Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 292bde8e466a4451c7319e3a072d118917957d6554Steve Block */ 302bde8e466a4451c7319e3a072d118917957d6554Steve Block 312bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "config.h" 322bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "PageScriptDebugServer.h" 332bde8e466a4451c7319e3a072d118917957d6554Steve Block 342bde8e466a4451c7319e3a072d118917957d6554Steve Block#if ENABLE(JAVASCRIPT_DEBUGGER) 352bde8e466a4451c7319e3a072d118917957d6554Steve Block 362bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "Frame.h" 372bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "FrameView.h" 382bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "JSDOMWindowCustom.h" 392bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "Page.h" 402bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "PageGroup.h" 412bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "PluginView.h" 422bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "ScriptDebugListener.h" 432bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "Widget.h" 442bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <runtime/JSLock.h> 452bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/MainThread.h> 462bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/OwnPtr.h> 472bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/PassOwnPtr.h> 482bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/StdLibExtras.h> 492bde8e466a4451c7319e3a072d118917957d6554Steve Block 502bde8e466a4451c7319e3a072d118917957d6554Steve Blockusing namespace JSC; 512bde8e466a4451c7319e3a072d118917957d6554Steve Block 522bde8e466a4451c7319e3a072d118917957d6554Steve Blocknamespace WebCore { 532bde8e466a4451c7319e3a072d118917957d6554Steve Block 542bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic Page* toPage(JSGlobalObject* globalObject) 552bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 562bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT_ARG(globalObject, globalObject); 572bde8e466a4451c7319e3a072d118917957d6554Steve Block 582bde8e466a4451c7319e3a072d118917957d6554Steve Block JSDOMWindow* window = asJSDOMWindow(globalObject); 592bde8e466a4451c7319e3a072d118917957d6554Steve Block Frame* frame = window->impl()->frame(); 602bde8e466a4451c7319e3a072d118917957d6554Steve Block return frame ? frame->page() : 0; 612bde8e466a4451c7319e3a072d118917957d6554Steve Block} 622bde8e466a4451c7319e3a072d118917957d6554Steve Block 632bde8e466a4451c7319e3a072d118917957d6554Steve BlockPageScriptDebugServer& PageScriptDebugServer::shared() 642bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 652bde8e466a4451c7319e3a072d118917957d6554Steve Block DEFINE_STATIC_LOCAL(PageScriptDebugServer, server, ()); 662bde8e466a4451c7319e3a072d118917957d6554Steve Block return server; 672bde8e466a4451c7319e3a072d118917957d6554Steve Block} 682bde8e466a4451c7319e3a072d118917957d6554Steve Block 692bde8e466a4451c7319e3a072d118917957d6554Steve BlockPageScriptDebugServer::PageScriptDebugServer() 702bde8e466a4451c7319e3a072d118917957d6554Steve Block : ScriptDebugServer() 712bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 722bde8e466a4451c7319e3a072d118917957d6554Steve Block} 732bde8e466a4451c7319e3a072d118917957d6554Steve Block 742bde8e466a4451c7319e3a072d118917957d6554Steve BlockPageScriptDebugServer::~PageScriptDebugServer() 752bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 762bde8e466a4451c7319e3a072d118917957d6554Steve Block deleteAllValues(m_pageListenersMap); 772bde8e466a4451c7319e3a072d118917957d6554Steve Block} 782bde8e466a4451c7319e3a072d118917957d6554Steve Block 792bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid PageScriptDebugServer::addListener(ScriptDebugListener* listener, Page* page) 802bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 812bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT_ARG(listener, listener); 822bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT_ARG(page, page); 832bde8e466a4451c7319e3a072d118917957d6554Steve Block 842bde8e466a4451c7319e3a072d118917957d6554Steve Block pair<PageListenersMap::iterator, bool> result = m_pageListenersMap.add(page, 0); 852bde8e466a4451c7319e3a072d118917957d6554Steve Block if (result.second) 862bde8e466a4451c7319e3a072d118917957d6554Steve Block result.first->second = new ListenerSet; 872bde8e466a4451c7319e3a072d118917957d6554Steve Block 882bde8e466a4451c7319e3a072d118917957d6554Steve Block ListenerSet* listeners = result.first->second; 892bde8e466a4451c7319e3a072d118917957d6554Steve Block listeners->add(listener); 902bde8e466a4451c7319e3a072d118917957d6554Steve Block 912bde8e466a4451c7319e3a072d118917957d6554Steve Block recompileAllJSFunctionsSoon(); 922bde8e466a4451c7319e3a072d118917957d6554Steve Block page->setDebugger(this); 932bde8e466a4451c7319e3a072d118917957d6554Steve Block} 942bde8e466a4451c7319e3a072d118917957d6554Steve Block 952bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid PageScriptDebugServer::removeListener(ScriptDebugListener* listener, Page* page) 962bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 972bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT_ARG(listener, listener); 982bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT_ARG(page, page); 992bde8e466a4451c7319e3a072d118917957d6554Steve Block 1002bde8e466a4451c7319e3a072d118917957d6554Steve Block PageListenersMap::iterator it = m_pageListenersMap.find(page); 1012bde8e466a4451c7319e3a072d118917957d6554Steve Block if (it == m_pageListenersMap.end()) 1022bde8e466a4451c7319e3a072d118917957d6554Steve Block return; 1032bde8e466a4451c7319e3a072d118917957d6554Steve Block 1042bde8e466a4451c7319e3a072d118917957d6554Steve Block ListenerSet* listeners = it->second; 1052bde8e466a4451c7319e3a072d118917957d6554Steve Block listeners->remove(listener); 1062bde8e466a4451c7319e3a072d118917957d6554Steve Block if (listeners->isEmpty()) { 1072bde8e466a4451c7319e3a072d118917957d6554Steve Block m_pageListenersMap.remove(it); 1082bde8e466a4451c7319e3a072d118917957d6554Steve Block delete listeners; 1092bde8e466a4451c7319e3a072d118917957d6554Steve Block didRemoveLastListener(page); 1102bde8e466a4451c7319e3a072d118917957d6554Steve Block } 1112bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1122bde8e466a4451c7319e3a072d118917957d6554Steve Block 1132bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid PageScriptDebugServer::recompileAllJSFunctions(Timer<ScriptDebugServer>*) 1142bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 1152bde8e466a4451c7319e3a072d118917957d6554Steve Block JSLock lock(SilenceAssertionsOnly); 1162bde8e466a4451c7319e3a072d118917957d6554Steve Block // If JavaScript stack is not empty postpone recompilation. 1172bde8e466a4451c7319e3a072d118917957d6554Steve Block if (JSDOMWindow::commonJSGlobalData()->dynamicGlobalObject) 1182bde8e466a4451c7319e3a072d118917957d6554Steve Block recompileAllJSFunctionsSoon(); 1192bde8e466a4451c7319e3a072d118917957d6554Steve Block else 1202bde8e466a4451c7319e3a072d118917957d6554Steve Block Debugger::recompileAllJSFunctions(JSDOMWindow::commonJSGlobalData()); 1212bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1222bde8e466a4451c7319e3a072d118917957d6554Steve Block 1232bde8e466a4451c7319e3a072d118917957d6554Steve BlockScriptDebugServer::ListenerSet* PageScriptDebugServer::getListenersForGlobalObject(JSGlobalObject* globalObject) 1242bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 1252bde8e466a4451c7319e3a072d118917957d6554Steve Block Page* page = toPage(globalObject); 1262bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!page) 1272bde8e466a4451c7319e3a072d118917957d6554Steve Block return 0; 1282bde8e466a4451c7319e3a072d118917957d6554Steve Block return m_pageListenersMap.get(page); 1292bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1302bde8e466a4451c7319e3a072d118917957d6554Steve Block 1312bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid PageScriptDebugServer::didPause(JSC::JSGlobalObject* globalObject) 1322bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 1332bde8e466a4451c7319e3a072d118917957d6554Steve Block Page* page = toPage(globalObject); 1342bde8e466a4451c7319e3a072d118917957d6554Steve Block m_pausedPage = page; 1352bde8e466a4451c7319e3a072d118917957d6554Steve Block setJavaScriptPaused(page->group(), true); 1362bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1372bde8e466a4451c7319e3a072d118917957d6554Steve Block 1382bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid PageScriptDebugServer::didContinue(JSC::JSGlobalObject* globalObject) 1392bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 1402bde8e466a4451c7319e3a072d118917957d6554Steve Block Page* page = toPage(globalObject); 1412bde8e466a4451c7319e3a072d118917957d6554Steve Block m_pausedPage = 0; 1422bde8e466a4451c7319e3a072d118917957d6554Steve Block setJavaScriptPaused(page->group(), false); 1432bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1442bde8e466a4451c7319e3a072d118917957d6554Steve Block 1452bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid PageScriptDebugServer::didRemoveLastListener(Page* page) 1462bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 1472bde8e466a4451c7319e3a072d118917957d6554Steve Block if (m_pausedPage == page) 1482bde8e466a4451c7319e3a072d118917957d6554Steve Block m_doneProcessingDebuggerEvents = true; 1492bde8e466a4451c7319e3a072d118917957d6554Steve Block 1502bde8e466a4451c7319e3a072d118917957d6554Steve Block recompileAllJSFunctionsSoon(); 1512bde8e466a4451c7319e3a072d118917957d6554Steve Block page->setDebugger(0); 1522bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1532bde8e466a4451c7319e3a072d118917957d6554Steve Block 1542bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid PageScriptDebugServer::setJavaScriptPaused(const PageGroup& pageGroup, bool paused) 1552bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 1562bde8e466a4451c7319e3a072d118917957d6554Steve Block setMainThreadCallbacksPaused(paused); 1572bde8e466a4451c7319e3a072d118917957d6554Steve Block 1582bde8e466a4451c7319e3a072d118917957d6554Steve Block const HashSet<Page*>& pages = pageGroup.pages(); 1592bde8e466a4451c7319e3a072d118917957d6554Steve Block 1602bde8e466a4451c7319e3a072d118917957d6554Steve Block HashSet<Page*>::const_iterator end = pages.end(); 1612bde8e466a4451c7319e3a072d118917957d6554Steve Block for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) 1622bde8e466a4451c7319e3a072d118917957d6554Steve Block setJavaScriptPaused(*it, paused); 1632bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1642bde8e466a4451c7319e3a072d118917957d6554Steve Block 1652bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid PageScriptDebugServer::setJavaScriptPaused(Page* page, bool paused) 1662bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 1672bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT_ARG(page, page); 1682bde8e466a4451c7319e3a072d118917957d6554Steve Block 1692bde8e466a4451c7319e3a072d118917957d6554Steve Block page->setDefersLoading(paused); 1702bde8e466a4451c7319e3a072d118917957d6554Steve Block 1712bde8e466a4451c7319e3a072d118917957d6554Steve Block for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) 1722bde8e466a4451c7319e3a072d118917957d6554Steve Block setJavaScriptPaused(frame, paused); 1732bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1742bde8e466a4451c7319e3a072d118917957d6554Steve Block 1752bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid PageScriptDebugServer::setJavaScriptPaused(Frame* frame, bool paused) 1762bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 1772bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT_ARG(frame, frame); 1782bde8e466a4451c7319e3a072d118917957d6554Steve Block 1792bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!frame->script()->canExecuteScripts(NotAboutToExecuteScript)) 1802bde8e466a4451c7319e3a072d118917957d6554Steve Block return; 1812bde8e466a4451c7319e3a072d118917957d6554Steve Block 1822bde8e466a4451c7319e3a072d118917957d6554Steve Block frame->script()->setPaused(paused); 1832bde8e466a4451c7319e3a072d118917957d6554Steve Block 1842bde8e466a4451c7319e3a072d118917957d6554Steve Block Document* document = frame->document(); 1852bde8e466a4451c7319e3a072d118917957d6554Steve Block if (paused) { 1862bde8e466a4451c7319e3a072d118917957d6554Steve Block document->suspendScriptedAnimationControllerCallbacks(); 1872bde8e466a4451c7319e3a072d118917957d6554Steve Block document->suspendActiveDOMObjects(ActiveDOMObject::JavaScriptDebuggerPaused); 1882bde8e466a4451c7319e3a072d118917957d6554Steve Block } else { 1892bde8e466a4451c7319e3a072d118917957d6554Steve Block document->resumeActiveDOMObjects(); 1902bde8e466a4451c7319e3a072d118917957d6554Steve Block document->resumeScriptedAnimationControllerCallbacks(); 1912bde8e466a4451c7319e3a072d118917957d6554Steve Block } 1922bde8e466a4451c7319e3a072d118917957d6554Steve Block 1932bde8e466a4451c7319e3a072d118917957d6554Steve Block setJavaScriptPaused(frame->view(), paused); 1942bde8e466a4451c7319e3a072d118917957d6554Steve Block} 1952bde8e466a4451c7319e3a072d118917957d6554Steve Block 1962bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid PageScriptDebugServer::setJavaScriptPaused(FrameView* view, bool paused) 1972bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 1982bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!view) 1992bde8e466a4451c7319e3a072d118917957d6554Steve Block return; 2002bde8e466a4451c7319e3a072d118917957d6554Steve Block 2012bde8e466a4451c7319e3a072d118917957d6554Steve Block const HashSet<RefPtr<Widget> >* children = view->children(); 2022bde8e466a4451c7319e3a072d118917957d6554Steve Block ASSERT(children); 2032bde8e466a4451c7319e3a072d118917957d6554Steve Block 2042bde8e466a4451c7319e3a072d118917957d6554Steve Block HashSet<RefPtr<Widget> >::const_iterator end = children->end(); 2052bde8e466a4451c7319e3a072d118917957d6554Steve Block for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) { 2062bde8e466a4451c7319e3a072d118917957d6554Steve Block Widget* widget = (*it).get(); 2072bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!widget->isPluginView()) 2082bde8e466a4451c7319e3a072d118917957d6554Steve Block continue; 2092bde8e466a4451c7319e3a072d118917957d6554Steve Block static_cast<PluginView*>(widget)->setJavaScriptPaused(paused); 2102bde8e466a4451c7319e3a072d118917957d6554Steve Block } 2112bde8e466a4451c7319e3a072d118917957d6554Steve Block} 2122bde8e466a4451c7319e3a072d118917957d6554Steve Block 2132bde8e466a4451c7319e3a072d118917957d6554Steve Block} // namespace WebCore 2142bde8e466a4451c7319e3a072d118917957d6554Steve Block 2152bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif // ENABLE(JAVASCRIPT_DEBUGGER) 216