static v8::Handle<v8::Value> closeCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.WorkerContext.close");
    WorkerContext* imp = V8WorkerContext::toNative(args.Holder());
    imp->close();
    return v8::Handle<v8::Value>();
}
static v8::Handle<v8::Value> openDatabaseSyncCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.WorkerContext.openDatabaseSync");
    if (args.Length() < 4)
        return throwError("Not enough arguments", V8Proxy::SyntaxError);
    WorkerContext* imp = V8WorkerContext::toNative(args.Holder());
    ExceptionCode ec = 0;
    {
    STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, name, args[0]);
    STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, version, args[1]);
    STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, displayName, args[2]);
    EXCEPTION_BLOCK(unsigned, estimatedSize, toUInt32(args[3]));
    RefPtr<DatabaseCallback> creationCallback;
    if (args.Length() > 4 && !args[4]->IsNull() && !args[4]->IsUndefined()) {
        if (!args[4]->IsObject())
            return throwError(TYPE_MISMATCH_ERR);
        creationCallback = V8DatabaseCallback::create(args[4], getScriptExecutionContext());
    }
    RefPtr<DatabaseSync> result = imp->openDatabaseSync(name, version, displayName, estimatedSize, creationCallback, ec);
    if (UNLIKELY(ec))
        goto fail;
    return toV8(result.release());
    }
    fail:
    V8Proxy::setDOMException(ec);
    return v8::Handle<v8::Value>();
}
Example #3
0
void setJSWorkerContextOnmessage(ExecState* exec, JSObject* thisObject, JSValue value)
{
    UNUSED_PARAM(exec);
    WorkerContext* imp = static_cast<WorkerContext*>(static_cast<JSWorkerContext*>(thisObject)->impl());
    JSDOMGlobalObject* globalObject = static_cast<JSWorkerContext*>(thisObject);
    imp->setOnmessage(globalObject->createJSAttributeEventListener(value));
}
Example #4
0
bool IDBFactoryBackendProxy::allowIndexedDB(ScriptExecutionContext* context, const String& name, const WebSecurityOrigin& origin, PassRefPtr<IDBCallbacks> callbacks)
{
    bool allowed;
    ASSERT(context->isDocument() || context->isWorkerContext());
    if (context->isDocument()) {
        Document* document = static_cast<Document*>(context);
        WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame());
        WebViewImpl* webView = webFrame->viewImpl();
        // FIXME: webView->permissionClient() returns 0 in test_shell and content_shell http://crbug.com/137269
        allowed = !webView->permissionClient() || webView->permissionClient()->allowIndexedDB(webFrame, name, origin);
    } else {
        WorkerContext* workerContext = static_cast<WorkerContext*>(context);
        WebWorkerBase* webWorkerBase = static_cast<WebWorkerBase*>(&workerContext->thread()->workerLoaderProxy());
        WorkerRunLoop& runLoop = workerContext->thread()->runLoop();

        String mode = allowIndexedDBMode;
        mode.append(String::number(runLoop.createUniqueId()));
        RefPtr<AllowIndexedDBMainThreadBridge> bridge = AllowIndexedDBMainThreadBridge::create(webWorkerBase, mode, name);

        // Either the bridge returns, or the queue gets terminated.
        if (runLoop.runInMode(workerContext, mode) == MessageQueueTerminated) {
            bridge->cancel();
            allowed = false;
        } else
            allowed = bridge->result();
    }

    if (!allowed)
        callbacks->onError(WebIDBDatabaseError(IDBDatabaseException::UNKNOWN_ERR, "The user denied permission to access the database."));

    return allowed;
}
Example #5
0
bool DatabaseObserver::canEstablishDatabase(ScriptExecutionContext* scriptExecutionContext, const String& name, const String& displayName, unsigned long estimatedSize)
{
    ASSERT(scriptExecutionContext->isContextThread());
    ASSERT(scriptExecutionContext->isDocument() || scriptExecutionContext->isWorkerContext());
    if (scriptExecutionContext->isDocument()) {
        Document* document = static_cast<Document*>(scriptExecutionContext);
        WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame());
        if (!webFrame)
            return false;
        WebViewImpl* webView = webFrame->viewImpl();
        if (!webView)
            return false;
        if (webView->permissionClient())
            return webView->permissionClient()->allowDatabase(webFrame, name, displayName, estimatedSize);
    } else {
#if ENABLE(WORKERS)
        WorkerContext* workerContext = static_cast<WorkerContext*>(scriptExecutionContext);
        WorkerLoaderProxy* workerLoaderProxy = &workerContext->thread()->workerLoaderProxy();
        NewWebWorkerBase* webWorker = static_cast<NewWebWorkerBase*>(workerLoaderProxy);
        return allowDatabaseForWorker(webWorker->newCommonClient(), webWorker->view()->mainFrame(), name, displayName, estimatedSize);
#else
        ASSERT_NOT_REACHED();
#endif
    }

    return true;
}
    virtual void performTask(ScriptExecutionContext *context)
    {
        ASSERT(context->isWorkerContext());
        WorkerContext* workerContext = static_cast<WorkerContext*>(context);

#if ENABLE(DATABASE)
        // We currently ignore any DatabasePolicy used for the document's
        // databases; if it's actually used anywhere, this should be revisited.
        DatabaseTaskSynchronizer cleanupSync;
        workerContext->stopDatabases(&cleanupSync);
#endif

        workerContext->stopActiveDOMObjects();

        // Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects,
        // which become dangling once Heap is destroyed.
        workerContext->removeAllEventListeners();

#if ENABLE(DATABASE)
        // We wait for the database thread to clean up all its stuff so that we
        // can do more stringent leak checks as we exit.
        cleanupSync.waitForTaskCompletion();
#endif

        // Stick a shutdown command at the end of the queue, so that we deal
        // with all the cleanup tasks the databases post first.
        workerContext->postTask(WorkerThreadShutdownFinishTask::create());
    }
