| Index: Source/bindings/core/v8/V8Initializer.cpp
|
| diff --git a/Source/bindings/core/v8/V8Initializer.cpp b/Source/bindings/core/v8/V8Initializer.cpp
|
| index 939d7928a04d57ddcd9d8bfae897a9eb4205ebe2..2f3c879468b6456de3265dd281a7d3c74f0b563e 100644
|
| --- a/Source/bindings/core/v8/V8Initializer.cpp
|
| +++ b/Source/bindings/core/v8/V8Initializer.cpp
|
| @@ -27,6 +27,7 @@
|
| #include "bindings/core/v8/V8Initializer.h"
|
|
|
| #include "bindings/core/v8/DOMWrapperWorld.h"
|
| +#include "bindings/core/v8/RejectedPromises.h"
|
| #include "bindings/core/v8/ScriptCallStackFactory.h"
|
| #include "bindings/core/v8/ScriptController.h"
|
| #include "bindings/core/v8/ScriptProfiler.h"
|
| @@ -40,6 +41,7 @@
|
| #include "bindings/core/v8/V8Location.h"
|
| #include "bindings/core/v8/V8PerContextData.h"
|
| #include "bindings/core/v8/V8Window.h"
|
| +#include "bindings/core/v8/WorkerScriptController.h"
|
| #include "core/dom/Document.h"
|
| #include "core/dom/ExceptionCode.h"
|
| #include "core/fetch/AccessControlStatus.h"
|
| @@ -47,9 +49,9 @@
|
| #include "core/frame/LocalDOMWindow.h"
|
| #include "core/frame/LocalFrame.h"
|
| #include "core/frame/csp/ContentSecurityPolicy.h"
|
| -#include "core/inspector/ConsoleMessage.h"
|
| #include "core/inspector/ScriptArguments.h"
|
| #include "core/inspector/ScriptCallStack.h"
|
| +#include "core/workers/WorkerGlobalScope.h"
|
| #include "platform/EventDispatchForbiddenScope.h"
|
| #include "platform/RuntimeEnabledFeatures.h"
|
| #include "platform/TraceEvent.h"
|
| @@ -58,7 +60,6 @@
|
| #include "public/platform/Platform.h"
|
| #include "wtf/ArrayBufferContents.h"
|
| #include "wtf/RefPtr.h"
|
| -#include "wtf/ThreadSpecific.h"
|
| #include "wtf/text/WTFString.h"
|
| #include <v8-debug.h>
|
|
|
| @@ -185,110 +186,18 @@ static void messageHandlerInMainThread(v8::Handle<v8::Message> message, v8::Hand
|
|
|
| namespace {
|
|
|
| -class PromiseRejectMessage {
|
| - ALLOW_ONLY_INLINE_ALLOCATION();
|
| -public:
|
| - PromiseRejectMessage(const ScriptValue& promise, const ScriptValue& exception, const String& errorMessage, const String& resourceName, int scriptId, int lineNumber, int columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack)
|
| - : m_promise(promise)
|
| - , m_exception(exception)
|
| - , m_errorMessage(errorMessage)
|
| - , m_resourceName(resourceName)
|
| - , m_scriptId(scriptId)
|
| - , m_lineNumber(lineNumber)
|
| - , m_columnNumber(columnNumber)
|
| - , m_callStack(callStack)
|
| - {
|
| - }
|
| -
|
| - void trace(Visitor* visitor)
|
| - {
|
| - visitor->trace(m_callStack);
|
| - }
|
| -
|
| - const ScriptValue m_promise;
|
| - const ScriptValue m_exception;
|
| - const String m_errorMessage;
|
| - const String m_resourceName;
|
| - const int m_scriptId;
|
| - const int m_lineNumber;
|
| - const int m_columnNumber;
|
| - const RefPtrWillBeMember<ScriptCallStack> m_callStack;
|
| -};
|
| -
|
| -class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
|
| - virtual void* Allocate(size_t size) override
|
| - {
|
| - void* data;
|
| - WTF::ArrayBufferContents::allocateMemory(size, WTF::ArrayBufferContents::ZeroInitialize, data);
|
| - return data;
|
| - }
|
| -
|
| - virtual void* AllocateUninitialized(size_t size) override
|
| - {
|
| - void* data;
|
| - WTF::ArrayBufferContents::allocateMemory(size, WTF::ArrayBufferContents::DontInitialize, data);
|
| - return data;
|
| - }
|
| -
|
| - virtual void Free(void* data, size_t size) override
|
| - {
|
| - WTF::ArrayBufferContents::freeMemory(data, size);
|
| - }
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -typedef Deque<PromiseRejectMessage> PromiseRejectMessageQueue;
|
| -
|
| -static PromiseRejectMessageQueue& promiseRejectMessageQueue()
|
| +static RejectedPromises& rejectedPromisesOnMainThread()
|
| {
|
| - AtomicallyInitializedStaticReference(ThreadSpecific<PromiseRejectMessageQueue>, queue, new ThreadSpecific<PromiseRejectMessageQueue>);
|
| - return *queue;
|
| + ASSERT(isMainThread());
|
| + DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<RejectedPromises>, rejectedPromises, (adoptPtrWillBeNoop(new RejectedPromises())));
|
| + return *rejectedPromises;
|
| }
|
|
|
| -void V8Initializer::reportRejectedPromises()
|
| -{
|
| - PromiseRejectMessageQueue& queue = promiseRejectMessageQueue();
|
| - while (!queue.isEmpty()) {
|
| - PromiseRejectMessage message = queue.takeFirst();
|
| - ScriptState* scriptState = message.m_promise.scriptState();
|
| - if (!scriptState->contextIsValid())
|
| - continue;
|
| - // If execution termination has been triggered, quietly bail out.
|
| - if (v8::V8::IsExecutionTerminating(scriptState->isolate()))
|
| - continue;
|
| - ExecutionContext* executionContext = scriptState->executionContext();
|
| - if (!executionContext)
|
| - continue;
|
| -
|
| - ScriptState::Scope scope(scriptState);
|
| -
|
| - ASSERT(!message.m_promise.isEmpty());
|
| - v8::Handle<v8::Value> value = message.m_promise.v8Value();
|
| - ASSERT(!value.IsEmpty() && value->IsPromise());
|
| - if (v8::Handle<v8::Promise>::Cast(value)->HasHandler())
|
| - continue;
|
| -
|
| - const String errorMessage = "Uncaught (in promise)";
|
| - Vector<ScriptValue> args;
|
| - args.append(ScriptValue(scriptState, v8String(scriptState->isolate(), errorMessage)));
|
| - args.append(message.m_exception);
|
| - RefPtrWillBeRawPtr<ScriptArguments> arguments = ScriptArguments::create(scriptState, args);
|
| -
|
| - String embedderErrorMessage = message.m_errorMessage;
|
| - if (embedderErrorMessage.isEmpty()) {
|
| - embedderErrorMessage = errorMessage;
|
| - } else {
|
| - if (embedderErrorMessage.startsWith("Uncaught "))
|
| - embedderErrorMessage.insert(" (in promise)", 8);
|
| - }
|
| +} // namespace
|
|
|
| - RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, embedderErrorMessage, message.m_resourceName, message.m_lineNumber, message.m_columnNumber);
|
| - consoleMessage->setScriptArguments(arguments);
|
| - consoleMessage->setCallStack(message.m_callStack);
|
| - consoleMessage->setScriptId(message.m_scriptId);
|
| - executionContext->addConsoleMessage(consoleMessage.release());
|
| - }
|
| +void V8Initializer::reportRejectedPromisesOnMainThread()
|
| +{
|
| + rejectedPromisesOnMainThread().processQueue();
|
| }
|
|
|
| static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage data)
|
| @@ -355,7 +264,7 @@ static void promiseRejectHandlerInMainThread(v8::PromiseRejectMessage data)
|
| errorMessage = "Uncaught " + messageForConsole;
|
|
|
| ScriptState* scriptState = ScriptState::from(context);
|
| - promiseRejectMessageQueue().append(PromiseRejectMessage(ScriptValue(scriptState, promise), ScriptValue(scriptState, data.GetValue()), errorMessage, resourceName, scriptId, lineNumber, columnNumber, callStack));
|
| + rejectedPromisesOnMainThread().add(scriptState, data, errorMessage, resourceName, scriptId, lineNumber, columnNumber, callStack);
|
| }
|
|
|
| static void promiseRejectHandlerInWorker(v8::PromiseRejectMessage data)
|
| @@ -367,10 +276,18 @@ static void promiseRejectHandlerInWorker(v8::PromiseRejectMessage data)
|
|
|
| // Bail out if called during context initialization.
|
| v8::Isolate* isolate = promise->GetIsolate();
|
| - v8::Handle<v8::Context> context = isolate->GetCurrentContext();
|
| - if (context.IsEmpty())
|
| + ScriptState* scriptState = ScriptState::current(isolate);
|
| + if (!scriptState->contextIsValid())
|
| return;
|
|
|
| + ExecutionContext* executionContext = scriptState->executionContext();
|
| + if (!executionContext)
|
| + return;
|
| +
|
| + ASSERT(executionContext->isWorkerGlobalScope());
|
| + WorkerScriptController* scriptController = toWorkerGlobalScope(executionContext)->script();
|
| + ASSERT(scriptController);
|
| +
|
| int scriptId = 0;
|
| int lineNumber = 0;
|
| int columnNumber = 0;
|
| @@ -385,9 +302,7 @@ static void promiseRejectHandlerInWorker(v8::PromiseRejectMessage data)
|
| columnNumber = message->GetStartColumn() + 1;
|
| errorMessage = toCoreString(message->Get());
|
| }
|
| -
|
| - ScriptState* scriptState = ScriptState::from(context);
|
| - promiseRejectMessageQueue().append(PromiseRejectMessage(ScriptValue(scriptState, promise), ScriptValue(scriptState, data.GetValue()), errorMessage, resourceName, scriptId, lineNumber, columnNumber, nullptr));
|
| + scriptController->rejectedPromises()->add(scriptState, data, errorMessage, resourceName, scriptId, lineNumber, columnNumber, nullptr);
|
| }
|
|
|
| static void failedAccessCheckCallbackInMainThread(v8::Local<v8::Object> host, v8::AccessType type, v8::Local<v8::Value> data)
|
| @@ -457,6 +372,31 @@ static void initializeV8Common(v8::Isolate* isolate)
|
| isolate->SetAutorunMicrotasks(false);
|
| }
|
|
|
| +namespace {
|
| +
|
| +class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
|
| + virtual void* Allocate(size_t size) override
|
| + {
|
| + void* data;
|
| + WTF::ArrayBufferContents::allocateMemory(size, WTF::ArrayBufferContents::ZeroInitialize, data);
|
| + return data;
|
| + }
|
| +
|
| + virtual void* AllocateUninitialized(size_t size) override
|
| + {
|
| + void* data;
|
| + WTF::ArrayBufferContents::allocateMemory(size, WTF::ArrayBufferContents::DontInitialize, data);
|
| + return data;
|
| + }
|
| +
|
| + virtual void Free(void* data, size_t size) override
|
| + {
|
| + WTF::ArrayBufferContents::freeMemory(data, size);
|
| + }
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| void V8Initializer::initializeMainThreadIfNeeded()
|
| {
|
| ASSERT(isMainThread());
|
|
|