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

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

Issue 404513002: Propagate nested importScripts() error events outwards. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fix RefPtr ownership bugaboo 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
OLDNEW
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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 #include "core/workers/WorkerGlobalScope.h" 51 #include "core/workers/WorkerGlobalScope.h"
52 #include "core/workers/WorkerObjectProxy.h" 52 #include "core/workers/WorkerObjectProxy.h"
53 #include "core/workers/WorkerThread.h" 53 #include "core/workers/WorkerThread.h"
54 #include "platform/heap/ThreadState.h" 54 #include "platform/heap/ThreadState.h"
55 #include "public/platform/Platform.h" 55 #include "public/platform/Platform.h"
56 #include "public/platform/WebWorkerRunLoop.h" 56 #include "public/platform/WebWorkerRunLoop.h"
57 #include <v8.h> 57 #include <v8.h>
58 58
59 namespace WebCore { 59 namespace WebCore {
60 60
61 class WorkerScriptController::WorkerGlobalScopeExecutionState FINAL {
62 DISALLOW_ALLOCATION();
haraken 2014/07/18 01:12:38 Can we use STACK_ALLOCATED()? I agree that this o
sof 2014/07/18 07:00:46 The use of STACK_ALLOCATED() makes the GC plugin c
haraken 2014/07/18 07:15:34 Makes sense. I don't think it's a bug of the plug
sof 2014/07/18 07:36:17 I think that is an improvement, the natural annota
63 public:
64 explicit WorkerGlobalScopeExecutionState(WorkerScriptController* controller)
65 : hadException(false)
66 , lineNumber(0)
67 , columnNumber(0)
68 , m_controller(controller)
69 , m_outerState(controller->m_globalScopeExecutionState)
70 {
71 m_controller->m_globalScopeExecutionState = this;
72 }
73
74 ~WorkerGlobalScopeExecutionState()
75 {
76 m_controller->m_globalScopeExecutionState = m_outerState;
77 }
78
79 void trace(Visitor* visitor)
80 {
81 visitor->trace(m_errorEventFromImportedScript);
82 }
83
84 bool hadException;
85 String errorMessage;
86 int lineNumber;
87 int columnNumber;
88 String sourceURL;
89 ScriptValue exception;
90 RefPtrWillBeMember<ErrorEvent> m_errorEventFromImportedScript;
91
92 WorkerScriptController* m_controller;
93 WorkerGlobalScopeExecutionState* m_outerState;
haraken 2014/07/18 01:12:38 Shall we add a comment about why we don't need to
sof 2014/07/18 07:00:46 Yes, these two deserve some explanation :)
94 };
95
61 WorkerScriptController::WorkerScriptController(WorkerGlobalScope& workerGlobalSc ope) 96 WorkerScriptController::WorkerScriptController(WorkerGlobalScope& workerGlobalSc ope)
62 : m_isolate(v8::Isolate::New()) 97 : m_isolate(v8::Isolate::New())
63 , m_workerGlobalScope(workerGlobalScope) 98 , m_workerGlobalScope(workerGlobalScope)
64 , m_executionForbidden(false) 99 , m_executionForbidden(false)
65 , m_executionScheduledToTerminate(false) 100 , m_executionScheduledToTerminate(false)
101 , m_globalScopeExecutionState(0)
66 { 102 {
67 m_isolate->Enter(); 103 m_isolate->Enter();
68 V8Initializer::initializeWorker(m_isolate); 104 V8Initializer::initializeWorker(m_isolate);
69 v8::V8::Initialize(); 105 v8::V8::Initialize();
70 V8PerIsolateData::ensureInitialized(m_isolate); 106 V8PerIsolateData::ensureInitialized(m_isolate);
71 m_world = DOMWrapperWorld::create(WorkerWorldId); 107 m_world = DOMWrapperWorld::create(WorkerWorldId);
72 m_interruptor = adoptPtr(new V8IsolateInterruptor(m_isolate)); 108 m_interruptor = adoptPtr(new V8IsolateInterruptor(m_isolate));
73 ThreadState::current()->addInterruptor(m_interruptor.get()); 109 ThreadState::current()->addInterruptor(m_interruptor.get());
74 } 110 }
75 111
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 182
147 V8DOMWrapper::associateObjectWithWrapper<V8WorkerGlobalScope>(PassRefPtrWill BeRawPtr<WorkerGlobalScope>(&m_workerGlobalScope), contextType, jsWorkerGlobalSc ope, m_isolate, WrapperConfiguration::Dependent); 183 V8DOMWrapper::associateObjectWithWrapper<V8WorkerGlobalScope>(PassRefPtrWill BeRawPtr<WorkerGlobalScope>(&m_workerGlobalScope), contextType, jsWorkerGlobalSc ope, m_isolate, WrapperConfiguration::Dependent);
148 184
149 // Insert the object instance as the prototype of the shadow object. 185 // Insert the object instance as the prototype of the shadow object.
150 v8::Handle<v8::Object> globalObject = v8::Handle<v8::Object>::Cast(m_scriptS tate->context()->Global()->GetPrototype()); 186 v8::Handle<v8::Object> globalObject = v8::Handle<v8::Object>::Cast(m_scriptS tate->context()->Global()->GetPrototype());
151 globalObject->SetPrototype(jsWorkerGlobalScope); 187 globalObject->SetPrototype(jsWorkerGlobalScope);
152 188
153 return true; 189 return true;
154 } 190 }
155 191
156 ScriptValue WorkerScriptController::evaluate(const String& script, const String& fileName, const TextPosition& scriptStartPosition, WorkerGlobalScopeExecutionSt ate* state) 192 ScriptValue WorkerScriptController::evaluate(const String& script, const String& fileName, const TextPosition& scriptStartPosition)
157 { 193 {
158 if (!initializeContextIfNeeded()) 194 if (!initializeContextIfNeeded())
159 return ScriptValue(); 195 return ScriptValue();
160 196
161 ScriptState::Scope scope(m_scriptState.get()); 197 ScriptState::Scope scope(m_scriptState.get());
162 198
163 if (!m_disableEvalPending.isEmpty()) { 199 if (!m_disableEvalPending.isEmpty()) {
164 m_scriptState->context()->AllowCodeGenerationFromStrings(false); 200 m_scriptState->context()->AllowCodeGenerationFromStrings(false);
165 m_scriptState->context()->SetErrorMessageForCodeGenerationFromStrings(v8 String(m_isolate, m_disableEvalPending)); 201 m_scriptState->context()->SetErrorMessageForCodeGenerationFromStrings(v8 String(m_isolate, m_disableEvalPending));
166 m_disableEvalPending = String(); 202 m_disableEvalPending = String();
167 } 203 }
168 204
169 v8::TryCatch block; 205 v8::TryCatch block;
170 206
171 v8::Handle<v8::String> scriptString = v8String(m_isolate, script); 207 v8::Handle<v8::String> scriptString = v8String(m_isolate, script);
172 v8::Handle<v8::Script> compiledScript = V8ScriptRunner::compileScript(script String, fileName, scriptStartPosition, 0, m_isolate); 208 v8::Handle<v8::Script> compiledScript = V8ScriptRunner::compileScript(script String, fileName, scriptStartPosition, 0, m_isolate);
173 v8::Local<v8::Value> result = V8ScriptRunner::runCompiledScript(compiledScri pt, &m_workerGlobalScope, m_isolate); 209 v8::Local<v8::Value> result = V8ScriptRunner::runCompiledScript(compiledScri pt, &m_workerGlobalScope, m_isolate);
174 210
175 if (!block.CanContinue()) { 211 if (!block.CanContinue()) {
176 m_workerGlobalScope.script()->forbidExecution(); 212 m_workerGlobalScope.script()->forbidExecution();
177 return ScriptValue(); 213 return ScriptValue();
178 } 214 }
179 215
180 if (block.HasCaught()) { 216 if (block.HasCaught()) {
181 v8::Local<v8::Message> message = block.Message(); 217 v8::Local<v8::Message> message = block.Message();
182 state->hadException = true; 218 m_globalScopeExecutionState->hadException = true;
183 state->errorMessage = toCoreString(message->Get()); 219 m_globalScopeExecutionState->errorMessage = toCoreString(message->Get()) ;
184 state->lineNumber = message->GetLineNumber(); 220 m_globalScopeExecutionState->lineNumber = message->GetLineNumber();
185 state->columnNumber = message->GetStartColumn() + 1; 221 m_globalScopeExecutionState->columnNumber = message->GetStartColumn() + 1;
186 TOSTRING_DEFAULT(V8StringResource<>, sourceURL, message->GetScriptOrigin ().ResourceName(), ScriptValue()); 222 TOSTRING_DEFAULT(V8StringResource<>, sourceURL, message->GetScriptOrigin ().ResourceName(), ScriptValue());
187 state->sourceURL = sourceURL; 223 m_globalScopeExecutionState->sourceURL = sourceURL;
188 state->exception = ScriptValue(m_scriptState.get(), block.Exception()); 224 m_globalScopeExecutionState->exception = ScriptValue(m_scriptState.get() , block.Exception());
189 block.Reset(); 225 block.Reset();
190 } else { 226 } else {
191 state->hadException = false; 227 m_globalScopeExecutionState->hadException = false;
192 } 228 }
193 229
194 if (result.IsEmpty() || result->IsUndefined()) 230 if (result.IsEmpty() || result->IsUndefined())
195 return ScriptValue(); 231 return ScriptValue();
196 232
197 return ScriptValue(m_scriptState.get(), result); 233 return ScriptValue(m_scriptState.get(), result);
198 } 234 }
199 235
200 void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, RefPtr WillBeRawPtr<ErrorEvent>* errorEvent) 236 void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, RefPtr WillBeRawPtr<ErrorEvent>* errorEvent)
201 { 237 {
202 if (isExecutionForbidden()) 238 if (isExecutionForbidden())
203 return; 239 return;
204 240
205 WorkerGlobalScopeExecutionState state; 241 WorkerGlobalScopeExecutionState state(this);
206 evaluate(sourceCode.source(), sourceCode.url().string(), sourceCode.startPos ition(), &state); 242 evaluate(sourceCode.source(), sourceCode.url().string(), sourceCode.startPos ition());
207 if (state.hadException) { 243 if (state.hadException) {
208 if (errorEvent) { 244 if (errorEvent) {
209 *errorEvent = m_workerGlobalScope.shouldSanitizeScriptError(state.so urceURL, NotSharableCrossOrigin) ? 245 if (state.m_errorEventFromImportedScript) {
210 ErrorEvent::createSanitizedError(m_world.get()) : ErrorEvent::cr eate(state.errorMessage, state.sourceURL, state.lineNumber, state.columnNumber, m_world.get()); 246 // Propagate inner error event outwards.
247 *errorEvent = state.m_errorEventFromImportedScript.release();
248 return;
249 }
250 if (m_workerGlobalScope.shouldSanitizeScriptError(state.sourceURL, N otSharableCrossOrigin))
251 *errorEvent = ErrorEvent::createSanitizedError(m_world.get());
252 else
253 *errorEvent = ErrorEvent::create(state.errorMessage, state.sourc eURL, state.lineNumber, state.columnNumber, m_world.get());
211 V8ErrorHandler::storeExceptionOnErrorEventWrapper(errorEvent->get(), state.exception.v8Value(), m_scriptState->context()->Global(), m_isolate); 254 V8ErrorHandler::storeExceptionOnErrorEventWrapper(errorEvent->get(), state.exception.v8Value(), m_scriptState->context()->Global(), m_isolate);
212 } else { 255 } else {
213 ASSERT(!m_workerGlobalScope.shouldSanitizeScriptError(state.sourceUR L, NotSharableCrossOrigin)); 256 ASSERT(!m_workerGlobalScope.shouldSanitizeScriptError(state.sourceUR L, NotSharableCrossOrigin));
214 RefPtrWillBeRawPtr<ErrorEvent> event = nullptr; 257 RefPtrWillBeRawPtr<ErrorEvent> event = nullptr;
215 if (m_errorEventFromImportedScript) { 258 if (state.m_errorEventFromImportedScript)
216 event = m_errorEventFromImportedScript.release(); 259 event = state.m_errorEventFromImportedScript.release();
217 } else { 260 else
218 event = ErrorEvent::create(state.errorMessage, state.sourceURL, state.lineNumber, state.columnNumber, m_world.get()); 261 event = ErrorEvent::create(state.errorMessage, state.sourceURL, state.lineNumber, state.columnNumber, m_world.get());
219 }
220 m_workerGlobalScope.reportException(event, nullptr, NotSharableCross Origin); 262 m_workerGlobalScope.reportException(event, nullptr, NotSharableCross Origin);
221 } 263 }
222 } 264 }
223 } 265 }
224 266
225 void WorkerScriptController::scheduleExecutionTermination() 267 void WorkerScriptController::scheduleExecutionTermination()
226 { 268 {
227 // The mutex provides a memory barrier to ensure that once 269 // The mutex provides a memory barrier to ensure that once
228 // termination is scheduled, isExecutionTerminating will 270 // termination is scheduled, isExecutionTerminating will
229 // accurately reflect that state when called from another thread. 271 // accurately reflect that state when called from another thread.
(...skipping 21 matching lines...) Expand all
251 { 293 {
252 ASSERT(m_workerGlobalScope.isContextThread()); 294 ASSERT(m_workerGlobalScope.isContextThread());
253 return m_executionForbidden; 295 return m_executionForbidden;
254 } 296 }
255 297
256 void WorkerScriptController::disableEval(const String& errorMessage) 298 void WorkerScriptController::disableEval(const String& errorMessage)
257 { 299 {
258 m_disableEvalPending = errorMessage; 300 m_disableEvalPending = errorMessage;
259 } 301 }
260 302
261 void WorkerScriptController::rethrowExceptionFromImportedScript(PassRefPtrWillBe RawPtr<ErrorEvent> errorEvent) 303 void WorkerScriptController::rethrowExceptionFromImportedScript(PassRefPtrWillBe RawPtr<ErrorEvent> errorEvent, ExceptionState& exceptionState)
262 { 304 {
263 m_errorEventFromImportedScript = errorEvent; 305 const String& errorMessage = errorEvent->message();
264 throwError(V8ThrowException::createError(v8GeneralError, m_errorEventFromImp ortedScript->message(), m_isolate), m_isolate); 306 if (m_globalScopeExecutionState)
307 m_globalScopeExecutionState->m_errorEventFromImportedScript = errorEvent ;
308 exceptionState.rethrowV8Exception(V8ThrowException::createError(v8GeneralErr or, errorMessage, m_isolate));
265 } 309 }
266 310
267 } // namespace WebCore 311 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698