v8::Handle<v8::Value> V8WorkerContext::importScriptsCallback(const v8::Arguments& args)
{
    INC_STATS(L"DOM.WorkerContext.importScripts()");
    if (!args.Length())
        return v8::Undefined();

    Vector<String> urls;
    for (int i = 0; i < args.Length(); i++) {
        v8::TryCatch tryCatch;
        v8::Handle<v8::String> scriptUrl = args[i]->ToString();
        if (tryCatch.HasCaught() || scriptUrl.IsEmpty())
            return v8::Undefined();
        urls.append(toWebCoreString(scriptUrl));
    }

    WorkerContext* workerContext = V8WorkerContext::toNative(args.Holder());

    ExceptionCode ec = 0;
    workerContext->importScripts(urls, ec);

    if (ec)
        return throwError(ec);

    return v8::Undefined();
}
v8::Handle<v8::Value> V8WorkerContext::importScriptsCallback(const v8::Arguments& args)
{
    INC_STATS(L"DOM.WorkerContext.importScripts()");
    if (!args.Length())
        return v8::Undefined();

    String callerURL;
    if (!V8Proxy::sourceName(callerURL))
        return v8::Undefined();
    int callerLine;
    if (!V8Proxy::sourceLineNumber(callerLine))
        return v8::Undefined();
    callerLine += 1;

    Vector<String> urls;
    for (int i = 0; i < args.Length(); i++) {
        v8::TryCatch tryCatch;
        v8::Handle<v8::String> scriptUrl = args[i]->ToString();
        if (tryCatch.HasCaught() || scriptUrl.IsEmpty())
            return v8::Undefined();
        urls.append(toWebCoreString(scriptUrl));
    }

    WorkerContext* workerContext = V8DOMWrapper::convertDOMWrapperToNative<WorkerContext>(args.Holder());

    ExceptionCode ec = 0;
    workerContext->importScripts(urls, callerURL, callerLine, ec);

    if (ec)
        return throwError(ec);

    return v8::Undefined();
}
v8::Handle<v8::Value> SetTimeoutOrInterval(const v8::Arguments& args, bool singleShot)
{
    WorkerContext* workerContext = V8DOMWrapper::convertDOMWrapperToNative<WorkerContext>(args.Holder());

    int argumentCount = args.Length();
    if (argumentCount < 1)
        return v8::Undefined();

    v8::Handle<v8::Value> function = args[0];
    int32_t timeout = argumentCount >= 2 ? args[1]->Int32Value() : 0;
    int timerId;

    v8::Handle<v8::Context> v8Context = workerContext->script()->proxy()->context();
    if (function->IsString()) {
        WebCore::String stringFunction = toWebCoreString(function);
        timerId = DOMTimer::install(workerContext, new ScheduledAction(v8Context, stringFunction, workerContext->url()), timeout, singleShot);
    } else if (function->IsFunction()) {
        size_t paramCount = argumentCount >= 2 ? argumentCount - 2 : 0;
        v8::Local<v8::Value>* params = 0;
        if (paramCount > 0) {
            params = new v8::Local<v8::Value>[paramCount];
            for (size_t i = 0; i < paramCount; ++i)
                params[i] = args[i+2];
        }
        // ScheduledAction takes ownership of actual params and releases them in its destructor.
        ScheduledAction* action = new ScheduledAction(v8Context, v8::Handle<v8::Function>::Cast(function), paramCount, params);
        delete [] params;
        timerId = DOMTimer::install(workerContext, action, timeout, singleShot);
    } else
        return v8::Undefined();

    return v8::Integer::New(timerId);
}
Example #10
0
 virtual void performTask(ScriptExecutionContext *context)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(context->isWorkerContext());
     WorkerContext* workerContext = static_cast<WorkerContext*>(context);
     // Notify parent that this context is closed. Parent is responsible for calling WorkerThread::stop().
     workerContext->thread()->workerReportingProxy().workerContextClosed();
 }
