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/ScriptCallStack.h" | |
9 #include "bindings/core/v8/ScriptState.h" | 8 #include "bindings/core/v8/ScriptState.h" |
10 #include "bindings/core/v8/ScriptValue.h" | 9 #include "bindings/core/v8/ScriptValue.h" |
11 #include "bindings/core/v8/V8Binding.h" | 10 #include "bindings/core/v8/V8Binding.h" |
12 #include "core/dom/ExecutionContext.h" | 11 #include "core/dom/ExecutionContext.h" |
13 #include "core/events/EventTarget.h" | 12 #include "core/events/EventTarget.h" |
14 #include "core/events/PromiseRejectionEvent.h" | 13 #include "core/events/PromiseRejectionEvent.h" |
15 #include "core/inspector/ConsoleMessage.h" | 14 #include "core/inspector/ConsoleMessage.h" |
16 #include "core/inspector/ScriptArguments.h" | 15 #include "core/inspector/ScriptArguments.h" |
17 #include "platform/RuntimeEnabledFeatures.h" | 16 #include "platform/RuntimeEnabledFeatures.h" |
18 #include "public/platform/Platform.h" | 17 #include "public/platform/Platform.h" |
19 #include "public/platform/WebScheduler.h" | 18 #include "public/platform/WebScheduler.h" |
20 #include "public/platform/WebTaskRunner.h" | 19 #include "public/platform/WebTaskRunner.h" |
21 #include "public/platform/WebThread.h" | 20 #include "public/platform/WebThread.h" |
22 #include "wtf/Functional.h" | 21 #include "wtf/Functional.h" |
23 | 22 |
24 namespace blink { | 23 namespace blink { |
25 | 24 |
26 static const unsigned maxReportedHandlersPendingResolution = 1000; | 25 static const unsigned maxReportedHandlersPendingResolution = 1000; |
27 | 26 |
28 class RejectedPromises::Message final { | 27 class RejectedPromises::Message final { |
29 public: | 28 public: |
30 static PassOwnPtr<Message> create(ScriptState* scriptState, v8::Local<v8::Pr
omise> promise, v8::Local<v8::Value> exception, const String& errorMessage, cons
t String& resourceName, int scriptId, int lineNumber, int columnNumber, PassRefP
tr<ScriptCallStack> callStack, AccessControlStatus corsStatus) | 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 { | 30 { |
32 return adoptPtr(new Message(scriptState, promise, exception, errorMessag
e, resourceName, scriptId, lineNumber, columnNumber, callStack, corsStatus)); | 31 return adoptPtr(new Message(scriptState, promise, exception, errorMessag
e, std::move(location), corsStatus)); |
33 } | 32 } |
34 | 33 |
35 bool isCollected() | 34 bool isCollected() |
36 { | 35 { |
37 return m_collected || !m_scriptState->contextIsValid(); | 36 return m_collected || !m_scriptState->contextIsValid(); |
38 } | 37 } |
39 | 38 |
40 bool hasPromise(v8::Local<v8::Value> promise) | 39 bool hasPromise(v8::Local<v8::Value> promise) |
41 { | 40 { |
42 ScriptState::Scope scope(m_scriptState); | 41 ScriptState::Scope scope(m_scriptState); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 args.append(ScriptValue(m_scriptState, v8String(m_scriptState->isola
te(), errorMessage))); | 78 args.append(ScriptValue(m_scriptState, v8String(m_scriptState->isola
te(), errorMessage))); |
80 args.append(ScriptValue(m_scriptState, reason)); | 79 args.append(ScriptValue(m_scriptState, reason)); |
81 ScriptArguments* arguments = ScriptArguments::create(m_scriptState,
args); | 80 ScriptArguments* arguments = ScriptArguments::create(m_scriptState,
args); |
82 | 81 |
83 String embedderErrorMessage = m_errorMessage; | 82 String embedderErrorMessage = m_errorMessage; |
84 if (embedderErrorMessage.isEmpty()) | 83 if (embedderErrorMessage.isEmpty()) |
85 embedderErrorMessage = errorMessage; | 84 embedderErrorMessage = errorMessage; |
86 else if (embedderErrorMessage.startsWith("Uncaught ")) | 85 else if (embedderErrorMessage.startsWith("Uncaught ")) |
87 embedderErrorMessage.insert(" (in promise)", 8); | 86 embedderErrorMessage.insert(" (in promise)", 8); |
88 | 87 |
89 ConsoleMessage* consoleMessage = ConsoleMessage::create(JSMessageSou
rce, ErrorMessageLevel, embedderErrorMessage, m_resourceName, m_lineNumber, m_co
lumnNumber, m_callStack, m_scriptId, arguments); | 88 ConsoleMessage* consoleMessage = ConsoleMessage::create(JSMessageSou
rce, ErrorMessageLevel, embedderErrorMessage, std::move(m_location), arguments); |
90 m_consoleMessageId = consoleMessage->assignMessageId(); | 89 m_consoleMessageId = consoleMessage->assignMessageId(); |
91 executionContext->addConsoleMessage(consoleMessage); | 90 executionContext->addConsoleMessage(consoleMessage); |
92 } | 91 } |
93 | 92 |
94 m_callStack.clear(); | 93 m_location.clear(); |
95 } | 94 } |
96 | 95 |
97 void revoke() | 96 void revoke() |
98 { | 97 { |
99 ExecutionContext* executionContext = m_scriptState->getExecutionContext(
); | 98 ExecutionContext* executionContext = m_scriptState->getExecutionContext(
); |
100 if (!executionContext) | 99 if (!executionContext) |
101 return; | 100 return; |
102 | 101 |
103 ScriptState::Scope scope(m_scriptState); | 102 ScriptState::Scope scope(m_scriptState); |
104 v8::Local<v8::Value> value = m_promise.newLocal(m_scriptState->isolate()
); | 103 v8::Local<v8::Value> value = m_promise.newLocal(m_scriptState->isolate()
); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 | 138 |
140 bool hasHandler() | 139 bool hasHandler() |
141 { | 140 { |
142 ASSERT(!isCollected()); | 141 ASSERT(!isCollected()); |
143 ScriptState::Scope scope(m_scriptState); | 142 ScriptState::Scope scope(m_scriptState); |
144 v8::Local<v8::Value> value = m_promise.newLocal(m_scriptState->isolate()
); | 143 v8::Local<v8::Value> value = m_promise.newLocal(m_scriptState->isolate()
); |
145 return v8::Local<v8::Promise>::Cast(value)->HasHandler(); | 144 return v8::Local<v8::Promise>::Cast(value)->HasHandler(); |
146 } | 145 } |
147 | 146 |
148 private: | 147 private: |
149 Message(ScriptState* scriptState, v8::Local<v8::Promise> promise, v8::Local<
v8::Value> exception, const String& errorMessage, const String& resourceName, in
t scriptId, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack> callSt
ack, AccessControlStatus corsStatus) | 148 Message(ScriptState* scriptState, v8::Local<v8::Promise> promise, v8::Local<
v8::Value> exception, const String& errorMessage, PassOwnPtr<SourceLocation> loc
ation, AccessControlStatus corsStatus) |
150 : m_scriptState(scriptState) | 149 : m_scriptState(scriptState) |
151 , m_promise(scriptState->isolate(), promise) | 150 , m_promise(scriptState->isolate(), promise) |
152 , m_exception(scriptState->isolate(), exception) | 151 , m_exception(scriptState->isolate(), exception) |
153 , m_errorMessage(errorMessage) | 152 , m_errorMessage(errorMessage) |
154 , m_resourceName(resourceName) | 153 , m_resourceName(location->url()) |
155 , m_scriptId(scriptId) | 154 , m_location(std::move(location)) |
156 , m_lineNumber(lineNumber) | |
157 , m_columnNumber(columnNumber) | |
158 , m_callStack(callStack) | |
159 , m_consoleMessageId(0) | 155 , m_consoleMessageId(0) |
160 , m_collected(false) | 156 , m_collected(false) |
161 , m_shouldLogToConsole(true) | 157 , m_shouldLogToConsole(true) |
162 , m_corsStatus(corsStatus) | 158 , m_corsStatus(corsStatus) |
163 { | 159 { |
164 } | 160 } |
165 | 161 |
166 static void didCollectPromise(const v8::WeakCallbackInfo<Message>& data) | 162 static void didCollectPromise(const v8::WeakCallbackInfo<Message>& data) |
167 { | 163 { |
168 data.GetParameter()->m_collected = true; | 164 data.GetParameter()->m_collected = true; |
169 data.GetParameter()->m_promise.clear(); | 165 data.GetParameter()->m_promise.clear(); |
170 } | 166 } |
171 | 167 |
172 static void didCollectException(const v8::WeakCallbackInfo<Message>& data) | 168 static void didCollectException(const v8::WeakCallbackInfo<Message>& data) |
173 { | 169 { |
174 data.GetParameter()->m_exception.clear(); | 170 data.GetParameter()->m_exception.clear(); |
175 } | 171 } |
176 | 172 |
177 ScriptState* m_scriptState; | 173 ScriptState* m_scriptState; |
178 ScopedPersistent<v8::Promise> m_promise; | 174 ScopedPersistent<v8::Promise> m_promise; |
179 ScopedPersistent<v8::Value> m_exception; | 175 ScopedPersistent<v8::Value> m_exception; |
180 String m_errorMessage; | 176 String m_errorMessage; |
181 String m_resourceName; | 177 String m_resourceName; |
182 int m_scriptId; | 178 OwnPtr<SourceLocation> m_location; |
183 int m_lineNumber; | |
184 int m_columnNumber; | |
185 RefPtr<ScriptCallStack> m_callStack; | |
186 unsigned m_consoleMessageId; | 179 unsigned m_consoleMessageId; |
187 bool m_collected; | 180 bool m_collected; |
188 bool m_shouldLogToConsole; | 181 bool m_shouldLogToConsole; |
189 AccessControlStatus m_corsStatus; | 182 AccessControlStatus m_corsStatus; |
190 }; | 183 }; |
191 | 184 |
192 RejectedPromises::RejectedPromises() | 185 RejectedPromises::RejectedPromises() |
193 { | 186 { |
194 } | 187 } |
195 | 188 |
196 RejectedPromises::~RejectedPromises() | 189 RejectedPromises::~RejectedPromises() |
197 { | 190 { |
198 } | 191 } |
199 | 192 |
200 void RejectedPromises::rejectedWithNoHandler(ScriptState* scriptState, v8::Promi
seRejectMessage data, const String& errorMessage, const String& resourceName, in
t scriptId, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack> callSt
ack, AccessControlStatus corsStatus) | 193 void RejectedPromises::rejectedWithNoHandler(ScriptState* scriptState, v8::Promi
seRejectMessage data, const String& errorMessage, PassOwnPtr<SourceLocation> loc
ation, AccessControlStatus corsStatus) |
201 { | 194 { |
202 m_queue.append(Message::create(scriptState, data.GetPromise(), data.GetValue
(), errorMessage, resourceName, scriptId, lineNumber, columnNumber, callStack, c
orsStatus)); | 195 m_queue.append(Message::create(scriptState, data.GetPromise(), data.GetValue
(), errorMessage, std::move(location), corsStatus)); |
203 } | 196 } |
204 | 197 |
205 void RejectedPromises::handlerAdded(v8::PromiseRejectMessage data) | 198 void RejectedPromises::handlerAdded(v8::PromiseRejectMessage data) |
206 { | 199 { |
207 // First look it up in the pending messages and fast return, it'll be covere
d by processQueue(). | 200 // First look it up in the pending messages and fast return, it'll be covere
d by processQueue(). |
208 for (auto it = m_queue.begin(); it != m_queue.end(); ++it) { | 201 for (auto it = m_queue.begin(); it != m_queue.end(); ++it) { |
209 if (!(*it)->isCollected() && (*it)->hasPromise(data.GetPromise())) { | 202 if (!(*it)->isCollected() && (*it)->hasPromise(data.GetPromise())) { |
210 m_queue.remove(it); | 203 m_queue.remove(it); |
211 return; | 204 return; |
212 } | 205 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 } | 265 } |
273 } | 266 } |
274 } | 267 } |
275 | 268 |
276 void RejectedPromises::revokeNow(PassOwnPtr<Message> message) | 269 void RejectedPromises::revokeNow(PassOwnPtr<Message> message) |
277 { | 270 { |
278 message->revoke(); | 271 message->revoke(); |
279 } | 272 } |
280 | 273 |
281 } // namespace blink | 274 } // namespace blink |
OLD | NEW |