Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: Source/bindings/v8/WorkerScriptController.cpp

Issue 351423002: Moved files under Source/bindings/v8 to Source/bindings/core/v8. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2009, 2012 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32
33 #include "bindings/v8/WorkerScriptController.h"
34
35 #include "bindings/core/v8/V8DedicatedWorkerGlobalScope.h"
36 #include "bindings/core/v8/V8SharedWorkerGlobalScope.h"
37 #include "bindings/core/v8/V8WorkerGlobalScope.h"
38 #include "bindings/modules/v8/V8ServiceWorkerGlobalScope.h"
39 #include "bindings/v8/ScriptSourceCode.h"
40 #include "bindings/v8/ScriptValue.h"
41 #include "bindings/v8/V8ErrorHandler.h"
42 #include "bindings/v8/V8GCController.h"
43 #include "bindings/v8/V8Initializer.h"
44 #include "bindings/v8/V8ObjectConstructor.h"
45 #include "bindings/v8/V8ScriptRunner.h"
46 #include "bindings/v8/WrapperTypeInfo.h"
47 #include "core/events/ErrorEvent.h"
48 #include "core/frame/DOMTimer.h"
49 #include "core/inspector/ScriptCallStack.h"
50 #include "core/workers/SharedWorkerGlobalScope.h"
51 #include "core/workers/WorkerGlobalScope.h"
52 #include "core/workers/WorkerObjectProxy.h"
53 #include "core/workers/WorkerThread.h"
54 #include "platform/heap/ThreadState.h"
55 #include <v8.h>
56
57 #include "public/platform/Platform.h"
58 #include "public/platform/WebWorkerRunLoop.h"
59
60 namespace WebCore {
61
62 WorkerScriptController::WorkerScriptController(WorkerGlobalScope& workerGlobalSc ope)
63 : m_isolate(v8::Isolate::New())
64 , m_workerGlobalScope(workerGlobalScope)
65 , m_executionForbidden(false)
66 , m_executionScheduledToTerminate(false)
67 {
68 m_isolate->Enter();
69 V8Initializer::initializeWorker(m_isolate);
70 v8::V8::Initialize();
71 V8PerIsolateData::ensureInitialized(m_isolate);
72 m_world = DOMWrapperWorld::create(WorkerWorldId);
73 m_interruptor = adoptPtr(new V8IsolateInterruptor(m_isolate));
74 ThreadState::current()->addInterruptor(m_interruptor.get());
75 }
76
77 // We need to postpone V8 Isolate destruction until the very end of
78 // worker thread finalization when all objects on the worker heap
79 // are destroyed.
80 class IsolateCleanupTask : public ThreadState::CleanupTask {
81 public:
82 static PassOwnPtr<IsolateCleanupTask> create(v8::Isolate* isolate)
83 {
84 return adoptPtr(new IsolateCleanupTask(isolate));
85 }
86
87 virtual void postCleanup()
88 {
89 V8PerIsolateData::dispose(m_isolate);
90 m_isolate->Exit();
91 m_isolate->Dispose();
92 }
93
94 private:
95 explicit IsolateCleanupTask(v8::Isolate* isolate) : m_isolate(isolate) { }
96
97 v8::Isolate* m_isolate;
98 };
99
100 WorkerScriptController::~WorkerScriptController()
101 {
102 ThreadState::current()->removeInterruptor(m_interruptor.get());
103
104 m_world->dispose();
105
106 // The corresponding call to didStartWorkerRunLoop is in
107 // WorkerThread::workerThread().
108 // See http://webkit.org/b/83104#c14 for why this is here.
109 blink::Platform::current()->didStopWorkerRunLoop(blink::WebWorkerRunLoop(&m_ workerGlobalScope.thread()->runLoop()));
110
111 if (isContextInitialized())
112 m_scriptState->disposePerContextData();
113
114 ThreadState::current()->addCleanupTask(IsolateCleanupTask::create(m_isolate) );
115 }
116
117 bool WorkerScriptController::initializeContextIfNeeded()
118 {
119 v8::HandleScope handleScope(m_isolate);
120
121 if (isContextInitialized())
122 return true;
123
124 v8::Handle<v8::Context> context = v8::Context::New(m_isolate);
125 if (context.IsEmpty())
126 return false;
127
128 m_scriptState = ScriptState::create(context, m_world);
129
130 ScriptState::Scope scope(m_scriptState.get());
131
132 // Set DebugId for the new context.
133 context->SetEmbedderData(0, v8AtomicString(m_isolate, "worker"));
134
135 // Create a new JS object and use it as the prototype for the shadow global object.
136 const WrapperTypeInfo* contextType = &V8DedicatedWorkerGlobalScope::wrapperT ypeInfo;
137 if (m_workerGlobalScope.isServiceWorkerGlobalScope())
138 contextType = &V8ServiceWorkerGlobalScope::wrapperTypeInfo;
139 else if (!m_workerGlobalScope.isDedicatedWorkerGlobalScope())
140 contextType = &V8SharedWorkerGlobalScope::wrapperTypeInfo;
141 v8::Handle<v8::Function> workerGlobalScopeConstructor = m_scriptState->perCo ntextData()->constructorForType(contextType);
142 v8::Local<v8::Object> jsWorkerGlobalScope = V8ObjectConstructor::newInstance (m_isolate, workerGlobalScopeConstructor);
143 if (jsWorkerGlobalScope.IsEmpty()) {
144 m_scriptState->disposePerContextData();
145 return false;
146 }
147
148 V8DOMWrapper::associateObjectWithWrapper<V8WorkerGlobalScope>(PassRefPtrWill BeRawPtr<WorkerGlobalScope>(&m_workerGlobalScope), contextType, jsWorkerGlobalSc ope, m_isolate, WrapperConfiguration::Dependent);
149
150 // Insert the object instance as the prototype of the shadow object.
151 v8::Handle<v8::Object> globalObject = v8::Handle<v8::Object>::Cast(m_scriptS tate->context()->Global()->GetPrototype());
152 globalObject->SetPrototype(jsWorkerGlobalScope);
153
154 return true;
155 }
156
157 ScriptValue WorkerScriptController::evaluate(const String& script, const String& fileName, const TextPosition& scriptStartPosition, WorkerGlobalScopeExecutionSt ate* state)
158 {
159 if (!initializeContextIfNeeded())
160 return ScriptValue();
161
162 ScriptState::Scope scope(m_scriptState.get());
163
164 if (!m_disableEvalPending.isEmpty()) {
165 m_scriptState->context()->AllowCodeGenerationFromStrings(false);
166 m_scriptState->context()->SetErrorMessageForCodeGenerationFromStrings(v8 String(m_isolate, m_disableEvalPending));
167 m_disableEvalPending = String();
168 }
169
170 v8::TryCatch block;
171
172 v8::Handle<v8::String> scriptString = v8String(m_isolate, script);
173 v8::Handle<v8::Script> compiledScript = V8ScriptRunner::compileScript(script String, fileName, scriptStartPosition, 0, m_isolate);
174 v8::Local<v8::Value> result = V8ScriptRunner::runCompiledScript(compiledScri pt, &m_workerGlobalScope, m_isolate);
175
176 if (!block.CanContinue()) {
177 m_workerGlobalScope.script()->forbidExecution();
178 return ScriptValue();
179 }
180
181 if (block.HasCaught()) {
182 v8::Local<v8::Message> message = block.Message();
183 state->hadException = true;
184 state->errorMessage = toCoreString(message->Get());
185 state->lineNumber = message->GetLineNumber();
186 state->columnNumber = message->GetStartColumn() + 1;
187 TOSTRING_DEFAULT(V8StringResource<>, sourceURL, message->GetScriptOrigin ().ResourceName(), ScriptValue());
188 state->sourceURL = sourceURL;
189 state->exception = ScriptValue(m_scriptState.get(), block.Exception());
190 block.Reset();
191 } else
192 state->hadException = false;
193
194 if (result.IsEmpty() || result->IsUndefined())
195 return ScriptValue();
196
197 return ScriptValue(m_scriptState.get(), result);
198 }
199
200 void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, RefPtr WillBeRawPtr<ErrorEvent>* errorEvent)
201 {
202 if (isExecutionForbidden())
203 return;
204
205 WorkerGlobalScopeExecutionState state;
206 evaluate(sourceCode.source(), sourceCode.url().string(), sourceCode.startPos ition(), &state);
207 if (state.hadException) {
208 if (errorEvent) {
209 *errorEvent = m_workerGlobalScope.shouldSanitizeScriptError(state.so urceURL, NotSharableCrossOrigin) ?
210 ErrorEvent::createSanitizedError(m_world.get()) : ErrorEvent::cr eate(state.errorMessage, state.sourceURL, state.lineNumber, state.columnNumber, m_world.get());
211 V8ErrorHandler::storeExceptionOnErrorEventWrapper(errorEvent->get(), state.exception.v8Value(), m_scriptState->context()->Global(), m_isolate);
212 } else {
213 ASSERT(!m_workerGlobalScope.shouldSanitizeScriptError(state.sourceUR L, NotSharableCrossOrigin));
214 RefPtrWillBeRawPtr<ErrorEvent> event = nullptr;
215 if (m_errorEventFromImportedScript) {
216 event = m_errorEventFromImportedScript.release();
217 } else {
218 event = ErrorEvent::create(state.errorMessage, state.sourceURL, state.lineNumber, state.columnNumber, m_world.get());
219 }
220 m_workerGlobalScope.reportException(event, nullptr, NotSharableCross Origin);
221 }
222 }
223 }
224
225 void WorkerScriptController::scheduleExecutionTermination()
226 {
227 // The mutex provides a memory barrier to ensure that once
228 // termination is scheduled, isExecutionTerminating will
229 // accurately reflect that state when called from another thread.
230 {
231 MutexLocker locker(m_scheduledTerminationMutex);
232 m_executionScheduledToTerminate = true;
233 }
234 v8::V8::TerminateExecution(m_isolate);
235 }
236
237 bool WorkerScriptController::isExecutionTerminating() const
238 {
239 // See comments in scheduleExecutionTermination regarding mutex usage.
240 MutexLocker locker(m_scheduledTerminationMutex);
241 return m_executionScheduledToTerminate;
242 }
243
244 void WorkerScriptController::forbidExecution()
245 {
246 ASSERT(m_workerGlobalScope.isContextThread());
247 m_executionForbidden = true;
248 }
249
250 bool WorkerScriptController::isExecutionForbidden() const
251 {
252 ASSERT(m_workerGlobalScope.isContextThread());
253 return m_executionForbidden;
254 }
255
256 void WorkerScriptController::disableEval(const String& errorMessage)
257 {
258 m_disableEvalPending = errorMessage;
259 }
260
261 void WorkerScriptController::rethrowExceptionFromImportedScript(PassRefPtrWillBe RawPtr<ErrorEvent> errorEvent)
262 {
263 m_errorEventFromImportedScript = errorEvent;
264 throwError(V8ThrowException::createError(v8GeneralError, m_errorEventFromImp ortedScript->message(), m_isolate), m_isolate);
265 }
266
267 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/bindings/v8/WorkerScriptController.h ('k') | Source/bindings/v8/WorkerScriptDebugServer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698