зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1864128 - Allow loading JSProcess Actors in the DevTools specific module loader. r=arai
Passing `loadInDevToolsLoader` to JSProcess actor options will force loading both parent and content modules in the distinct module loader used by DevTools. This distinct module loader is maintained by mozJSModuleLoader and is used by the DevTools Browser Console/Toolbox to debug privileged JS code typically using the "shared JSM Global" from DevTools modules loaded in a distinct and specific DevTools module loader. Differential Revision: https://phabricator.services.mozilla.com/D193280
This commit is contained in:
Родитель
d59b225e76
Коммит
b3006699b6
|
@ -54,6 +54,13 @@ dictionary ProcessActorOptions {
|
|||
*/
|
||||
boolean includeParent = false;
|
||||
|
||||
/**
|
||||
* If true, the actor will be loaded in the loader dedicated to DevTools.
|
||||
*
|
||||
* This ultimately prevents DevTools to debug itself.
|
||||
*/
|
||||
boolean loadInDevToolsLoader = false;
|
||||
|
||||
/** This fields are used for configuring individual sides of the actor. */
|
||||
ProcessActorSidedOptions parent;
|
||||
ProcessActorChildOptions child;
|
||||
|
|
|
@ -301,6 +301,10 @@ struct JSWindowActorInfo
|
|||
// False if `url` is for JSM or nothing.
|
||||
bool isESModule;
|
||||
|
||||
// This is to align with JSProcessActorInfo.
|
||||
// This attribute isn't used for JSWindow Actors.
|
||||
bool loadInDevToolsLoader;
|
||||
|
||||
// The module of the url.
|
||||
nsCString? url;
|
||||
|
||||
|
@ -322,6 +326,9 @@ struct JSProcessActorInfo
|
|||
// False if `url` is for JSM or nothing.
|
||||
bool isESModule;
|
||||
|
||||
// True if the actor should be loaded in the distinct loader dedicated to DevTools.
|
||||
bool loadInDevToolsLoader;
|
||||
|
||||
// The module of the url.
|
||||
nsCString? url;
|
||||
|
||||
|
|
|
@ -59,14 +59,18 @@ already_AddRefed<JSActor> JSActorManager::GetActor(JSContext* aCx,
|
|||
? protocol->Parent()
|
||||
: protocol->Child();
|
||||
|
||||
// We're about to construct the actor, so make sure we're in the JSM realm
|
||||
// while importing etc.
|
||||
JSAutoRealm ar(aCx, xpc::PrivilegedJunkScope());
|
||||
|
||||
// Load the module using mozJSModuleLoader.
|
||||
RefPtr loader = mozJSModuleLoader::Get();
|
||||
// If the JSActor uses `loadInDevToolsLoader`, force loading in the DevTools
|
||||
// specific's loader.
|
||||
RefPtr loader = protocol->mLoadInDevToolsLoader
|
||||
? mozJSModuleLoader::GetOrCreateDevToolsLoader()
|
||||
: mozJSModuleLoader::Get();
|
||||
MOZ_ASSERT(loader);
|
||||
|
||||
// We're about to construct the actor, so make sure we're in the loader realm
|
||||
// while importing etc.
|
||||
JSAutoRealm ar(aCx, loader->GetSharedGlobal(aCx));
|
||||
|
||||
// If a module URI was provided, use it to construct an instance of the actor.
|
||||
JS::Rooted<JSObject*> actorObj(aCx);
|
||||
if (side.mModuleURI || side.mESModuleURI) {
|
||||
|
|
|
@ -26,6 +26,8 @@ class JSActorProtocolUtils {
|
|||
aProto->mChild.mModuleURI = aInfo.url();
|
||||
}
|
||||
|
||||
aProto->mLoadInDevToolsLoader = aInfo.loadInDevToolsLoader();
|
||||
|
||||
aProto->mChild.mObservers = aInfo.observers().Clone();
|
||||
}
|
||||
|
||||
|
@ -43,6 +45,8 @@ class JSActorProtocolUtils {
|
|||
aInfo.isESModule() = true;
|
||||
}
|
||||
|
||||
aInfo.loadInDevToolsLoader() = aProto->mLoadInDevToolsLoader;
|
||||
|
||||
aInfo.observers() = aProto->mChild.mObservers.Clone();
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ class JSActorService final {
|
|||
};
|
||||
|
||||
/**
|
||||
* Base clsas for both `JSWindowActorProtocol` and `JSProcessActorProtocol`
|
||||
* Base class for both `JSWindowActorProtocol` and `JSProcessActorProtocol`
|
||||
* which can be used by generic code.
|
||||
*/
|
||||
class JSActorProtocol : public nsISupports {
|
||||
|
@ -104,6 +104,7 @@ class JSActorProtocol : public nsISupports {
|
|||
|
||||
virtual const Sided& Parent() const = 0;
|
||||
virtual const Sided& Child() const = 0;
|
||||
bool mLoadInDevToolsLoader = false;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -64,6 +64,8 @@ JSProcessActorProtocol::FromWebIDLOptions(const nsACString& aName,
|
|||
|
||||
proto->mIncludeParent = aOptions.mIncludeParent;
|
||||
|
||||
proto->mLoadInDevToolsLoader = aOptions.mLoadInDevToolsLoader;
|
||||
|
||||
return proto.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
[DEFAULT]
|
||||
support-files = ["head.js"]
|
||||
|
||||
["browser_devtools_loader.js"]
|
||||
|
||||
["browser_getActor.js"]
|
||||
|
||||
["browser_getActor_filter.js"]
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
declTest("getActor in the regular shared loader", {
|
||||
loadInDevToolsLoader: false,
|
||||
|
||||
async test(browser) {
|
||||
let parent = browser.browsingContext.currentWindowGlobal.domProcess;
|
||||
let parentActor = parent.getActor("TestProcessActor");
|
||||
ok(parentActor, "JSProcessActorParent should have value.");
|
||||
is(
|
||||
Cu.getRealmLocation(Cu.getGlobalForObject(parentActor)),
|
||||
"shared JSM global",
|
||||
"The JSActor module in the parent process should be loaded in the shared global"
|
||||
);
|
||||
|
||||
await SpecialPowers.spawn(browser, [], async function () {
|
||||
let child = ChromeUtils.domProcessChild;
|
||||
ok(child, "DOMProcessChild should have value.");
|
||||
let childActor = child.getActor("TestProcessActor");
|
||||
ok(childActor, "JSProcessActorChild should have value.");
|
||||
is(
|
||||
Cu.getRealmLocation(Cu.getGlobalForObject(childActor)),
|
||||
"shared JSM global",
|
||||
"The JSActor module in the child process should be loaded in the shared global"
|
||||
);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
declTest("getActor in the distinct DevTools loader", {
|
||||
loadInDevToolsLoader: true,
|
||||
|
||||
async test(browser) {
|
||||
let parent = browser.browsingContext.currentWindowGlobal.domProcess;
|
||||
let parentActor = parent.getActor("TestProcessActor");
|
||||
ok(parentActor, "JSProcessActorParent should have value.");
|
||||
is(
|
||||
Cu.getRealmLocation(Cu.getGlobalForObject(parentActor)),
|
||||
"DevTools global",
|
||||
"The JSActor module in the parent process should be loaded in the distinct DevTools global"
|
||||
);
|
||||
|
||||
await SpecialPowers.spawn(browser, [], async function () {
|
||||
let child = ChromeUtils.domProcessChild;
|
||||
ok(child, "DOMProcessChild should have value.");
|
||||
let childActor = child.getActor("TestProcessActor");
|
||||
ok(childActor, "JSProcessActorChild should have value.");
|
||||
is(
|
||||
Cu.getRealmLocation(Cu.getGlobalForObject(childActor)),
|
||||
"DevTools global",
|
||||
"The JSActor module in the child process should be loaded in the distinct DevTools global"
|
||||
);
|
||||
});
|
||||
},
|
||||
});
|
|
@ -46,7 +46,13 @@ function declTest(name, cfg) {
|
|||
}
|
||||
|
||||
function declTestWithOptions(name, cfg, fileExt) {
|
||||
let { url = "about:blank", includeParent = false, remoteTypes, test } = cfg;
|
||||
let {
|
||||
url = "about:blank",
|
||||
includeParent = false,
|
||||
remoteTypes,
|
||||
loadInDevToolsLoader = false,
|
||||
test,
|
||||
} = cfg;
|
||||
|
||||
// Build the actor options object which will be used to register & unregister
|
||||
// our process actor.
|
||||
|
@ -58,6 +64,9 @@ function declTestWithOptions(name, cfg, fileExt) {
|
|||
if (remoteTypes !== undefined) {
|
||||
actorOptions.remoteTypes = remoteTypes;
|
||||
}
|
||||
if (loadInDevToolsLoader) {
|
||||
actorOptions.loadInDevToolsLoader = true;
|
||||
}
|
||||
|
||||
// Add a new task for the actor test declared here.
|
||||
add_task(async function () {
|
||||
|
|
|
@ -65,6 +65,8 @@ class mozJSModuleLoader final : public nsIMemoryReporter {
|
|||
return sSelf;
|
||||
}
|
||||
|
||||
JSObject* GetSharedGlobal(JSContext* aCx);
|
||||
|
||||
static mozJSModuleLoader* GetDevToolsLoader() { return sDevToolsLoader; }
|
||||
static mozJSModuleLoader* GetOrCreateDevToolsLoader();
|
||||
|
||||
|
@ -146,8 +148,6 @@ class mozJSModuleLoader final : public nsIMemoryReporter {
|
|||
|
||||
bool CreateJSServices(JSContext* aCx);
|
||||
|
||||
JSObject* GetSharedGlobal(JSContext* aCx);
|
||||
|
||||
static nsresult GetSourceFile(nsIURI* aResolvedURI, nsIFile** aSourceFileOut);
|
||||
|
||||
static bool LocationIsRealFile(nsIURI* aURI);
|
||||
|
|
Загрузка…
Ссылка в новой задаче