mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1790383
- [devtools] Allow loading ESMs in a distinct loader specific to DevTools. r=arai
Differential Revision: https://phabricator.services.mozilla.com/D157618
This commit is contained in:
parent
7ad7c7e805
commit
8d2a615b2d
@ -572,12 +572,30 @@ void ChromeUtils::Import(const GlobalObject& aGlobal,
|
||||
aRetval.set(exports);
|
||||
}
|
||||
|
||||
static mozJSModuleLoader* GetContextualESLoader(
|
||||
const Optional<bool>& aLoadInDevToolsLoader, JSObject* aGlobal) {
|
||||
RefPtr devToolsModuleloader = mozJSModuleLoader::GetDevToolsLoader();
|
||||
// We should load the module in the DevTools loader if:
|
||||
// - ChromeUtils.importESModule's `loadInDevToolsLoader` option is true, or,
|
||||
// - if the callsite is from a module loaded in the DevTools loader and
|
||||
// `loadInDevToolsLoader` isn't an explicit false.
|
||||
bool shouldUseDevToolsLoader =
|
||||
(aLoadInDevToolsLoader.WasPassed() && aLoadInDevToolsLoader.Value()) ||
|
||||
(devToolsModuleloader && !aLoadInDevToolsLoader.WasPassed() &&
|
||||
devToolsModuleloader->IsLoaderGlobal(aGlobal));
|
||||
if (shouldUseDevToolsLoader) {
|
||||
return mozJSModuleLoader::GetOrCreateDevToolsLoader();
|
||||
}
|
||||
return mozJSModuleLoader::Get();
|
||||
}
|
||||
|
||||
/* static */
|
||||
void ChromeUtils::ImportESModule(const GlobalObject& aGlobal,
|
||||
const nsAString& aResourceURI,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv) {
|
||||
RefPtr moduleloader = mozJSModuleLoader::Get();
|
||||
void ChromeUtils::ImportESModule(
|
||||
const GlobalObject& aGlobal, const nsAString& aResourceURI,
|
||||
const ImportESModuleOptionsDictionary& aOptions,
|
||||
JS::MutableHandle<JSObject*> aRetval, ErrorResult& aRv) {
|
||||
RefPtr moduleloader =
|
||||
GetContextualESLoader(aOptions.mLoadInDevToolsLoader, aGlobal.Get());
|
||||
MOZ_ASSERT(moduleloader);
|
||||
|
||||
NS_ConvertUTF16toUTF8 registryLocation(aResourceURI);
|
||||
@ -605,6 +623,7 @@ void ChromeUtils::ImportESModule(const GlobalObject& aGlobal,
|
||||
}
|
||||
|
||||
namespace module_getter {
|
||||
|
||||
static const size_t SLOT_ID = 0;
|
||||
static const size_t SLOT_URI = 1;
|
||||
|
||||
@ -649,7 +668,12 @@ static bool ModuleGetterImpl(JSContext* aCx, unsigned aArgc, JS::Value* aVp,
|
||||
}
|
||||
nsDependentCString uri(bytes.get());
|
||||
|
||||
RefPtr moduleloader = mozJSModuleLoader::Get();
|
||||
RefPtr moduleloader =
|
||||
aType == ModuleType::JSM
|
||||
? mozJSModuleLoader::Get()
|
||||
: GetContextualESLoader(
|
||||
Optional<bool>(),
|
||||
JS::GetNonCCWObjectGlobal(js::UncheckedUnwrap(thisObj)));
|
||||
MOZ_ASSERT(moduleloader);
|
||||
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
|
@ -202,6 +202,7 @@ class ChromeUtils {
|
||||
|
||||
static void ImportESModule(const GlobalObject& aGlobal,
|
||||
const nsAString& aResourceURI,
|
||||
const ImportESModuleOptionsDictionary& aOptions,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv);
|
||||
|
||||
|
@ -446,7 +446,7 @@ partial namespace ChromeUtils {
|
||||
* the same file will not cause the module to be re-evaluated.
|
||||
*/
|
||||
[Throws]
|
||||
object importESModule(DOMString aResourceURI);
|
||||
object importESModule(DOMString aResourceURI, optional ImportESModuleOptionsDictionary options = {});
|
||||
|
||||
/**
|
||||
* Defines a property on the given target which lazily imports a JavaScript
|
||||
@ -918,6 +918,15 @@ dictionary CompileScriptOptionsDictionary {
|
||||
boolean hasReturnValue = false;
|
||||
};
|
||||
|
||||
dictionary ImportESModuleOptionsDictionary {
|
||||
/**
|
||||
* If true, a distinct module loader will be used, in the system principal,
|
||||
* but with a distinct global so that the DevTools can load a distinct set
|
||||
* of modules and do not interfere with its debuggee.
|
||||
*/
|
||||
boolean loadInDevToolsLoader;
|
||||
};
|
||||
|
||||
/**
|
||||
* A JS object whose properties specify what portion of the heap graph to
|
||||
* write. The recognized properties are:
|
||||
|
@ -107,7 +107,7 @@ nsresult ComponentModuleLoader::StartFetch(ModuleLoadRequest* aRequest) {
|
||||
JSContext* cx = jsapi.cx();
|
||||
RootedScript script(cx);
|
||||
nsresult rv =
|
||||
mozJSModuleLoader::LoadSingleModuleScript(cx, aRequest, &script);
|
||||
mozJSModuleLoader::LoadSingleModuleScript(this, cx, aRequest, &script);
|
||||
MOZ_ASSERT_IF(jsapi.HasException(), NS_FAILED(rv));
|
||||
MOZ_ASSERT(bool(script) == NS_SUCCEEDED(rv));
|
||||
|
||||
|
@ -272,7 +272,6 @@ mozJSModuleLoader::mozJSModuleLoader()
|
||||
mInitialized(false),
|
||||
mLoaderGlobal(dom::RootingCx()),
|
||||
mServicesObj(dom::RootingCx()) {
|
||||
MOZ_ASSERT(!sSelf, "mozJSModuleLoader should be a singleton");
|
||||
}
|
||||
|
||||
#define ENSURE_DEP(name) \
|
||||
@ -413,11 +412,10 @@ mozJSModuleLoader::~mozJSModuleLoader() {
|
||||
if (mInitialized) {
|
||||
UnloadModules();
|
||||
}
|
||||
|
||||
sSelf = nullptr;
|
||||
}
|
||||
|
||||
StaticRefPtr<mozJSModuleLoader> mozJSModuleLoader::sSelf;
|
||||
StaticRefPtr<mozJSModuleLoader> mozJSModuleLoader::sDevToolsLoader;
|
||||
|
||||
void mozJSModuleLoader::FindTargetObject(JSContext* aCx,
|
||||
MutableHandleObject aTargetObject) {
|
||||
@ -446,21 +444,42 @@ void mozJSModuleLoader::InitStatics() {
|
||||
RegisterWeakMemoryReporter(sSelf);
|
||||
}
|
||||
|
||||
void mozJSModuleLoader::Unload() {
|
||||
void mozJSModuleLoader::UnloadLoaders() {
|
||||
if (sSelf) {
|
||||
sSelf->UnloadModules();
|
||||
|
||||
if (sSelf->mModuleLoader) {
|
||||
sSelf->mModuleLoader->Shutdown();
|
||||
sSelf->mModuleLoader = nullptr;
|
||||
}
|
||||
sSelf->Unload();
|
||||
}
|
||||
if (sDevToolsLoader) {
|
||||
sDevToolsLoader->Unload();
|
||||
}
|
||||
}
|
||||
|
||||
void mozJSModuleLoader::Shutdown() {
|
||||
void mozJSModuleLoader::Unload() {
|
||||
UnloadModules();
|
||||
|
||||
if (mModuleLoader) {
|
||||
mModuleLoader->Shutdown();
|
||||
mModuleLoader = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void mozJSModuleLoader::ShutdownLoaders() {
|
||||
MOZ_ASSERT(sSelf);
|
||||
UnregisterWeakMemoryReporter(sSelf);
|
||||
sSelf = nullptr;
|
||||
|
||||
if (sDevToolsLoader) {
|
||||
UnregisterWeakMemoryReporter(sDevToolsLoader);
|
||||
sDevToolsLoader = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
mozJSModuleLoader* mozJSModuleLoader::GetOrCreateDevToolsLoader() {
|
||||
if (sDevToolsLoader) {
|
||||
return sDevToolsLoader;
|
||||
}
|
||||
sDevToolsLoader = new mozJSModuleLoader();
|
||||
RegisterWeakMemoryReporter(sDevToolsLoader);
|
||||
return sDevToolsLoader;
|
||||
}
|
||||
|
||||
// This requires that the keys be strings and the values be pointers.
|
||||
@ -566,10 +585,12 @@ void mozJSModuleLoader::CreateLoaderGlobal(JSContext* aCx,
|
||||
MutableHandleObject aGlobal) {
|
||||
auto backstagePass = MakeRefPtr<BackstagePass>();
|
||||
RealmOptions options;
|
||||
auto& creationOptions = options.creationOptions();
|
||||
|
||||
options.creationOptions()
|
||||
.setFreezeBuiltins(true)
|
||||
.setNewCompartmentInSystemZone();
|
||||
creationOptions.setFreezeBuiltins(true).setNewCompartmentInSystemZone();
|
||||
if (IsDevToolsLoader()) {
|
||||
creationOptions.setInvisibleToDebugger(true);
|
||||
}
|
||||
xpc::SetPrefableRealmOptions(options);
|
||||
|
||||
// Defer firing OnNewGlobalObject until after the __URI__ property has
|
||||
@ -622,7 +643,10 @@ void mozJSModuleLoader::CreateLoaderGlobal(JSContext* aCx,
|
||||
JSObject* mozJSModuleLoader::GetSharedGlobal(JSContext* aCx) {
|
||||
if (!mLoaderGlobal) {
|
||||
JS::RootedObject globalObj(aCx);
|
||||
CreateLoaderGlobal(aCx, "shared JSM global"_ns, &globalObj);
|
||||
|
||||
CreateLoaderGlobal(
|
||||
aCx, IsDevToolsLoader() ? "DevTools global"_ns : "shared JSM global"_ns,
|
||||
&globalObj);
|
||||
|
||||
// If we fail to create a module global this early, we're not going to
|
||||
// get very far, so just bail out now.
|
||||
@ -640,8 +664,8 @@ JSObject* mozJSModuleLoader::GetSharedGlobal(JSContext* aCx) {
|
||||
|
||||
/* static */
|
||||
nsresult mozJSModuleLoader::LoadSingleModuleScript(
|
||||
JSContext* aCx, JS::loader::ModuleLoadRequest* aRequest,
|
||||
MutableHandleScript aScriptOut) {
|
||||
ComponentModuleLoader* aModuleLoader, JSContext* aCx,
|
||||
JS::loader::ModuleLoadRequest* aRequest, MutableHandleScript aScriptOut) {
|
||||
ModuleLoaderInfo info(aRequest);
|
||||
nsresult rv = info.EnsureResolvedURI();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -657,7 +681,13 @@ nsresult mozJSModuleLoader::LoadSingleModuleScript(
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#ifdef STARTUP_RECORDER_ENABLED
|
||||
sSelf->RecordImportStack(aCx, aRequest);
|
||||
if (aModuleLoader == sSelf->mModuleLoader) {
|
||||
sSelf->RecordImportStack(aCx, aRequest);
|
||||
} else {
|
||||
MOZ_ASSERT(sDevToolsLoader);
|
||||
MOZ_ASSERT(aModuleLoader == sDevToolsLoader->mModuleLoader);
|
||||
sDevToolsLoader->RecordImportStack(aCx, aRequest);
|
||||
}
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
@ -1272,7 +1302,11 @@ nsresult mozJSModuleLoader::GetModuleImportStack(const nsACString& aLocation,
|
||||
nsACString& retval) {
|
||||
#ifdef STARTUP_RECORDER_ENABLED
|
||||
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
MOZ_ASSERT(mInitialized);
|
||||
|
||||
// When querying the DevTools loader, it may not be initialized yet
|
||||
if (!mInitialized) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
ModuleLoaderInfo info(aLocation);
|
||||
auto str = mImportStacks.Lookup(info.Key());
|
||||
@ -1698,7 +1732,7 @@ nsresult mozJSModuleLoader::ImportESModule(
|
||||
aSkipCheck /* = SkipCheckForBrokenURLOrZeroSized::No */) {
|
||||
using namespace JS::loader;
|
||||
|
||||
MOZ_ASSERT(mModuleLoader);
|
||||
mInitialized = true;
|
||||
|
||||
// Called from ChromeUtils::ImportESModule.
|
||||
nsCString str(aLocation);
|
||||
@ -1713,6 +1747,9 @@ nsresult mozJSModuleLoader::ImportESModule(
|
||||
NS_ENSURE_TRUE(globalObj, NS_ERROR_FAILURE);
|
||||
MOZ_ASSERT(xpc::Scriptability::Get(globalObj).Allowed());
|
||||
|
||||
// The module loader should be instantiated when fetching the shared global
|
||||
MOZ_ASSERT(mModuleLoader);
|
||||
|
||||
JSAutoRealm ar(aCx, globalObj);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
|
@ -57,14 +57,17 @@ class mozJSModuleLoader final : public nsIMemoryReporter {
|
||||
void FindTargetObject(JSContext* aCx, JS::MutableHandleObject aTargetObject);
|
||||
|
||||
static void InitStatics();
|
||||
static void Unload();
|
||||
static void Shutdown();
|
||||
static void UnloadLoaders();
|
||||
static void ShutdownLoaders();
|
||||
|
||||
static mozJSModuleLoader* Get() {
|
||||
MOZ_ASSERT(sSelf, "Should have already created the module loader");
|
||||
return sSelf;
|
||||
}
|
||||
|
||||
static mozJSModuleLoader* GetDevToolsLoader() { return sDevToolsLoader; }
|
||||
static mozJSModuleLoader* GetOrCreateDevToolsLoader();
|
||||
|
||||
nsresult ImportInto(const nsACString& aResourceURI,
|
||||
JS::HandleValue aTargetObj, JSContext* aCx, uint8_t aArgc,
|
||||
JS::MutableHandleValue aRetval);
|
||||
@ -110,11 +113,13 @@ class mozJSModuleLoader final : public nsIMemoryReporter {
|
||||
nsresult IsJSModuleLoaded(const nsACString& aResourceURI, bool* aRetval);
|
||||
nsresult IsESModuleLoaded(const nsACString& aResourceURI, bool* aRetval);
|
||||
bool IsLoaderGlobal(JSObject* aObj) { return mLoaderGlobal == aObj; }
|
||||
bool IsDevToolsLoader() const { return this == sDevToolsLoader; }
|
||||
|
||||
// Public methods for use from ComponentModuleLoader.
|
||||
static bool IsTrustedScheme(nsIURI* aURI);
|
||||
static nsresult LoadSingleModuleScript(
|
||||
JSContext* aCx, JS::loader::ModuleLoadRequest* aRequest,
|
||||
mozilla::loader::ComponentModuleLoader* aModuleLoader, JSContext* aCx,
|
||||
JS::loader::ModuleLoadRequest* aRequest,
|
||||
JS::MutableHandleScript aScriptOut);
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
|
||||
@ -129,11 +134,15 @@ class mozJSModuleLoader final : public nsIMemoryReporter {
|
||||
|
||||
private:
|
||||
static mozilla::StaticRefPtr<mozJSModuleLoader> sSelf;
|
||||
static mozilla::StaticRefPtr<mozJSModuleLoader> sDevToolsLoader;
|
||||
|
||||
void Unload();
|
||||
void UnloadModules();
|
||||
|
||||
void CreateLoaderGlobal(JSContext* aCx, const nsACString& aLocation,
|
||||
JS::MutableHandleObject aGlobal);
|
||||
void CreateDevToolsLoaderGlobal(JSContext* aCx, const nsACString& aLocation,
|
||||
JS::MutableHandleObject aGlobal);
|
||||
|
||||
bool CreateJSServices(JSContext* aCx);
|
||||
|
||||
|
@ -2557,7 +2557,14 @@ nsXPCComponents_Utils::GetLoadedESModules(
|
||||
NS_IMETHODIMP
|
||||
nsXPCComponents_Utils::GetModuleImportStack(const nsACString& aLocation,
|
||||
nsACString& aRetval) {
|
||||
return mozJSModuleLoader::Get()->GetModuleImportStack(aLocation, aRetval);
|
||||
nsresult rv =
|
||||
mozJSModuleLoader::Get()->GetModuleImportStack(aLocation, aRetval);
|
||||
// Fallback the query to the DevTools loader if not found in the shared loader
|
||||
if (rv == NS_ERROR_FAILURE && mozJSModuleLoader::GetDevToolsLoader()) {
|
||||
return mozJSModuleLoader::GetDevToolsLoader()->GetModuleImportStack(
|
||||
aLocation, aRetval);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -2278,6 +2278,9 @@ void JSReporter::CollectReports(WindowPaths* windowPaths,
|
||||
mozJSModuleLoader* loader = mozJSModuleLoader::Get();
|
||||
size_t jsModuleLoaderSize =
|
||||
loader ? loader->SizeOfIncludingThis(JSMallocSizeOf) : 0;
|
||||
mozJSModuleLoader* devToolsLoader = mozJSModuleLoader::GetDevToolsLoader();
|
||||
size_t jsDevToolsModuleLoaderSize =
|
||||
devToolsLoader ? devToolsLoader->SizeOfIncludingThis(JSMallocSizeOf) : 0;
|
||||
|
||||
// This is the second step (see above). First we report stuff in the
|
||||
// "explicit" tree, then we report other stuff.
|
||||
@ -2509,6 +2512,8 @@ void JSReporter::CollectReports(WindowPaths* windowPaths,
|
||||
|
||||
REPORT_BYTES("explicit/xpconnect/js-module-loader"_ns, KIND_HEAP,
|
||||
jsModuleLoaderSize, "XPConnect's JS module loader.");
|
||||
REPORT_BYTES("explicit/xpconnect/js-devtools-module-loader"_ns, KIND_HEAP,
|
||||
jsDevToolsModuleLoaderSize, "DevTools's JS module loader.");
|
||||
|
||||
// Report HelperThreadState.
|
||||
|
||||
|
@ -172,7 +172,7 @@ void nsXPConnect::ReleaseXPConnectSingleton() {
|
||||
NS_RELEASE2(xpc, cnt);
|
||||
}
|
||||
|
||||
mozJSModuleLoader::Shutdown();
|
||||
mozJSModuleLoader::ShutdownLoaders();
|
||||
}
|
||||
|
||||
// static
|
||||
|
1
js/xpconnect/tests/unit/es6module_devtoolsLoader.js
Normal file
1
js/xpconnect/tests/unit/es6module_devtoolsLoader.js
Normal file
@ -0,0 +1 @@
|
||||
export const object = { uniqueObjectPerLoader: true };
|
29
js/xpconnect/tests/unit/es6module_devtoolsLoader.sys.mjs
Normal file
29
js/xpconnect/tests/unit/es6module_devtoolsLoader.sys.mjs
Normal file
@ -0,0 +1,29 @@
|
||||
export let x = 0;
|
||||
|
||||
export function increment() {
|
||||
x++;
|
||||
};
|
||||
|
||||
import { object } from "resource://test/es6module_devtoolsLoader.js";
|
||||
export const importedObject = object;
|
||||
|
||||
const importTrue = ChromeUtils.importESModule("resource://test/es6module_devtoolsLoader.js", { loadInDevToolsLoader : true });
|
||||
export const importESModuleTrue = importTrue.object;
|
||||
|
||||
const importFalse = ChromeUtils.importESModule("resource://test/es6module_devtoolsLoader.js", { loadInDevToolsLoader : false });
|
||||
export const importESModuleFalse = importFalse.object;
|
||||
|
||||
const importNull = ChromeUtils.importESModule("resource://test/es6module_devtoolsLoader.js", {});
|
||||
export const importESModuleNull = importNull.object;
|
||||
|
||||
const importNull2 = ChromeUtils.importESModule("resource://test/es6module_devtoolsLoader.js");
|
||||
export const importESModuleNull2 = importNull2.object;
|
||||
|
||||
const lazy = {};
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
object: "resource://test/es6module_devtoolsLoader.js",
|
||||
});
|
||||
|
||||
export function importLazy() {
|
||||
return lazy.object;
|
||||
}
|
1
js/xpconnect/tests/unit/es6module_devtoolsLoader_only.js
Normal file
1
js/xpconnect/tests/unit/es6module_devtoolsLoader_only.js
Normal file
@ -0,0 +1 @@
|
||||
export const object = { onlyLoadedFromDevToolsModule: true };
|
78
js/xpconnect/tests/unit/test_import_devtools_loader.js
Normal file
78
js/xpconnect/tests/unit/test_import_devtools_loader.js
Normal file
@ -0,0 +1,78 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
|
||||
const { addDebuggerToGlobal } = ChromeUtils.import(
|
||||
"resource://gre/modules/jsdebugger.jsm"
|
||||
);
|
||||
addDebuggerToGlobal(this);
|
||||
|
||||
const ESM_URL = "resource://test/es6module_devtoolsLoader.sys.mjs";
|
||||
|
||||
// Toggle the following pref to enable Cu.getModuleImportStack()
|
||||
Services.prefs.setBoolPref("browser.startup.record", true);
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("browser.startup.record");
|
||||
});
|
||||
|
||||
add_task(async function testDevToolsModuleLoader() {
|
||||
const dbg = new Debugger();
|
||||
|
||||
const sharedGlobal = Cu.getGlobalForObject(Services);
|
||||
const sharedPrincipal = Cu.getObjectPrincipal(sharedGlobal);
|
||||
|
||||
info("Test importing in the regular shared loader");
|
||||
const ns = ChromeUtils.importESModule(ESM_URL);
|
||||
Assert.equal(ns.x, 0);
|
||||
ns.increment();
|
||||
Assert.equal(ns.x, 1);
|
||||
const nsGlobal = Cu.getGlobalForObject(ns);
|
||||
const nsPrincipal = Cu.getObjectPrincipal(nsGlobal);
|
||||
Assert.equal(nsGlobal, sharedGlobal, "Without any parameter, importESModule load in the shared JSM global");
|
||||
Assert.equal(nsPrincipal, sharedPrincipal);
|
||||
Assert.ok(nsPrincipal.isSystemPrincipal);
|
||||
info("Global of ESM loaded in the shared loader can be inspected by the Debugger");
|
||||
dbg.addDebuggee(nsGlobal);
|
||||
Assert.ok(true, "The global is accepted by the Debugger API");
|
||||
|
||||
const ns1 = ChromeUtils.importESModule(ESM_URL, { loadInDevToolsLoader : false });
|
||||
Assert.equal(ns1, ns, "Passing loadInDevToolsLoader=false from the shared JSM global is equivalent to regular importESModule");
|
||||
|
||||
info("Test importing in the devtools loader");
|
||||
const ns2 = ChromeUtils.importESModule(ESM_URL, { loadInDevToolsLoader: true });
|
||||
Assert.equal(ns2.x, 0, "We get a new module instance with a new incremented number");
|
||||
Assert.notEqual(ns2, ns, "We imported a new instance of the module");
|
||||
Assert.notEqual(ns2.importedObject, ns.importedObject, "The two module instances expose distinct objects");
|
||||
Assert.equal(ns2.importESModuleTrue, ns2.importedObject, "When using loadInDevToolsLoader:true from a devtools global, we keep loading in the same loader");
|
||||
Assert.equal(ns2.importESModuleNull, ns2.importedObject, "When having an undefined loadInDevToolsLoader from a devtools global, we keep loading in the same loader");
|
||||
Assert.equal(ns2.importESModuleNull2, ns2.importedObject, "When having no optional argument at all, we keep loading in the same loader");
|
||||
Assert.equal(ns2.importESModuleFalse, ns.importedObject, "When passing an explicit loadInDevToolsLoader:false, we load in the shared global, even from a devtools global");
|
||||
Assert.equal(ns2.importLazy(), ns2.importedObject, "ChromeUtils.defineESModuleGetters imports will follow the contextual loader");
|
||||
|
||||
info("When using the devtools loader, we load in a distinct global, but the same compartment");
|
||||
const ns2Global = Cu.getGlobalForObject(ns2);
|
||||
const ns2Principal = Cu.getObjectPrincipal(ns2Global);
|
||||
Assert.notEqual(ns2Global, sharedGlobal, "The module is loaded in a distinct global");
|
||||
Assert.equal(ns2Principal, sharedPrincipal, "The principal is still the shared system principal");
|
||||
Assert.equal(Cu.getGlobalForObject(ns2.importedObject), ns2Global, "Nested dependencies are also loaded in the same devtools global");
|
||||
Assert.throws(() => dbg.addDebuggee(ns2Global), /TypeError: passing non-debuggable global to addDebuggee/,
|
||||
"Global os ESM loaded in the devtools loader can't be inspected by the Debugee");
|
||||
|
||||
info("Re-import the same module in the devtools loader");
|
||||
const ns3 = ChromeUtils.importESModule(ESM_URL, { loadInDevToolsLoader: true });
|
||||
Assert.equal(ns3, ns2, "We import the exact same module");
|
||||
Assert.equal(ns3.importedObject, ns2.importedObject, "The two module expose the same objects");
|
||||
|
||||
info("Import a module only from the devtools loader");
|
||||
const ns4 = ChromeUtils.importESModule("resource://test/es6module_devtoolsLoader_only.js", { loadInDevToolsLoader: true });
|
||||
const ns4Global = Cu.getGlobalForObject(ns4);
|
||||
Assert.equal(ns4Global, ns2Global, "The module is loaded in the same devtools global");
|
||||
|
||||
info("Assert the behavior of getModuleImportStack on modules loaded in the devtools loader");
|
||||
Assert.ok(Cu.getModuleImportStack(ESM_URL).includes("testDevToolsModuleLoader"));
|
||||
Assert.ok(Cu.getModuleImportStack("resource://test/es6module_devtoolsLoader.js").includes("testDevToolsModuleLoader"));
|
||||
Assert.ok(Cu.getModuleImportStack("resource://test/es6module_devtoolsLoader.js").includes(ESM_URL));
|
||||
// Previous import stack were for module loaded via the shared jsm loader.
|
||||
// Let's also assert that we get stack traces for modules loaded via the devtools loader.
|
||||
Assert.ok(Cu.getModuleImportStack("resource://test/es6module_devtoolsLoader_only.js").includes("testDevToolsModuleLoader"));
|
||||
});
|
@ -29,6 +29,9 @@ support-files =
|
||||
es6module_cycle_b.js
|
||||
es6module_cycle_c.js
|
||||
es6module_top_level_await.js
|
||||
es6module_devtoolsLoader.js
|
||||
es6module_devtoolsLoader.sys.mjs
|
||||
es6module_devtoolsLoader_only.js
|
||||
esmified-1.sys.mjs
|
||||
esmified-2.sys.mjs
|
||||
esmified-3.sys.mjs
|
||||
@ -202,6 +205,7 @@ head = head_watchdog.js
|
||||
[test_uawidget_scope.js]
|
||||
[test_uninitialized_lexical.js]
|
||||
[test_print_stderr.js]
|
||||
[test_import_devtools_loader.js]
|
||||
[test_import_es6_modules.js]
|
||||
[test_import_shim.js]
|
||||
[test_defineESModuleGetters.js]
|
||||
|
@ -663,7 +663,7 @@ nsresult ShutdownXPCOM(nsIServiceManager* aServMgr) {
|
||||
// log files. We have to ignore them before we can move
|
||||
// the mozilla::PoisonWrite call before this point. See bug
|
||||
// 834945 for the details.
|
||||
mozJSModuleLoader::Unload();
|
||||
mozJSModuleLoader::UnloadLoaders();
|
||||
|
||||
// Clear the profiler's JS context before cycle collection. The profiler will
|
||||
// notify the JS engine that it can let go of any data it's holding on to for
|
||||
|
Loading…
Reference in New Issue
Block a user