15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009, 2012 Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 33197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/WorkerScriptController.h" 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 35197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ScriptSourceCode.h" 36197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ScriptValue.h" 37f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/core/v8/V8DedicatedWorkerGlobalScope.h" 38197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/V8ErrorHandler.h" 39197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/V8GCController.h" 40197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/V8Initializer.h" 41197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/V8ObjectConstructor.h" 42197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/V8ScriptRunner.h" 43f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/core/v8/V8SharedWorkerGlobalScope.h" 44f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/core/v8/V8WorkerGlobalScope.h" 45197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/WrapperTypeInfo.h" 46f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)#include "bindings/modules/v8/V8ServiceWorkerGlobalScope.h" 47197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/events/ErrorEvent.h" 481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/frame/DOMTimer.h" 49197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/inspector/ScriptCallStack.h" 5051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/workers/SharedWorkerGlobalScope.h" 51591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/workers/WorkerGlobalScope.h" 5253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/workers/WorkerObjectProxy.h" 5353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/workers/WorkerThread.h" 54a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch#include "platform/heap/ThreadState.h" 555267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/Platform.h" 565267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/WebWorkerRunLoop.h" 57197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include <v8.h> 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 59c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 60c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 61c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)class WorkerScriptController::WorkerGlobalScopeExecutionState FINAL { 62c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) STACK_ALLOCATED(); 63c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)public: 64c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) explicit WorkerGlobalScopeExecutionState(WorkerScriptController* controller) 65c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) : hadException(false) 66c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) , lineNumber(0) 67c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) , columnNumber(0) 68c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) , m_controller(controller) 69c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) , m_outerState(controller->m_globalScopeExecutionState) 70c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) { 71c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_controller->m_globalScopeExecutionState = this; 72c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 73c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 74c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ~WorkerGlobalScopeExecutionState() 75c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) { 76c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_controller->m_globalScopeExecutionState = m_outerState; 77c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 78c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 79c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) void trace(Visitor* visitor) 80c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) { 81c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) visitor->trace(m_errorEventFromImportedScript); 82c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 83c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 84c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) bool hadException; 85c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) String errorMessage; 86c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) int lineNumber; 87c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) int columnNumber; 88c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) String sourceURL; 89c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ScriptValue exception; 90c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) RefPtrWillBeMember<ErrorEvent> m_errorEventFromImportedScript; 91c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 92c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // A WorkerGlobalScopeExecutionState context is stack allocated by 93c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // WorkerScriptController::evaluate(), with the contoller using it 94c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // during script evaluation. To handle nested evaluate() uses, 95c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // WorkerGlobalScopeExecutionStates are chained together; 96c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // |m_outerState| keeps a pointer to the context object one level out 97c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // (or 0, if outermost.) Upon return from evaluate(), the 98c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // WorkerScriptController's WorkerGlobalScopeExecutionState is popped 99c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // and the previous one restored (see above dtor.) 100c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // 101c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // With Oilpan, |m_outerState| isn't traced. It'll be "up the stack" 102c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // and its fields will be traced when scanning the stack. 103c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) WorkerScriptController* m_controller; 104c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) WorkerGlobalScopeExecutionState* m_outerState; 105c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}; 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 107bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)WorkerScriptController::WorkerScriptController(WorkerGlobalScope& workerGlobalScope) 1087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci : m_isolate(0) 109d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) , m_workerGlobalScope(workerGlobalScope) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_executionForbidden(false) 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_executionScheduledToTerminate(false) 112c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) , m_globalScopeExecutionState(0) 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_isolate = V8PerIsolateData::initialize(); 115d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) V8Initializer::initializeWorker(m_isolate); 116d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_world = DOMWrapperWorld::create(WorkerWorldId); 117d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_interruptor = adoptPtr(new V8IsolateInterruptor(m_isolate)); 11809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ThreadState::current()->addInterruptor(m_interruptor.get()); 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// We need to postpone V8 Isolate destruction until the very end of 12209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// worker thread finalization when all objects on the worker heap 12309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// are destroyed. 12409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class IsolateCleanupTask : public ThreadState::CleanupTask { 12509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)public: 126d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) static PassOwnPtr<IsolateCleanupTask> create(v8::Isolate* isolate) 12709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) { 128d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return adoptPtr(new IsolateCleanupTask(isolate)); 12909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 13009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 13109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) virtual void postCleanup() 13209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) { 1337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci V8PerIsolateData::destroy(m_isolate); 13409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 13509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 13609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)private: 137d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) explicit IsolateCleanupTask(v8::Isolate* isolate) : m_isolate(isolate) { } 13809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 139d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) v8::Isolate* m_isolate; 14009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}; 14109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WorkerScriptController::~WorkerScriptController() 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ThreadState::current()->removeInterruptor(m_interruptor.get()); 14509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 146d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_world->dispose(); 14753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The corresponding call to didStartWorkerRunLoop is in 149c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // WorkerThread::initialize(). 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // See http://webkit.org/b/83104#c14 for why this is here. 151c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) blink::Platform::current()->didStopWorkerRunLoop(blink::WebWorkerRunLoop(m_workerGlobalScope.thread())); 15253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 153a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch if (isContextInitialized()) 154a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch m_scriptState->disposePerContextData(); 15509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 1567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci V8PerIsolateData::willBeDestroyed(m_isolate); 1577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 158d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ThreadState::current()->addCleanupTask(IsolateCleanupTask::create(m_isolate)); 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 161926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool WorkerScriptController::initializeContextIfNeeded() 162926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 163a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch v8::HandleScope handleScope(m_isolate); 164a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch 165a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch if (isContextInitialized()) 166926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return true; 167926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 168d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) v8::Handle<v8::Context> context = v8::Context::New(m_isolate); 169a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (context.IsEmpty()) 170926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 171926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 172f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu m_scriptState = ScriptState::create(context, m_world); 173926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 174f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) ScriptState::Scope scope(m_scriptState.get()); 175926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 176926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Set DebugId for the new context. 177d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) context->SetEmbedderData(0, v8AtomicString(m_isolate, "worker")); 178926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 179926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Create a new JS object and use it as the prototype for the shadow global object. 1807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci const WrapperTypeInfo* wrapperTypeInfo = m_workerGlobalScope.wrapperTypeInfo(); 1817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci v8::Handle<v8::Function> workerGlobalScopeConstructor = m_scriptState->perContextData()->constructorForType(wrapperTypeInfo); 182a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch v8::Local<v8::Object> jsWorkerGlobalScope = V8ObjectConstructor::newInstance(m_isolate, workerGlobalScopeConstructor); 183591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (jsWorkerGlobalScope.IsEmpty()) { 184a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch m_scriptState->disposePerContextData(); 185926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 186926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 187926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci V8DOMWrapper::associateObjectWithWrapperNonTemplate(&m_workerGlobalScope, wrapperTypeInfo, jsWorkerGlobalScope, m_isolate); 189926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 190926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Insert the object instance as the prototype of the shadow object. 191a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch v8::Handle<v8::Object> globalObject = v8::Handle<v8::Object>::Cast(m_scriptState->context()->Global()->GetPrototype()); 192591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch globalObject->SetPrototype(jsWorkerGlobalScope); 193926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 194926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return true; 195926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 196926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 197c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)ScriptValue WorkerScriptController::evaluate(const String& script, const String& fileName, const TextPosition& scriptStartPosition) 198926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 199926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!initializeContextIfNeeded()) 200926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return ScriptValue(); 201926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 202f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu ScriptState::Scope scope(m_scriptState.get()); 203a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch 204926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!m_disableEvalPending.isEmpty()) { 205a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch m_scriptState->context()->AllowCodeGenerationFromStrings(false); 206a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch m_scriptState->context()->SetErrorMessageForCodeGenerationFromStrings(v8String(m_isolate, m_disableEvalPending)); 207926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_disableEvalPending = String(); 208926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 209926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 210926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8::TryCatch block; 211926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 212d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) v8::Handle<v8::String> scriptString = v8String(m_isolate, script); 2137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci v8::Handle<v8::Script> compiledScript = V8ScriptRunner::compileScript(scriptString, fileName, scriptStartPosition, 0, 0, m_isolate); 214d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) v8::Local<v8::Value> result = V8ScriptRunner::runCompiledScript(compiledScript, &m_workerGlobalScope, m_isolate); 215926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 216926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!block.CanContinue()) { 217bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) m_workerGlobalScope.script()->forbidExecution(); 218926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return ScriptValue(); 219926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 220926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 221926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (block.HasCaught()) { 222926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) v8::Local<v8::Message> message = block.Message(); 223c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_globalScopeExecutionState->hadException = true; 224c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_globalScopeExecutionState->errorMessage = toCoreString(message->Get()); 225c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_globalScopeExecutionState->lineNumber = message->GetLineNumber(); 226c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_globalScopeExecutionState->columnNumber = message->GetStartColumn() + 1; 227197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch TOSTRING_DEFAULT(V8StringResource<>, sourceURL, message->GetScriptOrigin().ResourceName(), ScriptValue()); 228c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_globalScopeExecutionState->sourceURL = sourceURL; 229c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_globalScopeExecutionState->exception = ScriptValue(m_scriptState.get(), block.Exception()); 230926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) block.Reset(); 231197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } else { 232c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_globalScopeExecutionState->hadException = false; 233197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 234926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 235926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (result.IsEmpty() || result->IsUndefined()) 236926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return ScriptValue(); 237926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 238323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) return ScriptValue(m_scriptState.get(), result); 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 241a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochvoid WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, RefPtrWillBeRawPtr<ErrorEvent>* errorEvent) 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isExecutionForbidden()) 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 246c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) WorkerGlobalScopeExecutionState state(this); 247c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) evaluate(sourceCode.source(), sourceCode.url().string(), sourceCode.startPosition()); 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (state.hadException) { 2493c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch if (errorEvent) { 250c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (state.m_errorEventFromImportedScript) { 251c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // Propagate inner error event outwards. 252c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) *errorEvent = state.m_errorEventFromImportedScript.release(); 253c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return; 254c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 255c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_workerGlobalScope.shouldSanitizeScriptError(state.sourceURL, NotSharableCrossOrigin)) 256c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) *errorEvent = ErrorEvent::createSanitizedError(m_world.get()); 257c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) else 258c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) *errorEvent = ErrorEvent::create(state.errorMessage, state.sourceURL, state.lineNumber, state.columnNumber, m_world.get()); 259f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) V8ErrorHandler::storeExceptionOnErrorEventWrapper(errorEvent->get(), state.exception.v8Value(), m_scriptState->context()->Global(), m_isolate); 260f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) } else { 261bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) ASSERT(!m_workerGlobalScope.shouldSanitizeScriptError(state.sourceURL, NotSharableCrossOrigin)); 262a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch RefPtrWillBeRawPtr<ErrorEvent> event = nullptr; 263c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (state.m_errorEventFromImportedScript) 264c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) event = state.m_errorEventFromImportedScript.release(); 265c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) else 266a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch event = ErrorEvent::create(state.errorMessage, state.sourceURL, state.lineNumber, state.columnNumber, m_world.get()); 2677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_workerGlobalScope.reportException(event, 0, nullptr, NotSharableCrossOrigin); 268f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) } 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void WorkerScriptController::scheduleExecutionTermination() 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The mutex provides a memory barrier to ensure that once 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // termination is scheduled, isExecutionTerminating will 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // accurately reflect that state when called from another thread. 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MutexLocker locker(m_scheduledTerminationMutex); 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_executionScheduledToTerminate = true; 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 281d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) v8::V8::TerminateExecution(m_isolate); 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool WorkerScriptController::isExecutionTerminating() const 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // See comments in scheduleExecutionTermination regarding mutex usage. 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MutexLocker locker(m_scheduledTerminationMutex); 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_executionScheduledToTerminate; 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void WorkerScriptController::forbidExecution() 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 293bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) ASSERT(m_workerGlobalScope.isContextThread()); 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_executionForbidden = true; 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool WorkerScriptController::isExecutionForbidden() const 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 299bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) ASSERT(m_workerGlobalScope.isContextThread()); 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_executionForbidden; 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void WorkerScriptController::disableEval(const String& errorMessage) 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 305926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_disableEvalPending = errorMessage; 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 308c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void WorkerScriptController::rethrowExceptionFromImportedScript(PassRefPtrWillBeRawPtr<ErrorEvent> errorEvent, ExceptionState& exceptionState) 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 310c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) const String& errorMessage = errorEvent->message(); 311c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (m_globalScopeExecutionState) 312c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_globalScopeExecutionState->m_errorEventFromImportedScript = errorEvent; 313c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) exceptionState.rethrowV8Exception(V8ThrowException::createGeneralError(errorMessage, m_isolate)); 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 316c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 317