Bug 1864587 - [angle] Vendor mozilla/angle/firefox-123. r=gfx-reviewers,aosmond
[gecko.git] / js / loader / ScriptLoadRequest.cpp
blob1b3cb52f720677c507c7b3a474788f4e1d53c382
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 "ScriptLoadRequest.h"
8 #include "GeckoProfiler.h"
10 #include "mozilla/dom/Document.h"
11 #include "mozilla/dom/ScriptLoadContext.h"
12 #include "mozilla/dom/WorkerLoadContext.h"
13 #include "mozilla/dom/ScriptSettings.h"
14 #include "mozilla/HoldDropJSObjects.h"
15 #include "mozilla/StaticPrefs_dom.h"
16 #include "mozilla/Unused.h"
17 #include "mozilla/Utf8.h" // mozilla::Utf8Unit
19 #include "js/SourceText.h"
21 #include "ModuleLoadRequest.h"
22 #include "nsContentUtils.h"
23 #include "nsICacheInfoChannel.h"
24 #include "nsIClassOfService.h"
25 #include "nsISupportsPriority.h"
27 using JS::SourceText;
29 namespace JS::loader {
31 //////////////////////////////////////////////////////////////
32 // ScriptFetchOptions
33 //////////////////////////////////////////////////////////////
35 NS_IMPL_CYCLE_COLLECTION(ScriptFetchOptions, mTriggeringPrincipal, mElement)
37 ScriptFetchOptions::ScriptFetchOptions(
38 mozilla::CORSMode aCORSMode, const nsAString& aNonce,
39 mozilla::dom::RequestPriority aFetchPriority,
40 const ParserMetadata aParserMetadata, nsIPrincipal* aTriggeringPrincipal,
41 mozilla::dom::Element* aElement)
42 : mCORSMode(aCORSMode),
43 mNonce(aNonce),
44 mFetchPriority(aFetchPriority),
45 mParserMetadata(aParserMetadata),
46 mTriggeringPrincipal(aTriggeringPrincipal),
47 mElement(aElement) {}
49 ScriptFetchOptions::~ScriptFetchOptions() = default;
51 //////////////////////////////////////////////////////////////
52 // ScriptLoadRequest
53 //////////////////////////////////////////////////////////////
55 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ScriptLoadRequest)
56 NS_INTERFACE_MAP_ENTRY(nsISupports)
57 NS_INTERFACE_MAP_END
59 NS_IMPL_CYCLE_COLLECTING_ADDREF(ScriptLoadRequest)
60 NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptLoadRequest)
62 NS_IMPL_CYCLE_COLLECTION_CLASS(ScriptLoadRequest)
64 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ScriptLoadRequest)
65 NS_IMPL_CYCLE_COLLECTION_UNLINK(mFetchOptions, mCacheInfo, mLoadContext,
66 mLoadedScript)
67 tmp->mScriptForBytecodeEncoding = nullptr;
68 tmp->DropBytecodeCacheReferences();
69 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
71 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ScriptLoadRequest)
72 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFetchOptions, mCacheInfo, mLoadContext,
73 mLoadedScript)
74 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
76 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ScriptLoadRequest)
77 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mScriptForBytecodeEncoding)
78 NS_IMPL_CYCLE_COLLECTION_TRACE_END
80 ScriptLoadRequest::ScriptLoadRequest(
81 ScriptKind aKind, nsIURI* aURI,
82 mozilla::dom::ReferrerPolicy aReferrerPolicy,
83 ScriptFetchOptions* aFetchOptions, const SRIMetadata& aIntegrity,
84 nsIURI* aReferrer, LoadContextBase* aContext)
85 : mKind(aKind),
86 mState(State::CheckingCache),
87 mFetchSourceOnly(false),
88 mReferrerPolicy(aReferrerPolicy),
89 mFetchOptions(aFetchOptions),
90 mIntegrity(aIntegrity),
91 mReferrer(aReferrer),
92 mURI(aURI),
93 mLoadContext(aContext),
94 mEarlyHintPreloaderId(0) {
95 MOZ_ASSERT(mFetchOptions);
96 if (mLoadContext) {
97 mLoadContext->SetRequest(this);
101 ScriptLoadRequest::~ScriptLoadRequest() { DropJSObjects(this); }
103 void ScriptLoadRequest::SetReady() {
104 MOZ_ASSERT(!IsFinished());
105 mState = State::Ready;
108 void ScriptLoadRequest::Cancel() {
109 mState = State::Canceled;
110 if (HasScriptLoadContext()) {
111 GetScriptLoadContext()->MaybeCancelOffThreadScript();
115 void ScriptLoadRequest::DropBytecodeCacheReferences() {
116 mCacheInfo = nullptr;
117 DropJSObjects(this);
120 bool ScriptLoadRequest::HasScriptLoadContext() const {
121 return HasLoadContext() && mLoadContext->IsWindowContext();
124 bool ScriptLoadRequest::HasWorkerLoadContext() const {
125 return HasLoadContext() && mLoadContext->IsWorkerContext();
128 mozilla::dom::ScriptLoadContext* ScriptLoadRequest::GetScriptLoadContext() {
129 MOZ_ASSERT(mLoadContext);
130 return mLoadContext->AsWindowContext();
133 mozilla::loader::ComponentLoadContext*
134 ScriptLoadRequest::GetComponentLoadContext() {
135 MOZ_ASSERT(mLoadContext);
136 return mLoadContext->AsComponentContext();
139 mozilla::dom::WorkerLoadContext* ScriptLoadRequest::GetWorkerLoadContext() {
140 MOZ_ASSERT(mLoadContext);
141 return mLoadContext->AsWorkerContext();
144 mozilla::dom::WorkletLoadContext* ScriptLoadRequest::GetWorkletLoadContext() {
145 MOZ_ASSERT(mLoadContext);
146 return mLoadContext->AsWorkletContext();
149 ModuleLoadRequest* ScriptLoadRequest::AsModuleRequest() {
150 MOZ_ASSERT(IsModuleRequest());
151 return static_cast<ModuleLoadRequest*>(this);
154 const ModuleLoadRequest* ScriptLoadRequest::AsModuleRequest() const {
155 MOZ_ASSERT(IsModuleRequest());
156 return static_cast<const ModuleLoadRequest*>(this);
159 void ScriptLoadRequest::NoCacheEntryFound() {
160 MOZ_ASSERT(IsCheckingCache());
161 MOZ_ASSERT(mURI);
162 // At the time where we check in the cache, the mBaseURL is not set, as this
163 // is resolved by the network. Thus we use the mURI, for checking the cache
164 // and later replace the mBaseURL using what the Channel->GetURI will provide.
165 switch (mKind) {
166 case ScriptKind::eClassic:
167 case ScriptKind::eImportMap:
168 mLoadedScript = new ClassicScript(mReferrerPolicy, mFetchOptions, mURI);
169 break;
170 case ScriptKind::eModule:
171 mLoadedScript = new ModuleScript(mReferrerPolicy, mFetchOptions, mURI);
172 break;
173 case ScriptKind::eEvent:
174 MOZ_ASSERT_UNREACHABLE("EventScripts are not using ScriptLoadRequest");
175 break;
177 mState = State::Fetching;
180 void ScriptLoadRequest::SetPendingFetchingError() {
181 MOZ_ASSERT(IsCheckingCache());
182 mState = State::PendingFetchingError;
185 void ScriptLoadRequest::MarkForBytecodeEncoding(JSScript* aScript) {
186 MOZ_ASSERT(!IsModuleRequest());
187 MOZ_ASSERT(!IsMarkedForBytecodeEncoding());
188 mScriptForBytecodeEncoding = aScript;
189 HoldJSObjects(this);
192 bool ScriptLoadRequest::IsMarkedForBytecodeEncoding() const {
193 if (IsModuleRequest()) {
194 return AsModuleRequest()->IsModuleMarkedForBytecodeEncoding();
197 return !!mScriptForBytecodeEncoding;
200 //////////////////////////////////////////////////////////////
201 // ScriptLoadRequestList
202 //////////////////////////////////////////////////////////////
204 ScriptLoadRequestList::~ScriptLoadRequestList() { CancelRequestsAndClear(); }
206 void ScriptLoadRequestList::CancelRequestsAndClear() {
207 while (!isEmpty()) {
208 RefPtr<ScriptLoadRequest> first = StealFirst();
209 first->Cancel();
210 // And just let it go out of scope and die.
214 #ifdef DEBUG
215 bool ScriptLoadRequestList::Contains(ScriptLoadRequest* aElem) const {
216 for (const ScriptLoadRequest* req = getFirst(); req; req = req->getNext()) {
217 if (req == aElem) {
218 return true;
222 return false;
224 #endif // DEBUG
226 } // namespace JS::loader