ModuleLoadRequest.cpp (5237B)
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 #include "ModuleLoadRequest.h" 8 9 #include "mozilla/DebugOnly.h" 10 #include "mozilla/HoldDropJSObjects.h" 11 #include "mozilla/dom/ScriptLoadContext.h" 12 13 #include "LoadedScript.h" 14 #include "LoadContextBase.h" 15 #include "ModuleLoaderBase.h" 16 17 namespace JS::loader { 18 19 #undef LOG 20 #define LOG(args) \ 21 MOZ_LOG(ModuleLoaderBase::gModuleLoaderBaseLog, mozilla::LogLevel::Debug, \ 22 args) 23 24 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(ModuleLoadRequest, 25 ScriptLoadRequest) 26 27 NS_IMPL_CYCLE_COLLECTION_CLASS(ModuleLoadRequest) 28 29 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ModuleLoadRequest, 30 ScriptLoadRequest) 31 NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoader, mRootModule, mModuleScript) 32 tmp->ClearImport(); 33 NS_IMPL_CYCLE_COLLECTION_UNLINK_END 34 35 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ModuleLoadRequest, 36 ScriptLoadRequest) 37 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoader, mRootModule, mModuleScript) 38 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 39 40 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ModuleLoadRequest, 41 ScriptLoadRequest) 42 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mReferrerScript) 43 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mModuleRequestObj) 44 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mPayload) 45 NS_IMPL_CYCLE_COLLECTION_TRACE_END 46 47 ModuleLoadRequest::ModuleLoadRequest( 48 ModuleType aModuleType, const mozilla::dom::SRIMetadata& aIntegrity, 49 nsIURI* aReferrer, LoadContextBase* aContext, Kind aKind, 50 ModuleLoaderBase* aLoader, ModuleLoadRequest* aRootModule) 51 : ScriptLoadRequest(ScriptKind::eModule, aIntegrity, aReferrer, aContext), 52 mKind(aKind), 53 mModuleType(aModuleType), 54 mIsDynamicImport(aKind == Kind::DynamicImport), 55 mErroredLoadingImports(false), 56 mLoader(aLoader), 57 mRootModule(aRootModule) { 58 MOZ_ASSERT(mLoader); 59 } 60 61 ModuleLoadRequest::~ModuleLoadRequest() { 62 MOZ_ASSERT(!mReferrerScript); 63 MOZ_ASSERT(!mModuleRequestObj); 64 MOZ_ASSERT(mPayload.isUndefined()); 65 66 DropJSObjects(this); 67 } 68 69 nsIGlobalObject* ModuleLoadRequest::GetGlobalObject() { 70 return mLoader->GetGlobalObject(); 71 } 72 73 bool ModuleLoadRequest::IsErrored() const { 74 return !mModuleScript || mModuleScript->HasParseError(); 75 } 76 77 void ModuleLoadRequest::SetReady() { 78 MOZ_ASSERT(!IsFinished()); 79 80 // Mark a module as ready to execute. This means that this module and all it 81 // dependencies have had their source loaded, parsed as a module and the 82 // modules instantiated. 83 84 ScriptLoadRequest::SetReady(); 85 } 86 87 void ModuleLoadRequest::ModuleLoaded() { 88 // A module that was found to be marked as fetching in the module map has now 89 // been loaded. 90 91 LOG(("ScriptLoadRequest (%p): Module loaded", this)); 92 93 if (IsCanceled()) { 94 return; 95 } 96 97 MOZ_ASSERT(IsFetching()); 98 99 mModuleScript = mLoader->GetFetchedModule(ModuleMapKey(URI(), mModuleType)); 100 } 101 102 void ModuleLoadRequest::LoadFailed() { 103 // We failed to load the source text or an error occurred unrelated to the 104 // content of the module (e.g. OOM). 105 106 LOG(("ScriptLoadRequest (%p): Module load failed", this)); 107 108 if (IsCanceled()) { 109 return; 110 } 111 112 MOZ_ASSERT(IsFetching()); 113 MOZ_ASSERT(!mModuleScript); 114 115 Cancel(); 116 LoadFinished(); 117 } 118 119 void ModuleLoadRequest::ModuleErrored() { 120 // Parse error, failure to resolve imported modules or error loading import. 121 122 LOG(("ScriptLoadRequest (%p): Module errored", this)); 123 124 if (IsCanceled()) { 125 return; 126 } 127 128 MOZ_ASSERT(!IsFinished()); 129 130 mozilla::DebugOnly<bool> hasRethrow = 131 mModuleScript && mModuleScript->HasErrorToRethrow(); 132 MOZ_ASSERT_IF(hasRethrow, !IsDynamicImport()); 133 134 // When LoadRequestedModules fails, we will set error to rethrow to the module 135 // script or call SetErroredLoadingImports() and then call ModuleErrored(). 136 MOZ_ASSERT(IsErrored() || hasRethrow || mErroredLoadingImports); 137 138 if (IsFinished()) { 139 // Cancelling an outstanding import will error this request. 140 return; 141 } 142 143 SetReady(); 144 LoadFinished(); 145 } 146 147 void ModuleLoadRequest::LoadFinished() { 148 RefPtr<ModuleLoadRequest> request(this); 149 if (IsDynamicImport()) { 150 mLoader->RemoveDynamicImport(request); 151 } 152 153 mLoader->OnModuleLoadComplete(request); 154 } 155 156 void ModuleLoadRequest::SetImport(Handle<JSScript*> aReferrerScript, 157 Handle<JSObject*> aModuleRequestObj, 158 Handle<Value> aPayload) { 159 MOZ_ASSERT(mPayload.isUndefined()); 160 161 mReferrerScript = aReferrerScript; 162 mModuleRequestObj = aModuleRequestObj; 163 mPayload = aPayload; 164 165 mozilla::HoldJSObjects(this); 166 } 167 168 void ModuleLoadRequest::ClearImport() { 169 mReferrerScript = nullptr; 170 mModuleRequestObj = nullptr; 171 mPayload = UndefinedValue(); 172 } 173 174 } // namespace JS::loader