tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 982b4fcd355e6070ea31b8e78fa5c4a6cbb4c3bd
parent ed80307234536b92bdcb3aa1106c54f5f0172ca7
Author: Yoshi Cheng-Hao Huang <allstars.chh@gmail.com>
Date:   Fri,  3 Oct 2025 20:53:28 +0000

Bug 1968890 - Part 1: Dynamic import is not a top-level request. r=jonco,dom-worker-reviewers,edenchuang

According to the spec, requests created in HostLoadImportedModule have
the isTopLevel flag set to false. This means both static and dynamic
import requests should also have this flag set to false.

[HostLoadImportedModule](https://html.spec.whatwg.org/#hostloadimportedmodule)
Step 14. Fetch a single imported module script ...

[Fetch a single imported module script](https://html.spec.whatwg.org/#fetch-a-single-imported-module-script)
Step 4. Fetch a single module script given url, fetchClient, destination, options, settingsObject, referrer, moduleRequest, false, and onComplete.

The false argument in the second-to-last parameter of 'Fetch a single
module script' corresponds to the top-levl flag.

[Fetch a single module script](https://html.spec.whatwg.org/#fetch-a-single-module-script)
given a URL url, an environment settings object fetchClient, a
destination destination, a script fetch options options, an environment
settings object settingsObject, a referrer referrer, an optional
ModuleRequest Record moduleRequest, a boolean isTopLevel, an algorithm
onComplete,

The spec was updated in https://github.com/whatwg/html/issues/7996. We’re
updating the implementation to reflect this change.

Differential Revision: https://phabricator.services.mozilla.com/D265593

Diffstat:
Mdom/script/ModuleLoader.cpp | 2+-
Mdom/script/ScriptLoadContext.cpp | 3++-
Mdom/script/ScriptLoader.cpp | 17+++++++++++------
Mdom/workers/loader/WorkerModuleLoader.cpp | 29+++++++++++++++--------------
Mdom/worklet/loader/WorkletModuleLoader.cpp | 2+-
Mjs/loader/ModuleLoadRequest.cpp | 5++---
Mjs/loader/ModuleLoadRequest.h | 16+++++-----------
Mjs/loader/ModuleLoaderBase.cpp | 5++---
8 files changed, 39 insertions(+), 40 deletions(-)

diff --git a/dom/script/ModuleLoader.cpp b/dom/script/ModuleLoader.cpp @@ -164,7 +164,7 @@ void ModuleLoader::ExecuteInlineModule(ModuleLoadRequest* aRequest) { void ModuleLoader::OnModuleLoadComplete(ModuleLoadRequest* aRequest) { MOZ_ASSERT(aRequest->IsFinished()); - if (aRequest->IsTopLevel()) { + if (aRequest->IsTopLevel() || aRequest->IsDynamicImport()) { if (aRequest->GetScriptLoadContext()->mIsInline && aRequest->GetScriptLoadContext()->GetParserCreated() == NOT_FROM_PARSER) { diff --git a/dom/script/ScriptLoadContext.cpp b/dom/script/ScriptLoadContext.cpp @@ -131,7 +131,8 @@ void ScriptLoadContext::PrioritizeAsPreload(nsIChannel* aChannel) { } bool ScriptLoadContext::IsPreload() const { - if (mRequest->IsModuleRequest() && !mRequest->IsTopLevel()) { + if (mRequest->IsModuleRequest() && + mRequest->AsModuleRequest()->IsStaticImport()) { JS::loader::ModuleLoadRequest* root = mRequest->AsModuleRequest()->GetRootModule(); return root->GetScriptLoadContext()->IsPreload(); diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp @@ -2737,7 +2737,7 @@ void ScriptLoader::CalculateCacheFlag(ScriptLoadRequest* aRequest) { aRequest->MarkPassedConditionForMemoryCache(); if (aRequest->IsModuleRequest() && - !aRequest->AsModuleRequest()->IsTopLevel()) { + aRequest->AsModuleRequest()->IsStaticImport()) { MOZ_ASSERT(!aRequest->isInList()); mCacheableDependencyModules.AppendElement(aRequest); } @@ -2865,7 +2865,7 @@ void ScriptLoader::CalculateCacheFlag(ScriptLoadRequest* aRequest) { if (!aRequest->PassedConditionForMemoryCache() && aRequest->IsModuleRequest() && - !aRequest->AsModuleRequest()->IsTopLevel()) { + aRequest->AsModuleRequest()->IsStaticImport()) { MOZ_ASSERT(!aRequest->isInList()); mCacheableDependencyModules.AppendElement(aRequest); } @@ -4284,7 +4284,6 @@ void ScriptLoader::HandleLoadError(ScriptLoadRequest* aRequest, } else if (aRequest->IsModuleRequest()) { ModuleLoadRequest* modReq = aRequest->AsModuleRequest(); if (modReq->IsDynamicImport()) { - MOZ_ASSERT(modReq->IsTopLevel()); if (aRequest->isInList()) { modReq->CancelDynamicImport(aResult); } @@ -4747,7 +4746,14 @@ void ScriptLoader::AddAsyncRequest(ScriptLoadRequest* aRequest) { void ScriptLoader::MaybeMoveToLoadedList(ScriptLoadRequest* aRequest) { MOZ_ASSERT(aRequest->IsFinished()); - MOZ_ASSERT(aRequest->IsTopLevel()); + + bool isDynamicImport = false; + if (aRequest->IsModuleRequest()) { + ModuleLoadRequest* modReq = aRequest->AsModuleRequest(); + isDynamicImport = modReq->IsDynamicImport(); + } + + MOZ_ASSERT(aRequest->IsTopLevel() || isDynamicImport); // If it's async, move it to the loaded list. // aRequest->GetScriptLoadContext()->mInAsyncList really _should_ be in a @@ -4759,8 +4765,7 @@ void ScriptLoader::MaybeMoveToLoadedList(ScriptLoadRequest* aRequest) { RefPtr<ScriptLoadRequest> req = mLoadingAsyncRequests.Steal(aRequest); mLoadedAsyncRequests.AppendElement(req); } - } else if (aRequest->IsModuleRequest() && - aRequest->AsModuleRequest()->IsDynamicImport()) { + } else if (isDynamicImport) { // Process dynamic imports with async scripts. MOZ_ASSERT(!aRequest->isInList()); mLoadedAsyncRequests.AppendElement(aRequest); diff --git a/dom/workers/loader/WorkerModuleLoader.cpp b/dom/workers/loader/WorkerModuleLoader.cpp @@ -220,20 +220,21 @@ WorkerScriptLoader* WorkerModuleLoader::GetScriptLoaderFor( } void WorkerModuleLoader::OnModuleLoadComplete(ModuleLoadRequest* aRequest) { - if (aRequest->IsTopLevel()) { - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(GetGlobalObject()))) { - return; - } - RefPtr<WorkerScriptLoader> requestScriptLoader = - GetScriptLoaderFor(aRequest); - if (aRequest->IsDynamicImport()) { - aRequest->ProcessDynamicImport(); - requestScriptLoader->TryShutdown(); - } else { - requestScriptLoader->MaybeMoveToLoadedList(aRequest); - requestScriptLoader->ProcessPendingRequests(jsapi.cx()); - } + if (aRequest->IsStaticImport()) { + return; + } + + AutoJSAPI jsapi; + if (NS_WARN_IF(!jsapi.Init(GetGlobalObject()))) { + return; + } + RefPtr<WorkerScriptLoader> requestScriptLoader = GetScriptLoaderFor(aRequest); + if (aRequest->IsDynamicImport()) { + aRequest->ProcessDynamicImport(); + requestScriptLoader->TryShutdown(); + } else { + requestScriptLoader->MaybeMoveToLoadedList(aRequest); + requestScriptLoader->ProcessPendingRequests(jsapi.cx()); } } diff --git a/dom/worklet/loader/WorkletModuleLoader.cpp b/dom/worklet/loader/WorkletModuleLoader.cpp @@ -251,7 +251,7 @@ AddModuleThrowErrorRunnable::Run() { } void WorkletModuleLoader::OnModuleLoadComplete(ModuleLoadRequest* aRequest) { - if (!aRequest->IsTopLevel()) { + if (aRequest->IsStaticImport()) { return; } diff --git a/js/loader/ModuleLoadRequest.cpp b/js/loader/ModuleLoadRequest.cpp @@ -53,9 +53,8 @@ ModuleLoadRequest::ModuleLoadRequest( ModuleLoadRequest* aRootModule) : ScriptLoadRequest(ScriptKind::eModule, aURI, aReferrerPolicy, aFetchOptions, aIntegrity, aReferrer, aContext), - mIsTopLevel(aKind == Kind::TopLevel || aKind == Kind::DynamicImport), + mKind(aKind), mModuleType(aModuleType), - mIsDynamicImport(aKind == Kind::DynamicImport), mLoader(aLoader), mRootModule(aRootModule) { MOZ_ASSERT(mLoader); @@ -168,7 +167,7 @@ void ModuleLoadRequest::ModuleErrored() { void ModuleLoadRequest::LoadFinished() { RefPtr<ModuleLoadRequest> request(this); - if (IsTopLevel() && IsDynamicImport()) { + if (IsDynamicImport()) { mLoader->RemoveDynamicImport(request); } diff --git a/js/loader/ModuleLoadRequest.h b/js/loader/ModuleLoadRequest.h @@ -40,15 +40,13 @@ class ModuleLoadRequest final : public ScriptLoadRequest { using SRIMetadata = mozilla::dom::SRIMetadata; enum class Kind { - // Top-level modules, not imported statically or dynamically.. + // Top-level modules, not imported statically nor dynamically. TopLevel, // Modules imported statically with `import` declarations. StaticImport, // Modules imported dynamically with dynamic `import()`. - // This is actually also a top-level module, but this should be used for - // dynamic imports. DynamicImport, }; @@ -59,9 +57,9 @@ class ModuleLoadRequest final : public ScriptLoadRequest { LoadContextBase* aContext, Kind aKind, ModuleLoaderBase* aLoader, ModuleLoadRequest* aRootModule); - bool IsTopLevel() const override { return mIsTopLevel; } - - bool IsDynamicImport() const { return mIsDynamicImport; } + bool IsTopLevel() const override { return mKind == Kind::TopLevel; } + bool IsStaticImport() const { return mKind == Kind::StaticImport; } + bool IsDynamicImport() const { return mKind == Kind::DynamicImport; } bool IsErrored() const; @@ -113,15 +111,11 @@ class ModuleLoadRequest final : public ScriptLoadRequest { mReferrerPolicy = aReferrerPolicy; } - // Is this a request for a top level module script or an import? - const bool mIsTopLevel; + const Kind mKind; // Type of module (JavaScript, JSON) const ModuleType mModuleType; - // Is this the top level request for a dynamic module import? - const bool mIsDynamicImport; - // Pointer to the script loader, used to trigger actions when the module load // finishes. RefPtr<ModuleLoaderBase> mLoader; diff --git a/js/loader/ModuleLoaderBase.cpp b/js/loader/ModuleLoaderBase.cpp @@ -17,7 +17,6 @@ #include "js/ContextOptions.h" // JS::ContextOptionsRef #include "js/ErrorReport.h" // JSErrorBase #include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_* -#include "js/friend/StackLimits.h" // js::AutoCheckRecursionLimit #include "js/Modules.h" // JS::FinishLoadingImportedModule, JS::{G,S}etModuleResolveHook, JS::Get{ModulePrivate,ModuleScript,RequestedModule{s,Specifier,SourcePos}}, JS::SetModule{Load,Metadata}Hook #include "js/PropertyAndElement.h" // JS_DefineProperty, JS_GetElement #include "js/SourceText.h" @@ -789,7 +788,7 @@ nsresult ModuleLoaderBase::OnFetchComplete(ModuleLoadRequest* aRequest, } void ModuleLoaderBase::OnFetchSucceeded(ModuleLoadRequest* aRequest) { - if (aRequest->IsTopLevel()) { + if (aRequest->IsTopLevel() || aRequest->IsDynamicImport()) { StartFetchingModuleDependencies(aRequest); } else { MOZ_ASSERT(!aRequest->IsDynamicImport()); @@ -1150,7 +1149,7 @@ void ModuleLoaderBase::StartFetchingModuleDependencies( ModuleScript* moduleScript = aRequest->mModuleScript; MOZ_ASSERT(moduleScript->ModuleRecord()); MOZ_ASSERT(aRequest->IsFetching() || aRequest->IsCompiling()); - MOZ_ASSERT(aRequest->IsTopLevel()); + MOZ_ASSERT(aRequest->IsTopLevel() || aRequest->IsDynamicImport()); AutoJSAPI jsapi; if (NS_WARN_IF(!jsapi.Init(mGlobalObject))) {