Backed out 10 changesets (bug 1803810) for xpcshell failures on test_import_global. CLOSED TREE

Backed out changeset d5df64b38425 (bug 1803810)
Backed out changeset b8f45cbb5596 (bug 1803810)
Backed out changeset c02d879622bd (bug 1803810)
Backed out changeset 9593275c0195 (bug 1803810)
Backed out changeset 2e2f01296233 (bug 1803810)
Backed out changeset 9699c18e5bf7 (bug 1803810)
Backed out changeset 84cdfd738db6 (bug 1803810)
Backed out changeset 58160b9119ef (bug 1803810)
Backed out changeset 4aa6e036fe7a (bug 1803810)
Backed out changeset 656b61cbd15c (bug 1803810)
This commit is contained in:
Cosmin Sabou 2024-02-13 17:41:01 +02:00
parent 2414d5152e
commit e4edda3c7e
36 changed files with 102 additions and 2183 deletions

View file

@ -32,7 +32,6 @@
#include "mozilla/ScopeExit.h"
#include "mozilla/ScrollingMetrics.h"
#include "mozilla/SharedStyleSheetCache.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/IdleDeadline.h"
@ -619,150 +618,22 @@ static mozJSModuleLoader* GetContextualESLoader(
return mozJSModuleLoader::Get();
}
static mozJSModuleLoader* GetModuleLoaderForCurrentGlobal(
JSContext* aCx, const GlobalObject& aGlobal,
Maybe<loader::NonSharedGlobalSyncModuleLoaderScope>&
aMaybeSyncLoaderScope) {
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
if (mozJSModuleLoader::IsSharedSystemGlobal(global)) {
return mozJSModuleLoader::Get();
}
if (mozJSModuleLoader::IsDevToolsLoaderGlobal(global)) {
return mozJSModuleLoader::GetOrCreateDevToolsLoader();
}
if (loader::NonSharedGlobalSyncModuleLoaderScope::IsActive()) {
mozJSModuleLoader* moduleloader =
loader::NonSharedGlobalSyncModuleLoaderScope::ActiveLoader();
if (!moduleloader->IsLoaderGlobal(global->GetGlobalJSObject())) {
JS_ReportErrorASCII(aCx,
"global: \"current\" option cannot be used for "
"different global while other importESModule "
"with global: \"current\" is on the stack");
return nullptr;
}
return moduleloader;
}
RefPtr targetModuleLoader = global->GetModuleLoader(aCx);
if (!targetModuleLoader) {
// Sandbox without associated window returns nullptr for GetModuleLoader.
JS_ReportErrorASCII(aCx, "No ModuleLoader found for the current context");
return nullptr;
}
if (targetModuleLoader->HasFetchingModules()) {
if (!NS_IsMainThread()) {
JS_ReportErrorASCII(aCx,
"ChromeUtils.importESModule cannot be used in worker "
"when there is ongoing dynamic import");
return nullptr;
}
if (!mozilla::SpinEventLoopUntil(
"importESModule for current global"_ns, [&]() -> bool {
return !targetModuleLoader->HasFetchingModules();
})) {
JS_ReportErrorASCII(aCx, "Failed to wait for ongoing module requests");
return nullptr;
}
}
aMaybeSyncLoaderScope.emplace(aCx, global);
return aMaybeSyncLoaderScope->ActiveLoader();
}
static mozJSModuleLoader* GetModuleLoaderForOptions(
JSContext* aCx, const GlobalObject& aGlobal,
const ImportESModuleOptionsDictionary& aOptions,
Maybe<loader::NonSharedGlobalSyncModuleLoaderScope>&
aMaybeSyncLoaderScope) {
if (!aOptions.mGlobal.WasPassed()) {
return GetContextualESLoader(aOptions.mLoadInDevToolsLoader, aGlobal.Get());
}
switch (aOptions.mGlobal.Value()) {
case ImportESModuleTargetGlobal::Shared:
return mozJSModuleLoader::Get();
case ImportESModuleTargetGlobal::Devtools:
return mozJSModuleLoader::GetOrCreateDevToolsLoader();
case ImportESModuleTargetGlobal::Contextual: {
if (!NS_IsMainThread()) {
return GetModuleLoaderForCurrentGlobal(aCx, aGlobal,
aMaybeSyncLoaderScope);
}
RefPtr devToolsModuleloader = mozJSModuleLoader::GetDevToolsLoader();
if (devToolsModuleloader &&
devToolsModuleloader->IsLoaderGlobal(aGlobal.Get())) {
return mozJSModuleLoader::GetOrCreateDevToolsLoader();
}
return mozJSModuleLoader::Get();
}
case ImportESModuleTargetGlobal::Current:
return GetModuleLoaderForCurrentGlobal(aCx, aGlobal,
aMaybeSyncLoaderScope);
default:
MOZ_CRASH("Unknown ImportESModuleTargetGlobal");
}
}
static bool ValidateImportOptions(
JSContext* aCx, const ImportESModuleOptionsDictionary& aOptions) {
if (!NS_IsMainThread() &&
(!aOptions.mGlobal.WasPassed() ||
(aOptions.mGlobal.Value() != ImportESModuleTargetGlobal::Current &&
aOptions.mGlobal.Value() != ImportESModuleTargetGlobal::Contextual))) {
JS_ReportErrorASCII(aCx,
"ChromeUtils.importESModule: Only { global: "
"\"current\" } and { global: \"contextual\" } options "
"are supported on worker");
return false;
}
if (aOptions.mGlobal.WasPassed() &&
aOptions.mLoadInDevToolsLoader.WasPassed()) {
JS_ReportErrorASCII(aCx,
"global option and loadInDevToolsLoader option "
"cannot be used at the same time");
return false;
}
return true;
}
/* static */
void ChromeUtils::ImportESModule(
const GlobalObject& aGlobal, const nsAString& aResourceURI,
const ImportESModuleOptionsDictionary& aOptions,
JS::MutableHandle<JSObject*> aRetval, ErrorResult& aRv) {
JSContext* cx = aGlobal.Context();
if (!ValidateImportOptions(cx, aOptions)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
Maybe<loader::NonSharedGlobalSyncModuleLoaderScope> maybeSyncLoaderScope;
RefPtr<mozJSModuleLoader> moduleloader =
GetModuleLoaderForOptions(cx, aGlobal, aOptions, maybeSyncLoaderScope);
if (!moduleloader) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
RefPtr moduleloader =
GetContextualESLoader(aOptions.mLoadInDevToolsLoader, aGlobal.Get());
MOZ_ASSERT(moduleloader);
NS_ConvertUTF16toUTF8 registryLocation(aResourceURI);
AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING_NONSENSITIVE(
"ChromeUtils::ImportESModule", OTHER, registryLocation);
JSContext* cx = aGlobal.Context();
JS::Rooted<JSObject*> moduleNamespace(cx);
nsresult rv =
moduleloader->ImportESModule(cx, registryLocation, &moduleNamespace);
@ -778,10 +649,6 @@ void ChromeUtils::ImportESModule(
return;
}
aRetval.set(moduleNamespace);
if (maybeSyncLoaderScope) {
maybeSyncLoaderScope->Finish();
}
}
namespace lazy_getter {

View file

@ -313,25 +313,6 @@ namespace ChromeUtils {
[NewObject]
Promise<sequence<CDMInformation>> getGMPContentDecryptionModuleInformation();
/**
* Synchronously loads and evaluates the JS module source located at
* 'aResourceURI'.
*
* @param aResourceURI A resource:// URI string to load the module from.
* @param aOption An option to specify where to load the module into.
* @returns the module's namespace object.
*
* The implementation maintains a hash of aResourceURI->global obj.
* Subsequent invocations of import with 'aResourceURI' pointing to
* the same file will not cause the module to be re-evaluated.
*
* In worker threads, aOption is required and only { global: "current" } and
* { global: "contextual" } are supported.
*/
[Throws]
object importESModule(DOMString aResourceURI,
optional ImportESModuleOptionsDictionary aOptions = {});
/**
* IF YOU ADD NEW METHODS HERE, MAKE SURE THEY ARE THREAD-SAFE.
*/
@ -527,6 +508,20 @@ partial namespace ChromeUtils {
[Throws]
object import(UTF8String aResourceURI, optional object aTargetObj);
/**
* Synchronously loads and evaluates the JS module source located at
* 'aResourceURI'.
*
* @param aResourceURI A resource:// URI string to load the module from.
* @returns the module's namespace object.
*
* The implementation maintains a hash of aResourceURI->global obj.
* Subsequent invocations of import with 'aResourceURI' pointing to
* the same file will not cause the module to be re-evaluated.
*/
[Throws]
object importESModule(DOMString aResourceURI, optional ImportESModuleOptionsDictionary options = {});
/**
* Defines a property on the given target which lazily imports a JavaScript
* module when accessed.
@ -988,41 +983,6 @@ dictionary CompileScriptOptionsDictionary {
boolean hasReturnValue = false;
};
/**
* Where the modules are loaded into with importESModule.
*/
enum ImportESModuleTargetGlobal {
/**
* Load into the shared system global.
* This is the default value.
*/
"shared",
/**
* Load into a distinct system global for DevTools, so that the DevTools can
* load a distinct set of modules and do not interfere with its debuggee.
*/
"devtools",
/**
* If the current global is DevTools' distinct system global, load into the
* DevTools' distinct system global.
* If the current thread is worker thread, load into the current global.
* Otherwise load into the shared system global.
*
* This is a temporary workaround until DevTools modules are ESMified.
*/
"contextual",
/**
* Load into current global.
*
* This can be used for any global. If this is used for shared global or
* devtools global, this has the same effect as "shared" or "devtools".
*/
"current",
};
dictionary ImportESModuleOptionsDictionary {
/**
* If true, a distinct module loader will be used, in the system principal,
@ -1030,8 +990,6 @@ dictionary ImportESModuleOptionsDictionary {
* of modules and do not interfere with its debuggee.
*/
boolean loadInDevToolsLoader;
ImportESModuleTargetGlobal global;
};
/**

View file

@ -5,7 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/ScriptLoadContext.h"
#include "mozilla/loader/SyncModuleLoader.h"
#include "mozilla/loader/ComponentModuleLoader.h"
#include "mozilla/dom/WorkerLoadContext.h"
#include "mozilla/dom/worklet/WorkletModuleLoader.h" // WorkletLoadContext
#include "js/loader/LoadContextBase.h"
@ -42,9 +42,9 @@ mozilla::dom::ScriptLoadContext* LoadContextBase::AsWindowContext() {
return static_cast<mozilla::dom::ScriptLoadContext*>(this);
}
mozilla::loader::SyncLoadContext* LoadContextBase::AsSyncContext() {
MOZ_ASSERT(IsSyncContext());
return static_cast<mozilla::loader::SyncLoadContext*>(this);
mozilla::loader::ComponentLoadContext* LoadContextBase::AsComponentContext() {
MOZ_ASSERT(IsComponentContext());
return static_cast<mozilla::loader::ComponentLoadContext*>(this);
}
mozilla::dom::WorkerLoadContext* LoadContextBase::AsWorkerContext() {

View file

@ -17,7 +17,7 @@ class WorkletLoadContext;
} // namespace mozilla::dom
namespace mozilla::loader {
class SyncLoadContext;
class ComponentLoadContext;
}
namespace JS::loader {
@ -32,7 +32,7 @@ class ScriptLoadRequest;
*
*/
enum class ContextKind { Window, Sync, Worker, Worklet };
enum class ContextKind { Window, Component, Worker, Worklet };
class LoadContextBase : public nsISupports {
private:
@ -56,8 +56,8 @@ class LoadContextBase : public nsISupports {
bool IsWindowContext() const { return mKind == ContextKind::Window; }
mozilla::dom::ScriptLoadContext* AsWindowContext();
bool IsSyncContext() const { return mKind == ContextKind::Sync; }
mozilla::loader::SyncLoadContext* AsSyncContext();
bool IsComponentContext() const { return mKind == ContextKind::Component; }
mozilla::loader::ComponentLoadContext* AsComponentContext();
bool IsWorkerContext() const { return mKind == ContextKind::Worker; }
mozilla::dom::WorkerLoadContext* AsWorkerContext();

View file

@ -20,13 +20,11 @@
#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
@ -344,34 +342,6 @@ 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]() {
@ -396,11 +366,6 @@ 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;
}
@ -1047,10 +1012,6 @@ void ModuleLoaderBase::Shutdown() {
mLoader = nullptr;
}
bool ModuleLoaderBase::HasFetchingModules() const {
return !mFetchingModules.IsEmpty();
}
bool ModuleLoaderBase::HasPendingDynamicImports() const {
return !mDynamicImportRequests.isEmpty();
}
@ -1222,10 +1183,7 @@ nsresult ModuleLoaderBase::EvaluateModuleInContext(
JSContext* aCx, ModuleLoadRequest* aRequest,
JS::ModuleErrorBehaviour errorBehaviour) {
MOZ_ASSERT(aRequest->mLoader == this);
MOZ_ASSERT_IF(!mGlobalObject->GetModuleLoader(aCx)->IsOverridden(),
mGlobalObject->GetModuleLoader(aCx) == this);
MOZ_ASSERT_IF(mGlobalObject->GetModuleLoader(aCx)->IsOverridden(),
mGlobalObject->GetModuleLoader(aCx)->IsOverriddenBy(this));
MOZ_ASSERT(mGlobalObject->GetModuleLoader(aCx) == this);
AUTO_PROFILER_LABEL("ModuleLoaderBase::EvaluateModule", JS);
@ -1389,42 +1347,6 @@ void ModuleLoaderBase::RegisterImportMap(UniquePtr<ImportMap> aImportMap) {
mImportMap = std::move(aImportMap);
}
void ModuleLoaderBase::CopyModulesTo(ModuleLoaderBase* aDest) {
MOZ_ASSERT(aDest->mFetchingModules.IsEmpty());
MOZ_ASSERT(aDest->mFetchedModules.IsEmpty());
MOZ_ASSERT(mFetchingModules.IsEmpty());
for (const auto& entry : mFetchedModules) {
RefPtr<ModuleScript> moduleScript = entry.GetData();
if (!moduleScript) {
continue;
}
aDest->mFetchedModules.InsertOrUpdate(entry.GetKey(), moduleScript);
}
}
void ModuleLoaderBase::MoveModulesTo(ModuleLoaderBase* aDest) {
MOZ_ASSERT(mFetchingModules.IsEmpty());
MOZ_ASSERT(aDest->mFetchingModules.IsEmpty());
for (const auto& entry : mFetchedModules) {
RefPtr<ModuleScript> moduleScript = entry.GetData();
if (!moduleScript) {
continue;
}
#ifdef DEBUG
if (auto existingEntry = aDest->mFetchedModules.Lookup(entry.GetKey())) {
MOZ_ASSERT(moduleScript == existingEntry.Data());
}
#endif
aDest->mFetchedModules.InsertOrUpdate(entry.GetKey(), moduleScript);
}
mFetchedModules.Clear();
}
#undef LOG
#undef LOG_ENABLED

View file

@ -21,7 +21,6 @@
#include "nsINode.h" // nsIURI
#include "nsThreadUtils.h" // GetMainThreadSerialEventTarget
#include "nsURIHashKey.h"
#include "mozilla/Attributes.h" // MOZ_RAII
#include "mozilla/CORSMode.h"
#include "mozilla/dom/JSExecutionContext.h"
#include "mozilla/MaybeOneOf.h"
@ -186,11 +185,6 @@ class ModuleLoaderBase : public nsISupports {
nsCOMPtr<nsIGlobalObject> mGlobalObject;
// If non-null, this module loader is overridden by the module loader pointed
// by mOverriddenBy.
// See ModuleLoaderBase::GetCurrentModuleLoader for more details.
RefPtr<ModuleLoaderBase> mOverriddenBy;
// https://html.spec.whatwg.org/multipage/webappapis.html#import-maps-allowed
//
// Each Window has an import maps allowed boolean, initially true.
@ -282,8 +276,6 @@ class ModuleLoaderBase : public nsISupports {
nsIGlobalObject* GetGlobalObject() const { return mGlobalObject; }
bool HasFetchingModules() const;
bool HasPendingDynamicImports() const;
void CancelDynamicImport(ModuleLoadRequest* aRequest, nsresult aResult);
#ifdef DEBUG
@ -337,37 +329,6 @@ class ModuleLoaderBase : public nsISupports {
// unlinked. Extreme care should be taken when calling this method.
bool RemoveFetchedModule(nsIURI* aURL);
// Override the module loader with given loader until ResetOverride is called.
// While overridden, ModuleLoaderBase::GetCurrentModuleLoader returns aLoader.
//
// This is used by mozJSModuleLoader to temporarily override the global's
// module loader with SyncModuleLoader while importing a module graph
// synchronously.
void SetOverride(ModuleLoaderBase* aLoader);
// Returns true if SetOverride was called.
bool IsOverridden();
// Returns true if SetOverride was called with aLoader.
bool IsOverriddenBy(ModuleLoaderBase* aLoader);
void ResetOverride();
// Copy fetched modules to `aDest`.
// `this` shouldn't have any fetching.
// `aDest` shouldn't have any fetching or fetched modules.
//
// This is used when starting sync module load, to replicate the module cache
// in the sync module loader pointed by `aDest`.
void CopyModulesTo(ModuleLoaderBase* aDest);
// Move all fetched modules to `aDest`.
// Both `this` and `aDest` shouldn't have any fetching.
//
// This is used when finishing sync module load, to reflect the loaded modules
// to the async module loader pointed by `aDest`.
void MoveModulesTo(ModuleLoaderBase* aDest);
// Internal methods.
private:
@ -485,18 +446,6 @@ class ModuleLoaderBase : public nsISupports {
static mozilla::LazyLogModule gModuleLoaderBaseLog;
};
// Override the target module loader with given module loader while this
// instance is on the stack.
class MOZ_RAII AutoOverrideModuleLoader {
public:
AutoOverrideModuleLoader(ModuleLoaderBase* aTarget,
ModuleLoaderBase* aLoader);
~AutoOverrideModuleLoader();
private:
RefPtr<ModuleLoaderBase> mTarget;
};
} // namespace loader
} // namespace JS

View file

@ -130,9 +130,10 @@ mozilla::dom::ScriptLoadContext* ScriptLoadRequest::GetScriptLoadContext() {
return mLoadContext->AsWindowContext();
}
mozilla::loader::SyncLoadContext* ScriptLoadRequest::GetSyncLoadContext() {
mozilla::loader::ComponentLoadContext*
ScriptLoadRequest::GetComponentLoadContext() {
MOZ_ASSERT(mLoadContext);
return mLoadContext->AsSyncContext();
return mLoadContext->AsComponentContext();
}
mozilla::dom::WorkerLoadContext* ScriptLoadRequest::GetWorkerLoadContext() {

View file

@ -38,7 +38,7 @@ enum class RequestPriority : uint8_t;
} // namespace mozilla::dom
namespace mozilla::loader {
class SyncLoadContext;
class ComponentLoadContext;
} // namespace mozilla::loader
namespace JS {
@ -194,7 +194,7 @@ class ScriptLoadRequest : public nsISupports,
mozilla::dom::ScriptLoadContext* GetScriptLoadContext();
mozilla::loader::SyncLoadContext* GetSyncLoadContext();
mozilla::loader::ComponentLoadContext* GetComponentLoadContext();
mozilla::dom::WorkerLoadContext* GetWorkerLoadContext();

View file

@ -4,7 +4,7 @@
* 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 "SyncModuleLoader.h"
#include "ComponentModuleLoader.h"
#include "nsISupportsImpl.h"
@ -20,48 +20,50 @@ namespace mozilla {
namespace loader {
//////////////////////////////////////////////////////////////
// SyncScriptLoader
// ComponentScriptLoader
//////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS0(SyncScriptLoader)
NS_IMPL_ISUPPORTS0(ComponentScriptLoader)
nsIURI* SyncScriptLoader::GetBaseURI() const { return nullptr; }
nsIURI* ComponentScriptLoader::GetBaseURI() const { return nullptr; }
void SyncScriptLoader::ReportErrorToConsole(ScriptLoadRequest* aRequest,
nsresult aResult) const {}
void ComponentScriptLoader::ReportErrorToConsole(ScriptLoadRequest* aRequest,
nsresult aResult) const {}
void SyncScriptLoader::ReportWarningToConsole(
void ComponentScriptLoader::ReportWarningToConsole(
ScriptLoadRequest* aRequest, const char* aMessageName,
const nsTArray<nsString>& aParams) const {}
nsresult SyncScriptLoader::FillCompileOptionsForRequest(
nsresult ComponentScriptLoader::FillCompileOptionsForRequest(
JSContext* cx, ScriptLoadRequest* aRequest, JS::CompileOptions* aOptions,
JS::MutableHandle<JSScript*> aIntroductionScript) {
return NS_OK;
}
//////////////////////////////////////////////////////////////
// SyncModuleLoader
// ComponentModuleLoader
//////////////////////////////////////////////////////////////
NS_IMPL_ADDREF_INHERITED(SyncModuleLoader, JS::loader::ModuleLoaderBase)
NS_IMPL_RELEASE_INHERITED(SyncModuleLoader, JS::loader::ModuleLoaderBase)
NS_IMPL_ADDREF_INHERITED(ComponentModuleLoader, JS::loader::ModuleLoaderBase)
NS_IMPL_RELEASE_INHERITED(ComponentModuleLoader, JS::loader::ModuleLoaderBase)
NS_IMPL_CYCLE_COLLECTION_INHERITED(SyncModuleLoader,
NS_IMPL_CYCLE_COLLECTION_INHERITED(ComponentModuleLoader,
JS::loader::ModuleLoaderBase, mLoadRequests)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SyncModuleLoader)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ComponentModuleLoader)
NS_INTERFACE_MAP_END_INHERITING(JS::loader::ModuleLoaderBase)
SyncModuleLoader::SyncModuleLoader(SyncScriptLoader* aScriptLoader,
nsIGlobalObject* aGlobalObject)
ComponentModuleLoader::ComponentModuleLoader(
ComponentScriptLoader* aScriptLoader, nsIGlobalObject* aGlobalObject)
: ModuleLoaderBase(aScriptLoader, aGlobalObject) {}
SyncModuleLoader::~SyncModuleLoader() { MOZ_ASSERT(mLoadRequests.isEmpty()); }
ComponentModuleLoader::~ComponentModuleLoader() {
MOZ_ASSERT(mLoadRequests.isEmpty());
}
already_AddRefed<ModuleLoadRequest> SyncModuleLoader::CreateStaticImport(
already_AddRefed<ModuleLoadRequest> ComponentModuleLoader::CreateStaticImport(
nsIURI* aURI, ModuleLoadRequest* aParent) {
RefPtr<SyncLoadContext> context = new SyncLoadContext();
RefPtr<ComponentLoadContext> context = new ComponentLoadContext();
RefPtr<ModuleLoadRequest> request = new ModuleLoadRequest(
aURI, aParent->ReferrerPolicy(), aParent->mFetchOptions,
dom::SRIMetadata(), aParent->mURI, context, false, /* is top level */
@ -71,10 +73,10 @@ already_AddRefed<ModuleLoadRequest> SyncModuleLoader::CreateStaticImport(
return request.forget();
}
already_AddRefed<ModuleLoadRequest> SyncModuleLoader::CreateDynamicImport(
already_AddRefed<ModuleLoadRequest> ComponentModuleLoader::CreateDynamicImport(
JSContext* aCx, nsIURI* aURI, LoadedScript* aMaybeActiveScript,
JS::Handle<JSString*> aSpecifier, JS::Handle<JSObject*> aPromise) {
RefPtr<SyncLoadContext> context = new SyncLoadContext();
RefPtr<ComponentLoadContext> context = new ComponentLoadContext();
RefPtr<ModuleLoadRequest> request = new ModuleLoadRequest(
aURI, aMaybeActiveScript->ReferrerPolicy(),
aMaybeActiveScript->GetFetchOptions(), dom::SRIMetadata(),
@ -88,7 +90,8 @@ already_AddRefed<ModuleLoadRequest> SyncModuleLoader::CreateDynamicImport(
return request.forget();
}
void SyncModuleLoader::OnDynamicImportStarted(ModuleLoadRequest* aRequest) {
void ComponentModuleLoader::OnDynamicImportStarted(
ModuleLoadRequest* aRequest) {
MOZ_ASSERT(aRequest->IsDynamicImport());
MOZ_ASSERT(!mLoadRequests.Contains(aRequest));
@ -125,12 +128,12 @@ void SyncModuleLoader::OnDynamicImportStarted(ModuleLoadRequest* aRequest) {
ProcessDynamicImport(aRequest);
}
bool SyncModuleLoader::CanStartLoad(ModuleLoadRequest* aRequest,
nsresult* aRvOut) {
bool ComponentModuleLoader::CanStartLoad(ModuleLoadRequest* aRequest,
nsresult* aRvOut) {
return mozJSModuleLoader::IsTrustedScheme(aRequest->mURI);
}
nsresult SyncModuleLoader::StartFetch(ModuleLoadRequest* aRequest) {
nsresult ComponentModuleLoader::StartFetch(ModuleLoadRequest* aRequest) {
MOZ_ASSERT(aRequest->HasLoadContext());
aRequest->mBaseURL = aRequest->mURI;
@ -183,7 +186,7 @@ nsresult SyncModuleLoader::StartFetch(ModuleLoadRequest* aRequest) {
}
// Otherwise remember the results in this context so we can report them later.
SyncLoadContext* context = aRequest->GetSyncLoadContext();
ComponentLoadContext* context = aRequest->GetComponentLoadContext();
context->mRv = rv;
if (threwException) {
context->mExceptionValue.init(cx);
@ -204,11 +207,11 @@ nsresult SyncModuleLoader::StartFetch(ModuleLoadRequest* aRequest) {
return NS_OK;
}
nsresult SyncModuleLoader::CompileFetchedModule(
nsresult ComponentModuleLoader::CompileFetchedModule(
JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::CompileOptions& aOptions,
ModuleLoadRequest* aRequest, JS::MutableHandle<JSObject*> aModuleOut) {
// Compilation already happened in StartFetch. Report the result here.
SyncLoadContext* context = aRequest->GetSyncLoadContext();
ComponentLoadContext* context = aRequest->GetComponentLoadContext();
nsresult rv = context->mRv;
if (context->mScript) {
aModuleOut.set(JS::GetModuleObject(context->mScript));
@ -225,7 +228,7 @@ nsresult SyncModuleLoader::CompileFetchedModule(
return rv;
}
void SyncModuleLoader::MaybeReportLoadError(JSContext* aCx) {
void ComponentModuleLoader::MaybeReportLoadError(JSContext* aCx) {
if (JS_IsExceptionPending(aCx)) {
// Do not override.
return;
@ -239,9 +242,9 @@ void SyncModuleLoader::MaybeReportLoadError(JSContext* aCx) {
mLoadException = JS::UndefinedValue();
}
void SyncModuleLoader::OnModuleLoadComplete(ModuleLoadRequest* aRequest) {}
void ComponentModuleLoader::OnModuleLoadComplete(ModuleLoadRequest* aRequest) {}
nsresult SyncModuleLoader::ProcessRequests() {
nsresult ComponentModuleLoader::ProcessRequests() {
// Work list to drive module loader since this is all synchronous.
while (!mLoadRequests.isEmpty()) {
RefPtr<ScriptLoadRequest> request = mLoadRequests.StealFirst();

View file

@ -4,8 +4,8 @@
* 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/. */
#ifndef mozilla_loader_SyncModuleLoader_h
#define mozilla_loader_SyncModuleLoader_h
#ifndef mozilla_loader_ComponentModuleLoader_h
#define mozilla_loader_ComponentModuleLoader_h
#include "js/loader/LoadContextBase.h"
#include "js/loader/ModuleLoaderBase.h"
@ -17,12 +17,12 @@ class mozJSModuleLoader;
namespace mozilla {
namespace loader {
class SyncScriptLoader : public JS::loader::ScriptLoaderInterface {
class ComponentScriptLoader : public JS::loader::ScriptLoaderInterface {
public:
NS_DECL_ISUPPORTS
private:
~SyncScriptLoader() = default;
~ComponentScriptLoader() = default;
nsIURI* GetBaseURI() const override;
@ -38,21 +38,21 @@ class SyncScriptLoader : public JS::loader::ScriptLoaderInterface {
JS::MutableHandle<JSScript*> aIntroductionScript) override;
};
class SyncModuleLoader : public JS::loader::ModuleLoaderBase {
class ComponentModuleLoader : public JS::loader::ModuleLoaderBase {
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SyncModuleLoader,
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ComponentModuleLoader,
JS::loader::ModuleLoaderBase)
SyncModuleLoader(SyncScriptLoader* aScriptLoader,
nsIGlobalObject* aGlobalObject);
ComponentModuleLoader(ComponentScriptLoader* aScriptLoader,
nsIGlobalObject* aGlobalObject);
[[nodiscard]] nsresult ProcessRequests();
void MaybeReportLoadError(JSContext* aCx);
private:
~SyncModuleLoader();
~ComponentModuleLoader();
already_AddRefed<ModuleLoadRequest> CreateStaticImport(
nsIURI* aURI, ModuleLoadRequest* aParent) override;
@ -82,11 +82,12 @@ class SyncModuleLoader : public JS::loader::ModuleLoaderBase {
JS::PersistentRooted<JS::Value> mLoadException;
};
// Data specific to SyncModuleLoader that is associated with each load
// Data specific to ComponentModuleLoader that is associated with each load
// request.
class SyncLoadContext : public JS::loader::LoadContextBase {
class ComponentLoadContext : public JS::loader::LoadContextBase {
public:
SyncLoadContext() : LoadContextBase(JS::loader::ContextKind::Sync) {}
ComponentLoadContext()
: LoadContextBase(JS::loader::ContextKind::Component) {}
public:
// The result of compiling a module script. These fields are used temporarily
@ -105,4 +106,4 @@ class SyncLoadContext : public JS::loader::LoadContextBase {
} // namespace loader
} // namespace mozilla
#endif // mozilla_loader_SyncModuleLoader_h
#endif // mozilla_loader_ComponentModuleLoader_h

View file

@ -7,6 +7,7 @@
UNIFIED_SOURCES += [
"AutoMemMap.cpp",
"ChromeScriptLoader.cpp",
"ComponentModuleLoader.cpp",
"JSMEnvironmentProxy.cpp",
"ModuleEnvironmentProxy.cpp",
"mozJSLoaderUtils.cpp",
@ -14,7 +15,6 @@ UNIFIED_SOURCES += [
"nsImportModule.cpp",
"ScriptCacheActors.cpp",
"ScriptPreloader.cpp",
"SyncModuleLoader.cpp",
"URLPreloader.cpp",
]
@ -43,9 +43,9 @@ EXPORTS.mozilla.dom += [
EXPORTS.mozilla.loader += [
"AutoMemMap.h",
"ComponentModuleLoader.h",
"ScriptCacheActors.h",
"SkipCheckForBrokenURLOrZeroSized.h",
"SyncModuleLoader.h",
]
EXTRA_JS_MODULES += [

View file

@ -5,10 +5,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ScriptLoadRequest.h"
#include "mozilla/Assertions.h" // MOZ_ASSERT, MOZ_ASSERT_IF
#include "mozilla/Attributes.h"
#include "mozilla/ArrayUtils.h" // mozilla::ArrayLength
#include "mozilla/RefPtr.h" // RefPtr, mozilla::StaticRefPtr
#include "mozilla/Utf8.h" // mozilla::Utf8Unit
#include <cstdarg>
@ -46,7 +44,6 @@
#include "nsIFileURL.h"
#include "nsIJARURI.h"
#include "nsIChannel.h"
#include "nsIStreamListener.h"
#include "nsNetUtil.h"
#include "nsJSUtils.h"
#include "xpcprivate.h"
@ -72,9 +69,6 @@
#include "mozilla/dom/AutoEntryScript.h"
#include "mozilla/dom/ReferrerPolicyBinding.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/WorkerCommon.h" // dom::GetWorkerPrivateFromContext
#include "mozilla/dom/WorkerPrivate.h" // dom::WorkerPrivate, dom::AutoSyncLoopHolder
#include "mozilla/dom/WorkerRunnable.h" // dom::MainThreadStopSyncLoopRunnable
#include "mozilla/Unused.h"
using namespace mozilla;
@ -308,7 +302,7 @@ class MOZ_STACK_CLASS ModuleLoaderInfo {
: mLocation(nullptr),
mURI(aRequest->mURI),
mIsModule(true),
mSkipCheck(aRequest->GetSyncLoadContext()->mSkipCheck) {}
mSkipCheck(aRequest->GetComponentLoadContext()->mSkipCheck) {}
SkipCheckForBrokenURLOrZeroSized getSkipCheckForBrokenURLOrZeroSized() const {
return mSkipCheck;
@ -454,7 +448,6 @@ void mozJSModuleLoader::InitStatics() {
MOZ_ASSERT(!sSelf);
sSelf = new mozJSModuleLoader();
RegisterWeakMemoryReporter(sSelf);
NonSharedGlobalSyncModuleLoaderScope::InitStatics();
}
void mozJSModuleLoader::UnloadLoaders() {
@ -495,35 +488,6 @@ mozJSModuleLoader* mozJSModuleLoader::GetOrCreateDevToolsLoader() {
return sDevToolsLoader;
}
void mozJSModuleLoader::InitSyncModuleLoaderForGlobal(
nsIGlobalObject* aGlobal) {
MOZ_ASSERT(!mLoaderGlobal);
MOZ_ASSERT(!mModuleLoader);
RefPtr<SyncScriptLoader> scriptLoader = new SyncScriptLoader;
mModuleLoader = new SyncModuleLoader(scriptLoader, aGlobal);
mLoaderGlobal = aGlobal->GetGlobalJSObject();
}
void mozJSModuleLoader::DisconnectSyncModuleLoaderFromGlobal() {
MOZ_ASSERT(mLoaderGlobal);
MOZ_ASSERT(mModuleLoader);
mLoaderGlobal = nullptr;
Unload();
}
/* static */
bool mozJSModuleLoader::IsSharedSystemGlobal(nsIGlobalObject* aGlobal) {
return sSelf->IsLoaderGlobal(aGlobal->GetGlobalJSObject());
}
/* static */
bool mozJSModuleLoader::IsDevToolsLoaderGlobal(nsIGlobalObject* aGlobal) {
return sDevToolsLoader &&
sDevToolsLoader->IsLoaderGlobal(aGlobal->GetGlobalJSObject());
}
// This requires that the keys be strings and the values be pointers.
template <class Key, class Data, class UserData, class Converter>
static size_t SizeOfTableExcludingThis(
@ -675,8 +639,8 @@ void mozJSModuleLoader::CreateLoaderGlobal(JSContext* aCx,
xpc::SetLocationForGlobal(global, aLocation);
MOZ_ASSERT(!mModuleLoader);
RefPtr<SyncScriptLoader> scriptLoader = new SyncScriptLoader;
mModuleLoader = new SyncModuleLoader(scriptLoader, backstagePass);
RefPtr<ComponentScriptLoader> scriptLoader = new ComponentScriptLoader;
mModuleLoader = new ComponentModuleLoader(scriptLoader, backstagePass);
backstagePass->InitModuleLoader(mModuleLoader);
aGlobal.set(global);
@ -704,188 +668,9 @@ JSObject* mozJSModuleLoader::GetSharedGlobal(JSContext* aCx) {
return mLoaderGlobal;
}
// Read script file on the main thread and pass it back to worker.
class ScriptReaderRunnable final : public nsIRunnable,
public nsINamed,
public nsIStreamListener {
public:
ScriptReaderRunnable(dom::WorkerPrivate* aWorkerPrivate,
nsIEventTarget* aSyncLoopTarget,
const nsCString& aLocation)
: mLocation(aLocation),
mRv(NS_ERROR_FAILURE),
mWorkerPrivate(aWorkerPrivate),
mSyncLoopTarget(aSyncLoopTarget) {}
NS_DECL_THREADSAFE_ISUPPORTS
nsCString& Data() { return mData; }
nsresult Result() const { return mRv; }
// nsIRunnable
NS_IMETHOD
Run() override {
MOZ_ASSERT(NS_IsMainThread());
nsresult rv = StartReadScriptFromLocation();
if (NS_FAILED(rv)) {
OnComplete(rv);
}
return NS_OK;
}
// nsINamed
NS_IMETHOD
GetName(nsACString& aName) override {
aName.AssignLiteral("ScriptReaderRunnable");
return NS_OK;
}
// nsIStreamListener
NS_IMETHOD OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInputStream,
uint64_t aOffset, uint32_t aCount) override {
uint32_t read = 0;
return aInputStream->ReadSegments(AppendSegmentToData, this, aCount, &read);
}
// nsIRequestObserver
NS_IMETHOD OnStartRequest(nsIRequest* aRequest) override { return NS_OK; }
NS_IMETHOD OnStopRequest(nsIRequest* aRequest,
nsresult aStatusCode) override {
OnComplete(aStatusCode);
return NS_OK;
}
private:
~ScriptReaderRunnable() = default;
static nsresult AppendSegmentToData(nsIInputStream* aInputStream,
void* aClosure, const char* aRawSegment,
uint32_t aToOffset, uint32_t aCount,
uint32_t* outWrittenCount) {
auto* self = static_cast<ScriptReaderRunnable*>(aClosure);
self->mData.Append(aRawSegment, aCount);
*outWrittenCount = aCount;
return NS_OK;
}
void OnComplete(nsresult aRv) {
MOZ_ASSERT(NS_IsMainThread());
mRv = aRv;
RefPtr<dom::MainThreadStopSyncLoopRunnable> runnable =
new dom::MainThreadStopSyncLoopRunnable(
mWorkerPrivate, std::move(mSyncLoopTarget), mRv);
MOZ_ALWAYS_TRUE(runnable->Dispatch());
mWorkerPrivate = nullptr;
mSyncLoopTarget = nullptr;
}
nsresult StartReadScriptFromLocation() {
MOZ_ASSERT(NS_IsMainThread());
ModuleLoaderInfo info(mLocation);
nsresult rv = info.EnsureScriptChannel();
NS_ENSURE_SUCCESS(rv, rv);
return info.ScriptChannel()->AsyncOpen(this);
}
private:
nsAutoCString mLocation;
nsCString mData;
nsresult mRv;
// This pointer is guaranteed to be alive until OnComplete, given
// the worker thread is synchronously waiting with AutoSyncLoopHolder::Run
// until the corresponding WorkerPrivate::StopSyncLoop is called by
// MainThreadStopSyncLoopRunnable, which is dispatched from OnComplete.
dom::WorkerPrivate* mWorkerPrivate;
nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
};
NS_IMPL_ISUPPORTS(ScriptReaderRunnable, nsIRunnable, nsINamed,
nsIStreamListener)
/* static */
nsresult mozJSModuleLoader::ReadScriptOnMainThread(JSContext* aCx,
const nsCString& aLocation,
nsCString& aData) {
dom::WorkerPrivate* workerPrivate = dom::GetWorkerPrivateFromContext(aCx);
MOZ_ASSERT(workerPrivate);
dom::AutoSyncLoopHolder syncLoop(workerPrivate, dom::WorkerStatus::Canceling);
nsCOMPtr<nsISerialEventTarget> syncLoopTarget =
syncLoop.GetSerialEventTarget();
if (!syncLoopTarget) {
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
RefPtr<ScriptReaderRunnable> runnable =
new ScriptReaderRunnable(workerPrivate, syncLoopTarget, aLocation);
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
return NS_ERROR_FAILURE;
}
syncLoop.Run();
if (NS_FAILED(runnable->Result())) {
return runnable->Result();
}
aData = std::move(runnable->Data());
return NS_OK;
}
/* static */
nsresult mozJSModuleLoader::LoadSingleModuleScriptOnWorker(
SyncModuleLoader* aModuleLoader, JSContext* aCx,
JS::loader::ModuleLoadRequest* aRequest, MutableHandleScript aScriptOut) {
nsAutoCString location;
nsresult rv = aRequest->mURI->GetSpec(location);
NS_ENSURE_SUCCESS(rv, rv);
nsCString data;
rv = ReadScriptOnMainThread(aCx, location, data);
NS_ENSURE_SUCCESS(rv, rv);
CompileOptions options(aCx);
ScriptPreloader::FillCompileOptionsForCachedStencil(options);
options.setFileAndLine(location.BeginReading(), 1);
SetModuleOptions(options);
JS::SourceText<mozilla::Utf8Unit> srcBuf;
if (!srcBuf.init(aCx, data.get(), data.Length(),
JS::SourceOwnership::Borrowed)) {
return NS_ERROR_FAILURE;
}
RefPtr<JS::Stencil> stencil =
CompileStencil(aCx, options, srcBuf, /* aIsModule = */ true);
if (!stencil) {
return NS_ERROR_FAILURE;
}
aScriptOut.set(InstantiateStencil(aCx, stencil, /* aIsModule = */ true));
return NS_OK;
}
/* static */
nsresult mozJSModuleLoader::LoadSingleModuleScript(
SyncModuleLoader* aModuleLoader, JSContext* aCx,
ComponentModuleLoader* aModuleLoader, JSContext* aCx,
JS::loader::ModuleLoadRequest* aRequest, MutableHandleScript aScriptOut) {
AUTO_PROFILER_MARKER_TEXT(
"ChromeUtils.importESModule static import", JS,
@ -893,11 +678,6 @@ nsresult mozJSModuleLoader::LoadSingleModuleScript(
MarkerInnerWindowIdFromJSContext(aCx)),
nsContentUtils::TruncatedURLForDisplay(aRequest->mURI));
if (!NS_IsMainThread()) {
return LoadSingleModuleScriptOnWorker(aModuleLoader, aCx, aRequest,
aScriptOut);
}
ModuleLoaderInfo info(aRequest);
nsresult rv = info.EnsureResolvedURI();
NS_ENSURE_SUCCESS(rv, rv);
@ -915,12 +695,10 @@ nsresult mozJSModuleLoader::LoadSingleModuleScript(
#ifdef STARTUP_RECORDER_ENABLED
if (aModuleLoader == sSelf->mModuleLoader) {
sSelf->RecordImportStack(aCx, aRequest);
} else if (sDevToolsLoader &&
aModuleLoader == sDevToolsLoader->mModuleLoader) {
sDevToolsLoader->RecordImportStack(aCx, aRequest);
} else {
// NOTE: Do not record import stack for non-shared globals, given the
// loader is associated with the global only while importing.
MOZ_ASSERT(sDevToolsLoader);
MOZ_ASSERT(aModuleLoader == sDevToolsLoader->mModuleLoader);
sDevToolsLoader->RecordImportStack(aCx, aRequest);
}
#endif
@ -1115,17 +893,6 @@ nsresult mozJSModuleLoader::ObjectForLocation(
return rv;
}
/* static */
void mozJSModuleLoader::SetModuleOptions(CompileOptions& aOptions) {
aOptions.setModule();
// Top level await is not supported in synchronously loaded modules.
aOptions.topLevelAwait = false;
// Make all top-level `vars` available in `ModuleEnvironmentObject`.
aOptions.deoptimizeModuleGlobalVars = true;
}
/* static */
nsresult mozJSModuleLoader::GetScriptForLocation(
JSContext* aCx, ModuleLoaderInfo& aInfo, nsIFile* aModuleFile,
@ -1186,7 +953,12 @@ nsresult mozJSModuleLoader::GetScriptForLocation(
ScriptPreloader::FillCompileOptionsForCachedStencil(options);
options.setFileAndLine(nativePath.get(), 1);
if (aInfo.IsModule()) {
SetModuleOptions(options);
options.setModule();
// Top level await is not supported in synchronously loaded modules.
options.topLevelAwait = false;
// Make all top-level `vars` available in `ModuleEnvironmentObject`.
options.deoptimizeModuleGlobalVars = true;
} else {
options.setForceStrictMode();
options.setNonSyntacticScope(true);
@ -2020,8 +1792,7 @@ nsresult mozJSModuleLoader::ImportESModule(
RootedObject globalObj(aCx, GetSharedGlobal(aCx));
NS_ENSURE_TRUE(globalObj, NS_ERROR_FAILURE);
MOZ_ASSERT_IF(NS_IsMainThread(),
xpc::Scriptability::Get(globalObj).Allowed());
MOZ_ASSERT(xpc::Scriptability::Get(globalObj).Allowed());
// The module loader should be instantiated when fetching the shared global
MOZ_ASSERT(mModuleLoader);
@ -2040,7 +1811,7 @@ nsresult mozJSModuleLoader::ImportESModule(
CORS_NONE, /* aNonce = */ u""_ns, dom::RequestPriority::Auto,
ParserMetadata::NotParserInserted, principal);
RefPtr<SyncLoadContext> context = new SyncLoadContext();
RefPtr<ComponentLoadContext> context = new ComponentLoadContext();
context->mSkipCheck = aSkipCheck;
RefPtr<VisitedURLSet> visitedSet =
@ -2156,62 +1927,6 @@ size_t mozJSModuleLoader::ModuleEntry::SizeOfIncludingThis(
//----------------------------------------------------------------------
/* static */
MOZ_THREAD_LOCAL(mozJSModuleLoader*)
NonSharedGlobalSyncModuleLoaderScope::sTlsActiveLoader;
void NonSharedGlobalSyncModuleLoaderScope::InitStatics() {
sTlsActiveLoader.infallibleInit();
}
NonSharedGlobalSyncModuleLoaderScope::NonSharedGlobalSyncModuleLoaderScope(
JSContext* aCx, nsIGlobalObject* aGlobal) {
MOZ_ASSERT_IF(NS_IsMainThread(),
!mozJSModuleLoader::IsSharedSystemGlobal(aGlobal));
MOZ_ASSERT_IF(NS_IsMainThread(),
!mozJSModuleLoader::IsDevToolsLoaderGlobal(aGlobal));
mAsyncModuleLoader = aGlobal->GetModuleLoader(aCx);
MOZ_ASSERT(mAsyncModuleLoader,
"The consumer should guarantee the global returns non-null module "
"loader");
mLoader = new mozJSModuleLoader();
RegisterWeakMemoryReporter(mLoader);
mLoader->InitSyncModuleLoaderForGlobal(aGlobal);
mAsyncModuleLoader->CopyModulesTo(mLoader->mModuleLoader);
mMaybeOverride.emplace(mAsyncModuleLoader, mLoader->mModuleLoader);
MOZ_ASSERT(!sTlsActiveLoader.get());
sTlsActiveLoader.set(mLoader);
}
NonSharedGlobalSyncModuleLoaderScope::~NonSharedGlobalSyncModuleLoaderScope() {
MOZ_ASSERT(sTlsActiveLoader.get() == mLoader);
sTlsActiveLoader.set(nullptr);
mLoader->DisconnectSyncModuleLoaderFromGlobal();
UnregisterWeakMemoryReporter(mLoader);
}
void NonSharedGlobalSyncModuleLoaderScope::Finish() {
mLoader->mModuleLoader->MoveModulesTo(mAsyncModuleLoader);
}
/* static */
bool NonSharedGlobalSyncModuleLoaderScope::IsActive() {
return !!sTlsActiveLoader.get();
}
/*static */
mozJSModuleLoader* NonSharedGlobalSyncModuleLoaderScope::ActiveLoader() {
return sTlsActiveLoader.get();
}
//----------------------------------------------------------------------
JSCLContextHelper::JSCLContextHelper(JSContext* aCx)
: mContext(aCx), mBuf(nullptr) {}

View file

@ -7,21 +7,16 @@
#ifndef mozJSModuleLoader_h
#define mozJSModuleLoader_h
#include "SyncModuleLoader.h"
#include "mozilla/Attributes.h" // MOZ_STACK_CLASS
#include "ComponentModuleLoader.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/FileLocation.h"
#include "mozilla/Maybe.h" // mozilla::Maybe
#include "mozilla/MemoryReporting.h"
#include "mozilla/RefPtr.h" // RefPtr, mozilla::StaticRefPtr
#include "mozilla/StaticPtr.h"
#include "mozilla/ThreadLocal.h" // MOZ_THREAD_LOCAL
#include "nsIMemoryReporter.h"
#include "nsISupports.h"
#include "nsIURI.h"
#include "nsClassHashtable.h"
#include "jsapi.h"
#include "js/CompileOptions.h"
#include "js/experimental/JSStencil.h"
#include "SkipCheckForBrokenURLOrZeroSized.h"
@ -42,12 +37,6 @@ class ModuleLoadRequest;
# define STARTUP_RECORDER_ENABLED
#endif
namespace mozilla::loader {
class NonSharedGlobalSyncModuleLoaderScope;
} // namespace mozilla::loader
class mozJSModuleLoader final : public nsIMemoryReporter {
public:
NS_DECL_ISUPPORTS
@ -78,13 +67,6 @@ class mozJSModuleLoader final : public nsIMemoryReporter {
JSObject* GetSharedGlobal(JSContext* aCx);
private:
void InitSyncModuleLoaderForGlobal(nsIGlobalObject* aGlobal);
void DisconnectSyncModuleLoaderFromGlobal();
friend class mozilla::loader::NonSharedGlobalSyncModuleLoaderScope;
public:
static mozJSModuleLoader* GetDevToolsLoader() { return sDevToolsLoader; }
static mozJSModuleLoader* GetOrCreateDevToolsLoader();
@ -135,26 +117,13 @@ class mozJSModuleLoader final : public nsIMemoryReporter {
bool IsLoaderGlobal(JSObject* aObj) { return mLoaderGlobal == aObj; }
bool IsDevToolsLoader() const { return this == sDevToolsLoader; }
static bool IsSharedSystemGlobal(nsIGlobalObject* aGlobal);
static bool IsDevToolsLoaderGlobal(nsIGlobalObject* aGlobal);
// Public methods for use from SyncModuleLoader.
// Public methods for use from ComponentModuleLoader.
static bool IsTrustedScheme(nsIURI* aURI);
static nsresult LoadSingleModuleScript(
mozilla::loader::SyncModuleLoader* aModuleLoader, JSContext* aCx,
mozilla::loader::ComponentModuleLoader* aModuleLoader, JSContext* aCx,
JS::loader::ModuleLoadRequest* aRequest,
JS::MutableHandleScript aScriptOut);
private:
static nsresult ReadScriptOnMainThread(JSContext* aCx,
const nsCString& aLocation,
nsCString& aData);
static nsresult LoadSingleModuleScriptOnWorker(
mozilla::loader::SyncModuleLoader* aModuleLoader, JSContext* aCx,
JS::loader::ModuleLoadRequest* aRequest,
JS::MutableHandleScript aScriptOut);
public:
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
bool DefineJSServices(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
@ -192,8 +161,6 @@ class mozJSModuleLoader final : public nsIMemoryReporter {
char** aLocation, bool aCatchException,
JS::MutableHandleValue aException);
static void SetModuleOptions(JS::CompileOptions& aOptions);
// Get the script for a given location, either from a cached stencil or by
// compiling it from source.
static nsresult GetScriptForLocation(JSContext* aCx, ModuleLoaderInfo& aInfo,
@ -291,60 +258,7 @@ class mozJSModuleLoader final : public nsIMemoryReporter {
JS::PersistentRooted<JSObject*> mLoaderGlobal;
JS::PersistentRooted<JSObject*> mServicesObj;
RefPtr<mozilla::loader::SyncModuleLoader> mModuleLoader;
RefPtr<mozilla::loader::ComponentModuleLoader> mModuleLoader;
};
namespace mozilla::loader {
// Automatically allocate and initialize a sync module loader for given
// non-shared global, and override the module loader for the global with sync
// module loader.
//
// This is not re-entrant, and the consumer must check IsActive method before
// allocating this on the stack.
//
// The consumer should ensure the target global's module loader has no
// ongoing fetching modules (ModuleLoaderBase::HasFetchingModules).
// If there's any fetching modules, the consumer should wait for them before
// allocating this class on the stack.
//
// The consumer should also verify that the target global has module loader,
// as a part of the above step.
//
// The loader returned by ActiveLoader can be reused only when
// ActiveLoader's global matches the global the consumer wants to use.
class MOZ_STACK_CLASS NonSharedGlobalSyncModuleLoaderScope {
public:
NonSharedGlobalSyncModuleLoaderScope(JSContext* aCx,
nsIGlobalObject* aGlobal);
~NonSharedGlobalSyncModuleLoaderScope();
// After successfully importing a module graph, move all imported modules to
// the target global's module loader.
void Finish();
// Returns true if another instance of NonSharedGlobalSyncModuleLoaderScope
// is on stack.
static bool IsActive();
static mozJSModuleLoader* ActiveLoader();
static void InitStatics();
private:
RefPtr<mozJSModuleLoader> mLoader;
// Reference to thread-local module loader on the stack.
// This is used by another sync module load during a sync module load is
// ongoing.
static MOZ_THREAD_LOCAL(mozJSModuleLoader*) sTlsActiveLoader;
// The module loader of the target global.
RefPtr<JS::loader::ModuleLoaderBase> mAsyncModuleLoader;
mozilla::Maybe<JS::loader::AutoOverrideModuleLoader> mMaybeOverride;
};
} // namespace mozilla::loader
#endif // mozJSModuleLoader_h
#endif

View file

@ -1,3 +0,0 @@
export const ns = ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs", {
global: "contextual",
});

View file

@ -1,14 +0,0 @@
onmessage = event => {
const ns1 = ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs", {
global: "current",
});
const ns2 = ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs", {
global: "contextual",
});
const equal1 = ns1 == ns2;
const equal2 = ns1.obj == ns2.obj;
postMessage({ equal1, equal2 });
};

View file

@ -1,5 +1 @@
await 1;
export function foo() {
return 10;
}

View file

@ -13,20 +13,3 @@ function xpcWrap(obj, iface) {
}
return ifacePointer.data;
}
function createContentWindow(uri) {
const principal = Services.scriptSecurityManager
.createContentPrincipalFromOrigin(uri);
const webnav = Services.appShell.createWindowlessBrowser(false);
const docShell = webnav.docShell;
docShell.createAboutBlankDocumentViewer(principal, principal);
return webnav.document.defaultView;
}
function createChromeWindow() {
const principal = Services.scriptSecurityManager.getSystemPrincipal();
const webnav = Services.appShell.createWindowlessBrowser(true);
const docShell = webnav.docShell;
docShell.createAboutBlankDocumentViewer(principal, principal);
return webnav.document.defaultView;
}

View file

@ -1 +0,0 @@
export { getCounter, incCounter } from "./non_shared_1.mjs";

View file

@ -1,36 +0,0 @@
onmessage = event => {
let caught1 = false;
try {
ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs");
} catch (e) {
caught1 = true;
}
let caught2 = false;
try {
ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs", {
global: "shared",
});
} catch (e) {
caught2 = true;
}
let caught3 = false;
try {
ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs", {
global: "devtools",
});
} catch (e) {
caught3 = true;
}
let caught4 = false;
try {
ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs", {
loadInDevToolsLoader: true,
});
} catch (e) {
caught4 = true;
}
postMessage({ caught1, caught2, caught3, caught4 });
};

View file

@ -1,19 +0,0 @@
import { setGlobal } from "./non_shared_2.mjs";
globalThis["loaded"].push(1);
globalThis["counter"] = 0;
let counter = 0;
export function getCounter() {
return counter;
}
export function incCounter() {
counter++;
}
export function putCounter() {
setGlobal("counter", counter);
}

View file

@ -1,5 +0,0 @@
globalThis["loaded"].push(2);
export function setGlobal(name, value) {
globalThis[name] = value;
}

View file

@ -1,7 +0,0 @@
const { func2 } = ChromeUtils.importESModule("resource://test/non_shared_nest_import_non_shared_target_1.mjs", {
global: "current",
});
export function func() {
return func2();
}

View file

@ -1,5 +0,0 @@
Cu.evalInSandbox(`
ChromeUtils.importESModule("resource://test/non_shared_nest_import_non_shared_target_2.mjs", {
global: "current",
});
`, globalThis["sb"]);

View file

@ -1,14 +0,0 @@
export function func3() {
const { func3 } = ChromeUtils.importESModule("resource://test/non_shared_nest_import_non_shared_target_3.mjs", {
global: "current",
});
const result = Cu.evalInSandbox(`
const { func3 } = ChromeUtils.importESModule("resource://test/non_shared_nest_import_non_shared_target_3.mjs", {
global: "current",
});
func3();
`, globalThis["sb"]);
return func3() + result;
}

View file

@ -1,3 +0,0 @@
export function func2() {
return 10;
}

View file

@ -1,3 +0,0 @@
export function func2() {
return 11;
}

View file

@ -1,3 +0,0 @@
export function func3() {
return 11;
}

View file

@ -1,7 +0,0 @@
const { sys1 } = ChromeUtils.importESModule("resource://test/non_shared_nest_import_shared_target_1.sys.mjs");
export function func1() {
const { sys2 } = ChromeUtils.importESModule("resource://test/non_shared_nest_import_shared_target_2.sys.mjs");
return sys1() + sys2();
}

View file

@ -1,3 +0,0 @@
export function sys1() {
return 20;
}

View file

@ -1,3 +0,0 @@
export function sys2() {
return 7;
}

View file

@ -1,11 +0,0 @@
onmessage = event => {
globalThis["loaded"] = [];
var ns = ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
const c1 = ns.getCounter();
ns.incCounter();
const c2 = ns.getCounter();
postMessage({ c1, c2, loaded: globalThis["loaded"] });
};

View file

@ -1,124 +0,0 @@
onmessage = async event => {
if (event.data.order === "test") {
globalThis["loaded"] = [];
const ns = await import("resource://test/non_shared_1.mjs");
postMessage({});
return;
}
if (event.data.order === "sync-before-async") {
globalThis["loaded"] = [];
const ns = ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
const sync_beforeInc = ns.getCounter();
ns.incCounter();
const sync_afterInc = ns.getCounter();
const loaded1 = globalThis["loaded"].join(",");
let nsPromise;
if (event.data.target === "top-level") {
nsPromise = import("resource://test/non_shared_1.mjs");
} else {
nsPromise = import("resource://test/import_non_shared_1.mjs");
}
const ns2 = await nsPromise;
const async_beforeInc = ns2.getCounter();
ns2.incCounter();
const async_afterInc = ns2.getCounter();
const sync_afterIncInc = ns.getCounter();
const loaded2 = globalThis["loaded"].join(",");
postMessage({
sync_beforeInc,
sync_afterInc,
sync_afterIncInc,
async_beforeInc,
async_afterInc,
loaded1,
loaded2,
});
return;
}
if (event.data.order === "sync-after-async") {
globalThis["loaded"] = [];
const ns = await import("resource://test/non_shared_1.mjs");
const async_beforeInc = ns.getCounter();
ns.incCounter();
const async_afterInc = ns.getCounter();
const loaded1 = globalThis["loaded"].join(",");
let ns2;
if (event.data.target === "top-level") {
ns2 = ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
} else {
ns2 = ChromeUtils.importESModule("resource://test/import_non_shared_1.mjs", {
global: "current",
});
}
const sync_beforeInc = ns2.getCounter();
ns2.incCounter();
const sync_afterInc = ns2.getCounter();
const async_afterIncInc = ns.getCounter();
const loaded2 = globalThis["loaded"].join(",");
postMessage({
sync_beforeInc,
sync_afterInc,
async_beforeInc,
async_afterInc,
async_afterIncInc,
loaded1,
loaded2,
});
return;
}
if (event.data.order === "sync-while-async") {
globalThis["loaded"] = [];
const nsPromise = import("resource://test/non_shared_1.mjs");
let errorMessage = "";
try {
if (event.data.target === "top-level") {
ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
} else {
ChromeUtils.importESModule("resource://test/import_non_shared_1.mjs", {
global: "current",
});
}
} catch (e) {
errorMessage = e.message;
}
const ns = await nsPromise;
const async_beforeInc = ns.getCounter();
ns.incCounter();
const async_afterInc = ns.getCounter();
const loaded = globalThis["loaded"].join(",");
postMessage({
sync_error: errorMessage,
async_beforeInc,
async_afterInc,
loaded,
});
return;
}
};

View file

@ -1,65 +0,0 @@
/* 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/. */
add_task(async function testShared() {
const ns1 = ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs");
const ns2 = ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs", {
global: "shared",
});
Assert.equal(ns1, ns2);
Assert.equal(ns1.obj, ns2.obj);
});
add_task(async function testDevTools() {
const ns1 = ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs", {
loadInDevToolsLoader: true,
});
const ns2 = ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs", {
global: "devtools",
});
Assert.equal(ns1, ns2);
Assert.equal(ns1.obj, ns2.obj);
});
add_task(async function testInvalidOptions() {
// Unknown value is rejected.
Assert.throws(() => {
ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs", {
global: "invalid",
});
}, Error);
Assert.throws(() => {
ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs", {
global: globalThis,
});
}, Error);
// Unknown name is ignored.
ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs", {
global2: "shared",
});
});
add_task(async function testSharedInWorker() {
// Loading into shared global isn't allowed in worker.
let worker = new ChromeWorker("resource://test/import_shared_in_worker.js");
let { promise, resolve } = Promise.withResolvers();
worker.onmessage = event => {
resolve(event.data);
};
worker.postMessage("");
const result = await promise;
Assert.equal(result.caught1, true);
Assert.equal(result.caught2, true);
Assert.equal(result.caught3, true);
Assert.equal(result.caught4, true);
});

View file

@ -1,52 +0,0 @@
/* 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/. */
add_task(async function testInNonShared() {
const ns1 = ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs");
const ns2 = ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs", {
global: "contextual",
});
Assert.equal(ns1, ns2);
Assert.equal(ns1.obj, ns2.obj);
});
add_task(async function testInShared() {
const { ns: ns1 } = ChromeUtils.importESModule("resource://test/contextual.sys.mjs");
const ns2 = ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs", {
global: "shared",
});
Assert.equal(ns1, ns2);
Assert.equal(ns1.obj, ns2.obj);
});
add_task(async function testInShared() {
const { ns: ns1 } = ChromeUtils.importESModule("resource://test/contextual.sys.mjs", {
global: "devtools",
});
const ns2 = ChromeUtils.importESModule("resource://test/esmified-1.sys.mjs", {
global: "devtools",
});
Assert.equal(ns1, ns2);
Assert.equal(ns1.obj, ns2.obj);
});
add_task(async function testInWorker() {
const worker = new ChromeWorker("resource://test/contextual_worker.js");
const { promise, resolve } = Promise.withResolvers();
worker.onmessage = event => {
resolve(event.data);
};
worker.postMessage("");
const result = await promise;
Assert.ok(result.equal1);
Assert.ok(result.equal2);
});

View file

@ -1,989 +0,0 @@
/* 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/. */
add_task(async function testSandbox() {
const uri = "http://example.com/";
const window = createContentWindow(uri);
const sandboxOpts = {
sandboxPrototype: window,
wantGlobalProperties: ["ChromeUtils"],
};
const sb = new Cu.Sandbox(uri, sandboxOpts);
Cu.evalInSandbox(`
globalThis["loaded"] = [];
var ns = ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
`, sb);
Assert.equal(Cu.evalInSandbox(`ns.getCounter();`, sb), 0);
Cu.evalInSandbox(`ns.incCounter();`, sb);
Assert.equal(Cu.evalInSandbox(`ns.getCounter();`, sb), 1);
Assert.equal(Cu.evalInSandbox(`globalThis["loaded"].join(",")`, sb), "2,1");
});
add_task(async function testNoWindowSandbox() {
// Sandbox without window doesn't have ScriptLoader, and Sandbox's
// ModuleLoader cannot be created.
const systemPrincipal = Components.Constructor(
"@mozilla.org/systemprincipal;1",
"nsIPrincipal"
)();
const sandboxOpts = {
wantGlobalProperties: ["ChromeUtils"],
};
const sb = new Cu.Sandbox(systemPrincipal, sandboxOpts);
let caught = false;
try {
Cu.evalInSandbox(`
ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
`, sb);
} catch (e) {
caught = true;
Assert.stringMatches(e.message, /No ModuleLoader found/);
}
Assert.ok(caught);
});
add_task(async function testWindow() {
const win1 = createChromeWindow();
win1.eval(`
globalThis["loaded"] = [];
var ns = ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
`);
Assert.equal(win1.eval(`ns.getCounter();`), 0);
win1.eval(`ns.incCounter();`);
Assert.equal(win1.eval(`ns.getCounter();`), 1);
Assert.equal(win1.eval(`globalThis["loaded"].join(",")`), "2,1");
});
add_task(async function testWorker() {
const win1 = createChromeWindow();
const worker = new ChromeWorker("resource://test/non_shared_worker_1.js");
const { promise, resolve } = Promise.withResolvers();
worker.onmessage = event => {
resolve(event.data);
};
worker.postMessage("");
const result = await promise;
Assert.equal(result.c1, 0);
Assert.equal(result.c2, 1);
Assert.equal(result.loaded, "2,1");
});
add_task(async function testReImport() {
// Re-importing the same module should return the same thing.
const uri = "http://example.com/";
const window = createContentWindow(uri);
const sandboxOpts = {
sandboxPrototype: window,
wantGlobalProperties: ["ChromeUtils"],
};
const sb = new Cu.Sandbox(uri, sandboxOpts);
Cu.evalInSandbox(`
globalThis["loaded"] = [];
var ns = ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
`, sb);
Assert.equal(Cu.evalInSandbox(`ns.getCounter();`, sb), 0);
Cu.evalInSandbox(`ns.incCounter();`, sb);
Assert.equal(Cu.evalInSandbox(`ns.getCounter();`, sb), 1);
Assert.equal(Cu.evalInSandbox(`globalThis["loaded"].join(",")`, sb), "2,1");
Cu.evalInSandbox(`
var ns2 = ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
`, sb);
// The counter should be shared, and also not reset.
Assert.equal(Cu.evalInSandbox(`ns2.getCounter();`, sb), 1);
Cu.evalInSandbox(`ns2.incCounter();`, sb);
Assert.equal(Cu.evalInSandbox(`ns.getCounter();`, sb), 2);
Assert.equal(Cu.evalInSandbox(`ns2.getCounter();`, sb), 2);
// The top-level script shouldn't be executed twice.
Assert.equal(Cu.evalInSandbox(`globalThis["loaded"].join(",")`, sb), "2,1");
});
add_task(async function testNotFound() {
// Importing non-existent file should throw error.
const uri = "http://example.com/";
const window = createContentWindow(uri);
const sandboxOpts = {
sandboxPrototype: window,
wantGlobalProperties: ["ChromeUtils"],
};
const sb = new Cu.Sandbox(uri, sandboxOpts);
let caught = false;
try {
Cu.evalInSandbox(`
ChromeUtils.importESModule("resource://test/not_found.mjs", {
global: "current",
});
`, sb);
} catch (e) {
caught = true;
Assert.stringMatches(e.message, /Failed to load/);
}
Assert.ok(caught);
});
add_task(async function testParseError() {
// Parse error should be thrown.
const uri = "http://example.com/";
const window = createContentWindow(uri);
const sandboxOpts = {
sandboxPrototype: window,
wantGlobalProperties: ["ChromeUtils"],
};
const sb = new Cu.Sandbox(uri, sandboxOpts);
let caught = false;
try {
Cu.evalInSandbox(`
ChromeUtils.importESModule("resource://test/es6module_parse_error.js", {
global: "current",
});
`, sb);
} catch (e) {
caught = true;
Assert.stringMatches(e.message, /unexpected token/);
}
Assert.ok(caught);
});
add_task(async function testParseErrorInImport() {
// Parse error in imported module should be thrown.
const uri = "http://example.com/";
const window = createContentWindow(uri);
const sandboxOpts = {
sandboxPrototype: window,
wantGlobalProperties: ["ChromeUtils"],
};
const sb = new Cu.Sandbox(uri, sandboxOpts);
let caught = false;
try {
Cu.evalInSandbox(`
ChromeUtils.importESModule("resource://test/es6module_parse_error_in_import.js", {
global: "current",
});
`, sb);
} catch (e) {
caught = true;
Assert.stringMatches(e.message, /unexpected token/);
}
Assert.ok(caught);
});
add_task(async function testImportError() {
// Error for nested import should be thrown.
const uri = "http://example.com/";
const window = createContentWindow(uri);
const sandboxOpts = {
sandboxPrototype: window,
wantGlobalProperties: ["ChromeUtils"],
};
const sb = new Cu.Sandbox(uri, sandboxOpts);
let caught = false;
try {
Cu.evalInSandbox(`
ChromeUtils.importESModule("resource://test/es6module_import_error.js", {
global: "current",
});
`, sb);
} catch (e) {
caught = true;
Assert.stringMatches(e.message, /import not found/);
}
Assert.ok(caught);
});
add_task(async function testExecutionError() {
// Error while execution the top-level script should be thrown.
const uri = "http://example.com/";
const window = createContentWindow(uri);
const sandboxOpts = {
sandboxPrototype: window,
wantGlobalProperties: ["ChromeUtils"],
};
const sb = new Cu.Sandbox(uri, sandboxOpts);
let caught = false;
try {
Cu.evalInSandbox(`
ChromeUtils.importESModule("resource://test/es6module_throws.js", {
global: "current",
});
`, sb);
} catch (e) {
caught = true;
Assert.stringMatches(e.message, /foobar/);
}
Assert.ok(caught);
// Re-import should throw the same error.
caught = false;
try {
Cu.evalInSandbox(`
ChromeUtils.importESModule("resource://test/es6module_throws.js", {
global: "current",
});
`, sb);
} catch (e) {
caught = true;
Assert.stringMatches(e.message, /foobar/);
}
Assert.ok(caught);
});
add_task(async function testImportNestShared() {
// Importing system ESM should work.
const win1 = createChromeWindow();
const result = win1.eval(`
const { func1 } = ChromeUtils.importESModule("resource://test/non_shared_nest_import_shared_1.mjs", {
global: "current",
});
func1();
`);
Assert.equal(result, 27);
});
add_task(async function testImportNestNonSharedSame() {
// For the same global, nested import for non-shared global is allowed while
// executing top-level script.
const win1 = createChromeWindow();
const result = win1.eval(`
const { func } = ChromeUtils.importESModule("resource://test/non_shared_nest_import_non_shared_1.mjs", {
global: "current",
});
func();
`);
Assert.equal(result, 10);
});
add_task(async function testImportNestNonSharedDifferent() {
// For the different globals, nested import for non-shared global isn't
// allowed while executing top-level script.
const win1 = createChromeWindow();
const uri = "http://example.com/";
const window = createContentWindow(uri);
const sandboxOpts = {
sandboxPrototype: window,
wantGlobalProperties: ["ChromeUtils"],
};
win1.sb = new Cu.Sandbox(uri, sandboxOpts);
let caught = false;
try {
win1.eval(`
ChromeUtils.importESModule("resource://test/non_shared_nest_import_non_shared_2.mjs", {
global: "current",
});
`);
} catch (e) {
caught = true;
Assert.stringMatches(e.message, /cannot be used for different global/);
}
Assert.ok(caught);
});
add_task(async function testImportNestNonSharedAfterImport() {
// Nested import for non-shared global is allowed after the import, both for
// the same and different globals.
const win1 = createChromeWindow();
const uri = "http://example.com/";
const window = createContentWindow(uri);
const sandboxOpts = {
sandboxPrototype: window,
wantGlobalProperties: ["ChromeUtils"],
};
win1.sb = new Cu.Sandbox(uri, sandboxOpts);
const result = win1.eval(`
const { func3 } = ChromeUtils.importESModule("resource://test/non_shared_nest_import_non_shared_3.mjs", {
global: "current",
});
// Nested import happens here.
func3();
`);
Assert.equal(result, 22);
});
add_task(async function testIsolationWithSandbox() {
// Modules should be isolated for each sandbox.
const uri = "http://example.com/";
const window = createContentWindow(uri);
const sandboxOpts = {
sandboxPrototype: window,
wantGlobalProperties: ["ChromeUtils"],
};
const sb1 = new Cu.Sandbox(uri, sandboxOpts);
const sb2 = new Cu.Sandbox(uri, sandboxOpts);
const sb3 = new Cu.Sandbox(uri, sandboxOpts);
// Verify modules in 2 sandboxes are isolated.
Cu.evalInSandbox(`
globalThis["loaded"] = [];
var ns = ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
`, sb1);
Cu.evalInSandbox(`
globalThis["loaded"] = [];
var ns = ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
`, sb2);
Assert.equal(Cu.evalInSandbox(`ns.getCounter();`, sb1), 0);
Cu.evalInSandbox(`ns.incCounter();`, sb1);
Assert.equal(Cu.evalInSandbox(`ns.getCounter();`, sb1), 1);
Assert.equal(Cu.evalInSandbox(`globalThis["loaded"].join(",")`, sb1), "2,1");
Assert.equal(Cu.evalInSandbox(`ns.getCounter();`, sb2), 0);
Cu.evalInSandbox(`ns.incCounter();`, sb2);
Assert.equal(Cu.evalInSandbox(`ns.getCounter();`, sb2), 1);
Assert.equal(Cu.evalInSandbox(`globalThis["loaded"].join(",")`, sb2), "2,1");
// Verify importing after any modification to different global doesn't affect.
const ns3 = Cu.evalInSandbox(`
globalThis["loaded"] = [];
var ns = ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
`, sb3);
Assert.equal(Cu.evalInSandbox(`ns.getCounter();`, sb3), 0);
Cu.evalInSandbox(`ns.incCounter();`, sb3);
Assert.equal(Cu.evalInSandbox(`ns.getCounter();`, sb3), 1);
Assert.equal(Cu.evalInSandbox(`globalThis["loaded"].join(",")`, sb3), "2,1");
// Verify yet another modification are still isolated.
Assert.equal(Cu.evalInSandbox(`ns.getCounter();`, sb1), 1);
Cu.evalInSandbox(`ns.incCounter();`, sb1);
Assert.equal(Cu.evalInSandbox(`ns.getCounter();`, sb1), 2);
Assert.equal(Cu.evalInSandbox(`ns.getCounter();`, sb2), 1);
Cu.evalInSandbox(`ns.incCounter();`, sb2);
Cu.evalInSandbox(`ns.incCounter();`, sb2);
Assert.equal(Cu.evalInSandbox(`ns.getCounter();`, sb2), 3);
Assert.equal(Cu.evalInSandbox(`ns.getCounter();`, sb3), 1);
Cu.evalInSandbox(`ns.incCounter();`, sb3);
Cu.evalInSandbox(`ns.incCounter();`, sb3);
Cu.evalInSandbox(`ns.incCounter();`, sb3);
Assert.equal(Cu.evalInSandbox(`ns.getCounter();`, sb3), 4);
// Verify the module's `globalThis` points the target global.
Cu.evalInSandbox(`ns.putCounter();`, sb1);
Cu.evalInSandbox(`ns.putCounter();`, sb2);
Cu.evalInSandbox(`ns.putCounter();`, sb3);
const counter1 = Cu.evalInSandbox(`globalThis["counter"]`, sb1);
Assert.equal(counter1, 2);
const counter2 = Cu.evalInSandbox(`globalThis["counter"]`, sb2);
Assert.equal(counter2, 3);
const counter3 = Cu.evalInSandbox(`globalThis["counter"]`, sb3);
Assert.equal(counter3, 4);
});
add_task(async function testIsolationWithWindow() {
// Modules should be isolated for each window.
const win1 = createChromeWindow();
const win2 = createChromeWindow();
const win3 = createChromeWindow();
// Verify modules in 2 sandboxes are isolated.
win1.eval(`
globalThis["loaded"] = [];
var ns = ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
`);
win2.eval(`
globalThis["loaded"] = [];
var ns = ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
`);
Assert.equal(win1.eval(`ns.getCounter();`), 0);
win1.eval(`ns.incCounter();`);
Assert.equal(win1.eval(`ns.getCounter();`), 1);
Assert.equal(win1.eval(`globalThis["loaded"].join(",")`), "2,1");
Assert.equal(win2.eval(`ns.getCounter();`), 0);
win2.eval(`ns.incCounter();`);
Assert.equal(win2.eval(`ns.getCounter();`), 1);
Assert.equal(win2.eval(`globalThis["loaded"].join(",")`), "2,1");
// Verify importing after any modification to different global doesn't affect.
const ns3 = win3.eval(`
globalThis["loaded"] = [];
var ns = ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
`);
Assert.equal(win3.eval(`ns.getCounter();`), 0);
win3.eval(`ns.incCounter();`);
Assert.equal(win3.eval(`ns.getCounter();`), 1);
Assert.equal(win3.eval(`globalThis["loaded"].join(",")`), "2,1");
// Verify yet another modification are still isolated.
Assert.equal(win1.eval(`ns.getCounter();`), 1);
win1.eval(`ns.incCounter();`);
Assert.equal(win1.eval(`ns.getCounter();`), 2);
Assert.equal(win2.eval(`ns.getCounter();`), 1);
win2.eval(`ns.incCounter();`);
win2.eval(`ns.incCounter();`);
Assert.equal(win2.eval(`ns.getCounter();`), 3);
Assert.equal(win3.eval(`ns.getCounter();`), 1);
win3.eval(`ns.incCounter();`);
win3.eval(`ns.incCounter();`);
win3.eval(`ns.incCounter();`);
Assert.equal(win3.eval(`ns.getCounter();`), 4);
// Verify the module's `globalThis` points the target global.
win1.eval(`ns.putCounter();`);
win2.eval(`ns.putCounter();`);
win3.eval(`ns.putCounter();`);
const counter1 = win1.eval(`globalThis["counter"]`);
Assert.equal(counter1, 2);
const counter2 = win2.eval(`globalThis["counter"]`);
Assert.equal(counter2, 3);
const counter3 = win3.eval(`globalThis["counter"]`);
Assert.equal(counter3, 4);
});
add_task(async function testSyncImportBeforeAsyncImportTopLevel() {
const window = createChromeWindow();
window.eval(`
globalThis["loaded"] = [];
var ns = ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
`);
Assert.equal(window.eval(`ns.getCounter();`), 0);
window.eval(`ns.incCounter();`);
Assert.equal(window.eval(`ns.getCounter();`), 1);
Assert.equal(window.eval(`globalThis["loaded"].join(",")`), "2,1");
window.eval(`
var ns2 = null;
const nsPromise = import("resource://test/non_shared_1.mjs");
nsPromise.then(v => { ns2 = v; });
`);
Services.tm.spinEventLoopUntil(
"Wait until dynamic import finishes",
() => window.eval(`ns2 !== null`)
);
Assert.equal(window.eval(`ns2.getCounter();`), 1);
window.eval(`ns2.incCounter();`);
Assert.equal(window.eval(`ns2.getCounter();`), 2);
Assert.equal(window.eval(`ns.getCounter();`), 2);
Assert.equal(window.eval(`globalThis["loaded"].join(",")`), "2,1");
});
add_task(async function testSyncImportBeforeAsyncImportDependency() {
const window = createChromeWindow();
window.eval(`
globalThis["loaded"] = [];
var ns = ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
`);
Assert.equal(window.eval(`ns.getCounter();`), 0);
window.eval(`ns.incCounter();`);
Assert.equal(window.eval(`ns.getCounter();`), 1);
Assert.equal(window.eval(`globalThis["loaded"].join(",")`), "2,1");
window.eval(`
var ns2 = null;
const nsPromise = import("resource://test/import_non_shared_1.mjs");
nsPromise.then(v => { ns2 = v; });
`);
Services.tm.spinEventLoopUntil(
"Wait until dynamic import finishes",
() => window.eval(`ns2 !== null`)
);
Assert.equal(window.eval(`ns2.getCounter();`), 1);
window.eval(`ns2.incCounter();`);
Assert.equal(window.eval(`ns2.getCounter();`), 2);
Assert.equal(window.eval(`ns.getCounter();`), 2);
Assert.equal(window.eval(`globalThis["loaded"].join(",")`), "2,1");
});
add_task(async function testSyncImportAfterAsyncImportTopLevel() {
const window = createChromeWindow();
window.eval(`
var ns = null;
globalThis["loaded"] = [];
const nsPromise = import("resource://test/non_shared_1.mjs");
nsPromise.then(v => { ns = v; });
`);
Services.tm.spinEventLoopUntil(
"Wait until dynamic import finishes",
() => window.eval(`ns !== null`)
);
Assert.equal(window.eval(`ns.getCounter();`), 0);
window.eval(`ns.incCounter();`);
Assert.equal(window.eval(`ns.getCounter();`), 1);
Assert.equal(window.eval(`globalThis["loaded"].join(",")`), "2,1");
window.eval(`
var ns2 = ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
`);
Assert.equal(window.eval(`ns2.getCounter();`), 1);
window.eval(`ns2.incCounter();`);
Assert.equal(window.eval(`ns2.getCounter();`), 2);
Assert.equal(window.eval(`ns.getCounter();`), 2);
Assert.equal(window.eval(`globalThis["loaded"].join(",")`), "2,1");
});
add_task(async function testSyncImportAfterAsyncImportDependency() {
const window = createChromeWindow();
window.eval(`
var ns = null;
globalThis["loaded"] = [];
const nsPromise = import("resource://test/non_shared_1.mjs");
nsPromise.then(v => { ns = v; });
`);
Services.tm.spinEventLoopUntil(
"Wait until dynamic import finishes",
() => window.eval(`ns !== null`)
);
Assert.equal(window.eval(`ns.getCounter();`), 0);
window.eval(`ns.incCounter();`);
Assert.equal(window.eval(`ns.getCounter();`), 1);
Assert.equal(window.eval(`globalThis["loaded"].join(",")`), "2,1");
window.eval(`
var ns2 = ChromeUtils.importESModule("resource://test/import_non_shared_1.mjs", {
global: "current",
});
`);
Assert.equal(window.eval(`ns2.getCounter();`), 1);
window.eval(`ns2.incCounter();`);
Assert.equal(window.eval(`ns2.getCounter();`), 2);
Assert.equal(window.eval(`ns.getCounter();`), 2);
Assert.equal(window.eval(`globalThis["loaded"].join(",")`), "2,1");
});
add_task(async function testSyncImportWhileAsyncImportTopLevel() {
const window = createChromeWindow();
window.eval(`
var ns = null;
globalThis["loaded"] = [];
const nsPromise = import("resource://test/non_shared_1.mjs");
nsPromise.then(v => { ns = v; });
`);
window.eval(`
var ns2 = ChromeUtils.importESModule("resource://test/non_shared_1.mjs", {
global: "current",
});
`);
Assert.equal(window.eval(`ns2.getCounter();`), 0);
window.eval(`ns2.incCounter();`);
Assert.equal(window.eval(`ns2.getCounter();`), 1);
Services.tm.spinEventLoopUntil(
"Wait until dynamic import finishes",
() => window.eval(`ns !== null`)
);
Assert.equal(window.eval(`ns.getCounter();`), 1);
window.eval(`ns.incCounter();`);
Assert.equal(window.eval(`ns.getCounter();`), 2);
Assert.equal(window.eval(`ns2.getCounter();`), 2);
Assert.equal(window.eval(`globalThis["loaded"].join(",")`), "2,1");
});
add_task(async function testSyncImportWhileAsyncImportDependency() {
const window = createChromeWindow();
window.eval(`
var ns = null;
globalThis["loaded"] = [];
const nsPromise = import("resource://test/non_shared_1.mjs");
nsPromise.then(v => { ns = v; });
`);
window.eval(`
var ns2 = ChromeUtils.importESModule("resource://test/import_non_shared_1.mjs", {
global: "current",
});
`);
Assert.equal(window.eval(`ns2.getCounter();`), 0);
window.eval(`ns2.incCounter();`);
Assert.equal(window.eval(`ns2.getCounter();`), 1);
Services.tm.spinEventLoopUntil(
"Wait until dynamic import finishes",
() => window.eval(`ns !== null`)
);
Assert.equal(window.eval(`ns.getCounter();`), 1);
window.eval(`ns.incCounter();`);
Assert.equal(window.eval(`ns.getCounter();`), 2);
Assert.equal(window.eval(`ns2.getCounter();`), 2);
Assert.equal(window.eval(`globalThis["loaded"].join(",")`), "2,1");
});
add_task(async function testSyncImportBeforeAsyncImportTLA() {
// Top-level-await is not supported by sync import.
const window = createChromeWindow();
let caught = false;
try {
window.eval(`
ChromeUtils.importESModule("resource://test/es6module_top_level_await.js", {
global: "current",
});
`);
} catch (e) {
caught = true;
Assert.stringMatches(e.message, /top level await is not supported/);
}
Assert.ok(caught);
window.eval(`
var ns2 = null;
const nsPromise = import("resource://test/es6module_top_level_await.js");
nsPromise.then(v => { ns2 = v; });
`);
Services.tm.spinEventLoopUntil(
"Wait until dynamic import finishes",
() => window.eval(`ns2 !== null`)
);
Assert.equal(window.eval(`ns2.foo();`), 10);
});
add_task(async function testSyncImportAfterAsyncImportTLA() {
// Top-level-await is not supported by sync import, but if the module is
// already imported, the existing module namespace is returned.
const window = createChromeWindow();
window.eval(`
var ns2 = null;
const nsPromise = import("resource://test/es6module_top_level_await.js");
nsPromise.then(v => { ns2 = v; });
`);
Services.tm.spinEventLoopUntil(
"Wait until dynamic import finishes",
() => window.eval(`ns2 !== null`)
);
Assert.equal(window.eval(`ns2.foo();`), 10);
window.eval(`
var ns = ChromeUtils.importESModule("resource://test/es6module_top_level_await.js", {
global: "current",
});
`);
Assert.equal(window.eval(`ns.foo();`), 10);
Assert.equal(window.eval(`ns2.foo == ns.foo;`), true);
});
add_task(async function testSyncImportWhileAsyncImportTLA() {
// Top-level-await is not supported by sync import, but if the module is
// already fetching, ChromeUtils.importESModule waits for it and, the
// async-imported module namespace is returned.
const window = createChromeWindow();
window.eval(`
var ns2 = null;
const nsPromise = import("resource://test/es6module_top_level_await.js");
nsPromise.then(v => { ns2 = v; });
`);
window.eval(`
var ns = ChromeUtils.importESModule("resource://test/es6module_top_level_await.js", {
global: "current",
});
`);
Services.tm.spinEventLoopUntil(
"Wait until dynamic import finishes",
() => window.eval(`ns2 !== null`)
);
Assert.equal(window.eval(`ns2.foo();`), 10);
Assert.equal(window.eval(`ns.foo();`), 10);
Assert.equal(window.eval(`ns2.foo == ns.foo;`), true);
});
add_task(async function testSyncImportBeforeAsyncImportTopLevelInWorker() {
const window = createChromeWindow();
let worker = new ChromeWorker("resource://test/sync_and_async_in_worker.js");
let { promise, resolve } = Promise.withResolvers();
worker.onmessage = event => {
resolve(event.data);
};
worker.postMessage({ order: "sync-before-async", target: "top-level" });
const {
sync_beforeInc,
sync_afterInc,
sync_afterIncInc,
async_beforeInc,
async_afterInc,
loaded1,
loaded2,
} = await promise;
Assert.equal(sync_beforeInc, 0);
Assert.equal(sync_afterInc, 1);
Assert.equal(loaded1, "2,1");
Assert.equal(async_beforeInc, 1);
Assert.equal(async_afterInc, 2);
Assert.equal(sync_afterIncInc, 2);
Assert.equal(loaded2, "2,1");
});
add_task(async function testSyncImportBeforeAsyncImportDependencyInWorker() {
let worker = new ChromeWorker("resource://test/sync_and_async_in_worker.js");
let { promise, resolve } = Promise.withResolvers();
worker.onmessage = event => {
resolve(event.data);
};
worker.postMessage({ order: "sync-before-async", target: "dependency" });
const {
sync_beforeInc,
sync_afterInc,
sync_afterIncInc,
async_beforeInc,
async_afterInc,
loaded1,
loaded2,
} = await promise;
Assert.equal(sync_beforeInc, 0);
Assert.equal(sync_afterInc, 1);
Assert.equal(loaded1, "2,1");
Assert.equal(async_beforeInc, 1);
Assert.equal(async_afterInc, 2);
Assert.equal(sync_afterIncInc, 2);
Assert.equal(loaded2, "2,1");
});
add_task(async function testSyncImportAfterAsyncImportTopLevelInWorker() {
const window = createChromeWindow();
let worker = new ChromeWorker("resource://test/sync_and_async_in_worker.js");
let { promise, resolve } = Promise.withResolvers();
worker.onmessage = event => {
resolve(event.data);
};
worker.postMessage({ order: "sync-after-async", target: "top-level" });
const {
sync_beforeInc,
sync_afterInc,
async_beforeInc,
async_afterInc,
async_afterIncInc,
loaded1,
loaded2,
} = await promise;
Assert.equal(async_beforeInc, 0);
Assert.equal(async_afterInc, 1);
Assert.equal(loaded1, "2,1");
Assert.equal(sync_beforeInc, 1);
Assert.equal(sync_afterInc, 2);
Assert.equal(async_afterIncInc, 2);
Assert.equal(loaded2, "2,1");
});
add_task(async function testSyncImportAfterAsyncImportDependencyInWorker() {
const window = createChromeWindow();
let worker = new ChromeWorker("resource://test/sync_and_async_in_worker.js");
let { promise, resolve } = Promise.withResolvers();
worker.onmessage = event => {
resolve(event.data);
};
worker.postMessage({ order: "sync-after-async", target: "dependency" });
const {
sync_beforeInc,
sync_afterInc,
async_beforeInc,
async_afterInc,
async_afterIncInc,
loaded1,
loaded2,
} = await promise;
Assert.equal(async_beforeInc, 0);
Assert.equal(async_afterInc, 1);
Assert.equal(loaded1, "2,1");
Assert.equal(sync_beforeInc, 1);
Assert.equal(sync_afterInc, 2);
Assert.equal(async_afterIncInc, 2);
Assert.equal(loaded2, "2,1");
});
add_task(async function testSyncImportWhileAsyncImportTopLevelInWorker() {
const window = createChromeWindow();
let worker = new ChromeWorker("resource://test/sync_and_async_in_worker.js");
let { promise, resolve } = Promise.withResolvers();
worker.onmessage = event => {
resolve(event.data);
};
worker.postMessage({ order: "sync-while-async", target: "top-level" });
const {
sync_error,
async_beforeInc,
async_afterInc,
loaded,
} = await promise;
Assert.stringMatches(sync_error, /ChromeUtils.importESModule cannot be used/);
Assert.equal(async_beforeInc, 0);
Assert.equal(async_afterInc, 1);
Assert.equal(loaded, "2,1");
});
add_task(async function testSyncImportWhileAsyncImportDependencyInWorker() {
const window = createChromeWindow();
let worker = new ChromeWorker("resource://test/sync_and_async_in_worker.js");
let { promise, resolve } = Promise.withResolvers();
worker.onmessage = event => {
resolve(event.data);
};
worker.postMessage({ order: "sync-while-async", target: "dependency" });
const {
sync_error,
async_beforeInc,
async_afterInc,
loaded,
} = await promise;
Assert.stringMatches(sync_error, /ChromeUtils.importESModule cannot be used/);
Assert.equal(async_beforeInc, 0);
Assert.equal(async_afterInc, 1);
Assert.equal(loaded, "2,1");
});

View file

@ -75,23 +75,6 @@ support-files = [
"error_export.sys.mjs",
"error_import.sys.mjs",
"error_other.sys.mjs",
"non_shared_1.mjs",
"non_shared_2.mjs",
"import_non_shared_1.mjs",
"non_shared_nest_import_shared_1.mjs",
"non_shared_nest_import_shared_target_1.sys.mjs",
"non_shared_nest_import_shared_target_2.sys.mjs",
"non_shared_nest_import_non_shared_1.mjs",
"non_shared_nest_import_non_shared_target_1.mjs",
"non_shared_nest_import_non_shared_2.mjs",
"non_shared_nest_import_non_shared_target_2.mjs",
"non_shared_nest_import_non_shared_3.mjs",
"non_shared_nest_import_non_shared_target_3.mjs",
"contextual.sys.mjs",
"non_shared_worker_1.js",
"import_shared_in_worker.js",
"contextual_worker.js",
"sync_and_async_in_worker.js",
]
["test_ComponentEnvironment.js"]
@ -260,12 +243,6 @@ skip-if = ["os == 'android' && processor == 'x86_64'"]
["test_import_from_sandbox.js"]
["test_import_global.js"]
["test_import_global_contextual.js"]
["test_import_global_current.js"]
["test_import_shim.js"]
["test_import_stack.js"]