Bug 1803810 - Part 2: Make module loader overridable. r=jonco

In order to perform sync load in arbitrary global, add
ModuleLoaderBase::mOverriddenBy field, and let
ModuleLoaderBase::GetCurrentModuleLoader return the overridden loader,
so that the module loading can be overridden by SyncModuleLoader.

AutoOverrideModuleLoader manages the lifetime of the override.

Differential Revision: https://phabricator.services.mozilla.com/D199454
This commit is contained in:
Tooru Fujisawa
2024-02-13 14:34:21 +00:00
parent e39b7e1b3d
commit cd29228129
2 changed files with 73 additions and 1 deletions

View File

@@ -20,11 +20,13 @@
#include "js/Modules.h" // JS::FinishDynamicModuleImport, JS::{G,S}etModuleResolveHook, JS::Get{ModulePrivate,ModuleScript,RequestedModule{s,Specifier,SourcePos}}, JS::SetModule{DynamicImport,Metadata}Hook
#include "js/PropertyAndElement.h" // JS_DefineProperty, JS_GetElement
#include "js/SourceText.h"
#include "mozilla/Assertions.h" // MOZ_ASSERT
#include "mozilla/BasePrincipal.h"
#include "mozilla/dom/AutoEntryScript.h"
#include "mozilla/dom/ScriptLoadContext.h"
#include "mozilla/CycleCollectedJSContext.h" // nsAutoMicroTask
#include "mozilla/Preferences.h"
#include "mozilla/RefPtr.h" // mozilla::StaticRefPtr
#include "mozilla/StaticPrefs_dom.h"
#include "nsContentUtils.h"
#include "nsICacheInfoChannel.h" // nsICacheInfoChannel
@@ -342,6 +344,34 @@ bool ModuleLoaderBase::HostImportModuleDynamically(
return true;
}
AutoOverrideModuleLoader::AutoOverrideModuleLoader(ModuleLoaderBase* aTarget,
ModuleLoaderBase* aLoader)
: mTarget(aTarget) {
mTarget->SetOverride(aLoader);
}
AutoOverrideModuleLoader::~AutoOverrideModuleLoader() {
mTarget->ResetOverride();
}
void ModuleLoaderBase::SetOverride(ModuleLoaderBase* aLoader) {
MOZ_ASSERT(!mOverriddenBy);
MOZ_ASSERT(!aLoader->mOverriddenBy);
MOZ_ASSERT(mGlobalObject == aLoader->mGlobalObject);
mOverriddenBy = aLoader;
}
bool ModuleLoaderBase::IsOverridden() { return !!mOverriddenBy; }
bool ModuleLoaderBase::IsOverriddenBy(ModuleLoaderBase* aLoader) {
return mOverriddenBy == aLoader;
}
void ModuleLoaderBase::ResetOverride() {
MOZ_ASSERT(mOverriddenBy);
mOverriddenBy = nullptr;
}
// static
ModuleLoaderBase* ModuleLoaderBase::GetCurrentModuleLoader(JSContext* aCx) {
auto reportError = mozilla::MakeScopeExit([aCx]() {
@@ -366,6 +396,11 @@ ModuleLoaderBase* ModuleLoaderBase::GetCurrentModuleLoader(JSContext* aCx) {
MOZ_ASSERT(loader->mGlobalObject == global);
reportError.release();
if (loader->mOverriddenBy) {
MOZ_ASSERT(loader->mOverriddenBy->mGlobalObject == global);
return loader->mOverriddenBy;
}
return loader;
}
@@ -1183,7 +1218,10 @@ nsresult ModuleLoaderBase::EvaluateModuleInContext(
JSContext* aCx, ModuleLoadRequest* aRequest,
JS::ModuleErrorBehaviour errorBehaviour) {
MOZ_ASSERT(aRequest->mLoader == this);
MOZ_ASSERT(mGlobalObject->GetModuleLoader(aCx) == this);
MOZ_ASSERT_IF(!mGlobalObject->GetModuleLoader(aCx)->IsOverridden(),
mGlobalObject->GetModuleLoader(aCx) == this);
MOZ_ASSERT_IF(mGlobalObject->GetModuleLoader(aCx)->IsOverridden(),
mGlobalObject->GetModuleLoader(aCx)->IsOverriddenBy(this));
AUTO_PROFILER_LABEL("ModuleLoaderBase::EvaluateModule", JS);