Bug 1864587 - [angle] Vendor mozilla/angle/firefox-123. r=gfx-reviewers,aosmond
[gecko.git] / js / loader / ModuleLoadRequest.h
blob4413c5f00d41d97faa1bb949d2de846c388c04e6
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 URLs we have visited in the process of loading a
26 // module graph.
27 class VisitedURLSet : public nsTHashtable<nsURIHashKey> {
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, mozilla::dom::ReferrerPolicy aReferrerPolicy,
54 ScriptFetchOptions* aFetchOptions,
55 const SRIMetadata& aIntegrity, nsIURI* aReferrer,
56 LoadContextBase* aContext, bool aIsTopLevel,
57 bool aIsDynamicImport, ModuleLoaderBase* aLoader,
58 VisitedURLSet* aVisitedSet, ModuleLoadRequest* aRootModule);
60 static VisitedURLSet* NewVisitedSetForTopLevelImport(nsIURI* aURI);
62 bool IsTopLevel() const override { return mIsTopLevel; }
64 bool IsDynamicImport() const { return mIsDynamicImport; }
66 bool IsErrored() const;
68 nsIGlobalObject* GetGlobalObject();
70 void SetReady() override;
71 void Cancel() override;
72 void ClearDynamicImport();
74 void ModuleLoaded();
75 void ModuleErrored();
76 void DependenciesLoaded();
77 void LoadFailed();
79 ModuleLoadRequest* GetRootModule() {
80 if (!mRootModule) {
81 return this;
83 return mRootModule;
86 bool IsModuleMarkedForBytecodeEncoding() const {
87 return mIsMarkedForBytecodeEncoding;
89 void MarkModuleForBytecodeEncoding() {
90 MOZ_ASSERT(!IsModuleMarkedForBytecodeEncoding());
91 mIsMarkedForBytecodeEncoding = true;
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 AssertAllImportsFinished() const;
125 void AssertAllImportsCancelled() const;
127 public:
128 // Is this a request for a top level module script or an import?
129 const bool mIsTopLevel;
131 // Is this the top level request for a dynamic module import?
132 const bool mIsDynamicImport;
134 // True if this module is planned to be saved in the bytecode cache.
135 // ModuleLoadRequest doesn't use ScriptLoadRequest::mScriptForBytecodeEncoding
136 // field because the JSScript reference isn't always avaialble for module.
137 bool mIsMarkedForBytecodeEncoding = false;
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