ModuleLoadRequest.h (4883B)
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/. */ 6 7 #ifndef js_loader_ModuleLoadRequest_h 8 #define js_loader_ModuleLoadRequest_h 9 10 #include "LoadContextBase.h" 11 #include "ScriptLoadRequest.h" 12 #include "ModuleLoaderBase.h" 13 #include "mozilla/Assertions.h" 14 #include "mozilla/HoldDropJSObjects.h" 15 #include "js/RootingAPI.h" 16 #include "js/Value.h" 17 #include "nsURIHashKey.h" 18 #include "nsTHashtable.h" 19 20 namespace JS::loader { 21 22 class LoadedScript; 23 class ModuleScript; 24 class ModuleLoaderBase; 25 26 // A load request for a module, created for every top level module script and 27 // every module import. Load request can share an ModuleScript if there are 28 // multiple imports of the same module. 29 30 class ModuleLoadRequest final : public ScriptLoadRequest { 31 ~ModuleLoadRequest(); 32 33 ModuleLoadRequest(const ModuleLoadRequest& aOther) = delete; 34 ModuleLoadRequest(ModuleLoadRequest&& aOther) = delete; 35 36 public: 37 NS_DECL_ISUPPORTS_INHERITED 38 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ModuleLoadRequest, 39 ScriptLoadRequest) 40 using SRIMetadata = mozilla::dom::SRIMetadata; 41 42 enum class Kind { 43 // Top-level modules, not imported statically nor dynamically. 44 TopLevel, 45 46 // Modules imported statically with `import` declarations. 47 StaticImport, 48 49 // Modules imported dynamically with dynamic `import()`. 50 DynamicImport, 51 }; 52 53 ModuleLoadRequest(ModuleType aModuleType, const SRIMetadata& aIntegrity, 54 nsIURI* aReferrer, LoadContextBase* aContext, Kind aKind, 55 ModuleLoaderBase* aLoader, ModuleLoadRequest* aRootModule); 56 57 bool IsTopLevel() const override { return mKind == Kind::TopLevel; } 58 bool IsStaticImport() const { return mKind == Kind::StaticImport; } 59 bool IsDynamicImport() const { return mKind == Kind::DynamicImport; } 60 61 bool IsErrored() const; 62 63 nsIGlobalObject* GetGlobalObject(); 64 65 void SetReady() override; 66 void Cancel() override { mLoader->Cancel(this); }; 67 68 void SetImport(Handle<JSScript*> aReferrerScript, 69 Handle<JSObject*> aModuleRequestObj, Handle<Value> aPayload); 70 void ClearImport(); 71 72 void ModuleLoaded(); 73 void ModuleErrored(); 74 void LoadFailed(); 75 76 ModuleLoadRequest* GetRootModule() { 77 if (!mRootModule) { 78 return this; 79 } 80 return mRootModule; 81 } 82 83 // Convenience methods to call into the module loader for this request. 84 85 void CancelDynamicImport(nsresult aResult) { 86 MOZ_ASSERT(IsDynamicImport()); 87 mLoader->CancelDynamicImport(this, aResult); 88 } 89 #ifdef DEBUG 90 bool IsRegisteredDynamicImport() const { 91 return IsDynamicImport() && mLoader->HasDynamicImport(this); 92 } 93 #endif 94 nsresult StartModuleLoad() { return mLoader->StartModuleLoad(this); } 95 nsresult RestartModuleLoad() { return mLoader->RestartModuleLoad(this); } 96 nsresult OnFetchComplete(nsresult aRv) { 97 return mLoader->OnFetchComplete(this, aRv); 98 } 99 bool InstantiateModuleGraph() { 100 return mLoader->InstantiateModuleGraph(this); 101 } 102 nsresult EvaluateModule() { return mLoader->EvaluateModule(this); } 103 void ProcessDynamicImport() { mLoader->ProcessDynamicImport(this); } 104 105 void LoadFinished(); 106 107 #ifdef NIGHTLY_BUILD 108 void SetHasWasmMimeTypeEssence() { mHasWasmMimeTypeEssence = true; } 109 110 bool HasWasmMimeTypeEssence() { return mHasWasmMimeTypeEssence; } 111 #endif 112 113 void SetErroredLoadingImports() { 114 MOZ_ASSERT(IsDynamicImport()); 115 MOZ_ASSERT(IsFetching() || IsCompiling()); 116 mErroredLoadingImports = true; 117 } 118 119 public: 120 // Fields. 121 const Kind mKind; 122 123 // Type of module (JavaScript, JSON) 124 const ModuleType mModuleType; 125 126 // Is this the top level request for a dynamic module import? 127 const bool mIsDynamicImport; 128 129 #ifdef NIGHTLY_BUILD 130 // We can only distinguish JavaScript and Wasm modules by mime type essence. 131 bool mHasWasmMimeTypeEssence = false; 132 #endif 133 134 // A flag (for dynamic import) that indicates the module script is 135 // successfully fetched and compiled, but its dependencies are failed to load. 136 bool mErroredLoadingImports; 137 138 // Pointer to the script loader, used to trigger actions when the module load 139 // finishes. 140 RefPtr<ModuleLoaderBase> mLoader; 141 142 // Pointer to the top level module of this module graph, nullptr if this is a 143 // top level module 144 RefPtr<ModuleLoadRequest> mRootModule; 145 146 // Set to a module script object after a successful load or nullptr on 147 // failure. 148 RefPtr<ModuleScript> mModuleScript; 149 150 Heap<JSScript*> mReferrerScript; 151 Heap<JSObject*> mModuleRequestObj; 152 Heap<Value> mPayload; 153 }; 154 155 } // namespace JS::loader 156 157 #endif // js_loader_ModuleLoadRequest_h