| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. | 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| 11 * documentation and/or other materials provided with the distribution. | 11 * documentation and/or other materials provided with the distribution. |
| 12 * | 12 * |
| 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
| 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR | 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
| 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "core/dom/ScriptRunner.h" | 26 #include "core/dom/ScriptRunner.h" |
| 27 | 27 |
| 28 #include <algorithm> |
| 28 #include "core/dom/Document.h" | 29 #include "core/dom/Document.h" |
| 29 #include "core/dom/Element.h" | 30 #include "core/dom/Element.h" |
| 30 #include "core/dom/ScriptLoader.h" | 31 #include "core/dom/ScriptLoader.h" |
| 31 #include "core/dom/TaskRunnerHelper.h" | 32 #include "core/dom/TaskRunnerHelper.h" |
| 32 #include "platform/heap/Handle.h" | 33 #include "platform/heap/Handle.h" |
| 33 #include "public/platform/Platform.h" | 34 #include "public/platform/Platform.h" |
| 34 #include "public/platform/WebScheduler.h" | 35 #include "public/platform/WebScheduler.h" |
| 35 #include "public/platform/WebThread.h" | 36 #include "public/platform/WebThread.h" |
| 36 | 37 |
| 37 namespace blink { | 38 namespace blink { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 m_inOrderScriptsToExecuteSoon.append(m_pendingInOrderScripts.takeFirst()); | 103 m_inOrderScriptsToExecuteSoon.append(m_pendingInOrderScripts.takeFirst()); |
| 103 postTask(BLINK_FROM_HERE); | 104 postTask(BLINK_FROM_HERE); |
| 104 } | 105 } |
| 105 } | 106 } |
| 106 | 107 |
| 107 void ScriptRunner::notifyScriptReady(ScriptLoader* scriptLoader, | 108 void ScriptRunner::notifyScriptReady(ScriptLoader* scriptLoader, |
| 108 AsyncExecutionType executionType) { | 109 AsyncExecutionType executionType) { |
| 109 SECURITY_CHECK(scriptLoader); | 110 SECURITY_CHECK(scriptLoader); |
| 110 switch (executionType) { | 111 switch (executionType) { |
| 111 case Async: | 112 case Async: |
| 112 // RELEASE_ASSERT makes us crash in a controlled way in error cases | 113 // SECURITY_CHECK() makes us crash in a controlled way in error cases |
| 113 // where the ScriptLoader is associated with the wrong ScriptRunner | 114 // where the ScriptLoader is associated with the wrong ScriptRunner |
| 114 // (otherwise we'd cause a use-after-free in ~ScriptRunner when it tries | 115 // (otherwise we'd cause a use-after-free in ~ScriptRunner when it tries |
| 115 // to detach). | 116 // to detach). |
| 116 SECURITY_CHECK(m_pendingAsyncScripts.contains(scriptLoader)); | 117 SECURITY_CHECK(m_pendingAsyncScripts.contains(scriptLoader)); |
| 117 | 118 |
| 118 m_pendingAsyncScripts.erase(scriptLoader); | 119 m_pendingAsyncScripts.erase(scriptLoader); |
| 119 m_asyncScriptsToExecuteSoon.append(scriptLoader); | 120 m_asyncScriptsToExecuteSoon.append(scriptLoader); |
| 120 | 121 |
| 121 postTask(BLINK_FROM_HERE); | 122 postTask(BLINK_FROM_HERE); |
| 122 | 123 |
| 123 break; | 124 break; |
| 124 | 125 |
| 125 case InOrder: | 126 case InOrder: |
| 126 SECURITY_CHECK(m_numberOfInOrderScriptsWithPendingNotification > 0); | 127 SECURITY_CHECK(m_numberOfInOrderScriptsWithPendingNotification > 0); |
| 127 m_numberOfInOrderScriptsWithPendingNotification--; | 128 m_numberOfInOrderScriptsWithPendingNotification--; |
| 128 | 129 |
| 129 scheduleReadyInOrderScripts(); | 130 scheduleReadyInOrderScripts(); |
| 130 | 131 |
| 131 break; | 132 break; |
| 132 case None: | 133 case None: |
| 133 NOTREACHED(); | 134 NOTREACHED(); |
| 134 break; | 135 break; |
| 135 } | 136 } |
| 136 } | 137 } |
| 137 | 138 |
| 138 bool ScriptRunner::removePendingInOrderScript(ScriptLoader* scriptLoader) { | 139 bool ScriptRunner::removePendingInOrderScript(ScriptLoader* scriptLoader) { |
| 139 for (auto it = m_pendingInOrderScripts.begin(); | 140 auto it = std::find(m_pendingInOrderScripts.begin(), |
| 140 it != m_pendingInOrderScripts.end(); ++it) { | 141 m_pendingInOrderScripts.end(), scriptLoader); |
| 141 if (*it == scriptLoader) { | 142 if (it == m_pendingInOrderScripts.end()) |
| 142 m_pendingInOrderScripts.remove(it); | 143 return false; |
| 143 SECURITY_CHECK(m_numberOfInOrderScriptsWithPendingNotification > 0); | 144 m_pendingInOrderScripts.remove(it); |
| 144 m_numberOfInOrderScriptsWithPendingNotification--; | 145 SECURITY_CHECK(m_numberOfInOrderScriptsWithPendingNotification > 0); |
| 145 return true; | 146 m_numberOfInOrderScriptsWithPendingNotification--; |
| 146 } | 147 return true; |
| 147 } | |
| 148 return false; | |
| 149 } | 148 } |
| 150 | 149 |
| 151 void ScriptRunner::notifyScriptLoadError(ScriptLoader* scriptLoader, | 150 void ScriptRunner::notifyScriptLoadError(ScriptLoader* scriptLoader, |
| 152 AsyncExecutionType executionType) { | 151 AsyncExecutionType executionType) { |
| 153 switch (executionType) { | 152 switch (executionType) { |
| 154 case Async: { | 153 case Async: { |
| 155 // SECURITY_CHECK makes us crash in a controlled way in error cases | 154 // See notifyScriptReady() comment. |
| 156 // where the ScriptLoader is associated with the wrong ScriptRunner | |
| 157 // (otherwise we'd cause a use-after-free in ~ScriptRunner when it tries | |
| 158 // to detach). | |
| 159 SECURITY_CHECK(m_pendingAsyncScripts.contains(scriptLoader)); | 155 SECURITY_CHECK(m_pendingAsyncScripts.contains(scriptLoader)); |
| 160 m_pendingAsyncScripts.erase(scriptLoader); | 156 m_pendingAsyncScripts.erase(scriptLoader); |
| 161 break; | 157 break; |
| 162 } | 158 } |
| 163 case InOrder: | 159 case InOrder: { |
| 164 SECURITY_CHECK(removePendingInOrderScript(scriptLoader)); | 160 SECURITY_CHECK(removePendingInOrderScript(scriptLoader)); |
| 165 scheduleReadyInOrderScripts(); | 161 scheduleReadyInOrderScripts(); |
| 166 break; | 162 break; |
| 167 case None: | 163 } |
| 164 case None: { |
| 168 NOTREACHED(); | 165 NOTREACHED(); |
| 169 break; | 166 break; |
| 167 } |
| 170 } | 168 } |
| 171 m_document->decrementLoadEventDelayCount(); | 169 m_document->decrementLoadEventDelayCount(); |
| 172 } | 170 } |
| 173 | 171 |
| 174 void ScriptRunner::movePendingScript(Document& oldDocument, | 172 void ScriptRunner::movePendingScript(Document& oldDocument, |
| 175 Document& newDocument, | 173 Document& newDocument, |
| 176 ScriptLoader* scriptLoader) { | 174 ScriptLoader* scriptLoader) { |
| 177 Document* newContextDocument = newDocument.contextDocument(); | 175 Document* newContextDocument = newDocument.contextDocument(); |
| 178 if (!newContextDocument) { | 176 if (!newContextDocument) { |
| 179 // Document's contextDocument() method will return no Document if the | 177 // Document's contextDocument() method will return no Document if the |
| (...skipping 14 matching lines...) Expand all Loading... |
| 194 DCHECK(!oldDocument.frame()); | 192 DCHECK(!oldDocument.frame()); |
| 195 oldContextDocument = &oldDocument; | 193 oldContextDocument = &oldDocument; |
| 196 } | 194 } |
| 197 if (oldContextDocument != newContextDocument) | 195 if (oldContextDocument != newContextDocument) |
| 198 oldContextDocument->scriptRunner()->movePendingScript( | 196 oldContextDocument->scriptRunner()->movePendingScript( |
| 199 newContextDocument->scriptRunner(), scriptLoader); | 197 newContextDocument->scriptRunner(), scriptLoader); |
| 200 } | 198 } |
| 201 | 199 |
| 202 void ScriptRunner::movePendingScript(ScriptRunner* newRunner, | 200 void ScriptRunner::movePendingScript(ScriptRunner* newRunner, |
| 203 ScriptLoader* scriptLoader) { | 201 ScriptLoader* scriptLoader) { |
| 204 if (m_pendingAsyncScripts.contains(scriptLoader)) { | 202 auto it = m_pendingAsyncScripts.find(scriptLoader); |
| 203 if (it != m_pendingAsyncScripts.end()) { |
| 205 newRunner->queueScriptForExecution(scriptLoader, Async); | 204 newRunner->queueScriptForExecution(scriptLoader, Async); |
| 206 m_pendingAsyncScripts.erase(scriptLoader); | 205 m_pendingAsyncScripts.erase(it); |
| 207 m_document->decrementLoadEventDelayCount(); | 206 m_document->decrementLoadEventDelayCount(); |
| 208 return; | 207 return; |
| 209 } | 208 } |
| 210 if (removePendingInOrderScript(scriptLoader)) { | 209 if (removePendingInOrderScript(scriptLoader)) { |
| 211 newRunner->queueScriptForExecution(scriptLoader, InOrder); | 210 newRunner->queueScriptForExecution(scriptLoader, InOrder); |
| 212 m_document->decrementLoadEventDelayCount(); | 211 m_document->decrementLoadEventDelayCount(); |
| 213 } | 212 } |
| 214 } | 213 } |
| 215 | 214 |
| 216 // Returns true if task was run, and false otherwise. | 215 // Returns true if task was run, and false otherwise. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 242 | 241 |
| 243 DEFINE_TRACE(ScriptRunner) { | 242 DEFINE_TRACE(ScriptRunner) { |
| 244 visitor->trace(m_document); | 243 visitor->trace(m_document); |
| 245 visitor->trace(m_pendingInOrderScripts); | 244 visitor->trace(m_pendingInOrderScripts); |
| 246 visitor->trace(m_pendingAsyncScripts); | 245 visitor->trace(m_pendingAsyncScripts); |
| 247 visitor->trace(m_asyncScriptsToExecuteSoon); | 246 visitor->trace(m_asyncScriptsToExecuteSoon); |
| 248 visitor->trace(m_inOrderScriptsToExecuteSoon); | 247 visitor->trace(m_inOrderScriptsToExecuteSoon); |
| 249 } | 248 } |
| 250 | 249 |
| 251 } // namespace blink | 250 } // namespace blink |
| OLD | NEW |