Unreviewed, rolling out r234489.
[WebKit-https.git] / Source / WebCore / inspector / PageScriptDebugServer.cpp
1 /*
2  * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
3  * Copyright (c) 2011 Google Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "PageScriptDebugServer.h"
29
30 #include "CommonVM.h"
31 #include "Document.h"
32 #include "EventLoop.h"
33 #include "Frame.h"
34 #include "FrameView.h"
35 #include "InspectorController.h"
36 #include "InspectorFrontendClient.h"
37 #include "JSDOMExceptionHandling.h"
38 #include "JSDOMWindowCustom.h"
39 #include "Page.h"
40 #include "PageGroup.h"
41 #include "PluginViewBase.h"
42 #include "ScriptController.h"
43 #include "Timer.h"
44 #include <JavaScriptCore/JSLock.h>
45 #include <wtf/MainThread.h>
46 #include <wtf/StdLibExtras.h>
47
48 #if PLATFORM(IOS)
49 #include "WebCoreThreadInternal.h"
50 #endif
51
52
53 namespace WebCore {
54 using namespace JSC;
55 using namespace Inspector;
56
57 PageScriptDebugServer::PageScriptDebugServer(Page& page)
58     : ScriptDebugServer(WebCore::commonVM())
59     , m_page(page)
60 {
61 }
62
63 void PageScriptDebugServer::attachDebugger()
64 {
65     m_page.setDebugger(this);
66 }
67
68 void PageScriptDebugServer::detachDebugger(bool isBeingDestroyed)
69 {
70     m_page.setDebugger(nullptr);
71     if (!isBeingDestroyed)
72         recompileAllJSFunctions();
73 }
74
75 void PageScriptDebugServer::recompileAllJSFunctions()
76 {
77     JSLockHolder lock(vm());
78     Debugger::recompileAllJSFunctions();
79 }
80
81 void PageScriptDebugServer::didPause(JSGlobalObject*)
82 {
83     setJavaScriptPaused(m_page.group(), true);
84 }
85
86 void PageScriptDebugServer::didContinue(JSGlobalObject*)
87 {
88     setJavaScriptPaused(m_page.group(), false);
89 }
90
91 void PageScriptDebugServer::runEventLoopWhilePaused()
92 {
93 #if PLATFORM(IOS)
94     // On iOS, running an EventLoop causes us to run a nested WebRunLoop.
95     // Since the WebThread is autoreleased at the end of run loop iterations
96     // we need to gracefully handle releasing and reacquiring the lock.
97     if (WebThreadIsEnabled()) {
98         ASSERT(WebThreadIsLockedOrDisabled());
99         JSC::JSLock::DropAllLocks dropAllLocks(vm());
100         WebRunLoopEnableNested();
101
102         runEventLoopWhilePausedInternal();
103
104         WebRunLoopDisableNested();
105         ASSERT(WebThreadIsLockedOrDisabled());
106         return;
107     }
108 #endif
109
110     runEventLoopWhilePausedInternal();
111 }
112
113 void PageScriptDebugServer::runEventLoopWhilePausedInternal()
114 {
115     TimerBase::fireTimersInNestedEventLoop();
116
117     m_page.incrementNestedRunLoopCount();
118
119     EventLoop loop;
120     while (!m_doneProcessingDebuggerEvents && !loop.ended())
121         loop.cycle();
122
123     m_page.decrementNestedRunLoopCount();
124 }
125
126 bool PageScriptDebugServer::isContentScript(ExecState* state) const
127 {
128     return &currentWorld(*state) != &mainThreadNormalWorld();
129 }
130
131 void PageScriptDebugServer::reportException(ExecState* state, JSC::Exception* exception) const
132 {
133     WebCore::reportException(state, exception);
134 }
135
136 void PageScriptDebugServer::setJavaScriptPaused(const PageGroup& pageGroup, bool paused)
137 {
138     setMainThreadCallbacksPaused(paused);
139
140     for (auto& page : pageGroup.pages()) {
141         page->setDefersLoading(paused);
142
143         for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext())
144             setJavaScriptPaused(*frame, paused);
145
146         if (auto* frontendClient = page->inspectorController().inspectorFrontendClient()) {
147             if (paused)
148                 frontendClient->pagePaused();
149             else
150                 frontendClient->pageUnpaused();
151         }
152     }
153 }
154
155 void PageScriptDebugServer::setJavaScriptPaused(Frame& frame, bool paused)
156 {
157     if (!frame.script().canExecuteScripts(NotAboutToExecuteScript))
158         return;
159
160     frame.script().setPaused(paused);
161
162     ASSERT(frame.document());
163     auto& document = *frame.document();
164     if (paused) {
165         document.suspendScriptedAnimationControllerCallbacks();
166         document.suspendActiveDOMObjects(ReasonForSuspension::JavaScriptDebuggerPaused);
167     } else {
168         document.resumeActiveDOMObjects(ReasonForSuspension::JavaScriptDebuggerPaused);
169         document.resumeScriptedAnimationControllerCallbacks();
170     }
171
172     if (auto* view = frame.view()) {
173         for (auto& child : view->children()) {
174             if (!is<PluginViewBase>(child))
175                 continue;
176             downcast<PluginViewBase>(child.get()).setJavaScriptPaused(paused);
177         }
178     }
179 }
180
181 } // namespace WebCore