Example #11
0
    virtual void performTask(ScriptExecutionContext *context)
    {
        ASSERT(context->isWorkerContext());
        WorkerContext* workerContext = static_cast<WorkerContext*>(context);

#if ENABLE(SQL_DATABASE)
        // FIXME: Should we stop the databases as part of stopActiveDOMObjects() below?
        DatabaseTaskSynchronizer cleanupSync;
        DatabaseManager::manager().stopDatabases(workerContext, &cleanupSync);
#endif

        workerContext->stopActiveDOMObjects();

        workerContext->notifyObserversOfStop();

        // Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects,
        // which become dangling once Heap is destroyed.
        workerContext->removeAllEventListeners();

#if ENABLE(SQL_DATABASE)
        // We wait for the database thread to clean up all its stuff so that we
        // can do more stringent leak checks as we exit.
        cleanupSync.waitForTaskCompletion();
#endif

        // Stick a shutdown command at the end of the queue, so that we deal
        // with all the cleanup tasks the databases post first.
        workerContext->postTask(WorkerThreadShutdownFinishTask::create());
    }
static v8::Handle<v8::Value> clearIntervalCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.WorkerContext.clearInterval");
    WorkerContext* imp = V8WorkerContext::toNative(args.Holder());
    EXCEPTION_BLOCK(int, handle, toInt32(args[0]));
    imp->clearInterval(handle);
    return v8::Handle<v8::Value>();
}
 virtual void performTask(ScriptExecutionContext *context)
 {
     ASSERT(context->isWorkerContext());
     WorkerContext* workerContext = static_cast<WorkerContext*>(context);
     // It's not safe to call clearScript until all the cleanup tasks posted by functions initiated by WorkerThreadShutdownStartTask have completed.
     workerContext->clearScript();
     workerContext->thread()->runLoop().terminate();
 }
static void onerrorAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
{
    INC_STATS("DOM.WorkerContext.onerror._set");
    WorkerContext* imp = V8WorkerContext::toNative(info.Holder());
    transferHiddenDependency(info.Holder(), imp->onerror(), value, V8WorkerContext::eventListenerCacheIndex);
    imp->setOnerror(V8EventListenerList::findOrCreateWrapper<V8WorkerContextErrorHandler>(value, true));
    return;
}
 virtual void performTask(ScriptExecutionContext* scriptContext)
 {
     RefPtr<MessagePort> port = MessagePort::create(*scriptContext);
     port->entangle(m_channel.release());
     ASSERT(scriptContext->isWorkerContext());
     WorkerContext* workerContext = static_cast<WorkerContext*>(scriptContext);
     ASSERT(workerContext->isSharedWorkerContext());
     workerContext->toSharedWorkerContext()->dispatchConnect(port);
 }
