OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009, 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2009, 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 #include "core/workers/WorkerGlobalScope.h" | 48 #include "core/workers/WorkerGlobalScope.h" |
49 #include "core/workers/WorkerObjectProxy.h" | 49 #include "core/workers/WorkerObjectProxy.h" |
50 #include "core/workers/WorkerThread.h" | 50 #include "core/workers/WorkerThread.h" |
51 #include <v8.h> | 51 #include <v8.h> |
52 | 52 |
53 #include "public/platform/Platform.h" | 53 #include "public/platform/Platform.h" |
54 #include "public/platform/WebWorkerRunLoop.h" | 54 #include "public/platform/WebWorkerRunLoop.h" |
55 | 55 |
56 namespace WebCore { | 56 namespace WebCore { |
57 | 57 |
58 WorkerScriptController::WorkerScriptController(WorkerGlobalScope* workerGlobalSc
ope) | 58 WorkerScriptController::WorkerScriptController(WorkerGlobalScope& workerGlobalSc
ope) |
59 : m_workerGlobalScope(workerGlobalScope) | 59 : m_workerGlobalScope(workerGlobalScope) |
60 , m_isolate(v8::Isolate::New()) | 60 , m_isolate(v8::Isolate::New()) |
61 , m_executionForbidden(false) | 61 , m_executionForbidden(false) |
62 , m_executionScheduledToTerminate(false) | 62 , m_executionScheduledToTerminate(false) |
63 { | 63 { |
64 m_isolate->Enter(); | 64 m_isolate->Enter(); |
65 v8::V8::Initialize(); | 65 v8::V8::Initialize(); |
66 V8PerIsolateData* data = V8PerIsolateData::create(m_isolate); | 66 V8PerIsolateData* data = V8PerIsolateData::create(m_isolate); |
67 m_domDataStore = adoptPtr(new DOMDataStore(WorkerWorld)); | 67 m_domDataStore = adoptPtr(new DOMDataStore(WorkerWorld)); |
68 data->setWorkerDOMDataStore(m_domDataStore.get()); | 68 data->setWorkerDOMDataStore(m_domDataStore.get()); |
69 | 69 |
70 V8Initializer::initializeWorker(m_isolate); | 70 V8Initializer::initializeWorker(m_isolate); |
71 } | 71 } |
72 | 72 |
73 WorkerScriptController::~WorkerScriptController() | 73 WorkerScriptController::~WorkerScriptController() |
74 { | 74 { |
75 m_domDataStore.clear(); | 75 m_domDataStore.clear(); |
76 | 76 |
77 // The corresponding call to didStartWorkerRunLoop is in | 77 // The corresponding call to didStartWorkerRunLoop is in |
78 // WorkerThread::workerThread(). | 78 // WorkerThread::workerThread(). |
79 // See http://webkit.org/b/83104#c14 for why this is here. | 79 // See http://webkit.org/b/83104#c14 for why this is here. |
80 WebKit::Platform::current()->didStopWorkerRunLoop(WebKit::WebWorkerRunLoop(&
m_workerGlobalScope->thread()->runLoop())); | 80 WebKit::Platform::current()->didStopWorkerRunLoop(WebKit::WebWorkerRunLoop(&
m_workerGlobalScope.thread()->runLoop())); |
81 | 81 |
82 disposeContext(); | 82 disposeContext(); |
83 V8PerIsolateData::dispose(m_isolate); | 83 V8PerIsolateData::dispose(m_isolate); |
84 m_isolate->Exit(); | 84 m_isolate->Exit(); |
85 m_isolate->Dispose(); | 85 m_isolate->Dispose(); |
86 } | 86 } |
87 | 87 |
88 void WorkerScriptController::disposeContext() | 88 void WorkerScriptController::disposeContext() |
89 { | 89 { |
90 m_perContextData.clear(); | 90 m_perContextData.clear(); |
(...skipping 18 matching lines...) Expand all Loading... |
109 if (!m_perContextData->init()) { | 109 if (!m_perContextData->init()) { |
110 disposeContext(); | 110 disposeContext(); |
111 return false; | 111 return false; |
112 } | 112 } |
113 | 113 |
114 // Set DebugId for the new context. | 114 // Set DebugId for the new context. |
115 context->SetEmbedderData(0, v8::String::NewSymbol("worker")); | 115 context->SetEmbedderData(0, v8::String::NewSymbol("worker")); |
116 | 116 |
117 // Create a new JS object and use it as the prototype for the shadow global
object. | 117 // Create a new JS object and use it as the prototype for the shadow global
object. |
118 WrapperTypeInfo* contextType = &V8DedicatedWorkerGlobalScope::info; | 118 WrapperTypeInfo* contextType = &V8DedicatedWorkerGlobalScope::info; |
119 if (!m_workerGlobalScope->isDedicatedWorkerGlobalScope()) | 119 if (!m_workerGlobalScope.isDedicatedWorkerGlobalScope()) |
120 contextType = &V8SharedWorkerGlobalScope::info; | 120 contextType = &V8SharedWorkerGlobalScope::info; |
121 v8::Handle<v8::Function> workerGlobalScopeConstructor = m_perContextData->co
nstructorForType(contextType); | 121 v8::Handle<v8::Function> workerGlobalScopeConstructor = m_perContextData->co
nstructorForType(contextType); |
122 v8::Local<v8::Object> jsWorkerGlobalScope = V8ObjectConstructor::newInstance
(workerGlobalScopeConstructor); | 122 v8::Local<v8::Object> jsWorkerGlobalScope = V8ObjectConstructor::newInstance
(workerGlobalScopeConstructor); |
123 if (jsWorkerGlobalScope.IsEmpty()) { | 123 if (jsWorkerGlobalScope.IsEmpty()) { |
124 disposeContext(); | 124 disposeContext(); |
125 return false; | 125 return false; |
126 } | 126 } |
127 | 127 |
128 V8DOMWrapper::associateObjectWithWrapper<V8WorkerGlobalScope>(PassRefPtr<Wor
kerGlobalScope>(m_workerGlobalScope), contextType, jsWorkerGlobalScope, m_isolat
e, WrapperConfiguration::Dependent); | 128 V8DOMWrapper::associateObjectWithWrapper<V8WorkerGlobalScope>(PassRefPtr<Wor
kerGlobalScope>(m_workerGlobalScope), contextType, jsWorkerGlobalScope, m_isolat
e, WrapperConfiguration::Dependent); |
129 | 129 |
(...skipping 17 matching lines...) Expand all Loading... |
147 context->SetErrorMessageForCodeGenerationFromStrings(v8String(m_disableE
valPending, m_isolate)); | 147 context->SetErrorMessageForCodeGenerationFromStrings(v8String(m_disableE
valPending, m_isolate)); |
148 m_disableEvalPending = String(); | 148 m_disableEvalPending = String(); |
149 } | 149 } |
150 | 150 |
151 v8::Context::Scope scope(context); | 151 v8::Context::Scope scope(context); |
152 | 152 |
153 v8::TryCatch block; | 153 v8::TryCatch block; |
154 | 154 |
155 v8::Handle<v8::String> scriptString = v8String(script, m_isolate); | 155 v8::Handle<v8::String> scriptString = v8String(script, m_isolate); |
156 v8::Handle<v8::Script> compiledScript = V8ScriptRunner::compileScript(script
String, fileName, scriptStartPosition, 0, m_isolate); | 156 v8::Handle<v8::Script> compiledScript = V8ScriptRunner::compileScript(script
String, fileName, scriptStartPosition, 0, m_isolate); |
157 v8::Local<v8::Value> result = V8ScriptRunner::runCompiledScript(compiledScri
pt, m_workerGlobalScope, m_isolate); | 157 v8::Local<v8::Value> result = V8ScriptRunner::runCompiledScript(compiledScri
pt, &m_workerGlobalScope, m_isolate); |
158 | 158 |
159 if (!block.CanContinue()) { | 159 if (!block.CanContinue()) { |
160 m_workerGlobalScope->script()->forbidExecution(); | 160 m_workerGlobalScope.script()->forbidExecution(); |
161 return ScriptValue(); | 161 return ScriptValue(); |
162 } | 162 } |
163 | 163 |
164 if (block.HasCaught()) { | 164 if (block.HasCaught()) { |
165 v8::Local<v8::Message> message = block.Message(); | 165 v8::Local<v8::Message> message = block.Message(); |
166 state->hadException = true; | 166 state->hadException = true; |
167 state->errorMessage = toWebCoreString(message->Get()); | 167 state->errorMessage = toWebCoreString(message->Get()); |
168 state->lineNumber = message->GetLineNumber(); | 168 state->lineNumber = message->GetLineNumber(); |
169 state->columnNumber = message->GetStartColumn(); | 169 state->columnNumber = message->GetStartColumn(); |
170 state->sourceURL = toWebCoreString(message->GetScriptResourceName()); | 170 state->sourceURL = toWebCoreString(message->GetScriptResourceName()); |
(...skipping 10 matching lines...) Expand all Loading... |
181 | 181 |
182 void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, RefPtr
<ErrorEvent>* errorEvent) | 182 void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, RefPtr
<ErrorEvent>* errorEvent) |
183 { | 183 { |
184 if (isExecutionForbidden()) | 184 if (isExecutionForbidden()) |
185 return; | 185 return; |
186 | 186 |
187 WorkerGlobalScopeExecutionState state; | 187 WorkerGlobalScopeExecutionState state; |
188 evaluate(sourceCode.source(), sourceCode.url().string(), sourceCode.startPos
ition(), &state); | 188 evaluate(sourceCode.source(), sourceCode.url().string(), sourceCode.startPos
ition(), &state); |
189 if (state.hadException) { | 189 if (state.hadException) { |
190 if (errorEvent) { | 190 if (errorEvent) { |
191 *errorEvent = m_workerGlobalScope->shouldSanitizeScriptError(state.s
ourceURL, NotSharableCrossOrigin) ? | 191 *errorEvent = m_workerGlobalScope.shouldSanitizeScriptError(state.so
urceURL, NotSharableCrossOrigin) ? |
192 ErrorEvent::createSanitizedError(0) : ErrorEvent::create(state.e
rrorMessage, state.sourceURL, state.lineNumber, state.columnNumber, 0); | 192 ErrorEvent::createSanitizedError(0) : ErrorEvent::create(state.e
rrorMessage, state.sourceURL, state.lineNumber, state.columnNumber, 0); |
193 V8ErrorHandler::storeExceptionOnErrorEventWrapper(errorEvent->get(),
state.exception.v8Value(), m_isolate); | 193 V8ErrorHandler::storeExceptionOnErrorEventWrapper(errorEvent->get(),
state.exception.v8Value(), m_isolate); |
194 } else { | 194 } else { |
195 ASSERT(!m_workerGlobalScope->shouldSanitizeScriptError(state.sourceU
RL, NotSharableCrossOrigin)); | 195 ASSERT(!m_workerGlobalScope.shouldSanitizeScriptError(state.sourceUR
L, NotSharableCrossOrigin)); |
196 RefPtr<ErrorEvent> event = m_errorEventFromImportedScript ? m_errorE
ventFromImportedScript.release() : ErrorEvent::create(state.errorMessage, state.
sourceURL, state.lineNumber, state.columnNumber, 0); | 196 RefPtr<ErrorEvent> event = m_errorEventFromImportedScript ? m_errorE
ventFromImportedScript.release() : ErrorEvent::create(state.errorMessage, state.
sourceURL, state.lineNumber, state.columnNumber, 0); |
197 m_workerGlobalScope->reportException(event, 0, NotSharableCrossOrigi
n); | 197 m_workerGlobalScope.reportException(event, 0, NotSharableCrossOrigin
); |
198 } | 198 } |
199 } | 199 } |
200 } | 200 } |
201 | 201 |
202 void WorkerScriptController::scheduleExecutionTermination() | 202 void WorkerScriptController::scheduleExecutionTermination() |
203 { | 203 { |
204 // The mutex provides a memory barrier to ensure that once | 204 // The mutex provides a memory barrier to ensure that once |
205 // termination is scheduled, isExecutionTerminating will | 205 // termination is scheduled, isExecutionTerminating will |
206 // accurately reflect that state when called from another thread. | 206 // accurately reflect that state when called from another thread. |
207 { | 207 { |
208 MutexLocker locker(m_scheduledTerminationMutex); | 208 MutexLocker locker(m_scheduledTerminationMutex); |
209 m_executionScheduledToTerminate = true; | 209 m_executionScheduledToTerminate = true; |
210 } | 210 } |
211 v8::V8::TerminateExecution(m_isolate); | 211 v8::V8::TerminateExecution(m_isolate); |
212 } | 212 } |
213 | 213 |
214 bool WorkerScriptController::isExecutionTerminating() const | 214 bool WorkerScriptController::isExecutionTerminating() const |
215 { | 215 { |
216 // See comments in scheduleExecutionTermination regarding mutex usage. | 216 // See comments in scheduleExecutionTermination regarding mutex usage. |
217 MutexLocker locker(m_scheduledTerminationMutex); | 217 MutexLocker locker(m_scheduledTerminationMutex); |
218 return m_executionScheduledToTerminate; | 218 return m_executionScheduledToTerminate; |
219 } | 219 } |
220 | 220 |
221 void WorkerScriptController::forbidExecution() | 221 void WorkerScriptController::forbidExecution() |
222 { | 222 { |
223 ASSERT(m_workerGlobalScope->isContextThread()); | 223 ASSERT(m_workerGlobalScope.isContextThread()); |
224 m_executionForbidden = true; | 224 m_executionForbidden = true; |
225 } | 225 } |
226 | 226 |
227 bool WorkerScriptController::isExecutionForbidden() const | 227 bool WorkerScriptController::isExecutionForbidden() const |
228 { | 228 { |
229 ASSERT(m_workerGlobalScope->isContextThread()); | 229 ASSERT(m_workerGlobalScope.isContextThread()); |
230 return m_executionForbidden; | 230 return m_executionForbidden; |
231 } | 231 } |
232 | 232 |
233 void WorkerScriptController::disableEval(const String& errorMessage) | 233 void WorkerScriptController::disableEval(const String& errorMessage) |
234 { | 234 { |
235 m_disableEvalPending = errorMessage; | 235 m_disableEvalPending = errorMessage; |
236 } | 236 } |
237 | 237 |
238 void WorkerScriptController::rethrowExceptionFromImportedScript(PassRefPtr<Error
Event> errorEvent) | 238 void WorkerScriptController::rethrowExceptionFromImportedScript(PassRefPtr<Error
Event> errorEvent) |
239 { | 239 { |
(...skipping 10 matching lines...) Expand all Loading... |
250 v8::Handle<v8::Object> global = context->Global(); | 250 v8::Handle<v8::Object> global = context->Global(); |
251 global = global->FindInstanceInPrototypeChain(V8WorkerGlobalScope::GetTempla
te(context->GetIsolate(), WorkerWorld)); | 251 global = global->FindInstanceInPrototypeChain(V8WorkerGlobalScope::GetTempla
te(context->GetIsolate(), WorkerWorld)); |
252 // Return 0 if the current executing context is not the worker context. | 252 // Return 0 if the current executing context is not the worker context. |
253 if (global.IsEmpty()) | 253 if (global.IsEmpty()) |
254 return 0; | 254 return 0; |
255 WorkerGlobalScope* workerGlobalScope = V8WorkerGlobalScope::toNative(global)
; | 255 WorkerGlobalScope* workerGlobalScope = V8WorkerGlobalScope::toNative(global)
; |
256 return workerGlobalScope->script(); | 256 return workerGlobalScope->script(); |
257 } | 257 } |
258 | 258 |
259 } // namespace WebCore | 259 } // namespace WebCore |
OLD | NEW |