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