bool WorkerFileWriterCallbacksBridge::waitForOperationToComplete()
{
    while (m_operationInProgress) {
        WorkerContext* context = static_cast<WorkerContext*>(m_workerContext);
        if (context->thread()->runLoop().runInMode(context, m_mode) == MessageQueueTerminated)
            return false;
    }
    return true;
}
Example #17
0
    virtual void performTask(ScriptExecutionContext *context)
    {
        ASSERT(context->isWorkerContext());
        WorkerContext* workerContext = static_cast<WorkerContext*>(context);
#if ENABLE(INSPECTOR)
        workerContext->clearInspector();
#endif
        // It's not safe to call clearScript until all the cleanup tasks posted by functions initiated by WorkerThreadShutdownStartTask have completed.
        workerContext->clearScript();
    }
Example #18
0
void WebSharedWorkerImpl::connectTask(ScriptExecutionContext* context, PassOwnPtr<MessagePortChannel> channel)
{
    // Wrap the passed-in channel in a MessagePort, and send it off via a connect event.
    RefPtr<MessagePort> port = MessagePort::create(*context);
    port->entangle(channel);
    ASSERT(context->isWorkerContext());
    WorkerContext* workerContext = static_cast<WorkerContext*>(context);
    ASSERT(workerContext->isSharedWorkerContext());
    workerContext->dispatchEvent(createConnectEvent(port));
}
Example #19
0
JSValue jsWorkerContextOnmessage(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
    UNUSED_PARAM(exec);
    WorkerContext* imp = static_cast<WorkerContext*>(static_cast<JSWorkerContext*>(asObject(slot.slotBase()))->impl());
    if (EventListener* listener = imp->onmessage()) {
        if (JSObject* jsFunction = listener->jsFunction())
            return jsFunction;
    }
    return jsNull();
}
 virtual void performTask(ScriptExecutionContext* scriptContext)
 {
     RefPtr<MessagePort> port = MessagePort::create(*scriptContext);
     port->entangle(m_channel.release());
     ASSERT(scriptContext->isWorkerContext());
     WorkerContext* workerContext = static_cast<WorkerContext*>(scriptContext);
     // Since close() stops the thread event loop, this should not ever get called while closing.
     ASSERT(!workerContext->isClosing());
     ASSERT(workerContext->isSharedWorkerContext());
     workerContext->toSharedWorkerContext()->dispatchEvent(createConnectEvent(port));
 }
