Bug 1769170 [wpt PR 34049] - Update wpt metadata, a=testonly
[gecko.git] / js / loader / ModuleLoadRequest.cpp
blob92aca5048aa00da28f2d4fbc06951a555ad53b44
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_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ModuleLoadRequest)
24 NS_INTERFACE_MAP_END_INHERITING(ScriptLoadRequest)
26 NS_IMPL_CYCLE_COLLECTION_MULTI_ZONE_JSHOLDER_CLASS(ModuleLoadRequest)
28 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ModuleLoadRequest,
29 ScriptLoadRequest)
30 NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoader, mModuleScript, mImports, mRootModule)
31 tmp->ClearDynamicImport();
32 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
34 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ModuleLoadRequest,
35 ScriptLoadRequest)
36 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoader, mModuleScript, mImports,
37 mRootModule)
38 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
40 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ModuleLoadRequest,
41 ScriptLoadRequest)
42 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDynamicReferencingPrivate)
43 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDynamicSpecifier)
44 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDynamicPromise)
45 NS_IMPL_CYCLE_COLLECTION_TRACE_END
47 NS_IMPL_ADDREF_INHERITED(ModuleLoadRequest, ScriptLoadRequest)
48 NS_IMPL_RELEASE_INHERITED(ModuleLoadRequest, ScriptLoadRequest)
50 /* static */
51 VisitedURLSet* ModuleLoadRequest::NewVisitedSetForTopLevelImport(nsIURI* aURI) {
52 auto set = new VisitedURLSet();
53 set->PutEntry(aURI);
54 return set;
57 ModuleLoadRequest::ModuleLoadRequest(
58 nsIURI* aURI, 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, aFetchOptions, aIntegrity,
64 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 void ModuleLoadRequest::Cancel() {
78 ScriptLoadRequest::Cancel();
79 mModuleScript = nullptr;
80 CancelImports();
81 mReady.RejectIfExists(NS_ERROR_DOM_ABORT_ERR, __func__);
84 void ModuleLoadRequest::CancelImports() {
85 for (size_t i = 0; i < mImports.Length(); i++) {
86 mImports[i]->Cancel();
90 void ModuleLoadRequest::SetReady() {
91 // Mark a module as ready to execute. This means that this module and all it
92 // dependencies have had their source loaded, parsed as a module and the
93 // modules instantiated.
95 // The mReady promise is used to ensure that when all dependencies of a module
96 // have become ready, DependenciesLoaded is called on that module
97 // request. This is set up in StartFetchingModuleDependencies.
99 #ifdef DEBUG
100 for (size_t i = 0; i < mImports.Length(); i++) {
101 MOZ_ASSERT(mImports[i]->IsReadyToRun());
103 #endif
105 ScriptLoadRequest::SetReady();
106 mReady.ResolveIfExists(true, __func__);
109 void ModuleLoadRequest::ModuleLoaded() {
110 // A module that was found to be marked as fetching in the module map has now
111 // been loaded.
113 LOG(("ScriptLoadRequest (%p): Module loaded", this));
115 mModuleScript = mLoader->GetFetchedModule(mURI);
116 if (!mModuleScript || mModuleScript->HasParseError()) {
117 ModuleErrored();
118 return;
121 mLoader->StartFetchingModuleDependencies(this);
124 void ModuleLoadRequest::ModuleErrored() {
125 if (IsCanceled()) {
126 return;
129 LOG(("ScriptLoadRequest (%p): Module errored", this));
131 CheckModuleDependenciesLoaded();
132 MOZ_ASSERT(!mModuleScript || mModuleScript->HasParseError());
134 CancelImports();
135 SetReady();
136 LoadFinished();
139 void ModuleLoadRequest::DependenciesLoaded() {
140 if (IsCanceled()) {
141 return;
144 // The module and all of its dependencies have been successfully fetched and
145 // compiled.
147 LOG(("ScriptLoadRequest (%p): Module dependencies loaded", this));
149 MOZ_ASSERT(mModuleScript);
151 CheckModuleDependenciesLoaded();
152 SetReady();
153 LoadFinished();
156 void ModuleLoadRequest::CheckModuleDependenciesLoaded() {
157 LOG(("ScriptLoadRequest (%p): Check dependencies loaded", this));
159 if (!mModuleScript || mModuleScript->HasParseError()) {
160 return;
162 for (const auto& childRequest : mImports) {
163 ModuleScript* childScript = childRequest->mModuleScript;
164 if (!childScript) {
165 mModuleScript = nullptr;
166 LOG(("ScriptLoadRequest (%p): %p failed (load error)", this,
167 childRequest.get()));
168 return;
172 LOG(("ScriptLoadRequest (%p): all ok", this));
175 void ModuleLoadRequest::LoadFailed() {
176 // We failed to load the source text or an error occurred unrelated to the
177 // content of the module (e.g. OOM).
179 LOG(("ScriptLoadRequest (%p): Module load failed", this));
181 MOZ_ASSERT(!mModuleScript);
183 Cancel();
184 LoadFinished();
187 void ModuleLoadRequest::LoadFinished() {
188 RefPtr<ModuleLoadRequest> request(this);
189 if (IsTopLevel() && IsDynamicImport()) {
190 mLoader->RemoveDynamicImport(request);
193 mLoader->OnModuleLoadComplete(request);
196 void ModuleLoadRequest::ClearDynamicImport() {
197 mDynamicReferencingPrivate = JS::UndefinedValue();
198 mDynamicSpecifier = nullptr;
199 mDynamicPromise = nullptr;
202 } // namespace JS::loader