Bug 1890793: Assert CallArgs::newTarget is not gray. r=spidermonkey-reviewers,sfink...
[gecko.git] / dom / worklet / WorkletImpl.cpp
blob96f7b4c1c9cb0a2bdbc1424ba6f1f173e85cdbe7
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 https://mozilla.org/MPL/2.0/. */
7 #include "WorkletImpl.h"
9 #include "Worklet.h"
10 #include "WorkletThread.h"
12 #include "mozilla/BasePrincipal.h"
13 #include "mozilla/NullPrincipal.h"
14 #include "mozilla/dom/DocGroup.h"
15 #include "mozilla/dom/Document.h"
16 #include "mozilla/dom/RegisterWorkletBindings.h"
17 #include "mozilla/dom/ScriptSettings.h"
18 #include "mozilla/dom/WorkletBinding.h"
19 #include "mozilla/dom/WorkletGlobalScope.h"
20 #include "mozilla/dom/worklet/WorkletModuleLoader.h"
21 #include "nsGlobalWindowInner.h"
23 using mozilla::dom::loader::WorkletModuleLoader;
24 using mozilla::dom::loader::WorkletScriptLoader;
26 namespace mozilla {
27 // ---------------------------------------------------------------------------
28 // WorkletLoadInfo
30 WorkletLoadInfo::WorkletLoadInfo(nsPIDOMWindowInner* aWindow)
31 : mInnerWindowID(aWindow->WindowID()) {
32 MOZ_ASSERT(NS_IsMainThread());
33 nsPIDOMWindowOuter* outerWindow = aWindow->GetOuterWindow();
34 if (outerWindow) {
35 mOuterWindowID = outerWindow->WindowID();
36 } else {
37 mOuterWindowID = 0;
41 // ---------------------------------------------------------------------------
42 // WorkletImpl
44 WorkletImpl::WorkletImpl(nsPIDOMWindowInner* aWindow, nsIPrincipal* aPrincipal)
45 : mPrincipal(NullPrincipal::CreateWithInheritedAttributes(aPrincipal)),
46 mWorkletLoadInfo(aWindow),
47 mTerminated(false),
48 mFinishedOnExecutionThread(false),
49 mIsPrivateBrowsing(false),
50 mTrials(OriginTrials::FromWindow(nsGlobalWindowInner::Cast(aWindow))) {
51 Unused << NS_WARN_IF(
52 NS_FAILED(ipc::PrincipalToPrincipalInfo(mPrincipal, &mPrincipalInfo)));
54 if (aWindow->GetDocGroup()) {
55 mAgentClusterId.emplace(aWindow->GetDocGroup()->AgentClusterId());
58 mSharedMemoryAllowed =
59 nsGlobalWindowInner::Cast(aWindow)->IsSharedMemoryAllowed();
61 mShouldResistFingerprinting = aWindow->AsGlobal()->ShouldResistFingerprinting(
62 RFPTarget::IsAlwaysEnabledForPrecompute);
64 RefPtr<dom::Document> doc = nsGlobalWindowInner::Cast(aWindow)->GetDocument();
65 if (doc) {
66 mIsPrivateBrowsing = doc->IsInPrivateBrowsing();
67 mOverriddenFingerprintingSettings =
68 doc->GetOverriddenFingerprintingSettings();
72 WorkletImpl::~WorkletImpl() { MOZ_ASSERT(!mGlobalScope); }
74 JSObject* WorkletImpl::WrapWorklet(JSContext* aCx, dom::Worklet* aWorklet,
75 JS::Handle<JSObject*> aGivenProto) {
76 MOZ_ASSERT(NS_IsMainThread());
77 return dom::Worklet_Binding::Wrap(aCx, aWorklet, aGivenProto);
80 dom::WorkletGlobalScope* WorkletImpl::GetGlobalScope() {
81 dom::WorkletThread::AssertIsOnWorkletThread();
83 if (mGlobalScope) {
84 return mGlobalScope;
86 if (mFinishedOnExecutionThread) {
87 return nullptr;
90 dom::AutoJSAPI jsapi;
91 jsapi.Init();
92 JSContext* cx = jsapi.cx();
94 mGlobalScope = ConstructGlobalScope();
96 JS::Rooted<JSObject*> global(cx);
97 NS_ENSURE_TRUE(mGlobalScope->WrapGlobalObject(cx, &global), nullptr);
99 JSAutoRealm ar(cx, global);
101 // Init Web IDL bindings
102 if (!dom::RegisterWorkletBindings(cx, global)) {
103 return nullptr;
106 JS_FireOnNewGlobalObject(cx, global);
108 MOZ_ASSERT(!mGlobalScope->GetModuleLoader(cx));
110 RefPtr<WorkletScriptLoader> scriptLoader = new WorkletScriptLoader();
111 RefPtr<WorkletModuleLoader> moduleLoader =
112 new WorkletModuleLoader(scriptLoader, mGlobalScope);
113 mGlobalScope->InitModuleLoader(moduleLoader);
115 return mGlobalScope;
118 void WorkletImpl::NotifyWorkletFinished() {
119 MOZ_ASSERT(NS_IsMainThread());
121 if (mTerminated) {
122 return;
125 // Release global scope on its thread.
126 SendControlMessage(
127 NS_NewRunnableFunction("WorkletImpl::NotifyWorkletFinished",
128 [self = RefPtr<WorkletImpl>(this)]() {
129 self->mFinishedOnExecutionThread = true;
130 self->mGlobalScope = nullptr;
131 }));
133 mTerminated = true;
134 if (mWorkletThread) {
135 mWorkletThread->Terminate();
136 mWorkletThread = nullptr;
140 nsresult WorkletImpl::SendControlMessage(
141 already_AddRefed<nsIRunnable> aRunnable) {
142 MOZ_ASSERT(NS_IsMainThread());
143 RefPtr<nsIRunnable> runnable = std::move(aRunnable);
145 // TODO: bug 1492011 re ConsoleWorkletRunnable.
146 if (mTerminated) {
147 return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
150 if (!mWorkletThread) {
151 // Thread creation. FIXME: this will change.
152 mWorkletThread = dom::WorkletThread::Create(this);
153 if (!mWorkletThread) {
154 return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
158 return mWorkletThread->DispatchRunnable(runnable.forget());
161 } // namespace mozilla