Example #21
0
void MemoryCache::removeRequestFromCache(ScriptExecutionContext* context, const ResourceRequest& request)
{
#if ENABLE(WORKERS)
    if (context->isWorkerContext()) {
        WorkerContext* workerContext = static_cast<WorkerContext*>(context);
        workerContext->thread()->workerLoaderProxy().postTaskToLoader(createCallbackTask(&crossThreadRemoveRequestFromCache, request));
        return;
    }
#endif

    removeRequestFromCacheImpl(context, request);
}
Example #22
0
JSValue JSC_HOST_CALL jsWorkerContextPrototypeFunctionClearInterval(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.isObject(&JSWorkerContext::s_info))
        return throwError(exec, TypeError);
    JSWorkerContext* castedThisObj = static_cast<JSWorkerContext*>(asObject(thisValue));
    WorkerContext* imp = static_cast<WorkerContext*>(castedThisObj->impl());
    int handle = args.at(0).toInt32(exec);

    imp->clearInterval(handle);
    return jsUndefined();
}
Example #23
0
JSValue JSC_HOST_CALL jsWorkerContextPrototypeFunctionPostMessage(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.isObject(&JSWorkerContext::s_info))
        return throwError(exec, TypeError);
    JSWorkerContext* castedThisObj = static_cast<JSWorkerContext*>(asObject(thisValue));
    WorkerContext* imp = static_cast<WorkerContext*>(castedThisObj->impl());
    const UString& message = args.at(0).toString(exec);

    imp->postMessage(message);
    return jsUndefined();
}
static v8::Handle<v8::Value> navigatorAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
{
    INC_STATS("DOM.WorkerContext.navigator._get");
    WorkerContext* imp = V8WorkerContext::toNative(info.Holder());
    RefPtr<WorkerNavigator> result = imp->navigator();
    v8::Handle<v8::Value> wrapper = result.get() ? getDOMObjectMap().get(result.get()) : v8::Handle<v8::Value>();
    if (wrapper.IsEmpty()) {
        wrapper = toV8(result.get());
        if (!wrapper.IsEmpty())
            V8DOMWrapper::setHiddenReference(info.Holder(), wrapper);
    }
    return wrapper;
}
WorkerContextExecutionProxy* WorkerContextExecutionProxy::retrieve()
{
    // Happens on frame destruction, check otherwise GetCurrent() will crash.
    if (!v8::Context::InContext())
        return 0;
    v8::Handle<v8::Context> context = v8::Context::GetCurrent();
    v8::Handle<v8::Object> global = context->Global();
    global = V8DOMWrapper::lookupDOMWrapper(V8WorkerContext::GetTemplate(), global);
    // Return 0 if the current executing context is not the worker context.
    if (global.IsEmpty())
        return 0;
    WorkerContext* workerContext = V8WorkerContext::toNative(global);
    return workerContext->script()->proxy();
}
Example #26
0
WorkerScriptController* WorkerScriptController::controllerForContext()
{
    // Happens on frame destruction, check otherwise GetCurrent() will crash.
    if (!v8::Context::InContext())
        return 0;
    v8::Handle<v8::Context> context = v8::Context::GetCurrent();
    v8::Handle<v8::Object> global = context->Global();
    global = global->FindInstanceInPrototypeChain(V8WorkerContext::GetTemplate());
    // Return 0 if the current executing context is not the worker context.
    if (global.IsEmpty())
        return 0;
    WorkerContext* workerContext = V8WorkerContext::toNative(global);
    return workerContext->script();
}
v8::Handle<v8::Value> V8WorkerContext::removeEventListenerCallback(const v8::Arguments& args)
{
    INC_STATS(L"DOM.WorkerContext.removeEventListener()");
    WorkerContext* workerContext = V8DOMWrapper::convertDOMWrapperToNative<WorkerContext>(args.Holder());

    RefPtr<EventListener> listener = V8DOMWrapper::getEventListener(workerContext, args[1], false, ListenerFindOnly);
    if (listener) {
        String type = toWebCoreString(args[0]);
        bool useCapture = args[2]->BooleanValue();
        workerContext->removeEventListener(type, listener.get(), useCapture);

        removeHiddenDependency(args.Holder(), args[1], V8Custom::kWorkerContextRequestCacheIndex);
    }
    return v8::Undefined();
}
Example #28
0
JSValue JSC_HOST_CALL jsWorkerContextPrototypeFunctionDispatchEvent(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.isObject(&JSWorkerContext::s_info))
        return throwError(exec, TypeError);
    JSWorkerContext* castedThisObj = static_cast<JSWorkerContext*>(asObject(thisValue));
    WorkerContext* imp = static_cast<WorkerContext*>(castedThisObj->impl());
    ExceptionCode ec = 0;
    Event* evt = toEvent(args.at(0));


    JSC::JSValue result = jsBoolean(imp->dispatchEvent(evt, ec));
    setDOMException(exec, ec);
    return result;
}
static v8::Handle<v8::Value> dispatchEventCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.WorkerContext.dispatchEvent");
    WorkerContext* imp = V8WorkerContext::toNative(args.Holder());
    ExceptionCode ec = 0;
    {
    EXCEPTION_BLOCK(Event*, evt, V8Event::HasInstance(args[0]) ? V8Event::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0);
    bool result = imp->dispatchEvent(evt, ec);
    if (UNLIKELY(ec))
        goto fail;
    return v8Boolean(result);
    }
    fail:
    V8Proxy::setDOMException(ec);
    return v8::Handle<v8::Value>();
}
PassRefPtr<ThreadableWebSocketChannel> ThreadableWebSocketChannel::create(ScriptExecutionContext* context, WebSocketChannelClient* client)
{
    ASSERT(context);
    ASSERT(client);

#if ENABLE(WORKERS)
    if (context->isWorkerContext()) {
        WorkerContext* workerContext = static_cast<WorkerContext*>(context);
        WorkerRunLoop& runLoop = workerContext->thread()->runLoop();
        String mode = webSocketChannelMode;
        mode.append(String::number(runLoop.createUniqueId()));
        return WorkerThreadableWebSocketChannel::create(workerContext, client, mode);
    }
#endif // ENABLE(WORKERS)

    return WebSocketChannel::create(toDocument(context), client);
}