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/. */
7 #include "ChromeWorker.h"
9 #include "mozilla/AppShutdown.h"
10 #include "mozilla/dom/BindingUtils.h"
11 #include "mozilla/dom/WorkerBinding.h"
12 #include "nsContentUtils.h"
13 #include "nsIXPConnect.h"
14 #include "WorkerPrivate.h"
16 namespace mozilla::dom
{
19 already_AddRefed
<ChromeWorker
> ChromeWorker::Constructor(
20 const GlobalObject
& aGlobal
, const nsAString
& aScriptURL
,
21 const WorkerOptions
& aOptions
, ErrorResult
& aRv
) {
22 // Dump the JS stack if somebody's creating a ChromeWorker after shutdown has
23 // begun. See bug 1813353.
24 if (xpc::IsInAutomation() &&
25 AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdown
)) {
26 NS_WARNING("ChromeWorker construction during shutdown");
27 nsCOMPtr
<nsIXPConnect
> xpc
= nsIXPConnect::XPConnect();
28 Unused
<< xpc
->DebugDumpJSStack(true, true, false);
31 JSContext
* cx
= aGlobal
.Context();
33 RefPtr
<WorkerPrivate
> workerPrivate
= WorkerPrivate::Constructor(
34 cx
, aScriptURL
, true /* aIsChromeWorker */, WorkerKindDedicated
,
35 RequestCredentials::Omit
, aOptions
.mType
, aOptions
.mName
, VoidCString(),
36 nullptr /*aLoadInfo */, aRv
);
37 if (NS_WARN_IF(aRv
.Failed())) {
41 nsCOMPtr
<nsIGlobalObject
> globalObject
=
42 do_QueryInterface(aGlobal
.GetAsSupports());
44 RefPtr
<ChromeWorker
> worker
=
45 new ChromeWorker(globalObject
, workerPrivate
.forget());
46 return worker
.forget();
50 bool ChromeWorker::WorkerAvailable(JSContext
* aCx
, JSObject
* /* unused */) {
51 // Chrome is always allowed to use workers, and content is never
52 // allowed to use ChromeWorker, so all we have to check is the
53 // caller. However, chrome workers apparently might not have a
54 // system principal, so we have to check for them manually.
55 if (NS_IsMainThread()) {
56 return nsContentUtils::IsSystemCaller(aCx
);
59 return GetWorkerPrivateFromContext(aCx
)->IsChromeWorker();
62 ChromeWorker::ChromeWorker(nsIGlobalObject
* aGlobalObject
,
63 already_AddRefed
<WorkerPrivate
> aWorkerPrivate
)
64 : Worker(aGlobalObject
, std::move(aWorkerPrivate
)) {}
66 ChromeWorker::~ChromeWorker() = default;
68 JSObject
* ChromeWorker::WrapObject(JSContext
* aCx
,
69 JS::Handle
<JSObject
*> aGivenProto
) {
70 JS::Rooted
<JSObject
*> wrapper(
71 aCx
, ChromeWorker_Binding::Wrap(aCx
, this, aGivenProto
));
73 // Most DOM objects don't assume they have a reflector. If they don't have
74 // one and need one, they create it. But in workers code, we assume that the
75 // reflector is always present. In order to guarantee that it's always
76 // present, we have to preserve it. Otherwise the GC will happily collect it
78 MOZ_ALWAYS_TRUE(TryPreserveWrapper(wrapper
));
84 } // namespace mozilla::dom