OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 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 |
(...skipping 10 matching lines...) Expand all Loading... |
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
23 * THE POSSIBILITY OF SUCH DAMAGE. | 23 * THE POSSIBILITY OF SUCH DAMAGE. |
24 */ | 24 */ |
25 | 25 |
26 #include "bindings/core/v8/V8Initializer.h" | 26 #include "bindings/core/v8/V8Initializer.h" |
27 | 27 |
28 #include "bindings/core/v8/DOMWrapperWorld.h" | 28 #include "bindings/core/v8/DOMWrapperWorld.h" |
29 #include "bindings/core/v8/RejectedPromises.h" | 29 #include "bindings/core/v8/RejectedPromises.h" |
30 #include "bindings/core/v8/RetainedDOMInfo.h" | 30 #include "bindings/core/v8/RetainedDOMInfo.h" |
31 #include "bindings/core/v8/ScriptCallStack.h" | |
32 #include "bindings/core/v8/ScriptController.h" | 31 #include "bindings/core/v8/ScriptController.h" |
33 #include "bindings/core/v8/ScriptValue.h" | 32 #include "bindings/core/v8/ScriptValue.h" |
| 33 #include "bindings/core/v8/SourceLocation.h" |
34 #include "bindings/core/v8/V8Binding.h" | 34 #include "bindings/core/v8/V8Binding.h" |
35 #include "bindings/core/v8/V8DOMException.h" | 35 #include "bindings/core/v8/V8DOMException.h" |
36 #include "bindings/core/v8/V8ErrorEvent.h" | 36 #include "bindings/core/v8/V8ErrorEvent.h" |
37 #include "bindings/core/v8/V8ErrorHandler.h" | 37 #include "bindings/core/v8/V8ErrorHandler.h" |
38 #include "bindings/core/v8/V8GCController.h" | 38 #include "bindings/core/v8/V8GCController.h" |
39 #include "bindings/core/v8/V8History.h" | 39 #include "bindings/core/v8/V8History.h" |
40 #include "bindings/core/v8/V8IdleTaskRunner.h" | 40 #include "bindings/core/v8/V8IdleTaskRunner.h" |
41 #include "bindings/core/v8/V8Location.h" | 41 #include "bindings/core/v8/V8Location.h" |
42 #include "bindings/core/v8/V8PerContextData.h" | 42 #include "bindings/core/v8/V8PerContextData.h" |
43 #include "bindings/core/v8/V8Window.h" | 43 #include "bindings/core/v8/V8Window.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 return 0; | 88 return 0; |
89 } | 89 } |
90 | 90 |
91 static void reportFatalErrorInMainThread(const char* location, const char* messa
ge) | 91 static void reportFatalErrorInMainThread(const char* location, const char* messa
ge) |
92 { | 92 { |
93 int memoryUsageMB = Platform::current()->actualMemoryUsageMB(); | 93 int memoryUsageMB = Platform::current()->actualMemoryUsageMB(); |
94 printf("V8 error: %s (%s). Current memory usage: %d MB\n", message, locatio
n, memoryUsageMB); | 94 printf("V8 error: %s (%s). Current memory usage: %d MB\n", message, locatio
n, memoryUsageMB); |
95 CRASH(); | 95 CRASH(); |
96 } | 96 } |
97 | 97 |
98 static PassRefPtr<ScriptCallStack> extractCallStack(v8::Isolate* isolate, v8::Lo
cal<v8::Message> message, int* const scriptId) | |
99 { | |
100 v8::Local<v8::StackTrace> stackTrace = message->GetStackTrace(); | |
101 RefPtr<ScriptCallStack> callStack = ScriptCallStack::create(isolate, stackTr
ace); | |
102 *scriptId = message->GetScriptOrigin().ScriptID()->Value(); | |
103 if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0) { | |
104 int topScriptId = stackTrace->GetFrame(0)->GetScriptId(); | |
105 if (topScriptId == *scriptId) | |
106 *scriptId = 0; | |
107 } | |
108 return callStack.release(); | |
109 } | |
110 | |
111 static String extractResourceName(v8::Local<v8::Message> message, const Executio
nContext* context) | |
112 { | |
113 v8::Local<v8::Value> resourceName = message->GetScriptOrigin().ResourceName(
); | |
114 bool shouldUseDocumentURL = context->isDocument() && (resourceName.IsEmpty()
|| !resourceName->IsString()); | |
115 return shouldUseDocumentURL ? context->url() : toCoreString(resourceName.As<
v8::String>()); | |
116 } | |
117 | |
118 static String extractMessageForConsole(v8::Isolate* isolate, v8::Local<v8::Value
> data) | 98 static String extractMessageForConsole(v8::Isolate* isolate, v8::Local<v8::Value
> data) |
119 { | 99 { |
120 if (V8DOMWrapper::isWrapper(isolate, data)) { | 100 if (V8DOMWrapper::isWrapper(isolate, data)) { |
121 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(data); | 101 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(data); |
122 const WrapperTypeInfo* type = toWrapperTypeInfo(obj); | 102 const WrapperTypeInfo* type = toWrapperTypeInfo(obj); |
123 if (V8DOMException::wrapperTypeInfo.isSubclass(type)) { | 103 if (V8DOMException::wrapperTypeInfo.isSubclass(type)) { |
124 DOMException* exception = V8DOMException::toImpl(obj); | 104 DOMException* exception = V8DOMException::toImpl(obj); |
125 if (exception && !exception->messageForConsole().isEmpty()) | 105 if (exception && !exception->messageForConsole().isEmpty()) |
126 return exception->toStringForConsole(); | 106 return exception->toStringForConsole(); |
127 } | 107 } |
128 } | 108 } |
129 return emptyString(); | 109 return emptyString(); |
130 } | 110 } |
131 | 111 |
132 static ErrorEvent* createErrorEventFromMesssage(ScriptState* scriptState, v8::Lo
cal<v8::Message> message, String resourceName) | |
133 { | |
134 String errorMessage = toCoreStringWithNullCheck(message->Get()); | |
135 int lineNumber = 0; | |
136 int columnNumber = 0; | |
137 if (v8Call(message->GetLineNumber(scriptState->context()), lineNumber) | |
138 && v8Call(message->GetStartColumn(scriptState->context()), columnNumber)
) | |
139 ++columnNumber; | |
140 return ErrorEvent::create(errorMessage, resourceName, lineNumber, columnNumb
er, &scriptState->world()); | |
141 } | |
142 | |
143 static void messageHandlerInMainThread(v8::Local<v8::Message> message, v8::Local
<v8::Value> data) | 112 static void messageHandlerInMainThread(v8::Local<v8::Message> message, v8::Local
<v8::Value> data) |
144 { | 113 { |
145 ASSERT(isMainThread()); | 114 ASSERT(isMainThread()); |
146 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 115 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
147 | 116 |
148 // If called during context initialization, there will be no entered context
. | 117 // If called during context initialization, there will be no entered context
. |
149 ScriptState* scriptState = ScriptState::current(isolate); | 118 ScriptState* scriptState = ScriptState::current(isolate); |
150 if (!scriptState->contextIsValid()) | 119 if (!scriptState->contextIsValid()) |
151 return; | 120 return; |
152 | 121 |
153 int scriptId = 0; | 122 ExecutionContext* context = scriptState->getExecutionContext(); |
154 RefPtr<ScriptCallStack> callStack = extractCallStack(isolate, message, &scri
ptId); | 123 OwnPtr<SourceLocation> location = SourceLocation::fromMessage(isolate, messa
ge, context); |
155 | 124 |
156 AccessControlStatus accessControlStatus = NotSharableCrossOrigin; | 125 AccessControlStatus accessControlStatus = NotSharableCrossOrigin; |
157 if (message->IsOpaque()) | 126 if (message->IsOpaque()) |
158 accessControlStatus = OpaqueResource; | 127 accessControlStatus = OpaqueResource; |
159 else if (message->IsSharedCrossOrigin()) | 128 else if (message->IsSharedCrossOrigin()) |
160 accessControlStatus = SharableCrossOrigin; | 129 accessControlStatus = SharableCrossOrigin; |
161 | 130 |
162 ExecutionContext* context = scriptState->getExecutionContext(); | 131 ErrorEvent* event = ErrorEvent::create(toCoreStringWithNullCheck(message->Ge
t()), location->url(), location->lineNumber(), location->columnNumber(), &script
State->world()); |
163 String resourceName = extractResourceName(message, context); | |
164 ErrorEvent* event = createErrorEventFromMesssage(scriptState, message, resou
rceName); | |
165 | 132 |
166 String messageForConsole = extractMessageForConsole(isolate, data); | 133 String messageForConsole = extractMessageForConsole(isolate, data); |
167 if (!messageForConsole.isEmpty()) | 134 if (!messageForConsole.isEmpty()) |
168 event->setUnsanitizedMessage("Uncaught " + messageForConsole); | 135 event->setUnsanitizedMessage("Uncaught " + messageForConsole); |
169 | 136 |
170 // This method might be called while we're creating a new context. In this c
ase, we | 137 // This method might be called while we're creating a new context. In this c
ase, we |
171 // avoid storing the exception object, as we can't create a wrapper during c
ontext creation. | 138 // avoid storing the exception object, as we can't create a wrapper during c
ontext creation. |
172 // FIXME: Can we even get here during initialization now that we bail out wh
en GetEntered returns an empty handle? | 139 // FIXME: Can we even get here during initialization now that we bail out wh
en GetEntered returns an empty handle? |
173 if (context->isDocument()) { | 140 if (context->isDocument()) { |
174 LocalFrame* frame = toDocument(context)->frame(); | 141 LocalFrame* frame = toDocument(context)->frame(); |
175 if (frame && frame->script().existingWindowProxy(scriptState->world()))
{ | 142 if (frame && frame->script().existingWindowProxy(scriptState->world()))
{ |
176 V8ErrorHandler::storeExceptionOnErrorEventWrapper(scriptState, event
, data, scriptState->context()->Global()); | 143 V8ErrorHandler::storeExceptionOnErrorEventWrapper(scriptState, event
, data, scriptState->context()->Global()); |
177 } | 144 } |
178 } | 145 } |
179 | 146 |
180 if (scriptState->world().isPrivateScriptIsolatedWorld()) { | 147 if (scriptState->world().isPrivateScriptIsolatedWorld()) { |
181 // We allow a private script to dispatch error events even in a EventDis
patchForbiddenScope scope. | 148 // We allow a private script to dispatch error events even in a EventDis
patchForbiddenScope scope. |
182 // Without having this ability, it's hard to debug the private script be
cause syntax errors | 149 // Without having this ability, it's hard to debug the private script be
cause syntax errors |
183 // in the private script are not reported to console (the private script
just crashes silently). | 150 // in the private script are not reported to console (the private script
just crashes silently). |
184 // Allowing error events in private scripts is safe because error events
don't propagate to | 151 // Allowing error events in private scripts is safe because error events
don't propagate to |
185 // other isolated worlds (which means that the error events won't fire a
ny event listeners | 152 // other isolated worlds (which means that the error events won't fire a
ny event listeners |
186 // in user's scripts). | 153 // in user's scripts). |
187 EventDispatchForbiddenScope::AllowUserAgentEvents allowUserAgentEvents; | 154 EventDispatchForbiddenScope::AllowUserAgentEvents allowUserAgentEvents; |
188 context->reportException(event, scriptId, callStack, accessControlStatus
); | 155 context->reportException(event, std::move(location), accessControlStatus
); |
189 } else { | 156 } else { |
190 context->reportException(event, scriptId, callStack, accessControlStatus
); | 157 context->reportException(event, std::move(location), accessControlStatus
); |
191 } | 158 } |
192 } | 159 } |
193 | 160 |
194 namespace { | 161 namespace { |
195 | 162 |
196 static RejectedPromises& rejectedPromisesOnMainThread() | 163 static RejectedPromises& rejectedPromisesOnMainThread() |
197 { | 164 { |
198 ASSERT(isMainThread()); | 165 ASSERT(isMainThread()); |
199 DEFINE_STATIC_LOCAL(RefPtr<RejectedPromises>, rejectedPromises, (RejectedPro
mises::create())); | 166 DEFINE_STATIC_LOCAL(RefPtr<RejectedPromises>, rejectedPromises, (RejectedPro
mises::create())); |
200 return *rejectedPromises; | 167 return *rejectedPromises; |
201 } | 168 } |
202 | 169 |
203 } // namespace | 170 } // namespace |
204 | 171 |
205 void V8Initializer::reportRejectedPromisesOnMainThread() | 172 void V8Initializer::reportRejectedPromisesOnMainThread() |
206 { | 173 { |
207 rejectedPromisesOnMainThread().processQueue(); | 174 rejectedPromisesOnMainThread().processQueue(); |
208 } | 175 } |
209 | 176 |
210 static void promiseRejectHandler(v8::PromiseRejectMessage data, RejectedPromises
& rejectedPromises, const String& fallbackResourceName) | 177 static void promiseRejectHandler(v8::PromiseRejectMessage data, RejectedPromises
& rejectedPromises, ScriptState* scriptState) |
211 { | 178 { |
212 if (data.GetEvent() == v8::kPromiseHandlerAddedAfterReject) { | 179 if (data.GetEvent() == v8::kPromiseHandlerAddedAfterReject) { |
213 rejectedPromises.handlerAdded(data); | 180 rejectedPromises.handlerAdded(data); |
214 return; | 181 return; |
215 } | 182 } |
216 | 183 |
217 ASSERT(data.GetEvent() == v8::kPromiseRejectWithNoHandler); | 184 ASSERT(data.GetEvent() == v8::kPromiseRejectWithNoHandler); |
218 | 185 |
219 v8::Local<v8::Promise> promise = data.GetPromise(); | 186 v8::Local<v8::Promise> promise = data.GetPromise(); |
220 v8::Isolate* isolate = promise->GetIsolate(); | 187 v8::Isolate* isolate = promise->GetIsolate(); |
221 ScriptState* scriptState = ScriptState::current(isolate); | 188 ExecutionContext* context = scriptState->getExecutionContext(); |
222 | 189 |
223 v8::Local<v8::Value> exception = data.GetValue(); | 190 v8::Local<v8::Value> exception = data.GetValue(); |
224 if (V8DOMWrapper::isWrapper(isolate, exception)) { | 191 if (V8DOMWrapper::isWrapper(isolate, exception)) { |
225 // Try to get the stack & location from a wrapped exception object (e.g.
DOMException). | 192 // Try to get the stack & location from a wrapped exception object (e.g.
DOMException). |
226 ASSERT(exception->IsObject()); | 193 ASSERT(exception->IsObject()); |
227 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(exception); | 194 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(exception); |
228 v8::Local<v8::Value> error = V8HiddenValue::getHiddenValue(scriptState,
obj, V8HiddenValue::error(isolate)); | 195 v8::Local<v8::Value> error = V8HiddenValue::getHiddenValue(scriptState,
obj, V8HiddenValue::error(isolate)); |
229 if (!error.IsEmpty()) | 196 if (!error.IsEmpty()) |
230 exception = error; | 197 exception = error; |
231 } | 198 } |
232 | 199 |
233 int scriptId = 0; | |
234 int lineNumber = 0; | |
235 int columnNumber = 0; | |
236 String resourceName = fallbackResourceName; | |
237 String errorMessage; | 200 String errorMessage; |
238 AccessControlStatus corsStatus = NotSharableCrossOrigin; | 201 AccessControlStatus corsStatus = NotSharableCrossOrigin; |
239 RefPtr<ScriptCallStack> callStack; | 202 OwnPtr<SourceLocation> location; |
240 | 203 |
241 v8::Local<v8::Message> message = v8::Exception::CreateMessage(isolate, excep
tion); | 204 v8::Local<v8::Message> message = v8::Exception::CreateMessage(isolate, excep
tion); |
242 if (!message.IsEmpty()) { | 205 if (!message.IsEmpty()) { |
243 V8StringResource<> v8ResourceName(message->GetScriptOrigin().ResourceNam
e()); | |
244 if (v8ResourceName.prepare()) | |
245 resourceName = v8ResourceName; | |
246 scriptId = message->GetScriptOrigin().ScriptID()->Value(); | |
247 if (v8Call(message->GetLineNumber(scriptState->context()), lineNumber) | |
248 && v8Call(message->GetStartColumn(scriptState->context()), columnNum
ber)) | |
249 ++columnNumber; | |
250 // message->Get() can be empty here. https://crbug.com/450330 | 206 // message->Get() can be empty here. https://crbug.com/450330 |
251 errorMessage = toCoreStringWithNullCheck(message->Get()); | 207 errorMessage = toCoreStringWithNullCheck(message->Get()); |
252 callStack = extractCallStack(isolate, message, &scriptId); | 208 location = SourceLocation::fromMessage(isolate, message, context); |
253 if (message->IsSharedCrossOrigin()) | 209 if (message->IsSharedCrossOrigin()) |
254 corsStatus = SharableCrossOrigin; | 210 corsStatus = SharableCrossOrigin; |
| 211 } else { |
| 212 location = SourceLocation::create(context->url().getString(), 0, 0, null
ptr); |
255 } | 213 } |
256 | 214 |
257 String messageForConsole = extractMessageForConsole(isolate, data.GetValue()
); | 215 String messageForConsole = extractMessageForConsole(isolate, data.GetValue()
); |
258 if (!messageForConsole.isEmpty()) | 216 if (!messageForConsole.isEmpty()) |
259 errorMessage = "Uncaught " + messageForConsole; | 217 errorMessage = "Uncaught " + messageForConsole; |
260 | 218 |
261 rejectedPromises.rejectedWithNoHandler(scriptState, data, errorMessage, reso
urceName, scriptId, lineNumber, columnNumber, callStack, corsStatus); | 219 rejectedPromises.rejectedWithNoHandler(scriptState, data, errorMessage, std:
:move(location), corsStatus); |
262 } | 220 } |
263 | 221 |
264 static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage data) | 222 static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage data) |
265 { | 223 { |
266 ASSERT(isMainThread()); | 224 ASSERT(isMainThread()); |
267 | 225 |
268 v8::Local<v8::Promise> promise = data.GetPromise(); | 226 v8::Local<v8::Promise> promise = data.GetPromise(); |
269 | 227 |
270 v8::Isolate* isolate = promise->GetIsolate(); | 228 v8::Isolate* isolate = promise->GetIsolate(); |
271 | 229 |
272 // TODO(ikilpatrick): Remove this check, extensions tests that use | 230 // TODO(ikilpatrick): Remove this check, extensions tests that use |
273 // extensions::ModuleSystemTest incorrectly don't have a valid script state. | 231 // extensions::ModuleSystemTest incorrectly don't have a valid script state. |
274 LocalDOMWindow* window = currentDOMWindow(isolate); | 232 LocalDOMWindow* window = currentDOMWindow(isolate); |
275 if (!window || !window->isCurrentlyDisplayedInFrame()) | 233 if (!window || !window->isCurrentlyDisplayedInFrame()) |
276 return; | 234 return; |
277 | 235 |
278 // Bail out if called during context initialization. | 236 // Bail out if called during context initialization. |
279 ScriptState* scriptState = ScriptState::current(isolate); | 237 ScriptState* scriptState = ScriptState::current(isolate); |
280 if (!scriptState->contextIsValid()) | 238 if (!scriptState->contextIsValid()) |
281 return; | 239 return; |
282 | 240 |
283 promiseRejectHandler(data, rejectedPromisesOnMainThread(), scriptState->getE
xecutionContext()->url()); | 241 promiseRejectHandler(data, rejectedPromisesOnMainThread(), scriptState); |
284 } | 242 } |
285 | 243 |
286 static void promiseRejectHandlerInWorker(v8::PromiseRejectMessage data) | 244 static void promiseRejectHandlerInWorker(v8::PromiseRejectMessage data) |
287 { | 245 { |
288 v8::Local<v8::Promise> promise = data.GetPromise(); | 246 v8::Local<v8::Promise> promise = data.GetPromise(); |
289 | 247 |
290 // Bail out if called during context initialization. | 248 // Bail out if called during context initialization. |
291 v8::Isolate* isolate = promise->GetIsolate(); | 249 v8::Isolate* isolate = promise->GetIsolate(); |
292 ScriptState* scriptState = ScriptState::current(isolate); | 250 ScriptState* scriptState = ScriptState::current(isolate); |
293 if (!scriptState->contextIsValid()) | 251 if (!scriptState->contextIsValid()) |
294 return; | 252 return; |
295 | 253 |
296 ExecutionContext* executionContext = scriptState->getExecutionContext(); | 254 ExecutionContext* executionContext = scriptState->getExecutionContext(); |
297 if (!executionContext) | 255 if (!executionContext) |
298 return; | 256 return; |
299 | 257 |
300 ASSERT(executionContext->isWorkerGlobalScope()); | 258 ASSERT(executionContext->isWorkerGlobalScope()); |
301 WorkerOrWorkletScriptController* scriptController = toWorkerGlobalScope(exec
utionContext)->scriptController(); | 259 WorkerOrWorkletScriptController* scriptController = toWorkerGlobalScope(exec
utionContext)->scriptController(); |
302 ASSERT(scriptController); | 260 ASSERT(scriptController); |
303 | 261 |
304 promiseRejectHandler(data, *scriptController->getRejectedPromises(), String(
)); | 262 promiseRejectHandler(data, *scriptController->getRejectedPromises(), scriptS
tate); |
305 } | 263 } |
306 | 264 |
307 static void failedAccessCheckCallbackInMainThread(v8::Local<v8::Object> host, v8
::AccessType type, v8::Local<v8::Value> data) | 265 static void failedAccessCheckCallbackInMainThread(v8::Local<v8::Object> host, v8
::AccessType type, v8::Local<v8::Value> data) |
308 { | 266 { |
309 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 267 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
310 Frame* target = findFrame(isolate, host, data); | 268 Frame* target = findFrame(isolate, host, data); |
311 if (!target) | 269 if (!target) |
312 return; | 270 return; |
313 DOMWindow* targetWindow = target->domWindow(); | 271 DOMWindow* targetWindow = target->domWindow(); |
314 | 272 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 if (!scriptState->contextIsValid()) | 391 if (!scriptState->contextIsValid()) |
434 return; | 392 return; |
435 | 393 |
436 // Exceptions that occur in error handler should be ignored since in that ca
se | 394 // Exceptions that occur in error handler should be ignored since in that ca
se |
437 // WorkerGlobalScope::reportException will send the exception to the worker
object. | 395 // WorkerGlobalScope::reportException will send the exception to the worker
object. |
438 if (perIsolateData->isReportingException()) | 396 if (perIsolateData->isReportingException()) |
439 return; | 397 return; |
440 | 398 |
441 perIsolateData->setReportingException(true); | 399 perIsolateData->setReportingException(true); |
442 | 400 |
443 TOSTRING_VOID(V8StringResource<>, resourceName, message->GetScriptOrigin().R
esourceName()); | 401 ExecutionContext* context = scriptState->getExecutionContext(); |
444 ErrorEvent* event = createErrorEventFromMesssage(scriptState, message, resou
rceName); | 402 OwnPtr<SourceLocation> location = SourceLocation::fromMessage(isolate, messa
ge, context); |
445 | 403 ErrorEvent* event = ErrorEvent::create(toCoreStringWithNullCheck(message->Ge
t()), location->url(), location->lineNumber(), location->columnNumber(), &script
State->world()); |
446 int scriptId = 0; | |
447 RefPtr<ScriptCallStack> callStack = extractCallStack(isolate, message, &scri
ptId); | |
448 | 404 |
449 AccessControlStatus corsStatus = message->IsSharedCrossOrigin() ? SharableCr
ossOrigin : NotSharableCrossOrigin; | 405 AccessControlStatus corsStatus = message->IsSharedCrossOrigin() ? SharableCr
ossOrigin : NotSharableCrossOrigin; |
450 | 406 |
451 // If execution termination has been triggered as part of constructing | 407 // If execution termination has been triggered as part of constructing |
452 // the error event from the v8::Message, quietly leave. | 408 // the error event from the v8::Message, quietly leave. |
453 if (!isolate->IsExecutionTerminating()) { | 409 if (!isolate->IsExecutionTerminating()) { |
454 V8ErrorHandler::storeExceptionOnErrorEventWrapper(scriptState, event, da
ta, scriptState->context()->Global()); | 410 V8ErrorHandler::storeExceptionOnErrorEventWrapper(scriptState, event, da
ta, scriptState->context()->Global()); |
455 scriptState->getExecutionContext()->reportException(event, scriptId, cal
lStack, corsStatus); | 411 scriptState->getExecutionContext()->reportException(event, std::move(loc
ation), corsStatus); |
456 } | 412 } |
457 | 413 |
458 perIsolateData->setReportingException(false); | 414 perIsolateData->setReportingException(false); |
459 } | 415 } |
460 | 416 |
461 static const int kWorkerMaxStackSize = 500 * 1024; | 417 static const int kWorkerMaxStackSize = 500 * 1024; |
462 | 418 |
463 // This function uses a local stack variable to determine the isolate's stack li
mit. AddressSanitizer may | 419 // This function uses a local stack variable to determine the isolate's stack li
mit. AddressSanitizer may |
464 // relocate that local variable to a fake stack, which may lead to problems duri
ng JavaScript execution. | 420 // relocate that local variable to a fake stack, which may lead to problems duri
ng JavaScript execution. |
465 // Therefore we disable AddressSanitizer for V8Initializer::initializeWorker(). | 421 // Therefore we disable AddressSanitizer for V8Initializer::initializeWorker(). |
466 NO_SANITIZE_ADDRESS | 422 NO_SANITIZE_ADDRESS |
467 void V8Initializer::initializeWorker(v8::Isolate* isolate) | 423 void V8Initializer::initializeWorker(v8::Isolate* isolate) |
468 { | 424 { |
469 initializeV8Common(isolate); | 425 initializeV8Common(isolate); |
470 | 426 |
471 isolate->AddMessageListener(messageHandlerInWorker); | 427 isolate->AddMessageListener(messageHandlerInWorker); |
472 isolate->SetFatalErrorHandler(reportFatalErrorInWorker); | 428 isolate->SetFatalErrorHandler(reportFatalErrorInWorker); |
473 | 429 |
474 uint32_t here; | 430 uint32_t here; |
475 isolate->SetStackLimit(reinterpret_cast<uintptr_t>(&here - kWorkerMaxStackSi
ze / sizeof(uint32_t*))); | 431 isolate->SetStackLimit(reinterpret_cast<uintptr_t>(&here - kWorkerMaxStackSi
ze / sizeof(uint32_t*))); |
476 isolate->SetPromiseRejectCallback(promiseRejectHandlerInWorker); | 432 isolate->SetPromiseRejectCallback(promiseRejectHandlerInWorker); |
477 } | 433 } |
478 | 434 |
479 } // namespace blink | 435 } // namespace blink |
OLD | NEW |