LCOV - code coverage report
Current view: top level - dom/workers - WorkerScope.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 53 498 10.6 %
Date: 2017-07-14 16:53:18 Functions: 9 102 8.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "WorkerScope.h"
       8             : 
       9             : #include "jsapi.h"
      10             : #include "mozilla/EventListenerManager.h"
      11             : #include "mozilla/dom/BindingDeclarations.h"
      12             : #include "mozilla/dom/Console.h"
      13             : #include "mozilla/dom/DedicatedWorkerGlobalScopeBinding.h"
      14             : #include "mozilla/dom/Fetch.h"
      15             : #include "mozilla/dom/FunctionBinding.h"
      16             : #include "mozilla/dom/IDBFactory.h"
      17             : #include "mozilla/dom/ImageBitmap.h"
      18             : #include "mozilla/dom/ImageBitmapBinding.h"
      19             : #include "mozilla/dom/Performance.h"
      20             : #include "mozilla/dom/Promise.h"
      21             : #include "mozilla/dom/PromiseWorkerProxy.h"
      22             : #include "mozilla/dom/ServiceWorkerGlobalScopeBinding.h"
      23             : #include "mozilla/dom/SharedWorkerGlobalScopeBinding.h"
      24             : #include "mozilla/dom/SimpleGlobalObject.h"
      25             : #include "mozilla/dom/WorkerDebuggerGlobalScopeBinding.h"
      26             : #include "mozilla/dom/WorkerGlobalScopeBinding.h"
      27             : #include "mozilla/dom/WorkerLocation.h"
      28             : #include "mozilla/dom/WorkerNavigator.h"
      29             : #include "mozilla/dom/cache/CacheStorage.h"
      30             : #include "mozilla/Services.h"
      31             : #include "nsServiceManagerUtils.h"
      32             : 
      33             : #include "nsIDocument.h"
      34             : #include "nsIServiceWorkerManager.h"
      35             : #include "nsIScriptTimeoutHandler.h"
      36             : 
      37             : #ifdef ANDROID
      38             : #include <android/log.h>
      39             : #endif
      40             : 
      41             : #include "Crypto.h"
      42             : #include "Principal.h"
      43             : #include "RuntimeService.h"
      44             : #include "ScriptLoader.h"
      45             : #include "WorkerPrivate.h"
      46             : #include "WorkerRunnable.h"
      47             : #include "ServiceWorkerClients.h"
      48             : #include "ServiceWorkerManager.h"
      49             : #include "ServiceWorkerRegistration.h"
      50             : 
      51             : #ifdef XP_WIN
      52             : #undef PostMessage
      53             : #endif
      54             : 
      55             : extern already_AddRefed<nsIScriptTimeoutHandler>
      56             : NS_CreateJSTimeoutHandler(JSContext* aCx,
      57             :                           mozilla::dom::workers::WorkerPrivate* aWorkerPrivate,
      58             :                           mozilla::dom::Function& aFunction,
      59             :                           const mozilla::dom::Sequence<JS::Value>& aArguments,
      60             :                           mozilla::ErrorResult& aError);
      61             : 
      62             : extern already_AddRefed<nsIScriptTimeoutHandler>
      63             : NS_CreateJSTimeoutHandler(JSContext* aCx,
      64             :                           mozilla::dom::workers::WorkerPrivate* aWorkerPrivate,
      65             :                           const nsAString& aExpression);
      66             : 
      67             : using namespace mozilla;
      68             : using namespace mozilla::dom;
      69             : USING_WORKERS_NAMESPACE
      70             : 
      71             : using mozilla::dom::cache::CacheStorage;
      72             : using mozilla::ipc::PrincipalInfo;
      73             : 
      74           1 : WorkerGlobalScope::WorkerGlobalScope(WorkerPrivate* aWorkerPrivate)
      75           2 : : mSerialEventTarget(aWorkerPrivate->GetEventTarget())
      76             : , mWindowInteractionsAllowed(0)
      77           3 : , mWorkerPrivate(aWorkerPrivate)
      78             : {
      79           1 :   mWorkerPrivate->AssertIsOnWorkerThread();
      80             : 
      81             :   // We should always have an event target when the global is created.
      82           1 :   MOZ_DIAGNOSTIC_ASSERT(mSerialEventTarget);
      83           1 : }
      84             : 
      85           0 : WorkerGlobalScope::~WorkerGlobalScope()
      86             : {
      87           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
      88           0 : }
      89             : 
      90             : NS_IMPL_CYCLE_COLLECTION_CLASS(WorkerGlobalScope)
      91             : 
      92           1 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(WorkerGlobalScope,
      93             :                                                   DOMEventTargetHelper)
      94           1 :   tmp->mWorkerPrivate->AssertIsOnWorkerThread();
      95           1 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsole)
      96           1 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCrypto)
      97           1 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPerformance)
      98           1 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocation)
      99           1 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNavigator)
     100           1 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIndexedDB)
     101           1 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheStorage)
     102           1 :   tmp->TraverseHostObjectURIs(cb);
     103           1 :   tmp->mWorkerPrivate->TraverseTimeouts(cb);
     104           1 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     105             : 
     106           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(WorkerGlobalScope,
     107             :                                                 DOMEventTargetHelper)
     108           0 :   tmp->mWorkerPrivate->AssertIsOnWorkerThread();
     109           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsole)
     110           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mCrypto)
     111           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mPerformance)
     112           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocation)
     113           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigator)
     114           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mIndexedDB)
     115           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheStorage)
     116           0 :   tmp->UnlinkHostObjectURIs();
     117           0 :   tmp->mWorkerPrivate->UnlinkTimeouts();
     118           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     119             : 
     120           2 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(WorkerGlobalScope,
     121             :                                                DOMEventTargetHelper)
     122           2 :   tmp->mWorkerPrivate->AssertIsOnWorkerThread();
     123           2 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
     124             : 
     125         239 : NS_IMPL_ADDREF_INHERITED(WorkerGlobalScope, DOMEventTargetHelper)
     126         231 : NS_IMPL_RELEASE_INHERITED(WorkerGlobalScope, DOMEventTargetHelper)
     127             : 
     128         151 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WorkerGlobalScope)
     129         136 :   NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
     130           1 :   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
     131           1 : NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
     132             : 
     133             : JSObject*
     134           0 : WorkerGlobalScope::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
     135             : {
     136           0 :   MOZ_CRASH("We should never get here!");
     137             : }
     138             : 
     139             : Console*
     140           0 : WorkerGlobalScope::GetConsole(ErrorResult& aRv)
     141             : {
     142           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     143             : 
     144           0 :   if (!mConsole) {
     145           0 :     mConsole = Console::Create(nullptr, aRv);
     146           0 :     if (NS_WARN_IF(aRv.Failed())) {
     147           0 :       return nullptr;
     148             :     }
     149             :   }
     150             : 
     151           0 :   return mConsole;
     152             : }
     153             : 
     154             : Crypto*
     155           0 : WorkerGlobalScope::GetCrypto(ErrorResult& aError)
     156             : {
     157           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     158             : 
     159           0 :   if (!mCrypto) {
     160           0 :     mCrypto = new Crypto();
     161           0 :     mCrypto->Init(this);
     162             :   }
     163             : 
     164           0 :   return mCrypto;
     165             : }
     166             : 
     167             : already_AddRefed<CacheStorage>
     168           0 : WorkerGlobalScope::GetCaches(ErrorResult& aRv)
     169             : {
     170           0 :   if (!mCacheStorage) {
     171           0 :     MOZ_ASSERT(mWorkerPrivate);
     172           0 :     mCacheStorage = CacheStorage::CreateOnWorker(cache::DEFAULT_NAMESPACE, this,
     173           0 :                                                  mWorkerPrivate, aRv);
     174             :   }
     175             : 
     176           0 :   RefPtr<CacheStorage> ref = mCacheStorage;
     177           0 :   return ref.forget();
     178             : }
     179             : 
     180             : bool
     181           0 : WorkerGlobalScope::IsSecureContext() const
     182             : {
     183             :   bool globalSecure =
     184           0 :     JS_GetIsSecureContext(js::GetObjectCompartment(GetWrapperPreserveColor()));
     185           0 :   MOZ_ASSERT(globalSecure == mWorkerPrivate->IsSecureContext());
     186           0 :   return globalSecure;
     187             : }
     188             : 
     189             : already_AddRefed<WorkerLocation>
     190           0 : WorkerGlobalScope::Location()
     191             : {
     192           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     193             : 
     194           0 :   if (!mLocation) {
     195           0 :     WorkerPrivate::LocationInfo& info = mWorkerPrivate->GetLocationInfo();
     196             : 
     197           0 :     mLocation = WorkerLocation::Create(info);
     198           0 :     MOZ_ASSERT(mLocation);
     199             :   }
     200             : 
     201           0 :   RefPtr<WorkerLocation> location = mLocation;
     202           0 :   return location.forget();
     203             : }
     204             : 
     205             : already_AddRefed<WorkerNavigator>
     206           0 : WorkerGlobalScope::Navigator()
     207             : {
     208           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     209             : 
     210           0 :   if (!mNavigator) {
     211           0 :     mNavigator = WorkerNavigator::Create(mWorkerPrivate->OnLine());
     212           0 :     MOZ_ASSERT(mNavigator);
     213             :   }
     214             : 
     215           0 :   RefPtr<WorkerNavigator> navigator = mNavigator;
     216           0 :   return navigator.forget();
     217             : }
     218             : 
     219             : already_AddRefed<WorkerNavigator>
     220           0 : WorkerGlobalScope::GetExistingNavigator() const
     221             : {
     222           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     223             : 
     224           0 :   RefPtr<WorkerNavigator> navigator = mNavigator;
     225           0 :   return navigator.forget();
     226             : }
     227             : 
     228             : OnErrorEventHandlerNonNull*
     229           0 : WorkerGlobalScope::GetOnerror()
     230             : {
     231           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     232             : 
     233           0 :   EventListenerManager* elm = GetExistingListenerManager();
     234           0 :   return elm ? elm->GetOnErrorEventHandler() : nullptr;
     235             : }
     236             : 
     237             : void
     238           0 : WorkerGlobalScope::SetOnerror(OnErrorEventHandlerNonNull* aHandler)
     239             : {
     240           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     241             : 
     242           0 :   EventListenerManager* elm = GetOrCreateListenerManager();
     243           0 :   if (elm) {
     244           0 :     elm->SetEventHandler(aHandler);
     245             :   }
     246           0 : }
     247             : 
     248             : void
     249           4 : WorkerGlobalScope::ImportScripts(const Sequence<nsString>& aScriptURLs,
     250             :                                  ErrorResult& aRv)
     251             : {
     252           4 :   mWorkerPrivate->AssertIsOnWorkerThread();
     253           4 :   scriptloader::Load(mWorkerPrivate, aScriptURLs, WorkerScript, aRv);
     254           2 : }
     255             : 
     256             : int32_t
     257           0 : WorkerGlobalScope::SetTimeout(JSContext* aCx,
     258             :                               Function& aHandler,
     259             :                               const int32_t aTimeout,
     260             :                               const Sequence<JS::Value>& aArguments,
     261             :                               ErrorResult& aRv)
     262             : {
     263           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     264             : 
     265             :   nsCOMPtr<nsIScriptTimeoutHandler> handler =
     266           0 :     NS_CreateJSTimeoutHandler(aCx, mWorkerPrivate, aHandler, aArguments, aRv);
     267           0 :   if (NS_WARN_IF(aRv.Failed())) {
     268           0 :     return 0;
     269             :   }
     270             : 
     271           0 :   return mWorkerPrivate->SetTimeout(aCx, handler, aTimeout, false, aRv);
     272             : }
     273             : 
     274             : int32_t
     275           0 : WorkerGlobalScope::SetTimeout(JSContext* aCx,
     276             :                               const nsAString& aHandler,
     277             :                               const int32_t aTimeout,
     278             :                               const Sequence<JS::Value>& /* unused */,
     279             :                               ErrorResult& aRv)
     280             : {
     281           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     282             : 
     283             :   nsCOMPtr<nsIScriptTimeoutHandler> handler =
     284           0 :     NS_CreateJSTimeoutHandler(aCx, mWorkerPrivate, aHandler);
     285           0 :   return mWorkerPrivate->SetTimeout(aCx, handler, aTimeout, false, aRv);
     286             : }
     287             : 
     288             : void
     289           0 : WorkerGlobalScope::ClearTimeout(int32_t aHandle)
     290             : {
     291           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     292           0 :   mWorkerPrivate->ClearTimeout(aHandle);
     293           0 : }
     294             : 
     295             : int32_t
     296           0 : WorkerGlobalScope::SetInterval(JSContext* aCx,
     297             :                                Function& aHandler,
     298             :                                const Optional<int32_t>& aTimeout,
     299             :                                const Sequence<JS::Value>& aArguments,
     300             :                                ErrorResult& aRv)
     301             : {
     302           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     303             : 
     304           0 :   bool isInterval = aTimeout.WasPassed();
     305           0 :   int32_t timeout = aTimeout.WasPassed() ? aTimeout.Value() : 0;
     306             : 
     307             :   nsCOMPtr<nsIScriptTimeoutHandler> handler =
     308           0 :     NS_CreateJSTimeoutHandler(aCx, mWorkerPrivate, aHandler, aArguments, aRv);
     309           0 :   if (NS_WARN_IF(aRv.Failed())) {
     310           0 :     return 0;
     311             :   }
     312             : 
     313           0 :   return mWorkerPrivate->SetTimeout(aCx, handler,  timeout, isInterval, aRv);
     314             : }
     315             : 
     316             : int32_t
     317           0 : WorkerGlobalScope::SetInterval(JSContext* aCx,
     318             :                                const nsAString& aHandler,
     319             :                                const Optional<int32_t>& aTimeout,
     320             :                                const Sequence<JS::Value>& /* unused */,
     321             :                                ErrorResult& aRv)
     322             : {
     323           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     324             : 
     325           0 :   Sequence<JS::Value> dummy;
     326             : 
     327           0 :   bool isInterval = aTimeout.WasPassed();
     328           0 :   int32_t timeout = aTimeout.WasPassed() ? aTimeout.Value() : 0;
     329             : 
     330             :   nsCOMPtr<nsIScriptTimeoutHandler> handler =
     331           0 :     NS_CreateJSTimeoutHandler(aCx, mWorkerPrivate, aHandler);
     332           0 :   return mWorkerPrivate->SetTimeout(aCx, handler, timeout, isInterval, aRv);
     333             : }
     334             : 
     335             : void
     336           0 : WorkerGlobalScope::ClearInterval(int32_t aHandle)
     337             : {
     338           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     339           0 :   mWorkerPrivate->ClearTimeout(aHandle);
     340           0 : }
     341             : 
     342             : void
     343           0 : WorkerGlobalScope::GetOrigin(nsAString& aOrigin) const
     344             : {
     345           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     346           0 :   aOrigin = mWorkerPrivate->Origin();
     347           0 : }
     348             : 
     349             : void
     350           0 : WorkerGlobalScope::Atob(const nsAString& aAtob, nsAString& aOutput, ErrorResult& aRv) const
     351             : {
     352           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     353           0 :   aRv = nsContentUtils::Atob(aAtob, aOutput);
     354           0 : }
     355             : 
     356             : void
     357           0 : WorkerGlobalScope::Btoa(const nsAString& aBtoa, nsAString& aOutput, ErrorResult& aRv) const
     358             : {
     359           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     360           0 :   aRv = nsContentUtils::Btoa(aBtoa, aOutput);
     361           0 : }
     362             : 
     363             : void
     364           0 : WorkerGlobalScope::Dump(const Optional<nsAString>& aString) const
     365             : {
     366           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     367             : 
     368           0 :   if (!aString.WasPassed()) {
     369           0 :     return;
     370             :   }
     371             : 
     372             : #if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
     373             :   if (!mWorkerPrivate->DumpEnabled()) {
     374             :     return;
     375             :   }
     376             : #endif
     377             : 
     378           0 :   NS_ConvertUTF16toUTF8 str(aString.Value());
     379             : 
     380           0 :   MOZ_LOG(nsContentUtils::DOMDumpLog(), LogLevel::Debug, ("[Worker.Dump] %s", str.get()));
     381             : #ifdef ANDROID
     382             :   __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", str.get());
     383             : #endif
     384           0 :   fputs(str.get(), stdout);
     385           0 :   fflush(stdout);
     386             : }
     387             : 
     388             : Performance*
     389           0 : WorkerGlobalScope::GetPerformance()
     390             : {
     391           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     392             : 
     393           0 :   if (!mPerformance) {
     394           0 :     mPerformance = Performance::CreateForWorker(mWorkerPrivate);
     395             :   }
     396             : 
     397           0 :   return mPerformance;
     398             : }
     399             : 
     400             : already_AddRefed<Promise>
     401           0 : WorkerGlobalScope::Fetch(const RequestOrUSVString& aInput,
     402             :                          const RequestInit& aInit,
     403             :                          CallerType aCallerType, ErrorResult& aRv)
     404             : {
     405           0 :   return FetchRequest(this, aInput, aInit, aCallerType, aRv);
     406             : }
     407             : 
     408             : already_AddRefed<IDBFactory>
     409           0 : WorkerGlobalScope::GetIndexedDB(ErrorResult& aErrorResult)
     410             : {
     411           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     412             : 
     413           0 :   RefPtr<IDBFactory> indexedDB = mIndexedDB;
     414             : 
     415           0 :   if (!indexedDB) {
     416           0 :     if (!mWorkerPrivate->IsStorageAllowed()) {
     417           0 :       NS_WARNING("IndexedDB is not allowed in this worker!");
     418           0 :       aErrorResult = NS_ERROR_DOM_SECURITY_ERR;
     419           0 :       return nullptr;
     420             :     }
     421             : 
     422           0 :     JSContext* cx = mWorkerPrivate->GetJSContext();
     423           0 :     MOZ_ASSERT(cx);
     424             : 
     425           0 :     JS::Rooted<JSObject*> owningObject(cx, GetGlobalJSObject());
     426           0 :     MOZ_ASSERT(owningObject);
     427             : 
     428           0 :     const PrincipalInfo& principalInfo = mWorkerPrivate->GetPrincipalInfo();
     429             : 
     430             :     nsresult rv =
     431           0 :       IDBFactory::CreateForWorker(cx,
     432             :                                   owningObject,
     433             :                                   principalInfo,
     434           0 :                                   mWorkerPrivate->WindowID(),
     435           0 :                                   getter_AddRefs(indexedDB));
     436           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     437           0 :       aErrorResult = rv;
     438           0 :       return nullptr;
     439             :     }
     440             : 
     441           0 :     mIndexedDB = indexedDB;
     442             :   }
     443             : 
     444           0 :   return indexedDB.forget();
     445             : }
     446             : 
     447             : already_AddRefed<Promise>
     448           0 : WorkerGlobalScope::CreateImageBitmap(JSContext* aCx,
     449             :                                      const ImageBitmapSource& aImage,
     450             :                                      ErrorResult& aRv)
     451             : {
     452           0 :   if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
     453           0 :     aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
     454           0 :     return nullptr;
     455             :   }
     456             : 
     457           0 :   return ImageBitmap::Create(this, aImage, Nothing(), aRv);
     458             : }
     459             : 
     460             : already_AddRefed<Promise>
     461           0 : WorkerGlobalScope::CreateImageBitmap(JSContext* aCx,
     462             :                                      const ImageBitmapSource& aImage,
     463             :                                      int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
     464             :                                      ErrorResult& aRv)
     465             : {
     466           0 :   if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
     467           0 :     aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
     468           0 :     return nullptr;
     469             :   }
     470             : 
     471           0 :   return ImageBitmap::Create(this, aImage, Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aRv);
     472             : }
     473             : 
     474             : already_AddRefed<mozilla::dom::Promise>
     475           0 : WorkerGlobalScope::CreateImageBitmap(JSContext* aCx,
     476             :                                      const ImageBitmapSource& aImage,
     477             :                                      int32_t aOffset, int32_t aLength,
     478             :                                      ImageBitmapFormat aFormat,
     479             :                                      const Sequence<ChannelPixelLayout>& aLayout,
     480             :                                      ErrorResult& aRv)
     481             : {
     482           0 :   if (!ImageBitmap::ExtensionsEnabled(aCx)) {
     483           0 :     aRv.Throw(NS_ERROR_TYPE_ERR);
     484           0 :     return nullptr;
     485             :   }
     486             : 
     487           0 :   if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
     488             :     return ImageBitmap::Create(this, aImage, aOffset, aLength, aFormat, aLayout,
     489           0 :                                aRv);
     490             :   } else {
     491           0 :     aRv.Throw(NS_ERROR_TYPE_ERR);
     492           0 :     return nullptr;
     493             :   }
     494             : }
     495             : 
     496             : nsresult
     497           0 : WorkerGlobalScope::Dispatch(const char* aName, TaskCategory aCategory,
     498             :                             already_AddRefed<nsIRunnable>&& aRunnable)
     499             : {
     500           0 :   return EventTargetFor(aCategory)->Dispatch(Move(aRunnable),
     501           0 :                                              NS_DISPATCH_NORMAL);
     502             : }
     503             : 
     504             : nsISerialEventTarget*
     505           0 : WorkerGlobalScope::EventTargetFor(TaskCategory aCategory) const
     506             : {
     507           0 :   return mSerialEventTarget;
     508             : }
     509             : 
     510             : AbstractThread*
     511           0 : WorkerGlobalScope::AbstractMainThreadFor(TaskCategory aCategory)
     512             : {
     513           0 :   MOZ_CRASH("AbstractMainThreadFor not supported for workers.");
     514             : }
     515             : 
     516           1 : DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate,
     517           1 :                                                        const nsString& aName)
     518             :   : WorkerGlobalScope(aWorkerPrivate)
     519           1 :   , mName(aName)
     520             : {
     521           1 : }
     522             : 
     523             : bool
     524           1 : DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx,
     525             :                                              JS::MutableHandle<JSObject*> aReflector)
     526             : {
     527           1 :   mWorkerPrivate->AssertIsOnWorkerThread();
     528           1 :   MOZ_ASSERT(!mWorkerPrivate->IsSharedWorker());
     529             : 
     530           1 :   JS::CompartmentOptions options;
     531           1 :   mWorkerPrivate->CopyJSCompartmentOptions(options);
     532             : 
     533           1 :   const bool usesSystemPrincipal = mWorkerPrivate->UsesSystemPrincipal();
     534             : 
     535             :   // Note that xpc::ShouldDiscardSystemSource() and
     536             :   // xpc::ExtraWarningsForSystemJS() read prefs that are cached on the main
     537             :   // thread. This is benignly racey.
     538           2 :   const bool discardSource = usesSystemPrincipal &&
     539           2 :                              xpc::ShouldDiscardSystemSource();
     540           2 :   const bool extraWarnings = usesSystemPrincipal &&
     541           2 :                              xpc::ExtraWarningsForSystemJS();
     542             : 
     543           1 :   JS::CompartmentBehaviors& behaviors = options.behaviors();
     544           1 :   behaviors.setDiscardSource(discardSource)
     545           2 :            .extraWarningsOverride().set(extraWarnings);
     546             : 
     547           1 :   const bool sharedMemoryEnabled = xpc::SharedMemoryEnabled();
     548             : 
     549           1 :   JS::CompartmentCreationOptions& creationOptions = options.creationOptions();
     550           1 :   creationOptions.setSharedMemoryAndAtomicsEnabled(sharedMemoryEnabled);
     551             : 
     552           1 :   return DedicatedWorkerGlobalScopeBinding::Wrap(aCx, this, this,
     553             :                                                  options,
     554             :                                                  GetWorkerPrincipal(),
     555           1 :                                                  true, aReflector);
     556             : }
     557             : 
     558             : void
     559           0 : DedicatedWorkerGlobalScope::PostMessage(JSContext* aCx,
     560             :                                         JS::Handle<JS::Value> aMessage,
     561             :                                         const Sequence<JSObject*>& aTransferable,
     562             :                                         ErrorResult& aRv)
     563             : {
     564           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     565           0 :   mWorkerPrivate->PostMessageToParent(aCx, aMessage, aTransferable, aRv);
     566           0 : }
     567             : 
     568             : void
     569           0 : DedicatedWorkerGlobalScope::Close(JSContext* aCx)
     570             : {
     571           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     572           0 :   mWorkerPrivate->CloseInternal(aCx);
     573           0 : }
     574             : 
     575           0 : SharedWorkerGlobalScope::SharedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate,
     576           0 :                                                  const nsString& aName)
     577           0 : : WorkerGlobalScope(aWorkerPrivate), mName(aName)
     578             : {
     579           0 : }
     580             : 
     581             : bool
     582           0 : SharedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx,
     583             :                                           JS::MutableHandle<JSObject*> aReflector)
     584             : {
     585           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     586           0 :   MOZ_ASSERT(mWorkerPrivate->IsSharedWorker());
     587             : 
     588           0 :   JS::CompartmentOptions options;
     589           0 :   mWorkerPrivate->CopyJSCompartmentOptions(options);
     590             : 
     591           0 :   return SharedWorkerGlobalScopeBinding::Wrap(aCx, this, this, options,
     592             :                                               GetWorkerPrincipal(),
     593           0 :                                               true, aReflector);
     594             : }
     595             : 
     596             : void
     597           0 : SharedWorkerGlobalScope::Close(JSContext* aCx)
     598             : {
     599           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     600           0 :   mWorkerPrivate->CloseInternal(aCx);
     601           0 : }
     602             : 
     603           0 : NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerGlobalScope, WorkerGlobalScope,
     604             :                                    mClients, mRegistration)
     605           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorkerGlobalScope)
     606           0 : NS_INTERFACE_MAP_END_INHERITING(WorkerGlobalScope)
     607             : 
     608           0 : NS_IMPL_ADDREF_INHERITED(ServiceWorkerGlobalScope, WorkerGlobalScope)
     609           0 : NS_IMPL_RELEASE_INHERITED(ServiceWorkerGlobalScope, WorkerGlobalScope)
     610             : 
     611           0 : ServiceWorkerGlobalScope::ServiceWorkerGlobalScope(WorkerPrivate* aWorkerPrivate,
     612           0 :                                                    const nsACString& aScope)
     613             :   : WorkerGlobalScope(aWorkerPrivate),
     614           0 :     mScope(NS_ConvertUTF8toUTF16(aScope))
     615             : {
     616           0 : }
     617             : 
     618           0 : ServiceWorkerGlobalScope::~ServiceWorkerGlobalScope()
     619             : {
     620           0 : }
     621             : 
     622             : bool
     623           0 : ServiceWorkerGlobalScope::WrapGlobalObject(JSContext* aCx,
     624             :                                            JS::MutableHandle<JSObject*> aReflector)
     625             : {
     626           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     627           0 :   MOZ_ASSERT(mWorkerPrivate->IsServiceWorker());
     628             : 
     629           0 :   JS::CompartmentOptions options;
     630           0 :   mWorkerPrivate->CopyJSCompartmentOptions(options);
     631             : 
     632           0 :   return ServiceWorkerGlobalScopeBinding::Wrap(aCx, this, this, options,
     633             :                                                GetWorkerPrincipal(),
     634           0 :                                                true, aReflector);
     635             : }
     636             : 
     637             : ServiceWorkerClients*
     638           0 : ServiceWorkerGlobalScope::Clients()
     639             : {
     640           0 :   if (!mClients) {
     641           0 :     mClients = new ServiceWorkerClients(this);
     642             :   }
     643             : 
     644           0 :   return mClients;
     645             : }
     646             : 
     647             : ServiceWorkerRegistration*
     648           0 : ServiceWorkerGlobalScope::Registration()
     649             : {
     650           0 :   if (!mRegistration) {
     651             :     mRegistration =
     652           0 :       ServiceWorkerRegistration::CreateForWorker(mWorkerPrivate, mScope);
     653             :   }
     654             : 
     655           0 :   return mRegistration;
     656             : }
     657             : 
     658             : EventHandlerNonNull*
     659           0 : ServiceWorkerGlobalScope::GetOnfetch()
     660             : {
     661           0 :   MOZ_ASSERT(mWorkerPrivate);
     662           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     663             : 
     664           0 :   return GetEventHandler(nullptr, NS_LITERAL_STRING("fetch"));
     665             : }
     666             : 
     667             : namespace {
     668             : 
     669           0 : class ReportFetchListenerWarningRunnable final : public Runnable
     670             : {
     671             :   const nsCString mScope;
     672             :   nsCString mSourceSpec;
     673             :   uint32_t mLine;
     674             :   uint32_t mColumn;
     675             : 
     676             : public:
     677           0 :   explicit ReportFetchListenerWarningRunnable(const nsString& aScope)
     678           0 :     : mozilla::Runnable("ReportFetchListenerWarningRunnable")
     679           0 :     , mScope(NS_ConvertUTF16toUTF8(aScope))
     680             :   {
     681           0 :     WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
     682           0 :     MOZ_ASSERT(workerPrivate);
     683           0 :     JSContext* cx = workerPrivate->GetJSContext();
     684           0 :     MOZ_ASSERT(cx);
     685             : 
     686           0 :     nsJSUtils::GetCallingLocation(cx, mSourceSpec, &mLine, &mColumn);
     687           0 :   }
     688             : 
     689             :   NS_IMETHOD
     690           0 :   Run() override
     691             :   {
     692           0 :     AssertIsOnMainThread();
     693             : 
     694           0 :     ServiceWorkerManager::LocalizeAndReportToAllClients(mScope, "ServiceWorkerNoFetchHandler",
     695           0 :         nsTArray<nsString>{}, nsIScriptError::warningFlag, NS_ConvertUTF8toUTF16(mSourceSpec),
     696           0 :         EmptyString(), mLine, mColumn);
     697             : 
     698           0 :     return NS_OK;
     699             :   }
     700             : };
     701             : 
     702             : } // anonymous namespace
     703             : 
     704             : void
     705           0 : ServiceWorkerGlobalScope::SetOnfetch(mozilla::dom::EventHandlerNonNull* aCallback)
     706             : {
     707           0 :   MOZ_ASSERT(mWorkerPrivate);
     708           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     709             : 
     710           0 :   if (aCallback) {
     711           0 :     if (mWorkerPrivate->WorkerScriptExecutedSuccessfully()) {
     712           0 :       RefPtr<Runnable> r = new ReportFetchListenerWarningRunnable(mScope);
     713           0 :       mWorkerPrivate->DispatchToMainThread(r.forget());
     714             :     }
     715           0 :     mWorkerPrivate->SetFetchHandlerWasAdded();
     716             :   }
     717           0 :   SetEventHandler(nullptr, NS_LITERAL_STRING("fetch"), aCallback);
     718           0 : }
     719             : 
     720             : void
     721           0 : ServiceWorkerGlobalScope::AddEventListener(
     722             :                           const nsAString& aType,
     723             :                           dom::EventListener* aListener,
     724             :                           const dom::AddEventListenerOptionsOrBoolean& aOptions,
     725             :                           const dom::Nullable<bool>& aWantsUntrusted,
     726             :                           ErrorResult& aRv)
     727             : {
     728           0 :   MOZ_ASSERT(mWorkerPrivate);
     729           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     730             : 
     731           0 :   DOMEventTargetHelper::AddEventListener(aType, aListener, aOptions,
     732           0 :                                          aWantsUntrusted, aRv);
     733             : 
     734           0 :   if (!aType.EqualsLiteral("fetch")) {
     735           0 :     return;
     736             :   }
     737             : 
     738           0 :   if (mWorkerPrivate->WorkerScriptExecutedSuccessfully()) {
     739           0 :     RefPtr<Runnable> r = new ReportFetchListenerWarningRunnable(mScope);
     740           0 :     mWorkerPrivate->DispatchToMainThread(r.forget());
     741             :   }
     742             : 
     743           0 :   if (!aRv.Failed()) {
     744           0 :     mWorkerPrivate->SetFetchHandlerWasAdded();
     745             :   }
     746             : }
     747             : 
     748             : namespace {
     749             : 
     750           0 : class SkipWaitingResultRunnable final : public WorkerRunnable
     751             : {
     752             :   RefPtr<PromiseWorkerProxy> mPromiseProxy;
     753             : 
     754             : public:
     755           0 :   SkipWaitingResultRunnable(WorkerPrivate* aWorkerPrivate,
     756             :                             PromiseWorkerProxy* aPromiseProxy)
     757           0 :     : WorkerRunnable(aWorkerPrivate)
     758           0 :     , mPromiseProxy(aPromiseProxy)
     759             :   {
     760           0 :     AssertIsOnMainThread();
     761           0 :   }
     762             : 
     763             :   virtual bool
     764           0 :   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
     765             :   {
     766           0 :     MOZ_ASSERT(aWorkerPrivate);
     767           0 :     aWorkerPrivate->AssertIsOnWorkerThread();
     768             : 
     769           0 :     RefPtr<Promise> promise = mPromiseProxy->WorkerPromise();
     770           0 :     promise->MaybeResolveWithUndefined();
     771             : 
     772             :     // Release the reference on the worker thread.
     773           0 :     mPromiseProxy->CleanUp();
     774             : 
     775           0 :     return true;
     776             :   }
     777             : };
     778             : 
     779           0 : class WorkerScopeSkipWaitingRunnable final : public Runnable
     780             : {
     781             :   RefPtr<PromiseWorkerProxy> mPromiseProxy;
     782             :   nsCString mScope;
     783             : 
     784             : public:
     785           0 :   WorkerScopeSkipWaitingRunnable(PromiseWorkerProxy* aPromiseProxy,
     786             :                                  const nsCString& aScope)
     787           0 :     : mozilla::Runnable("WorkerScopeSkipWaitingRunnable")
     788             :     , mPromiseProxy(aPromiseProxy)
     789           0 :     , mScope(aScope)
     790             :   {
     791           0 :     MOZ_ASSERT(aPromiseProxy);
     792           0 :   }
     793             : 
     794             :   NS_IMETHOD
     795           0 :   Run() override
     796             :   {
     797           0 :     AssertIsOnMainThread();
     798             : 
     799           0 :     MutexAutoLock lock(mPromiseProxy->Lock());
     800           0 :     if (mPromiseProxy->CleanedUp()) {
     801           0 :       return NS_OK;
     802             :     }
     803             : 
     804           0 :     WorkerPrivate* workerPrivate = mPromiseProxy->GetWorkerPrivate();
     805           0 :     MOZ_DIAGNOSTIC_ASSERT(workerPrivate);
     806             : 
     807           0 :     RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
     808           0 :     if (swm) {
     809           0 :       swm->SetSkipWaitingFlag(workerPrivate->GetPrincipal(), mScope,
     810           0 :                               workerPrivate->ServiceWorkerID());
     811             :     }
     812             : 
     813             :     RefPtr<SkipWaitingResultRunnable> runnable =
     814           0 :       new SkipWaitingResultRunnable(workerPrivate, mPromiseProxy);
     815             : 
     816           0 :     if (!runnable->Dispatch()) {
     817           0 :       NS_WARNING("Failed to dispatch SkipWaitingResultRunnable to the worker.");
     818             :     }
     819           0 :     return NS_OK;
     820             :   }
     821             : };
     822             : 
     823             : } // namespace
     824             : 
     825             : already_AddRefed<Promise>
     826           0 : ServiceWorkerGlobalScope::SkipWaiting(ErrorResult& aRv)
     827             : {
     828           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     829           0 :   MOZ_ASSERT(mWorkerPrivate->IsServiceWorker());
     830             : 
     831           0 :   RefPtr<Promise> promise = Promise::Create(this, aRv);
     832           0 :   if (NS_WARN_IF(aRv.Failed())) {
     833           0 :     return nullptr;
     834             :   }
     835             : 
     836             :   RefPtr<PromiseWorkerProxy> promiseProxy =
     837           0 :     PromiseWorkerProxy::Create(mWorkerPrivate, promise);
     838           0 :   if (!promiseProxy) {
     839           0 :     promise->MaybeResolveWithUndefined();
     840           0 :     return promise.forget();
     841             :   }
     842             : 
     843             :   RefPtr<WorkerScopeSkipWaitingRunnable> runnable =
     844             :     new WorkerScopeSkipWaitingRunnable(promiseProxy,
     845           0 :                                        NS_ConvertUTF16toUTF8(mScope));
     846             : 
     847           0 :   MOZ_ALWAYS_SUCCEEDS(mWorkerPrivate->DispatchToMainThread(runnable.forget()));
     848           0 :   return promise.forget();
     849             : }
     850             : 
     851             : bool
     852           0 : ServiceWorkerGlobalScope::OpenWindowEnabled(JSContext* aCx, JSObject* aObj)
     853             : {
     854           0 :   WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
     855           0 :   MOZ_ASSERT(worker);
     856           0 :   worker->AssertIsOnWorkerThread();
     857           0 :   return worker->OpenWindowEnabled();
     858             : }
     859             : 
     860           0 : WorkerDebuggerGlobalScope::WorkerDebuggerGlobalScope(
     861           0 :                                                   WorkerPrivate* aWorkerPrivate)
     862             : : mWorkerPrivate(aWorkerPrivate)
     863           0 : , mSerialEventTarget(aWorkerPrivate->GetEventTarget())
     864             : {
     865           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     866             : 
     867             :   // We should always have an event target when the global is created.
     868           0 :   MOZ_DIAGNOSTIC_ASSERT(mSerialEventTarget);
     869           0 : }
     870             : 
     871           0 : WorkerDebuggerGlobalScope::~WorkerDebuggerGlobalScope()
     872             : {
     873           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     874           0 : }
     875             : 
     876             : NS_IMPL_CYCLE_COLLECTION_CLASS(WorkerDebuggerGlobalScope)
     877             : 
     878           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(WorkerDebuggerGlobalScope,
     879             :                                                   DOMEventTargetHelper)
     880           0 :   tmp->mWorkerPrivate->AssertIsOnWorkerThread();
     881           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsole)
     882           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     883             : 
     884           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(WorkerDebuggerGlobalScope,
     885             :                                                 DOMEventTargetHelper)
     886           0 :   tmp->mWorkerPrivate->AssertIsOnWorkerThread();
     887           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsole)
     888           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     889             : 
     890           0 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(WorkerDebuggerGlobalScope,
     891             :                                                DOMEventTargetHelper)
     892           0 :   tmp->mWorkerPrivate->AssertIsOnWorkerThread();
     893           0 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
     894             : 
     895           0 : NS_IMPL_ADDREF_INHERITED(WorkerDebuggerGlobalScope, DOMEventTargetHelper)
     896           0 : NS_IMPL_RELEASE_INHERITED(WorkerDebuggerGlobalScope, DOMEventTargetHelper)
     897             : 
     898           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WorkerDebuggerGlobalScope)
     899           0 :   NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
     900           0 : NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
     901             : 
     902             : bool
     903           0 : WorkerDebuggerGlobalScope::WrapGlobalObject(JSContext* aCx,
     904             :                                             JS::MutableHandle<JSObject*> aReflector)
     905             : {
     906           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     907             : 
     908           0 :   JS::CompartmentOptions options;
     909           0 :   mWorkerPrivate->CopyJSCompartmentOptions(options);
     910             : 
     911           0 :   return WorkerDebuggerGlobalScopeBinding::Wrap(aCx, this, this, options,
     912             :                                                 GetWorkerPrincipal(), true,
     913           0 :                                                 aReflector);
     914             : }
     915             : 
     916             : void
     917           0 : WorkerDebuggerGlobalScope::GetGlobal(JSContext* aCx,
     918             :                                      JS::MutableHandle<JSObject*> aGlobal,
     919             :                                      ErrorResult& aRv)
     920             : {
     921           0 :   WorkerGlobalScope* scope = mWorkerPrivate->GetOrCreateGlobalScope(aCx);
     922           0 :   if (!scope) {
     923           0 :     aRv.Throw(NS_ERROR_FAILURE);
     924           0 :     return;
     925             :   }
     926             : 
     927           0 :   aGlobal.set(scope->GetWrapper());
     928             : }
     929             : 
     930             : void
     931           0 : WorkerDebuggerGlobalScope::CreateSandbox(JSContext* aCx, const nsAString& aName,
     932             :                                          JS::Handle<JSObject*> aPrototype,
     933             :                                          JS::MutableHandle<JSObject*> aResult,
     934             :                                          ErrorResult& aRv)
     935             : {
     936           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     937             : 
     938           0 :   aResult.set(nullptr);
     939             : 
     940           0 :   JS::Rooted<JS::Value> protoVal(aCx);
     941           0 :   protoVal.setObjectOrNull(aPrototype);
     942             :   JS::Rooted<JSObject*> sandbox(aCx,
     943           0 :     SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::WorkerDebuggerSandbox,
     944           0 :                                protoVal));
     945             : 
     946           0 :   if (!sandbox) {
     947           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     948           0 :     return;
     949             :   }
     950             : 
     951           0 :   if (!JS_WrapObject(aCx, &sandbox)) {
     952           0 :     aRv.NoteJSContextException(aCx);
     953           0 :     return;
     954             :   }
     955             : 
     956           0 :   aResult.set(sandbox);
     957             : }
     958             : 
     959             : void
     960           0 : WorkerDebuggerGlobalScope::LoadSubScript(JSContext* aCx,
     961             :                                          const nsAString& aURL,
     962             :                                          const Optional<JS::Handle<JSObject*>>& aSandbox,
     963             :                                          ErrorResult& aRv)
     964             : {
     965           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
     966             : 
     967           0 :   Maybe<JSAutoCompartment> ac;
     968           0 :   if (aSandbox.WasPassed()) {
     969           0 :     JS::Rooted<JSObject*> sandbox(aCx, js::CheckedUnwrap(aSandbox.Value()));
     970           0 :     if (!IsDebuggerSandbox(sandbox)) {
     971           0 :       aRv.Throw(NS_ERROR_INVALID_ARG);
     972           0 :       return;
     973             :     }
     974             : 
     975           0 :     ac.emplace(aCx, sandbox);
     976             :   }
     977             : 
     978           0 :   nsTArray<nsString> urls;
     979           0 :   urls.AppendElement(aURL);
     980           0 :   scriptloader::Load(mWorkerPrivate, urls, DebuggerScript, aRv);
     981             : }
     982             : 
     983             : void
     984           0 : WorkerDebuggerGlobalScope::EnterEventLoop()
     985             : {
     986           0 :   mWorkerPrivate->EnterDebuggerEventLoop();
     987           0 : }
     988             : 
     989             : void
     990           0 : WorkerDebuggerGlobalScope::LeaveEventLoop()
     991             : {
     992           0 :   mWorkerPrivate->LeaveDebuggerEventLoop();
     993           0 : }
     994             : 
     995             : void
     996           0 : WorkerDebuggerGlobalScope::PostMessage(const nsAString& aMessage)
     997             : {
     998           0 :   mWorkerPrivate->PostMessageToDebugger(aMessage);
     999           0 : }
    1000             : 
    1001             : void
    1002           0 : WorkerDebuggerGlobalScope::SetImmediate(Function& aHandler, ErrorResult& aRv)
    1003             : {
    1004           0 :   mWorkerPrivate->SetDebuggerImmediate(aHandler, aRv);
    1005           0 : }
    1006             : 
    1007             : void
    1008           0 : WorkerDebuggerGlobalScope::ReportError(JSContext* aCx,
    1009             :                                        const nsAString& aMessage)
    1010             : {
    1011           0 :   JS::AutoFilename chars;
    1012           0 :   uint32_t lineno = 0;
    1013           0 :   JS::DescribeScriptedCaller(aCx, &chars, &lineno);
    1014           0 :   nsString filename(NS_ConvertUTF8toUTF16(chars.get()));
    1015           0 :   mWorkerPrivate->ReportErrorToDebugger(filename, lineno, aMessage);
    1016           0 : }
    1017             : 
    1018             : void
    1019           0 : WorkerDebuggerGlobalScope::RetrieveConsoleEvents(JSContext* aCx,
    1020             :                                                  nsTArray<JS::Value>& aEvents,
    1021             :                                                  ErrorResult& aRv)
    1022             : {
    1023           0 :   WorkerGlobalScope* scope = mWorkerPrivate->GetOrCreateGlobalScope(aCx);
    1024           0 :   if (!scope) {
    1025           0 :     aRv.Throw(NS_ERROR_FAILURE);
    1026           0 :     return;
    1027             :   }
    1028             : 
    1029           0 :   RefPtr<Console> console = scope->GetConsole(aRv);
    1030           0 :   if (NS_WARN_IF(aRv.Failed())) {
    1031           0 :     return;
    1032             :   }
    1033             : 
    1034           0 :   console->RetrieveConsoleEvents(aCx, aEvents, aRv);
    1035             : }
    1036             : 
    1037             : void
    1038           0 : WorkerDebuggerGlobalScope::SetConsoleEventHandler(JSContext* aCx,
    1039             :                                                   AnyCallback* aHandler,
    1040             :                                                   ErrorResult& aRv)
    1041             : {
    1042           0 :   WorkerGlobalScope* scope = mWorkerPrivate->GetOrCreateGlobalScope(aCx);
    1043           0 :   if (!scope) {
    1044           0 :     aRv.Throw(NS_ERROR_FAILURE);
    1045           0 :     return;
    1046             :   }
    1047             : 
    1048           0 :   RefPtr<Console> console = scope->GetConsole(aRv);
    1049           0 :   if (NS_WARN_IF(aRv.Failed())) {
    1050           0 :     return;
    1051             :   }
    1052             : 
    1053           0 :   console->SetConsoleEventHandler(aHandler);
    1054             : }
    1055             : 
    1056             : Console*
    1057           0 : WorkerDebuggerGlobalScope::GetConsole(ErrorResult& aRv)
    1058             : {
    1059           0 :   mWorkerPrivate->AssertIsOnWorkerThread();
    1060             : 
    1061             :   // Debugger console has its own console object.
    1062           0 :   if (!mConsole) {
    1063           0 :     mConsole = Console::Create(nullptr, aRv);
    1064           0 :     if (NS_WARN_IF(aRv.Failed())) {
    1065           0 :       return nullptr;
    1066             :     }
    1067             :   }
    1068             : 
    1069           0 :   return mConsole;
    1070             : }
    1071             : 
    1072             : void
    1073           0 : WorkerDebuggerGlobalScope::Dump(JSContext* aCx,
    1074             :                                 const Optional<nsAString>& aString) const
    1075             : {
    1076           0 :   WorkerGlobalScope* scope = mWorkerPrivate->GetOrCreateGlobalScope(aCx);
    1077           0 :   if (scope) {
    1078           0 :     scope->Dump(aString);
    1079             :   }
    1080           0 : }
    1081             : 
    1082             : nsresult
    1083           0 : WorkerDebuggerGlobalScope::Dispatch(const char* aName, TaskCategory aCategory,
    1084             :                                     already_AddRefed<nsIRunnable>&& aRunnable)
    1085             : {
    1086           0 :   return EventTargetFor(aCategory)->Dispatch(Move(aRunnable),
    1087           0 :                                              NS_DISPATCH_NORMAL);
    1088             : }
    1089             : 
    1090             : nsISerialEventTarget*
    1091           0 : WorkerDebuggerGlobalScope::EventTargetFor(TaskCategory aCategory) const
    1092             : {
    1093           0 :   return mSerialEventTarget;
    1094             : }
    1095             : 
    1096             : AbstractThread*
    1097           0 : WorkerDebuggerGlobalScope::AbstractMainThreadFor(TaskCategory aCategory)
    1098             : {
    1099           0 :   MOZ_CRASH("AbstractMainThreadFor not supported for workers.");
    1100             : }
    1101             : 
    1102             : BEGIN_WORKERS_NAMESPACE
    1103             : 
    1104             : bool
    1105           0 : IsWorkerGlobal(JSObject* object)
    1106             : {
    1107           0 :   return IS_INSTANCE_OF(WorkerGlobalScope, object);
    1108             : }
    1109             : 
    1110             : bool
    1111           0 : IsDebuggerGlobal(JSObject* object)
    1112             : {
    1113           0 :   return IS_INSTANCE_OF(WorkerDebuggerGlobalScope, object);
    1114             : }
    1115             : 
    1116             : bool
    1117           0 : IsDebuggerSandbox(JSObject* object)
    1118             : {
    1119           0 :   return SimpleGlobalObject::SimpleGlobalType(object) ==
    1120           0 :     SimpleGlobalObject::GlobalType::WorkerDebuggerSandbox;
    1121             : }
    1122             : 
    1123             : END_WORKERS_NAMESPACE

Generated by: LCOV version 1.13