Bug 1874684 - Part 38: Enable now passing tests. r=allstarschh
[gecko.git] / dom / workers / ChromeWorker.cpp
blob7fda84f7f59a389d1c9ffd538c5e838e7f015ff0
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 {
18 /* static */
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())) {
38 return nullptr;
41 nsCOMPtr<nsIGlobalObject> globalObject =
42 do_QueryInterface(aGlobal.GetAsSupports());
44 RefPtr<ChromeWorker> worker =
45 new ChromeWorker(globalObject, workerPrivate.forget());
46 return worker.forget();
49 /* static */
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));
72 if (wrapper) {
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
77 // as needed.
78 MOZ_ALWAYS_TRUE(TryPreserveWrapper(wrapper));
81 return wrapper;
84 } // namespace mozilla::dom