/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "ModuleLoadRequest.h" #include "mozilla/DebugOnly.h" #include "mozilla/HoldDropJSObjects.h" #include "mozilla/dom/ScriptLoadContext.h" #include "LoadedScript.h" #include "LoadContextBase.h" #include "ModuleLoaderBase.h" namespace JS::loader { #undef LOG #define LOG(args) \ MOZ_LOG(ModuleLoaderBase::gModuleLoaderBaseLog, mozilla::LogLevel::Debug, \ args) NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(ModuleLoadRequest, ScriptLoadRequest) NS_IMPL_CYCLE_COLLECTION_CLASS(ModuleLoadRequest) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ModuleLoadRequest, ScriptLoadRequest) NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoader, mRootModule, mModuleScript) tmp->ClearImport(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ModuleLoadRequest, ScriptLoadRequest) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoader, mRootModule, mModuleScript) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ModuleLoadRequest, ScriptLoadRequest) NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mReferrerScript) NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mModuleRequestObj) NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mPayload) NS_IMPL_CYCLE_COLLECTION_TRACE_END ModuleLoadRequest::ModuleLoadRequest( nsIURI* aURI, ModuleType aModuleType, mozilla::dom::ReferrerPolicy aReferrerPolicy, ScriptFetchOptions* aFetchOptions, const mozilla::dom::SRIMetadata& aIntegrity, nsIURI* aReferrer, LoadContextBase* aContext, Kind aKind, ModuleLoaderBase* aLoader, ModuleLoadRequest* aRootModule) : ScriptLoadRequest(ScriptKind::eModule, aURI, aReferrerPolicy, aFetchOptions, aIntegrity, aReferrer, aContext), mKind(aKind), mModuleType(aModuleType), mErroredLoadingImports(false), mLoader(aLoader), mRootModule(aRootModule) { MOZ_ASSERT(mLoader); } ModuleLoadRequest::~ModuleLoadRequest() { MOZ_ASSERT(!mReferrerScript); MOZ_ASSERT(!mModuleRequestObj); MOZ_ASSERT(mPayload.isUndefined()); DropJSObjects(this); } nsIGlobalObject* ModuleLoadRequest::GetGlobalObject() { return mLoader->GetGlobalObject(); } bool ModuleLoadRequest::IsErrored() const { return !mModuleScript || mModuleScript->HasParseError(); } void ModuleLoadRequest::SetReady() { MOZ_ASSERT(!IsFinished()); // Mark a module as ready to execute. This means that this module and all it // dependencies have had their source loaded, parsed as a module and the // modules instantiated. ScriptLoadRequest::SetReady(); } void ModuleLoadRequest::ModuleLoaded() { // A module that was found to be marked as fetching in the module map has now // been loaded. LOG(("ScriptLoadRequest (%p): Module loaded", this)); if (IsCanceled()) { return; } MOZ_ASSERT(IsFetching() || IsPendingFetchingError()); mModuleScript = mLoader->GetFetchedModule(ModuleMapKey(mURI, mModuleType)); } void ModuleLoadRequest::LoadFailed() { // We failed to load the source text or an error occurred unrelated to the // content of the module (e.g. OOM). LOG(("ScriptLoadRequest (%p): Module load failed", this)); if (IsCanceled()) { return; } MOZ_ASSERT(IsFetching() || IsPendingFetchingError()); MOZ_ASSERT(!mModuleScript); Cancel(); LoadFinished(); } void ModuleLoadRequest::ModuleErrored() { // Parse error, failure to resolve imported modules or error loading import. LOG(("ScriptLoadRequest (%p): Module errored", this)); if (IsCanceled()) { return; } MOZ_ASSERT(!IsFinished()); mozilla::DebugOnly hasRethrow = mModuleScript && mModuleScript->HasErrorToRethrow(); MOZ_ASSERT_IF(hasRethrow, !IsDynamicImport()); // When LoadRequestedModules fails, we will set error to rethrow to the module // script or call SetErroredLoadingImports() and then call ModuleErrored(). MOZ_ASSERT(IsErrored() || hasRethrow || mErroredLoadingImports); if (IsFinished()) { // Cancelling an outstanding import will error this request. return; } SetReady(); LoadFinished(); } void ModuleLoadRequest::LoadFinished() { RefPtr request(this); if (IsDynamicImport()) { mLoader->RemoveDynamicImport(request); } mLoader->OnModuleLoadComplete(request); } void ModuleLoadRequest::SetImport(Handle aReferrerScript, Handle aModuleRequestObj, Handle aPayload) { MOZ_ASSERT(mPayload.isUndefined()); mReferrerScript = aReferrerScript; mModuleRequestObj = aModuleRequestObj; mPayload = aPayload; mozilla::HoldJSObjects(this); } void ModuleLoadRequest::ClearImport() { mReferrerScript = nullptr; mModuleRequestObj = nullptr; mPayload = UndefinedValue(); } } // namespace JS::loader