OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. | 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. |
3 * Copyright (C) 2009 Google Inc. All Rights Reserved. | 3 * Copyright (C) 2009 Google Inc. All Rights Reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. 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 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 29 matching lines...) Expand all Loading... |
40 #include "core/frame/csp/ContentSecurityPolicy.h" | 40 #include "core/frame/csp/ContentSecurityPolicy.h" |
41 #include "core/inspector/ConsoleMessage.h" | 41 #include "core/inspector/ConsoleMessage.h" |
42 #include "core/inspector/ScriptCallStack.h" | 42 #include "core/inspector/ScriptCallStack.h" |
43 #include "core/inspector/WorkerDebuggerAgent.h" | 43 #include "core/inspector/WorkerDebuggerAgent.h" |
44 #include "core/loader/DocumentLoadTiming.h" | 44 #include "core/loader/DocumentLoadTiming.h" |
45 #include "core/loader/DocumentLoader.h" | 45 #include "core/loader/DocumentLoader.h" |
46 #include "core/workers/InProcessWorkerBase.h" | 46 #include "core/workers/InProcessWorkerBase.h" |
47 #include "core/workers/WorkerClients.h" | 47 #include "core/workers/WorkerClients.h" |
48 #include "core/workers/WorkerInspectorProxy.h" | 48 #include "core/workers/WorkerInspectorProxy.h" |
49 #include "core/workers/WorkerObjectProxy.h" | 49 #include "core/workers/WorkerObjectProxy.h" |
50 #include "core/workers/WorkerThreadStartupData.h" | 50 #include "core/workers/WorkerScriptStartupData.h" |
51 #include "platform/heap/Handle.h" | 51 #include "platform/heap/Handle.h" |
52 #include "wtf/Functional.h" | 52 #include "wtf/Functional.h" |
53 #include "wtf/MainThread.h" | 53 #include "wtf/MainThread.h" |
54 | 54 |
55 namespace blink { | 55 namespace blink { |
56 | 56 |
57 namespace { | 57 namespace { |
58 | 58 |
59 void processMessageOnWorkerGlobalScope(PassRefPtr<SerializedScriptValue> message
, PassOwnPtr<MessagePortChannelArray> channels, WorkerObjectProxy* workerObjectP
roxy, ExecutionContext* scriptContext) | 59 void processMessageOnWorkerGlobalScope(PassRefPtr<SerializedScriptValue> message
, PassOwnPtr<MessagePortChannelArray> channels, WorkerObjectProxy* workerObjectP
roxy, ExecutionContext* scriptContext) |
60 { | 60 { |
61 WorkerGlobalScope* globalScope = toWorkerGlobalScope(scriptContext); | 61 WorkerGlobalScope* globalScope = toWorkerGlobalScope(scriptContext); |
62 OwnPtrWillBeRawPtr<MessagePortArray> ports = MessagePort::entanglePorts(*scr
iptContext, channels); | 62 OwnPtrWillBeRawPtr<MessagePortArray> ports = MessagePort::entanglePorts(*scr
iptContext, channels); |
63 globalScope->dispatchEvent(MessageEvent::create(ports.release(), message)); | 63 globalScope->dispatchEvent(MessageEvent::create(ports.release(), message)); |
64 workerObjectProxy->confirmMessageFromWorkerObject(scriptContext->hasPendingA
ctivity()); | 64 workerObjectProxy->confirmMessageFromWorkerObject(scriptContext->hasPendingA
ctivity()); |
65 } | 65 } |
66 | 66 |
67 } // namespace | 67 } // namespace |
68 | 68 |
69 WorkerMessagingProxy::WorkerMessagingProxy(InProcessWorkerBase* workerObject, Pa
ssOwnPtrWillBeRawPtr<WorkerClients> workerClients) | 69 WorkerMessagingProxy::WorkerMessagingProxy(InProcessWorkerBase* workerObject, Pa
ssOwnPtrWillBeRawPtr<WorkerClients> workerClients) |
70 : m_executionContext(workerObject->executionContext()) | 70 : m_executionContext(workerObject->executionContext()) |
71 , m_workerObjectProxy(WorkerObjectProxy::create(m_executionContext.get(), th
is)) | 71 , m_workerObjectProxy(WorkerObjectProxy::create(m_executionContext.get(), th
is)) |
72 , m_workerObject(workerObject) | 72 , m_workerObject(workerObject) |
73 , m_mayBeDestroyed(false) | 73 , m_mayBeDestroyed(false) |
74 , m_unconfirmedMessageCount(0) | 74 , m_unconfirmedMessageCount(0) |
75 , m_workerThreadHadPendingActivity(false) | 75 , m_workerScriptHadPendingActivity(false) |
76 , m_askedToTerminate(false) | 76 , m_askedToTerminate(false) |
77 , m_workerInspectorProxy(WorkerInspectorProxy::create()) | 77 , m_workerInspectorProxy(WorkerInspectorProxy::create()) |
78 , m_workerClients(workerClients) | 78 , m_workerClients(workerClients) |
79 { | 79 { |
80 ASSERT(m_workerObject); | 80 ASSERT(m_workerObject); |
81 ASSERT((m_executionContext->isDocument() && isMainThread()) | 81 ASSERT((m_executionContext->isDocument() && isMainThread()) |
82 || (m_executionContext->isWorkerGlobalScope() && toWorkerGlobalScope(m_e
xecutionContext.get())->thread()->isCurrentThread())); | 82 || (m_executionContext->isWorkerGlobalScope() && toWorkerGlobalScope(m_e
xecutionContext.get())->script()->isCurrentThread())); |
83 m_workerInspectorProxy->setWorkerGlobalScopeProxy(this); | 83 m_workerInspectorProxy->setWorkerGlobalScopeProxy(this); |
84 } | 84 } |
85 | 85 |
86 WorkerMessagingProxy::~WorkerMessagingProxy() | 86 WorkerMessagingProxy::~WorkerMessagingProxy() |
87 { | 87 { |
88 ASSERT(!m_workerObject); | 88 ASSERT(!m_workerObject); |
89 ASSERT((m_executionContext->isDocument() && isMainThread()) | 89 ASSERT((m_executionContext->isDocument() && isMainThread()) |
90 || (m_executionContext->isWorkerGlobalScope() && toWorkerGlobalScope(m_e
xecutionContext.get())->thread()->isCurrentThread())); | 90 || (m_executionContext->isWorkerGlobalScope() && toWorkerGlobalScope(m_e
xecutionContext.get())->script()->isCurrentThread())); |
91 if (m_loaderProxy) | 91 if (m_loaderProxy) |
92 m_loaderProxy->detachProvider(this); | 92 m_loaderProxy->detachProvider(this); |
93 } | 93 } |
94 | 94 |
95 void WorkerMessagingProxy::startWorkerGlobalScope(const KURL& scriptURL, const S
tring& userAgent, const String& sourceCode, WorkerThreadStartMode startMode) | 95 void WorkerMessagingProxy::startWorkerGlobalScope(const KURL& scriptURL, const S
tring& userAgent, const String& sourceCode, WorkerThreadStartMode startMode) |
96 { | 96 { |
97 // FIXME: This need to be revisited when we support nested worker one day | 97 // FIXME: This need to be revisited when we support nested worker one day |
98 ASSERT(m_executionContext->isDocument()); | 98 ASSERT(m_executionContext->isDocument()); |
99 if (m_askedToTerminate) { | 99 if (m_askedToTerminate) { |
100 // Worker.terminate() could be called from JS before the thread was crea
ted. | 100 // Worker.terminate() could be called from JS before the thread was crea
ted. |
101 return; | 101 return; |
102 } | 102 } |
103 Document* document = toDocument(m_executionContext.get()); | 103 Document* document = toDocument(m_executionContext.get()); |
104 SecurityOrigin* starterOrigin = document->securityOrigin(); | 104 SecurityOrigin* starterOrigin = document->securityOrigin(); |
105 | 105 |
106 RefPtr<ContentSecurityPolicy> csp = m_workerObject->contentSecurityPolicy()
? m_workerObject->contentSecurityPolicy() : document->contentSecurityPolicy(); | 106 RefPtr<ContentSecurityPolicy> csp = m_workerObject->contentSecurityPolicy()
? m_workerObject->contentSecurityPolicy() : document->contentSecurityPolicy(); |
107 ASSERT(csp); | 107 ASSERT(csp); |
108 | 108 |
109 OwnPtr<WorkerThreadStartupData> startupData = WorkerThreadStartupData::creat
e(scriptURL, userAgent, sourceCode, nullptr, startMode, csp->deprecatedHeader(),
csp->deprecatedHeaderType(), starterOrigin, m_workerClients.release()); | 109 OwnPtr<WorkerScriptStartupData> startupData = WorkerScriptStartupData::creat
e(scriptURL, userAgent, sourceCode, nullptr, startMode, csp->deprecatedHeader(),
csp->deprecatedHeaderType(), starterOrigin, m_workerClients.release()); |
110 double originTime = document->loader() ? document->loader()->timing().refere
nceMonotonicTime() : monotonicallyIncreasingTime(); | 110 double originTime = document->loader() ? document->loader()->timing().refere
nceMonotonicTime() : monotonicallyIncreasingTime(); |
111 | 111 |
112 m_loaderProxy = WorkerLoaderProxy::create(this); | 112 m_loaderProxy = WorkerLoaderProxy::create(this); |
113 RefPtr<WorkerThread> thread = createWorkerThread(originTime, startupData.rel
ease()); | 113 RefPtr<WorkerScript> script = createWorkerScript(originTime, startupData.rel
ease()); |
114 thread->start(); | 114 script->start(); |
115 workerThreadCreated(thread); | 115 workerScriptCreated(script); |
116 m_workerInspectorProxy->workerThreadCreated(m_executionContext.get(), m_work
erThread.get(), scriptURL); | 116 m_workerInspectorProxy->workerScriptCreated(m_executionContext.get(), m_work
erScript.get(), scriptURL); |
117 } | 117 } |
118 | 118 |
119 void WorkerMessagingProxy::postMessageToWorkerObject(PassRefPtr<SerializedScript
Value> message, PassOwnPtr<MessagePortChannelArray> channels) | 119 void WorkerMessagingProxy::postMessageToWorkerObject(PassRefPtr<SerializedScript
Value> message, PassOwnPtr<MessagePortChannelArray> channels) |
120 { | 120 { |
121 if (!m_workerObject || m_askedToTerminate) | 121 if (!m_workerObject || m_askedToTerminate) |
122 return; | 122 return; |
123 | 123 |
124 OwnPtrWillBeRawPtr<MessagePortArray> ports = MessagePort::entanglePorts(*m_e
xecutionContext.get(), channels); | 124 OwnPtrWillBeRawPtr<MessagePortArray> ports = MessagePort::entanglePorts(*m_e
xecutionContext.get(), channels); |
125 m_workerObject->dispatchEvent(MessageEvent::create(ports.release(), message)
); | 125 m_workerObject->dispatchEvent(MessageEvent::create(ports.release(), message)
); |
126 } | 126 } |
127 | 127 |
128 void WorkerMessagingProxy::postMessageToWorkerGlobalScope(PassRefPtr<SerializedS
criptValue> message, PassOwnPtr<MessagePortChannelArray> channels) | 128 void WorkerMessagingProxy::postMessageToWorkerGlobalScope(PassRefPtr<SerializedS
criptValue> message, PassOwnPtr<MessagePortChannelArray> channels) |
129 { | 129 { |
130 if (m_askedToTerminate) | 130 if (m_askedToTerminate) |
131 return; | 131 return; |
132 | 132 |
133 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&processMessageOnW
orkerGlobalScope, message, channels, AllowCrossThreadAccess(&workerObjectProxy()
)); | 133 OwnPtr<ExecutionContextTask> task = createCrossThreadTask(&processMessageOnW
orkerGlobalScope, message, channels, AllowCrossThreadAccess(&workerObjectProxy()
)); |
134 if (m_workerThread) { | 134 if (m_workerScript) { |
135 ++m_unconfirmedMessageCount; | 135 ++m_unconfirmedMessageCount; |
136 m_workerThread->postTask(FROM_HERE, task.release()); | 136 m_workerScript->postTask(FROM_HERE, task.release()); |
137 } else { | 137 } else { |
138 m_queuedEarlyTasks.append(task.release()); | 138 m_queuedEarlyTasks.append(task.release()); |
139 } | 139 } |
140 } | 140 } |
141 | 141 |
142 bool WorkerMessagingProxy::postTaskToWorkerGlobalScope(PassOwnPtr<ExecutionConte
xtTask> task) | 142 bool WorkerMessagingProxy::postTaskToWorkerGlobalScope(PassOwnPtr<ExecutionConte
xtTask> task) |
143 { | 143 { |
144 if (m_askedToTerminate) | 144 if (m_askedToTerminate) |
145 return false; | 145 return false; |
146 | 146 |
147 ASSERT(m_workerThread); | 147 ASSERT(m_workerScript); |
148 m_workerThread->postTask(FROM_HERE, task); | 148 m_workerScript->postTask(FROM_HERE, task); |
149 return true; | 149 return true; |
150 } | 150 } |
151 | 151 |
152 void WorkerMessagingProxy::postTaskToLoader(PassOwnPtr<ExecutionContextTask> tas
k) | 152 void WorkerMessagingProxy::postTaskToLoader(PassOwnPtr<ExecutionContextTask> tas
k) |
153 { | 153 { |
154 // FIXME: In case of nested workers, this should go directly to the root Doc
ument context. | 154 // FIXME: In case of nested workers, this should go directly to the root Doc
ument context. |
155 ASSERT(m_executionContext->isDocument()); | 155 ASSERT(m_executionContext->isDocument()); |
156 m_executionContext->postTask(FROM_HERE, task); | 156 m_executionContext->postTask(FROM_HERE, task); |
157 } | 157 } |
158 | 158 |
159 void WorkerMessagingProxy::reportException(const String& errorMessage, int lineN
umber, int columnNumber, const String& sourceURL, int exceptionId) | 159 void WorkerMessagingProxy::reportException(const String& errorMessage, int lineN
umber, int columnNumber, const String& sourceURL, int exceptionId) |
160 { | 160 { |
161 if (!m_workerObject) | 161 if (!m_workerObject) |
162 return; | 162 return; |
163 | 163 |
164 // We don't bother checking the askedToTerminate() flag here, because except
ions should *always* be reported even if the thread is terminated. | 164 // We don't bother checking the askedToTerminate() flag here, because except
ions should *always* be reported even if the thread is terminated. |
165 // This is intentionally different than the behavior in MessageWorkerTask, b
ecause terminated workers no longer deliver messages (section 4.6 of the WebWork
er spec), but they do report exceptions. | 165 // This is intentionally different than the behavior in MessageWorkerTask, b
ecause terminated workers no longer deliver messages (section 4.6 of the WebWork
er spec), but they do report exceptions. |
166 | 166 |
167 RefPtrWillBeRawPtr<ErrorEvent> event = ErrorEvent::create(errorMessage, sour
ceURL, lineNumber, columnNumber, nullptr); | 167 RefPtrWillBeRawPtr<ErrorEvent> event = ErrorEvent::create(errorMessage, sour
ceURL, lineNumber, columnNumber, nullptr); |
168 bool errorHandled = !m_workerObject->dispatchEvent(event); | 168 bool errorHandled = !m_workerObject->dispatchEvent(event); |
169 | 169 |
170 postTaskToWorkerGlobalScope(createCrossThreadTask(&WorkerGlobalScope::except
ionHandled, m_workerThread->workerGlobalScope(), exceptionId, errorHandled)); | 170 postTaskToWorkerGlobalScope(createCrossThreadTask(&WorkerGlobalScope::except
ionHandled, m_workerScript->workerGlobalScope(), exceptionId, errorHandled)); |
171 } | 171 } |
172 | 172 |
173 void WorkerMessagingProxy::reportConsoleMessage(MessageSource source, MessageLev
el level, const String& message, int lineNumber, const String& sourceURL) | 173 void WorkerMessagingProxy::reportConsoleMessage(MessageSource source, MessageLev
el level, const String& message, int lineNumber, const String& sourceURL) |
174 { | 174 { |
175 if (m_askedToTerminate) | 175 if (m_askedToTerminate) |
176 return; | 176 return; |
177 // FIXME: In case of nested workers, this should go directly to the root Doc
ument context. | 177 // FIXME: In case of nested workers, this should go directly to the root Doc
ument context. |
178 ASSERT(m_executionContext->isDocument()); | 178 ASSERT(m_executionContext->isDocument()); |
179 Document* document = toDocument(m_executionContext.get()); | 179 Document* document = toDocument(m_executionContext.get()); |
180 LocalFrame* frame = document->frame(); | 180 LocalFrame* frame = document->frame(); |
181 if (!frame) | 181 if (!frame) |
182 return; | 182 return; |
183 | 183 |
184 RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(s
ource, level, message, sourceURL, lineNumber); | 184 RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(s
ource, level, message, sourceURL, lineNumber); |
185 consoleMessage->setWorkerGlobalScopeProxy(this); | 185 consoleMessage->setWorkerGlobalScopeProxy(this); |
186 frame->console().addMessage(consoleMessage.release()); | 186 frame->console().addMessage(consoleMessage.release()); |
187 } | 187 } |
188 | 188 |
189 void WorkerMessagingProxy::workerThreadCreated(PassRefPtr<WorkerThread> workerTh
read) | 189 void WorkerMessagingProxy::workerScriptCreated(PassRefPtr<WorkerScript> workerSc
ript) |
190 { | 190 { |
191 ASSERT(!m_askedToTerminate); | 191 ASSERT(!m_askedToTerminate); |
192 m_workerThread = workerThread; | 192 m_workerScript = workerScript; |
193 | 193 |
194 ASSERT(!m_unconfirmedMessageCount); | 194 ASSERT(!m_unconfirmedMessageCount); |
195 m_unconfirmedMessageCount = m_queuedEarlyTasks.size(); | 195 m_unconfirmedMessageCount = m_queuedEarlyTasks.size(); |
196 m_workerThreadHadPendingActivity = true; // Worker initialization means a pe
nding activity. | 196 m_workerScriptHadPendingActivity = true; // Worker initialization means a pe
nding activity. |
197 | 197 |
198 for (auto& earlyTasks : m_queuedEarlyTasks) | 198 for (auto& earlyTasks : m_queuedEarlyTasks) |
199 m_workerThread->postTask(FROM_HERE, earlyTasks.release()); | 199 m_workerScript->postTask(FROM_HERE, earlyTasks.release()); |
200 m_queuedEarlyTasks.clear(); | 200 m_queuedEarlyTasks.clear(); |
201 } | 201 } |
202 | 202 |
203 void WorkerMessagingProxy::workerObjectDestroyed() | 203 void WorkerMessagingProxy::workerObjectDestroyed() |
204 { | 204 { |
205 m_workerObject = nullptr; | 205 m_workerObject = nullptr; |
206 m_executionContext->postTask(FROM_HERE, createCrossThreadTask(&WorkerMessagi
ngProxy::workerObjectDestroyedInternal, this)); | 206 m_executionContext->postTask(FROM_HERE, createCrossThreadTask(&WorkerMessagi
ngProxy::workerObjectDestroyedInternal, this)); |
207 } | 207 } |
208 | 208 |
209 void WorkerMessagingProxy::workerObjectDestroyedInternal() | 209 void WorkerMessagingProxy::workerObjectDestroyedInternal() |
210 { | 210 { |
211 m_mayBeDestroyed = true; | 211 m_mayBeDestroyed = true; |
212 if (m_workerThread) | 212 if (m_workerScript) |
213 terminateWorkerGlobalScope(); | 213 terminateWorkerGlobalScope(); |
214 else | 214 else |
215 workerThreadTerminated(); | 215 workerScriptTerminated(); |
216 } | 216 } |
217 | 217 |
218 void WorkerMessagingProxy::workerThreadTerminated() | 218 void WorkerMessagingProxy::workerScriptTerminated() |
219 { | 219 { |
220 // This method is always the last to be performed, so the proxy is not neede
d for communication | 220 // This method is always the last to be performed, so the proxy is not neede
d for communication |
221 // in either side any more. However, the Worker object may still exist, and
it assumes that the proxy exists, too. | 221 // in either side any more. However, the Worker object may still exist, and
it assumes that the proxy exists, too. |
222 m_askedToTerminate = true; | 222 m_askedToTerminate = true; |
223 m_workerThread = nullptr; | 223 m_workerScript = nullptr; |
224 terminateInternally(); | 224 terminateInternally(); |
225 if (m_mayBeDestroyed) | 225 if (m_mayBeDestroyed) |
226 delete this; | 226 delete this; |
227 } | 227 } |
228 | 228 |
229 void WorkerMessagingProxy::terminateWorkerGlobalScope() | 229 void WorkerMessagingProxy::terminateWorkerGlobalScope() |
230 { | 230 { |
231 if (m_askedToTerminate) | 231 if (m_askedToTerminate) |
232 return; | 232 return; |
233 m_askedToTerminate = true; | 233 m_askedToTerminate = true; |
234 | 234 |
235 if (m_workerThread) | 235 if (m_workerScript) |
236 m_workerThread->stop(); | 236 m_workerScript->stop(); |
237 | 237 |
238 terminateInternally(); | 238 terminateInternally(); |
239 } | 239 } |
240 | 240 |
241 void WorkerMessagingProxy::postMessageToPageInspector(const String& message) | 241 void WorkerMessagingProxy::postMessageToPageInspector(const String& message) |
242 { | 242 { |
243 if (!m_workerInspectorProxy) | 243 if (!m_workerInspectorProxy) |
244 return; | 244 return; |
245 WorkerInspectorProxy::PageInspector* pageInspector = m_workerInspectorProxy-
>pageInspector(); | 245 WorkerInspectorProxy::PageInspector* pageInspector = m_workerInspectorProxy-
>pageInspector(); |
246 if (pageInspector) | 246 if (pageInspector) |
(...skipping 18 matching lines...) Expand all Loading... |
265 { | 265 { |
266 if (!m_askedToTerminate) { | 266 if (!m_askedToTerminate) { |
267 ASSERT(m_unconfirmedMessageCount); | 267 ASSERT(m_unconfirmedMessageCount); |
268 --m_unconfirmedMessageCount; | 268 --m_unconfirmedMessageCount; |
269 } | 269 } |
270 reportPendingActivity(hasPendingActivity); | 270 reportPendingActivity(hasPendingActivity); |
271 } | 271 } |
272 | 272 |
273 void WorkerMessagingProxy::reportPendingActivity(bool hasPendingActivity) | 273 void WorkerMessagingProxy::reportPendingActivity(bool hasPendingActivity) |
274 { | 274 { |
275 m_workerThreadHadPendingActivity = hasPendingActivity; | 275 m_workerScriptHadPendingActivity = hasPendingActivity; |
276 } | 276 } |
277 | 277 |
278 bool WorkerMessagingProxy::hasPendingActivity() const | 278 bool WorkerMessagingProxy::hasPendingActivity() const |
279 { | 279 { |
280 return (m_unconfirmedMessageCount || m_workerThreadHadPendingActivity) && !m
_askedToTerminate; | 280 return (m_unconfirmedMessageCount || m_workerScriptHadPendingActivity) && !m
_askedToTerminate; |
281 } | 281 } |
282 | 282 |
283 void WorkerMessagingProxy::terminateInternally() | 283 void WorkerMessagingProxy::terminateInternally() |
284 { | 284 { |
285 m_workerInspectorProxy->workerThreadTerminated(); | 285 m_workerInspectorProxy->workerScriptTerminated(); |
286 | 286 |
287 // FIXME: This need to be revisited when we support nested worker one day | 287 // FIXME: This need to be revisited when we support nested worker one day |
288 ASSERT(m_executionContext->isDocument()); | 288 ASSERT(m_executionContext->isDocument()); |
289 Document* document = toDocument(m_executionContext.get()); | 289 Document* document = toDocument(m_executionContext.get()); |
290 LocalFrame* frame = document->frame(); | 290 LocalFrame* frame = document->frame(); |
291 if (frame) | 291 if (frame) |
292 frame->console().adoptWorkerMessagesAfterTermination(this); | 292 frame->console().adoptWorkerMessagesAfterTermination(this); |
293 } | 293 } |
294 | 294 |
295 } // namespace blink | 295 } // namespace blink |
OLD | NEW |