Backed out changeset 9d8b4c0b99ed (bug 1945683) for causing btime failures. CLOSED...
[gecko.git] / js / loader / ModuleLoadRequest.h
blobbd2033ee1922c1f47b98368c67fe78424bcc817f
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 #ifndef js_loader_ModuleLoadRequest_h
8 #define js_loader_ModuleLoadRequest_h
10 #include "LoadContextBase.h"
11 #include "ScriptLoadRequest.h"
12 #include "ModuleLoaderBase.h"
13 #include "mozilla/Assertions.h"
14 #include "js/RootingAPI.h"
15 #include "js/Value.h"
16 #include "nsURIHashKey.h"
17 #include "nsTHashtable.h"
19 namespace JS::loader {
21 class LoadedScript;
22 class ModuleScript;
23 class ModuleLoaderBase;
25 // A reference counted set of module keys (URL and module type) we have visited
26 // in the process of loading a module graph.
27 class VisitedURLSet : public nsTHashtable<ModuleMapKey> {
28 NS_INLINE_DECL_REFCOUNTING(VisitedURLSet)
30 private:
31 ~VisitedURLSet() = default;
34 // A load request for a module, created for every top level module script and
35 // every module import. Load request can share an ModuleScript if there are
36 // multiple imports of the same module.
38 class ModuleLoadRequest final : public ScriptLoadRequest {
39 ~ModuleLoadRequest() {
40 MOZ_ASSERT(!mWaitingParentRequest);
41 MOZ_ASSERT(mAwaitingImports == 0);
44 ModuleLoadRequest(const ModuleLoadRequest& aOther) = delete;
45 ModuleLoadRequest(ModuleLoadRequest&& aOther) = delete;
47 public:
48 NS_DECL_ISUPPORTS_INHERITED
49 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ModuleLoadRequest,
50 ScriptLoadRequest)
51 using SRIMetadata = mozilla::dom::SRIMetadata;
53 ModuleLoadRequest(nsIURI* aURI, JS::ModuleType aModuleType,
54 mozilla::dom::ReferrerPolicy aReferrerPolicy,
55 ScriptFetchOptions* aFetchOptions,
56 const SRIMetadata& aIntegrity, nsIURI* aReferrer,
57 LoadContextBase* aContext, bool aIsTopLevel,
58 bool aIsDynamicImport, ModuleLoaderBase* aLoader,
59 VisitedURLSet* aVisitedSet, ModuleLoadRequest* aRootModule);
61 static VisitedURLSet* NewVisitedSetForTopLevelImport(
62 nsIURI* aURI, JS::ModuleType aModuleType);
64 bool IsTopLevel() const override { return mIsTopLevel; }
66 bool IsDynamicImport() const { return mIsDynamicImport; }
68 bool IsErrored() const;
70 nsIGlobalObject* GetGlobalObject();
72 void SetReady() override;
73 void Cancel() override;
75 void SetDynamicImport(LoadedScript* aReferencingScript,
76 JS::Handle<JSString*> aSpecifier,
77 JS::Handle<JSObject*> aPromise);
78 void ClearDynamicImport();
80 void ModuleLoaded();
81 void ModuleErrored();
82 void DependenciesLoaded();
83 void LoadFailed();
85 ModuleLoadRequest* GetRootModule() {
86 if (!mRootModule) {
87 return this;
89 return mRootModule;
92 void MarkModuleForBytecodeEncoding() { MarkForBytecodeEncoding(); }
94 // Convenience methods to call into the module loader for this request.
96 void CancelDynamicImport(nsresult aResult) {
97 MOZ_ASSERT(IsDynamicImport());
98 mLoader->CancelDynamicImport(this, aResult);
100 #ifdef DEBUG
101 bool IsRegisteredDynamicImport() const {
102 return IsDynamicImport() && mLoader->HasDynamicImport(this);
104 #endif
105 nsresult StartModuleLoad() { return mLoader->StartModuleLoad(this); }
106 nsresult RestartModuleLoad() { return mLoader->RestartModuleLoad(this); }
107 nsresult OnFetchComplete(nsresult aRv) {
108 return mLoader->OnFetchComplete(this, aRv);
110 bool InstantiateModuleGraph() {
111 return mLoader->InstantiateModuleGraph(this);
113 nsresult EvaluateModule() { return mLoader->EvaluateModule(this); }
114 void StartDynamicImport() { mLoader->StartDynamicImport(this); }
115 void ProcessDynamicImport() { mLoader->ProcessDynamicImport(this); }
117 void ChildLoadComplete(bool aSuccess);
119 private:
120 void LoadFinished();
121 void CancelImports();
122 void CheckModuleDependenciesLoaded();
124 void ChildModuleUnlinked();
126 void AssertAllImportsFinished() const;
127 void AssertAllImportsCancelled() const;
129 public:
130 // Is this a request for a top level module script or an import?
131 const bool mIsTopLevel;
133 // Type of module (JavaScript, JSON)
134 const JS::ModuleType mModuleType;
136 // Is this the top level request for a dynamic module import?
137 const bool mIsDynamicImport;
139 // Pointer to the script loader, used to trigger actions when the module load
140 // finishes.
141 RefPtr<ModuleLoaderBase> mLoader;
143 // Pointer to the top level module of this module graph, nullptr if this is a
144 // top level module
145 RefPtr<ModuleLoadRequest> mRootModule;
147 // Set to a module script object after a successful load or nullptr on
148 // failure.
149 RefPtr<ModuleScript> mModuleScript;
151 // Array of imported modules.
152 nsTArray<RefPtr<ModuleLoadRequest>> mImports;
154 // Parent module (i.e. importer of this module) that is waiting for this
155 // module and its dependencies to load, or null.
156 RefPtr<ModuleLoadRequest> mWaitingParentRequest;
158 // Number of child modules (i.e. imported modules) that this module is waiting
159 // for.
160 size_t mAwaitingImports = 0;
162 // Set of module URLs visited while fetching the module graph this request is
163 // part of.
164 RefPtr<VisitedURLSet> mVisitedSet;
166 // For dynamic imports, the details to pass to FinishDynamicImport.
167 RefPtr<LoadedScript> mDynamicReferencingScript;
168 JS::Heap<JSString*> mDynamicSpecifier;
169 JS::Heap<JSObject*> mDynamicPromise;
172 } // namespace JS::loader
174 #endif // js_loader_ModuleLoadRequest_h