1 /* 2 * Copyright (C) 2009 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 #if ENABLE(WORKERS) 34 35 #include "WorkerScriptController.h" 36 37 #include "DOMTimer.h" 38 #include "ScriptCallStack.h" 39 #include "ScriptSourceCode.h" 40 #include "ScriptValue.h" 41 #include "V8DOMMap.h" 42 #include "V8Proxy.h" 43 #include "V8WorkerContext.h" 44 #include "WorkerContext.h" 45 #include "WorkerContextExecutionProxy.h" 46 #include "WorkerObjectProxy.h" 47 #include "WorkerThread.h" 48 #include <v8.h> 49 50 namespace WebCore { 51 52 WorkerScriptController::WorkerScriptController(WorkerContext* workerContext) 53 : m_workerContext(workerContext) 54 , m_proxy(new WorkerContextExecutionProxy(workerContext)) 55 , m_executionForbidden(false) 56 { 57 } 58 59 WorkerScriptController::~WorkerScriptController() 60 { 61 removeAllDOMObjectsInCurrentThread(); 62 } 63 64 ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode) 65 { 66 return evaluate(sourceCode, 0); 67 } 68 69 ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, ScriptValue* exception) 70 { 71 if (isExecutionForbidden()) 72 return ScriptValue(); 73 74 WorkerContextExecutionState state; 75 ScriptValue result = m_proxy->evaluate(sourceCode.source(), sourceCode.url().string(), WTF::toZeroBasedTextPosition(sourceCode.startPosition()), &state); 76 if (state.hadException) { 77 if (exception) 78 *exception = state.exception; 79 else 80 m_workerContext->reportException(state.errorMessage, state.lineNumber, state.sourceURL, 0); 81 } 82 83 return result; 84 } 85 86 void WorkerScriptController::scheduleExecutionTermination() 87 { 88 v8::V8::TerminateExecution(); 89 } 90 91 void WorkerScriptController::forbidExecution() 92 { 93 ASSERT(m_workerContext->isContextThread()); 94 m_executionForbidden = true; 95 } 96 97 bool WorkerScriptController::isExecutionForbidden() const 98 { 99 ASSERT(m_workerContext->isContextThread()); 100 return m_executionForbidden; 101 } 102 103 void WorkerScriptController::setException(ScriptValue exception) 104 { 105 throwError(*exception.v8Value()); 106 } 107 108 WorkerScriptController* WorkerScriptController::controllerForContext() 109 { 110 // Happens on frame destruction, check otherwise GetCurrent() will crash. 111 if (!v8::Context::InContext()) 112 return 0; 113 v8::Handle<v8::Context> context = v8::Context::GetCurrent(); 114 v8::Handle<v8::Object> global = context->Global(); 115 global = V8DOMWrapper::lookupDOMWrapper(V8WorkerContext::GetTemplate(), global); 116 // Return 0 if the current executing context is not the worker context. 117 if (global.IsEmpty()) 118 return 0; 119 WorkerContext* workerContext = V8WorkerContext::toNative(global); 120 return workerContext->script(); 121 } 122 123 } // namespace WebCore 124 125 #endif // ENABLE(WORKERS) 126