18f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian/*
22fc2651226baac27029e38c9d6ef883fa32084dbSteve Block * Copyright (C) 2009, 2011 Google Inc. All rights reserved.
38f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *
48f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Redistribution and use in source and binary forms, with or without
58f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * modification, are permitted provided that the following conditions are
68f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * met:
78f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *
88f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *     * Redistributions of source code must retain the above copyright
98f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * notice, this list of conditions and the following disclaimer.
108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *     * Redistributions in binary form must reproduce the above
118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * copyright notice, this list of conditions and the following disclaimer
128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * in the documentation and/or other materials provided with the
138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * distribution.
148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *     * Neither the name of Google Inc. nor the names of its
158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * contributors may be used to endorse or promote products derived from
168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * this software without specific prior written permission.
178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian *
188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian */
308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "config.h"
338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#if ENABLE(WORKERS)
358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "WorkerContextExecutionProxy.h"
378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "DedicatedWorkerContext.h"
390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "Event.h"
40ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "ScriptCallStack.h"
41cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include "SharedWorker.h"
42cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include "SharedWorkerContext.h"
438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "V8Binding.h"
440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "V8DOMMap.h"
45dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "V8DedicatedWorkerContext.h"
468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "V8Proxy.h"
47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "V8SharedWorkerContext.h"
485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "Worker.h"
498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "WorkerContext.h"
508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "WorkerScriptController.h"
51dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "WrapperTypeInfo.h"
522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <wtf/text/CString.h>
538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qiannamespace WebCore {
558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianstatic void reportFatalErrorInV8(const char* location, const char* message)
575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // FIXME: We temporarily deal with V8 internal error situations such as out-of-memory by crashing the worker.
595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    CRASH();
605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
62dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic void v8MessageHandler(v8::Handle<v8::Message> message, v8::Handle<v8::Value> data)
63dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
64dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static bool isReportingException = false;
65dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Exceptions that occur in error handler should be ignored since in that case
66dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // WorkerContext::reportException will send the exception to the worker object.
67dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (isReportingException)
68dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return;
69dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    isReportingException = true;
70dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
71dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // During the frame teardown, there may not be a valid context.
72dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (ScriptExecutionContext* context = getScriptExecutionContext()) {
73dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        String errorMessage = toWebCoreString(message->Get());
74dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        int lineNumber = message->GetLineNumber();
75dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        String sourceURL = toWebCoreString(message->GetScriptResourceName());
76ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        context->reportException(errorMessage, lineNumber, sourceURL, 0);
77dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
78dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
79dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    isReportingException = false;
80dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
81dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianWorkerContextExecutionProxy::WorkerContextExecutionProxy(WorkerContext* workerContext)
838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    : m_workerContext(workerContext)
848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_recursion(0)
858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    initV8IfNeeded();
878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianWorkerContextExecutionProxy::~WorkerContextExecutionProxy()
908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    dispose();
928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid WorkerContextExecutionProxy::dispose()
958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Detach all events from their JS wrappers.
978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (size_t eventIndex = 0; eventIndex < m_events.size(); ++eventIndex) {
988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        Event* event = m_events[eventIndex];
998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (forgetV8EventObject(event))
1008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian          event->deref();
1018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_events.clear();
1038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Dispose the context.
1058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!m_context.IsEmpty()) {
1068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_context.Dispose();
1078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_context.Clear();
1088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid WorkerContextExecutionProxy::initV8IfNeeded()
1125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
1135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    static bool v8Initialized = false;
1145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (v8Initialized)
1165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return;
1175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Tell V8 not to call the default OOM handler, binding code will handle it.
1195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    v8::V8::IgnoreOutOfMemoryException();
1205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    v8::V8::SetFatalErrorHandler(reportFatalErrorInV8);
1215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
122cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    v8::ResourceConstraints resource_constraints;
123cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    uint32_t here;
124cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    resource_constraints.set_stack_limit(&here - kWorkerMaxStackSize / sizeof(uint32_t*));
125cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    v8::SetResourceConstraints(&resource_constraints);
126cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
1275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    v8Initialized = true;
1285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
1295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
130dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool WorkerContextExecutionProxy::initContextIfNeeded()
1318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
1328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Bail out if the context has already been initialized.
1338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!m_context.IsEmpty())
134dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return true;
135dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
136dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Setup the security handlers and message listener. This only has
137dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // to be done once.
138dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static bool isV8Initialized = false;
139dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!isV8Initialized)
140dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        v8::V8::AddMessageListener(&v8MessageHandler);
1418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Create a new environment
1438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    v8::Persistent<v8::ObjectTemplate> globalTemplate;
1445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_context = v8::Context::New(0, globalTemplate);
145dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (m_context.IsEmpty())
146dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return false;
1478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Starting from now, use local context only.
1498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    v8::Local<v8::Context> context = v8::Local<v8::Context>::New(m_context);
1508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
151dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    v8::Context::Scope scope(context);
1528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // Set DebugId for the new context.
1542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    context->SetData(v8::String::New("worker"));
1552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Create a new JS object and use it as the prototype for the shadow global object.
157dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    WrapperTypeInfo* contextType = &V8DedicatedWorkerContext::info;
158643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#if ENABLE(SHARED_WORKERS)
159643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!m_workerContext->isDedicatedWorkerContext())
160dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        contextType = &V8SharedWorkerContext::info;
161643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#endif
162643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    v8::Handle<v8::Function> workerContextConstructor = V8DOMWrapper::getConstructorForContext(contextType, context);
1635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    v8::Local<v8::Object> jsWorkerContext = SafeAllocation::newInstance(workerContextConstructor);
1648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Bail out if allocation failed.
1658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (jsWorkerContext.IsEmpty()) {
1668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        dispose();
167dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return false;
1688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Wrap the object.
171dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    V8DOMWrapper::setDOMWrapper(jsWorkerContext, contextType, m_workerContext);
1728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    V8DOMWrapper::setJSWrapperForDOMObject(m_workerContext, v8::Persistent<v8::Object>::New(jsWorkerContext));
1745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_workerContext->ref();
1758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Insert the object instance as the prototype of the shadow object.
177dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    v8::Handle<v8::Object> globalObject = v8::Handle<v8::Object>::Cast(m_context->Global()->GetPrototype());
178dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    globalObject->SetPrototype(jsWorkerContext);
179dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return true;
1808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianbool WorkerContextExecutionProxy::forgetV8EventObject(Event* event)
1838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
1840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (getDOMObjectMap().contains(event)) {
1850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        getDOMObjectMap().forget(event);
1868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return true;
1870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
1880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return false;
1898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1916b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerScriptValue WorkerContextExecutionProxy::evaluate(const String& script, const String& fileName, const TextPosition0& scriptStartPosition, WorkerContextExecutionState* state)
1928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
1938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    v8::HandleScope hs;
1948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
195dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!initContextIfNeeded())
196dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return ScriptValue();
197dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    v8::Context::Scope scope(m_context);
1998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::TryCatch exceptionCatcher;
2010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    v8::Local<v8::String> scriptString = v8ExternalString(script);
2036b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    v8::Handle<v8::Script> compiledScript = V8Proxy::compileScript(scriptString, fileName, scriptStartPosition);
2040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    v8::Local<v8::Value> result = runScript(compiledScript);
2050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!exceptionCatcher.CanContinue()) {
2072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_workerContext->script()->forbidExecution();
208dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return ScriptValue();
2092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
210dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (exceptionCatcher.HasCaught()) {
2120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        v8::Local<v8::Message> message = exceptionCatcher.Message();
2130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        state->hadException = true;
2140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        state->errorMessage = toWebCoreString(message->Get());
2150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        state->lineNumber = message->GetLineNumber();
2160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        state->sourceURL = toWebCoreString(message->GetScriptResourceName());
2172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (m_workerContext->sanitizeScriptError(state->errorMessage, state->lineNumber, state->sourceURL))
2182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            state->exception = V8Proxy::throwError(V8Proxy::GeneralError, state->errorMessage.utf8().data());
2192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        else
2202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            state->exception = ScriptValue(exceptionCatcher.Exception());
2212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        exceptionCatcher.Reset();
2230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    } else
2240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        state->hadException = false;
2250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (result.IsEmpty() || result->IsUndefined())
2270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return ScriptValue();
2280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return ScriptValue(result);
2308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
2318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianv8::Local<v8::Value> WorkerContextExecutionProxy::runScript(v8::Handle<v8::Script> script)
2338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
2348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (script.IsEmpty())
2358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return v8::Local<v8::Value>();
2368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Compute the source string and prevent against infinite recursion.
2388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_recursion >= kMaxRecursionDepth) {
2398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        v8::Local<v8::String> code = v8ExternalString("throw RangeError('Recursion too deep')");
2406b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        script = V8Proxy::compileScript(code, "", TextPosition0::minimumPosition());
2418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
2428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (V8Proxy::handleOutOfMemory())
2448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ASSERT(script.IsEmpty());
2458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (script.IsEmpty())
2478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return v8::Local<v8::Value>();
2488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Run the script and keep track of the current recursion depth.
2508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    v8::Local<v8::Value> result;
2518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    {
2528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_recursion++;
2538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        result = script->Run();
2548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_recursion--;
2558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
2568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Handle V8 internal error situation (Out-of-memory).
2588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (result.IsEmpty())
2598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return v8::Local<v8::Value>();
2608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return result;
2628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
2638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid WorkerContextExecutionProxy::trackEvent(Event* event)
2658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
2668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_events.append(event);
2678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
2688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} // namespace WebCore
2708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif // ENABLE(WORKERS)
272