Backed out changeset 88fbb17e3c20 (bug 1865637) for causing animation related mochite...
[gecko.git] / js / loader / ModuleLoadRequest.cpp
blobd90d41da5868b9147035ab358f722e991c560356
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 "ModuleLoadRequest.h"
9 #include "mozilla/HoldDropJSObjects.h"
10 #include "mozilla/dom/ScriptLoadContext.h"
12 #include "LoadedScript.h"
13 #include "LoadContextBase.h"
14 #include "ModuleLoaderBase.h"
16 namespace JS::loader {
18 #undef LOG
19 #define LOG(args) \
20 MOZ_LOG(ModuleLoaderBase::gModuleLoaderBaseLog, mozilla::LogLevel::Debug, \
21 args)
23 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(ModuleLoadRequest,
24 ScriptLoadRequest)
26 NS_IMPL_CYCLE_COLLECTION_CLASS(ModuleLoadRequest)
28 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ModuleLoadRequest,
29 ScriptLoadRequest)
30 NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoader, mRootModule, mModuleScript, mImports,
31 mWaitingParentRequest,
32 mDynamicReferencingScript)
33 tmp->ClearDynamicImport();
34 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
36 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ModuleLoadRequest,
37 ScriptLoadRequest)
38 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoader, mRootModule, mModuleScript,
39 mImports, mWaitingParentRequest,
40 mDynamicReferencingScript)
41 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
43 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ModuleLoadRequest,
44 ScriptLoadRequest)
45 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDynamicSpecifier)
46 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDynamicPromise)
47 NS_IMPL_CYCLE_COLLECTION_TRACE_END
49 /* static */
50 VisitedURLSet* ModuleLoadRequest::NewVisitedSetForTopLevelImport(nsIURI* aURI) {
51 auto set = new VisitedURLSet();
52 set->PutEntry(aURI);
53 return set;
56 ModuleLoadRequest::ModuleLoadRequest(
57 nsIURI* aURI, mozilla::dom::ReferrerPolicy aReferrerPolicy,
58 ScriptFetchOptions* aFetchOptions,
59 const mozilla::dom::SRIMetadata& aIntegrity, nsIURI* aReferrer,
60 LoadContextBase* aContext, bool aIsTopLevel, bool aIsDynamicImport,
61 ModuleLoaderBase* aLoader, VisitedURLSet* aVisitedSet,
62 ModuleLoadRequest* aRootModule)
63 : ScriptLoadRequest(ScriptKind::eModule, aURI, aReferrerPolicy,
64 aFetchOptions, aIntegrity, aReferrer, aContext),
65 mIsTopLevel(aIsTopLevel),
66 mIsDynamicImport(aIsDynamicImport),
67 mLoader(aLoader),
68 mRootModule(aRootModule),
69 mVisitedSet(aVisitedSet) {
70 MOZ_ASSERT(mLoader);
73 nsIGlobalObject* ModuleLoadRequest::GetGlobalObject() {
74 return mLoader->GetGlobalObject();
77 bool ModuleLoadRequest::IsErrored() const {
78 return !mModuleScript || mModuleScript->HasParseError();
81 void ModuleLoadRequest::Cancel() {
82 if (IsCanceled()) {
83 AssertAllImportsCancelled();
84 return;
87 if (IsFinished()) {
88 return;
91 ScriptLoadRequest::Cancel();
93 mModuleScript = nullptr;
94 CancelImports();
96 if (mWaitingParentRequest) {
97 ChildLoadComplete(false);
101 void ModuleLoadRequest::SetReady() {
102 MOZ_ASSERT(!IsFinished());
104 // Mark a module as ready to execute. This means that this module and all it
105 // dependencies have had their source loaded, parsed as a module and the
106 // modules instantiated.
108 AssertAllImportsFinished();
110 ScriptLoadRequest::SetReady();
112 if (mWaitingParentRequest) {
113 ChildLoadComplete(true);
117 void ModuleLoadRequest::ModuleLoaded() {
118 // A module that was found to be marked as fetching in the module map has now
119 // been loaded.
121 LOG(("ScriptLoadRequest (%p): Module loaded", this));
123 if (IsCanceled()) {
124 AssertAllImportsCancelled();
125 return;
128 MOZ_ASSERT(IsFetching() || IsPendingFetchingError());
130 mModuleScript = mLoader->GetFetchedModule(mURI);
131 if (IsErrored()) {
132 ModuleErrored();
133 return;
136 mLoader->StartFetchingModuleDependencies(this);
139 void ModuleLoadRequest::LoadFailed() {
140 // We failed to load the source text or an error occurred unrelated to the
141 // content of the module (e.g. OOM).
143 LOG(("ScriptLoadRequest (%p): Module load failed", this));
145 if (IsCanceled()) {
146 AssertAllImportsCancelled();
147 return;
150 MOZ_ASSERT(IsFetching() || IsPendingFetchingError());
151 MOZ_ASSERT(!mModuleScript);
153 Cancel();
154 LoadFinished();
157 void ModuleLoadRequest::ModuleErrored() {
158 // Parse error, failure to resolve imported modules or error loading import.
160 LOG(("ScriptLoadRequest (%p): Module errored", this));
162 if (IsCanceled()) {
163 return;
166 MOZ_ASSERT(!IsFinished());
168 CheckModuleDependenciesLoaded();
169 MOZ_ASSERT(IsErrored());
171 CancelImports();
172 if (IsFinished()) {
173 // Cancelling an outstanding import will error this request.
174 return;
177 SetReady();
178 LoadFinished();
181 void ModuleLoadRequest::DependenciesLoaded() {
182 // The module and all of its dependencies have been successfully fetched and
183 // compiled.
185 LOG(("ScriptLoadRequest (%p): Module dependencies loaded", this));
187 if (IsCanceled()) {
188 return;
191 MOZ_ASSERT(IsLoadingImports());
192 MOZ_ASSERT(!IsErrored());
194 CheckModuleDependenciesLoaded();
195 SetReady();
196 LoadFinished();
199 void ModuleLoadRequest::CheckModuleDependenciesLoaded() {
200 LOG(("ScriptLoadRequest (%p): Check dependencies loaded", this));
202 if (!mModuleScript || mModuleScript->HasParseError()) {
203 return;
205 for (const auto& childRequest : mImports) {
206 ModuleScript* childScript = childRequest->mModuleScript;
207 if (!childScript) {
208 mModuleScript = nullptr;
209 LOG(("ScriptLoadRequest (%p): %p failed (load error)", this,
210 childRequest.get()));
211 return;
215 LOG(("ScriptLoadRequest (%p): all ok", this));
218 void ModuleLoadRequest::CancelImports() {
219 for (size_t i = 0; i < mImports.Length(); i++) {
220 mImports[i]->Cancel();
224 void ModuleLoadRequest::LoadFinished() {
225 RefPtr<ModuleLoadRequest> request(this);
226 if (IsTopLevel() && IsDynamicImport()) {
227 mLoader->RemoveDynamicImport(request);
230 mLoader->OnModuleLoadComplete(request);
233 void ModuleLoadRequest::SetDynamicImport(LoadedScript* aReferencingScript,
234 JS::Handle<JSString*> aSpecifier,
235 JS::Handle<JSObject*> aPromise) {
236 mDynamicReferencingScript = aReferencingScript;
237 mDynamicSpecifier = aSpecifier;
238 mDynamicPromise = aPromise;
240 mozilla::HoldJSObjects(this);
243 void ModuleLoadRequest::ClearDynamicImport() {
244 mDynamicReferencingScript = nullptr;
245 mDynamicSpecifier = nullptr;
246 mDynamicPromise = nullptr;
249 inline void ModuleLoadRequest::AssertAllImportsFinished() const {
250 #ifdef DEBUG
251 for (const auto& request : mImports) {
252 MOZ_ASSERT(request->IsFinished());
254 #endif
257 inline void ModuleLoadRequest::AssertAllImportsCancelled() const {
258 #ifdef DEBUG
259 for (const auto& request : mImports) {
260 MOZ_ASSERT(request->IsCanceled());
262 #endif
265 } // namespace JS::loader