Chromium Code Reviews| Index: Source/bindings/core/v8/V8Initializer.cpp |
| diff --git a/Source/bindings/core/v8/V8Initializer.cpp b/Source/bindings/core/v8/V8Initializer.cpp |
| index c015f4369ba6bc07caa1c6e6c5cabf3bde7b8558..eedbde6f1e810b2f74fcced568643b7485739254 100644 |
| --- a/Source/bindings/core/v8/V8Initializer.cpp |
| +++ b/Source/bindings/core/v8/V8Initializer.cpp |
| @@ -166,8 +166,12 @@ namespace { |
| class PromiseRejectMessage { |
| ALLOW_ONLY_INLINE_ALLOCATION(); |
| public: |
| - PromiseRejectMessage(const ScriptValue& promise, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack) |
| + PromiseRejectMessage(const ScriptValue& promise, const String& resourceURL, int scriptId, unsigned lineNumber, unsigned columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack) |
| : m_promise(promise) |
| + , m_resourceURL(resourceURL) |
| + , m_scriptId(scriptId) |
| + , m_lineNumber(lineNumber) |
| + , m_columnNumber(columnNumber) |
| , m_callStack(callStack) |
| { |
| } |
| @@ -178,6 +182,10 @@ public: |
| } |
| const ScriptValue m_promise; |
| + const String m_resourceURL; |
| + const int m_scriptId; |
| + const unsigned m_lineNumber; |
| + const unsigned m_columnNumber; |
| const RefPtrWillBeMember<ScriptCallStack> m_callStack; |
| }; |
| @@ -220,18 +228,19 @@ void V8Initializer::reportRejectedPromises() |
| args.append(message.m_promise); |
| RefPtrWillBeRawPtr<ScriptArguments> arguments = ScriptArguments::create(scriptState, args); |
| - RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage); |
| + RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage, message.m_resourceURL, message.m_lineNumber, message.m_columnNumber); |
| consoleMessage->setScriptArguments(arguments); |
| consoleMessage->setCallStack(message.m_callStack); |
| + consoleMessage->setScriptId(message.m_scriptId); |
| executionContext->addConsoleMessage(consoleMessage.release()); |
| } |
| } |
| -static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage message) |
| +static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage data) |
| { |
| ASSERT(isMainThread()); |
| - if (message.GetEvent() != v8::kPromiseRejectWithNoHandler) |
| + if (data.GetEvent() != v8::kPromiseRejectWithNoHandler) |
| return; |
| // It's possible that promiseRejectHandlerInMainThread() is invoked while we're initializing a window. |
| @@ -240,7 +249,7 @@ static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage message) |
| if (DOMWrapperWorld::windowIsBeingInitialized()) |
| return; |
| - v8::Handle<v8::Promise> promise = message.GetPromise(); |
| + v8::Handle<v8::Promise> promise = data.GetPromise(); |
| // Bail out if called during context initialization. |
| v8::Isolate* isolate = promise->GetIsolate(); |
| @@ -250,35 +259,59 @@ static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage message) |
| v8::Handle<v8::Value> global = V8Window::findInstanceInPrototypeChain(context->Global(), context->GetIsolate()); |
| if (global.IsEmpty()) |
| return; |
| - if (!toFrameIfNotDetached(context)) |
| + |
| + // There is no entered window during microtask callbacks from V8, |
| + // thus we call toDOMWindow() instead of enteredDOMWindow(). |
| + LocalDOMWindow* window = toDOMWindow(context); |
| + if (!window || !window->isCurrentlyDisplayedInFrame()) |
| return; |
| + v8::Handle<v8::Value> exception = data.GetValue(); |
| + if (V8DOMWrapper::isDOMWrapper(exception)) { |
| + // Try to get the stack & location from a wrapped exception object (e.g. DOMException). |
| + ASSERT(exception->IsObject()); |
| + v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(exception); |
| + v8::Handle<v8::Value> error = V8HiddenValue::getHiddenValue(isolate, obj, V8HiddenValue::error(isolate)); |
| + if (!error.IsEmpty()) |
| + exception = error; |
| + } |
| + |
| + int scriptId = 0; |
| + unsigned lineNumber = 0; |
| + unsigned columnNumber = 0; |
| + String resourceURL; |
| RefPtrWillBeRawPtr<ScriptCallStack> callStack = nullptr; |
| - v8::Handle<v8::StackTrace> stackTrace = message.GetStackTrace(); |
| - if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0) |
| - callStack = createScriptCallStack(stackTrace, ScriptCallStack::maxCallStackSizeToCapture, isolate); |
| - if (!callStack && V8DOMWrapper::isDOMWrapper(message.GetValue())) { |
| - // Try to get the stack from a wrapped exception object (e.g. DOMException). |
| - v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(message.GetValue()); |
| - v8::Handle<v8::Value> error = V8HiddenValue::getHiddenValue(isolate, obj, V8HiddenValue::error(isolate)); |
| - if (!error.IsEmpty()) { |
| - stackTrace = v8::Exception::GetStackTrace(error); |
| - if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0) |
| - callStack = createScriptCallStack(stackTrace, ScriptCallStack::maxCallStackSizeToCapture, isolate); |
| + v8::Handle<v8::Message> message = v8::Exception::GetMessage(exception); |
| + if (!message.IsEmpty()) { |
| + scriptId = message->GetScriptOrigin().ScriptID()->Value(); |
| + lineNumber = static_cast<unsigned>(message->GetLineNumber()); |
| + columnNumber = static_cast<unsigned>(message->GetStartColumn() + 1); |
| + |
| + v8::Handle<v8::Value> resourceName = message->GetScriptOrigin().ResourceName(); |
|
vsevik
2014/11/07 06:26:38
Looks like a lot of copy-paste here.
Can we at lea
aandrey
2014/11/10 11:44:33
Done.
|
| + bool shouldUseDocumentURL = window->document() && (resourceName.IsEmpty() || !resourceName->IsString()); |
| + resourceURL = shouldUseDocumentURL ? window->document()->url() : toCoreString(resourceName.As<v8::String>()); |
| + |
| + v8::Handle<v8::StackTrace> stackTrace = message->GetStackTrace(); |
|
vsevik
2014/11/07 06:26:39
extract callStack(stackTrace, isolate)?
aandrey
2014/11/10 11:44:33
Done.
|
| + if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0) { |
| + callStack = createScriptCallStack(stackTrace, ScriptCallStack::maxCallStackSizeToCapture, isolate); |
| + bool success = false; |
| + int topScriptId = callStack->at(0).scriptId().toInt(&success); |
| + if (success && topScriptId == scriptId) |
| + scriptId = 0; |
|
vsevik
2014/11/07 06:26:38
extract scriptId(callStack, scriptOrigin)?
aandrey
2014/11/10 11:44:33
Acknowledged.
|
| } |
| } |
| ScriptState* scriptState = ScriptState::from(context); |
| - promiseRejectMessageQueue().append(PromiseRejectMessage(ScriptValue(scriptState, promise), callStack)); |
| + promiseRejectMessageQueue().append(PromiseRejectMessage(ScriptValue(scriptState, promise), resourceURL, scriptId, lineNumber, columnNumber, callStack)); |
| } |
| -static void promiseRejectHandlerInWorker(v8::PromiseRejectMessage message) |
| +static void promiseRejectHandlerInWorker(v8::PromiseRejectMessage data) |
| { |
| - if (message.GetEvent() != v8::kPromiseRejectWithNoHandler) |
| + if (data.GetEvent() != v8::kPromiseRejectWithNoHandler) |
| return; |
| - v8::Handle<v8::Promise> promise = message.GetPromise(); |
| + v8::Handle<v8::Promise> promise = data.GetPromise(); |
| // Bail out if called during context initialization. |
| v8::Isolate* isolate = promise->GetIsolate(); |
| @@ -286,13 +319,21 @@ static void promiseRejectHandlerInWorker(v8::PromiseRejectMessage message) |
| if (context.IsEmpty()) |
| return; |
| - RefPtrWillBeRawPtr<ScriptCallStack> callStack = nullptr; |
| - v8::Handle<v8::StackTrace> stackTrace = message.GetStackTrace(); |
| - if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0) |
| - callStack = createScriptCallStack(stackTrace, ScriptCallStack::maxCallStackSizeToCapture, isolate); |
| + int scriptId = 0; |
| + unsigned lineNumber = 0; |
| + unsigned columnNumber = 0; |
| + String resourceURL; |
| + |
| + v8::Handle<v8::Message> message = v8::Exception::GetMessage(data.GetValue()); |
| + if (!message.IsEmpty()) { |
| + TOSTRING_VOID(V8StringResource<>, resourceURL, message->GetScriptOrigin().ResourceName()); |
| + scriptId = message->GetScriptOrigin().ScriptID()->Value(); |
|
vsevik
2014/11/07 06:26:38
This is not correct way to use scriptId parameter
yurys
2014/11/07 12:49:27
Can you file a bug on this?
|
| + lineNumber = static_cast<unsigned>(message->GetLineNumber()); |
| + columnNumber = static_cast<unsigned>(message->GetStartColumn() + 1); |
| + } |
| ScriptState* scriptState = ScriptState::from(context); |
| - promiseRejectMessageQueue().append(PromiseRejectMessage(ScriptValue(scriptState, promise), callStack)); |
| + promiseRejectMessageQueue().append(PromiseRejectMessage(ScriptValue(scriptState, promise), resourceURL, scriptId, lineNumber, columnNumber, nullptr)); |
| } |
| static void failedAccessCheckCallbackInMainThread(v8::Local<v8::Object> host, v8::AccessType type, v8::Local<v8::Value> data) |