summaryrefslogtreecommitdiff
path: root/Source/WebCore/bindings/js/WorkerScriptController.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/bindings/js/WorkerScriptController.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/bindings/js/WorkerScriptController.cpp')
-rw-r--r--Source/WebCore/bindings/js/WorkerScriptController.cpp127
1 files changed, 67 insertions, 60 deletions
diff --git a/Source/WebCore/bindings/js/WorkerScriptController.cpp b/Source/WebCore/bindings/js/WorkerScriptController.cpp
index 579a0b4af..230af90bd 100644
--- a/Source/WebCore/bindings/js/WorkerScriptController.cpp
+++ b/Source/WebCore/bindings/js/WorkerScriptController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2016 Apple Inc. All Rights Reserved.
* Copyright (C) 2011, 2012 Google Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -11,18 +11,17 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -30,23 +29,18 @@
#include "JSDOMBinding.h"
#include "JSDedicatedWorkerGlobalScope.h"
+#include "JSEventTarget.h"
#include "ScriptSourceCode.h"
#include "WebCoreJSClientData.h"
+#include "WorkerConsoleClient.h"
#include "WorkerGlobalScope.h"
-#include "WorkerObjectProxy.h"
-#include "WorkerScriptDebugServer.h"
-#include "WorkerThread.h"
#include <bindings/ScriptValue.h>
#include <heap/StrongInlines.h>
-#include <interpreter/Interpreter.h>
#include <runtime/Completion.h>
+#include <runtime/Exception.h>
#include <runtime/ExceptionHelpers.h>
-#include <runtime/Error.h>
#include <runtime/JSLock.h>
-
-#if ENABLE(SHARED_WORKERS)
-#include "JSSharedWorkerGlobalScope.h"
-#endif
+#include <runtime/Watchdog.h>
using namespace JSC;
@@ -56,16 +50,21 @@ WorkerScriptController::WorkerScriptController(WorkerGlobalScope* workerGlobalSc
: m_vm(VM::create())
, m_workerGlobalScope(workerGlobalScope)
, m_workerGlobalScopeWrapper(*m_vm)
- , m_executionForbidden(false)
{
- initNormalWorldClientData(m_vm.get());
+ m_vm->heap.acquireAccess(); // It's not clear that we have good discipline for heap access, so turn it on permanently.
+ m_vm->ensureWatchdog();
+ JSVMClientData::initNormalWorld(m_vm.get());
}
WorkerScriptController::~WorkerScriptController()
{
JSLockHolder lock(vm());
+ if (m_workerGlobalScopeWrapper) {
+ m_workerGlobalScopeWrapper->setConsoleClient(nullptr);
+ m_consoleClient = nullptr;
+ }
m_workerGlobalScopeWrapper.clear();
- m_vm.clear();
+ m_vm = nullptr;
}
void WorkerScriptController::initScript()
@@ -77,35 +76,28 @@ void WorkerScriptController::initScript()
// Explicitly protect the global object's prototype so it isn't collected
// when we allocate the global object. (Once the global object is fully
// constructed, it can mark its own prototype.)
- Structure* workerGlobalScopePrototypeStructure = JSWorkerGlobalScopePrototype::createStructure(*m_vm, 0, jsNull());
- Strong<JSWorkerGlobalScopePrototype> workerGlobalScopePrototype(*m_vm, JSWorkerGlobalScopePrototype::create(*m_vm, 0, workerGlobalScopePrototypeStructure));
-
if (m_workerGlobalScope->isDedicatedWorkerGlobalScope()) {
- Structure* dedicatedContextPrototypeStructure = JSDedicatedWorkerGlobalScopePrototype::createStructure(*m_vm, 0, workerGlobalScopePrototype.get());
- Strong<JSDedicatedWorkerGlobalScopePrototype> dedicatedContextPrototype(*m_vm, JSDedicatedWorkerGlobalScopePrototype::create(*m_vm, 0, dedicatedContextPrototypeStructure));
- Structure* structure = JSDedicatedWorkerGlobalScope::createStructure(*m_vm, 0, dedicatedContextPrototype.get());
+ Structure* dedicatedContextPrototypeStructure = JSDedicatedWorkerGlobalScopePrototype::createStructure(*m_vm, nullptr, jsNull());
+ Strong<JSDedicatedWorkerGlobalScopePrototype> dedicatedContextPrototype(*m_vm, JSDedicatedWorkerGlobalScopePrototype::create(*m_vm, nullptr, dedicatedContextPrototypeStructure));
+ Structure* structure = JSDedicatedWorkerGlobalScope::createStructure(*m_vm, nullptr, dedicatedContextPrototype.get());
+ auto* proxyStructure = JSProxy::createStructure(*m_vm, nullptr, jsNull(), PureForwardingProxyType);
+ auto* proxy = JSProxy::create(*m_vm, proxyStructure);
- m_workerGlobalScopeWrapper.set(*m_vm, JSDedicatedWorkerGlobalScope::create(*m_vm, structure, static_cast<DedicatedWorkerGlobalScope*>(m_workerGlobalScope)));
- workerGlobalScopePrototypeStructure->setGlobalObject(*m_vm, m_workerGlobalScopeWrapper.get());
+ m_workerGlobalScopeWrapper.set(*m_vm, JSDedicatedWorkerGlobalScope::create(*m_vm, structure, static_cast<DedicatedWorkerGlobalScope&>(*m_workerGlobalScope), proxy));
dedicatedContextPrototypeStructure->setGlobalObject(*m_vm, m_workerGlobalScopeWrapper.get());
ASSERT(structure->globalObject() == m_workerGlobalScopeWrapper);
ASSERT(m_workerGlobalScopeWrapper->structure()->globalObject() == m_workerGlobalScopeWrapper);
- workerGlobalScopePrototype->structure()->setGlobalObject(*m_vm, m_workerGlobalScopeWrapper.get());
dedicatedContextPrototype->structure()->setGlobalObject(*m_vm, m_workerGlobalScopeWrapper.get());
-#if ENABLE(SHARED_WORKERS)
- } else {
- ASSERT(m_workerGlobalScope->isSharedWorkerGlobalScope());
- Structure* sharedContextPrototypeStructure = JSSharedWorkerGlobalScopePrototype::createStructure(*m_vm, 0, workerGlobalScopePrototype.get());
- Strong<JSSharedWorkerGlobalScopePrototype> sharedContextPrototype(*m_vm, JSSharedWorkerGlobalScopePrototype::create(*m_vm, 0, sharedContextPrototypeStructure));
- Structure* structure = JSSharedWorkerGlobalScope::createStructure(*m_vm, 0, sharedContextPrototype.get());
-
- m_workerGlobalScopeWrapper.set(*m_vm, JSSharedWorkerGlobalScope::create(*m_vm, structure, static_cast<SharedWorkerGlobalScope*>(m_workerGlobalScope)));
- workerGlobalScopePrototype->structure()->setGlobalObject(*m_vm, m_workerGlobalScopeWrapper.get());
- sharedContextPrototype->structure()->setGlobalObject(*m_vm, m_workerGlobalScopeWrapper.get());
-#endif
+ dedicatedContextPrototype->structure()->setPrototypeWithoutTransition(*m_vm, JSWorkerGlobalScope::prototype(*m_vm, m_workerGlobalScopeWrapper.get()));
+
+ proxy->setTarget(*m_vm, m_workerGlobalScopeWrapper.get());
+ proxy->structure()->setGlobalObject(*m_vm, m_workerGlobalScopeWrapper.get());
}
ASSERT(m_workerGlobalScopeWrapper->globalObject() == m_workerGlobalScopeWrapper);
- ASSERT(asObject(m_workerGlobalScopeWrapper->prototype())->globalObject() == m_workerGlobalScopeWrapper);
+ ASSERT(asObject(m_workerGlobalScopeWrapper->getPrototypeDirect())->globalObject() == m_workerGlobalScopeWrapper);
+
+ m_consoleClient = std::make_unique<WorkerConsoleClient>(*m_workerGlobalScope);
+ m_workerGlobalScopeWrapper->setConsoleClient(m_consoleClient.get());
}
void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode)
@@ -113,15 +105,15 @@ void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode)
if (isExecutionForbidden())
return;
- Deprecated::ScriptValue exception;
- evaluate(sourceCode, &exception);
- if (exception.jsValue()) {
+ NakedPtr<JSC::Exception> exception;
+ evaluate(sourceCode, exception);
+ if (exception) {
JSLockHolder lock(vm());
- reportException(m_workerGlobalScopeWrapper->globalExec(), exception.jsValue());
+ reportException(m_workerGlobalScopeWrapper->globalExec(), exception);
}
}
-void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, Deprecated::ScriptValue* exception)
+void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, NakedPtr<JSC::Exception>& returnedException)
{
if (isExecutionForbidden())
return;
@@ -129,47 +121,52 @@ void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, Deprec
initScriptIfNeeded();
ExecState* exec = m_workerGlobalScopeWrapper->globalExec();
- JSLockHolder lock(exec);
+ VM& vm = exec->vm();
+ JSLockHolder lock(vm);
- JSValue evaluationException;
- JSC::evaluate(exec, sourceCode.jsSourceCode(), m_workerGlobalScopeWrapper.get(), &evaluationException);
+ JSC::evaluate(exec, sourceCode.jsSourceCode(), m_workerGlobalScopeWrapper->globalThis(), returnedException);
- if ((evaluationException && isTerminatedExecutionException(evaluationException)) || m_workerGlobalScopeWrapper->vm().watchdog.didFire()) {
+ if ((returnedException && isTerminatedExecutionException(vm, returnedException)) || isTerminatingExecution()) {
forbidExecution();
return;
}
- if (evaluationException) {
+ if (returnedException) {
String errorMessage;
int lineNumber = 0;
int columnNumber = 0;
String sourceURL = sourceCode.url().string();
- if (m_workerGlobalScope->sanitizeScriptError(errorMessage, lineNumber, columnNumber, sourceURL, sourceCode.cachedScript()))
- *exception = Deprecated::ScriptValue(*m_vm, exec->vm().throwException(exec, createError(exec, errorMessage.impl())));
- else
- *exception = Deprecated::ScriptValue(*m_vm, evaluationException);
+ JSC::Strong<JSC::Unknown> error;
+ if (m_workerGlobalScope->sanitizeScriptError(errorMessage, lineNumber, columnNumber, sourceURL, error, sourceCode.cachedScript()))
+ returnedException = JSC::Exception::create(vm, createError(exec, errorMessage.impl()));
}
}
-void WorkerScriptController::setException(const Deprecated::ScriptValue& exception)
+void WorkerScriptController::setException(JSC::Exception* exception)
{
- m_workerGlobalScopeWrapper->globalExec()->vm().throwException(m_workerGlobalScopeWrapper->globalExec(), exception.jsValue());
+ JSC::ExecState* exec = m_workerGlobalScopeWrapper->globalExec();
+ VM& vm = exec->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ throwException(exec, scope, exception);
}
void WorkerScriptController::scheduleExecutionTermination()
{
// The mutex provides a memory barrier to ensure that once
- // termination is scheduled, isExecutionTerminating will
+ // termination is scheduled, isTerminatingExecution() will
// accurately reflect that state when called from another thread.
- MutexLocker locker(m_scheduledTerminationMutex);
- m_vm->watchdog.fire();
+ LockHolder locker(m_scheduledTerminationMutex);
+ m_isTerminatingExecution = true;
+
+ ASSERT(m_vm->watchdog());
+ m_vm->watchdog()->terminateSoon();
}
-bool WorkerScriptController::isExecutionTerminating() const
+bool WorkerScriptController::isTerminatingExecution() const
{
// See comments in scheduleExecutionTermination regarding mutex usage.
- MutexLocker locker(m_scheduledTerminationMutex);
- return m_vm->watchdog.didFire();
+ LockHolder locker(m_scheduledTerminationMutex);
+ return m_isTerminatingExecution;
}
void WorkerScriptController::forbidExecution()
@@ -192,6 +189,16 @@ void WorkerScriptController::disableEval(const String& errorMessage)
m_workerGlobalScopeWrapper->setEvalEnabled(false, errorMessage);
}
+void WorkerScriptController::releaseHeapAccess()
+{
+ m_vm->heap.releaseAccess();
+}
+
+void WorkerScriptController::acquireHeapAccess()
+{
+ m_vm->heap.acquireAccess();
+}
+
void WorkerScriptController::attachDebugger(JSC::Debugger* debugger)
{
initScriptIfNeeded();