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>(); }
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)); }
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; }
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); }
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(); }
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; }
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(); }
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)); }
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)); }
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); }
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(); }
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(); }
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(); }
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); }