OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "bindings/core/v8/RejectedPromises.h" | 5 #include "bindings/core/v8/RejectedPromises.h" |
6 | 6 |
7 #include "bindings/core/v8/ScopedPersistent.h" | 7 #include "bindings/core/v8/ScopedPersistent.h" |
8 #include "bindings/core/v8/ScriptState.h" | 8 #include "bindings/core/v8/ScriptState.h" |
9 #include "bindings/core/v8/ScriptValue.h" | 9 #include "bindings/core/v8/ScriptValue.h" |
10 #include "bindings/core/v8/V8Binding.h" | 10 #include "bindings/core/v8/V8Binding.h" |
11 #include "core/dom/ExecutionContext.h" | 11 #include "core/dom/ExecutionContext.h" |
12 #include "core/events/EventTarget.h" | 12 #include "core/events/EventTarget.h" |
13 #include "core/events/PromiseRejectionEvent.h" | 13 #include "core/events/PromiseRejectionEvent.h" |
14 #include "core/inspector/ConsoleMessage.h" | 14 #include "core/inspector/ConsoleMessage.h" |
15 #include "core/inspector/ScriptArguments.h" | 15 #include "core/inspector/ScriptArguments.h" |
16 #include "platform/RuntimeEnabledFeatures.h" | 16 #include "platform/RuntimeEnabledFeatures.h" |
17 #include "public/platform/Platform.h" | 17 #include "public/platform/Platform.h" |
18 #include "public/platform/WebScheduler.h" | 18 #include "public/platform/WebScheduler.h" |
19 #include "public/platform/WebTaskRunner.h" | 19 #include "public/platform/WebTaskRunner.h" |
20 #include "public/platform/WebThread.h" | 20 #include "public/platform/WebThread.h" |
21 #include "wtf/Functional.h" | 21 #include "wtf/Functional.h" |
| 22 #include "wtf/PtrUtil.h" |
| 23 #include <memory> |
22 | 24 |
23 namespace blink { | 25 namespace blink { |
24 | 26 |
25 static const unsigned maxReportedHandlersPendingResolution = 1000; | 27 static const unsigned maxReportedHandlersPendingResolution = 1000; |
26 | 28 |
27 class RejectedPromises::Message final { | 29 class RejectedPromises::Message final { |
28 public: | 30 public: |
29 static PassOwnPtr<Message> create(ScriptState* scriptState, v8::Local<v8::Pr
omise> promise, v8::Local<v8::Value> exception, const String& errorMessage, Pass
OwnPtr<SourceLocation> location, AccessControlStatus corsStatus) | 31 static std::unique_ptr<Message> create(ScriptState* scriptState, v8::Local<v
8::Promise> promise, v8::Local<v8::Value> exception, const String& errorMessage,
std::unique_ptr<SourceLocation> location, AccessControlStatus corsStatus) |
30 { | 32 { |
31 return adoptPtr(new Message(scriptState, promise, exception, errorMessag
e, std::move(location), corsStatus)); | 33 return wrapUnique(new Message(scriptState, promise, exception, errorMess
age, std::move(location), corsStatus)); |
32 } | 34 } |
33 | 35 |
34 bool isCollected() | 36 bool isCollected() |
35 { | 37 { |
36 return m_collected || !m_scriptState->contextIsValid(); | 38 return m_collected || !m_scriptState->contextIsValid(); |
37 } | 39 } |
38 | 40 |
39 bool hasPromise(v8::Local<v8::Value> promise) | 41 bool hasPromise(v8::Local<v8::Value> promise) |
40 { | 42 { |
41 ScriptState::Scope scope(m_scriptState); | 43 ScriptState::Scope scope(m_scriptState); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 | 140 |
139 bool hasHandler() | 141 bool hasHandler() |
140 { | 142 { |
141 ASSERT(!isCollected()); | 143 ASSERT(!isCollected()); |
142 ScriptState::Scope scope(m_scriptState); | 144 ScriptState::Scope scope(m_scriptState); |
143 v8::Local<v8::Value> value = m_promise.newLocal(m_scriptState->isolate()
); | 145 v8::Local<v8::Value> value = m_promise.newLocal(m_scriptState->isolate()
); |
144 return v8::Local<v8::Promise>::Cast(value)->HasHandler(); | 146 return v8::Local<v8::Promise>::Cast(value)->HasHandler(); |
145 } | 147 } |
146 | 148 |
147 private: | 149 private: |
148 Message(ScriptState* scriptState, v8::Local<v8::Promise> promise, v8::Local<
v8::Value> exception, const String& errorMessage, PassOwnPtr<SourceLocation> loc
ation, AccessControlStatus corsStatus) | 150 Message(ScriptState* scriptState, v8::Local<v8::Promise> promise, v8::Local<
v8::Value> exception, const String& errorMessage, std::unique_ptr<SourceLocation
> location, AccessControlStatus corsStatus) |
149 : m_scriptState(scriptState) | 151 : m_scriptState(scriptState) |
150 , m_promise(scriptState->isolate(), promise) | 152 , m_promise(scriptState->isolate(), promise) |
151 , m_exception(scriptState->isolate(), exception) | 153 , m_exception(scriptState->isolate(), exception) |
152 , m_errorMessage(errorMessage) | 154 , m_errorMessage(errorMessage) |
153 , m_resourceName(location->url()) | 155 , m_resourceName(location->url()) |
154 , m_location(std::move(location)) | 156 , m_location(std::move(location)) |
155 , m_consoleMessageId(0) | 157 , m_consoleMessageId(0) |
156 , m_collected(false) | 158 , m_collected(false) |
157 , m_shouldLogToConsole(true) | 159 , m_shouldLogToConsole(true) |
158 , m_corsStatus(corsStatus) | 160 , m_corsStatus(corsStatus) |
159 { | 161 { |
160 } | 162 } |
161 | 163 |
162 static void didCollectPromise(const v8::WeakCallbackInfo<Message>& data) | 164 static void didCollectPromise(const v8::WeakCallbackInfo<Message>& data) |
163 { | 165 { |
164 data.GetParameter()->m_collected = true; | 166 data.GetParameter()->m_collected = true; |
165 data.GetParameter()->m_promise.clear(); | 167 data.GetParameter()->m_promise.clear(); |
166 } | 168 } |
167 | 169 |
168 static void didCollectException(const v8::WeakCallbackInfo<Message>& data) | 170 static void didCollectException(const v8::WeakCallbackInfo<Message>& data) |
169 { | 171 { |
170 data.GetParameter()->m_exception.clear(); | 172 data.GetParameter()->m_exception.clear(); |
171 } | 173 } |
172 | 174 |
173 ScriptState* m_scriptState; | 175 ScriptState* m_scriptState; |
174 ScopedPersistent<v8::Promise> m_promise; | 176 ScopedPersistent<v8::Promise> m_promise; |
175 ScopedPersistent<v8::Value> m_exception; | 177 ScopedPersistent<v8::Value> m_exception; |
176 String m_errorMessage; | 178 String m_errorMessage; |
177 String m_resourceName; | 179 String m_resourceName; |
178 OwnPtr<SourceLocation> m_location; | 180 std::unique_ptr<SourceLocation> m_location; |
179 unsigned m_consoleMessageId; | 181 unsigned m_consoleMessageId; |
180 bool m_collected; | 182 bool m_collected; |
181 bool m_shouldLogToConsole; | 183 bool m_shouldLogToConsole; |
182 AccessControlStatus m_corsStatus; | 184 AccessControlStatus m_corsStatus; |
183 }; | 185 }; |
184 | 186 |
185 RejectedPromises::RejectedPromises() | 187 RejectedPromises::RejectedPromises() |
186 { | 188 { |
187 } | 189 } |
188 | 190 |
189 RejectedPromises::~RejectedPromises() | 191 RejectedPromises::~RejectedPromises() |
190 { | 192 { |
191 } | 193 } |
192 | 194 |
193 void RejectedPromises::rejectedWithNoHandler(ScriptState* scriptState, v8::Promi
seRejectMessage data, const String& errorMessage, PassOwnPtr<SourceLocation> loc
ation, AccessControlStatus corsStatus) | 195 void RejectedPromises::rejectedWithNoHandler(ScriptState* scriptState, v8::Promi
seRejectMessage data, const String& errorMessage, std::unique_ptr<SourceLocation
> location, AccessControlStatus corsStatus) |
194 { | 196 { |
195 m_queue.append(Message::create(scriptState, data.GetPromise(), data.GetValue
(), errorMessage, std::move(location), corsStatus)); | 197 m_queue.append(Message::create(scriptState, data.GetPromise(), data.GetValue
(), errorMessage, std::move(location), corsStatus)); |
196 } | 198 } |
197 | 199 |
198 void RejectedPromises::handlerAdded(v8::PromiseRejectMessage data) | 200 void RejectedPromises::handlerAdded(v8::PromiseRejectMessage data) |
199 { | 201 { |
200 // First look it up in the pending messages and fast return, it'll be covere
d by processQueue(). | 202 // First look it up in the pending messages and fast return, it'll be covere
d by processQueue(). |
201 for (auto it = m_queue.begin(); it != m_queue.end(); ++it) { | 203 for (auto it = m_queue.begin(); it != m_queue.end(); ++it) { |
202 if (!(*it)->isCollected() && (*it)->hasPromise(data.GetPromise())) { | 204 if (!(*it)->isCollected() && (*it)->hasPromise(data.GetPromise())) { |
203 m_queue.remove(it); | 205 m_queue.remove(it); |
204 return; | 206 return; |
205 } | 207 } |
206 } | 208 } |
207 | 209 |
208 // Then look it up in the reported errors. | 210 // Then look it up in the reported errors. |
209 for (size_t i = 0; i < m_reportedAsErrors.size(); ++i) { | 211 for (size_t i = 0; i < m_reportedAsErrors.size(); ++i) { |
210 OwnPtr<Message>& message = m_reportedAsErrors.at(i); | 212 std::unique_ptr<Message>& message = m_reportedAsErrors.at(i); |
211 if (!message->isCollected() && message->hasPromise(data.GetPromise())) { | 213 if (!message->isCollected() && message->hasPromise(data.GetPromise())) { |
212 message->makePromiseStrong(); | 214 message->makePromiseStrong(); |
213 Platform::current()->currentThread()->scheduler()->timerTaskRunner()
->postTask(BLINK_FROM_HERE, bind(&RejectedPromises::revokeNow, this, passed(std:
:move(message)))); | 215 Platform::current()->currentThread()->scheduler()->timerTaskRunner()
->postTask(BLINK_FROM_HERE, WTF::bind(&RejectedPromises::revokeNow, this, passed
(std::move(message)))); |
214 m_reportedAsErrors.remove(i); | 216 m_reportedAsErrors.remove(i); |
215 return; | 217 return; |
216 } | 218 } |
217 } | 219 } |
218 } | 220 } |
219 | 221 |
220 PassOwnPtr<RejectedPromises::MessageQueue> RejectedPromises::createMessageQueue(
) | 222 std::unique_ptr<RejectedPromises::MessageQueue> RejectedPromises::createMessageQ
ueue() |
221 { | 223 { |
222 return adoptPtr(new MessageQueue()); | 224 return wrapUnique(new MessageQueue()); |
223 } | 225 } |
224 | 226 |
225 void RejectedPromises::dispose() | 227 void RejectedPromises::dispose() |
226 { | 228 { |
227 if (m_queue.isEmpty()) | 229 if (m_queue.isEmpty()) |
228 return; | 230 return; |
229 | 231 |
230 OwnPtr<MessageQueue> queue = createMessageQueue(); | 232 std::unique_ptr<MessageQueue> queue = createMessageQueue(); |
231 queue->swap(m_queue); | 233 queue->swap(m_queue); |
232 processQueueNow(std::move(queue)); | 234 processQueueNow(std::move(queue)); |
233 } | 235 } |
234 | 236 |
235 void RejectedPromises::processQueue() | 237 void RejectedPromises::processQueue() |
236 { | 238 { |
237 if (m_queue.isEmpty()) | 239 if (m_queue.isEmpty()) |
238 return; | 240 return; |
239 | 241 |
240 OwnPtr<MessageQueue> queue = createMessageQueue(); | 242 std::unique_ptr<MessageQueue> queue = createMessageQueue(); |
241 queue->swap(m_queue); | 243 queue->swap(m_queue); |
242 Platform::current()->currentThread()->scheduler()->timerTaskRunner()->postTa
sk(BLINK_FROM_HERE, bind(&RejectedPromises::processQueueNow, PassRefPtr<Rejected
Promises>(this), passed(std::move(queue)))); | 244 Platform::current()->currentThread()->scheduler()->timerTaskRunner()->postTa
sk(BLINK_FROM_HERE, WTF::bind(&RejectedPromises::processQueueNow, PassRefPtr<Rej
ectedPromises>(this), passed(std::move(queue)))); |
243 } | 245 } |
244 | 246 |
245 void RejectedPromises::processQueueNow(PassOwnPtr<MessageQueue> queue) | 247 void RejectedPromises::processQueueNow(std::unique_ptr<MessageQueue> queue) |
246 { | 248 { |
247 // Remove collected handlers. | 249 // Remove collected handlers. |
248 for (size_t i = 0; i < m_reportedAsErrors.size();) { | 250 for (size_t i = 0; i < m_reportedAsErrors.size();) { |
249 if (m_reportedAsErrors.at(i)->isCollected()) | 251 if (m_reportedAsErrors.at(i)->isCollected()) |
250 m_reportedAsErrors.remove(i); | 252 m_reportedAsErrors.remove(i); |
251 else | 253 else |
252 ++i; | 254 ++i; |
253 } | 255 } |
254 | 256 |
255 while (!queue->isEmpty()) { | 257 while (!queue->isEmpty()) { |
256 OwnPtr<Message> message = queue->takeFirst(); | 258 std::unique_ptr<Message> message = queue->takeFirst(); |
257 if (message->isCollected()) | 259 if (message->isCollected()) |
258 continue; | 260 continue; |
259 if (!message->hasHandler()) { | 261 if (!message->hasHandler()) { |
260 message->report(); | 262 message->report(); |
261 message->makePromiseWeak(); | 263 message->makePromiseWeak(); |
262 m_reportedAsErrors.append(std::move(message)); | 264 m_reportedAsErrors.append(std::move(message)); |
263 if (m_reportedAsErrors.size() > maxReportedHandlersPendingResolution
) | 265 if (m_reportedAsErrors.size() > maxReportedHandlersPendingResolution
) |
264 m_reportedAsErrors.remove(0, maxReportedHandlersPendingResolutio
n / 10); | 266 m_reportedAsErrors.remove(0, maxReportedHandlersPendingResolutio
n / 10); |
265 } | 267 } |
266 } | 268 } |
267 } | 269 } |
268 | 270 |
269 void RejectedPromises::revokeNow(PassOwnPtr<Message> message) | 271 void RejectedPromises::revokeNow(std::unique_ptr<Message> message) |
270 { | 272 { |
271 message->revoke(); | 273 message->revoke(); |
272 } | 274 } |
273 | 275 |
274 } // namespace blink | 276 } // namespace blink |
OLD | NEW |