mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 08:42:13 +00:00
Bug 1013997 - Use only one compartment for all devtools modules. r=mossop, r=past
This commit is contained in:
parent
84f485d505
commit
f2b703b3b6
@ -11,7 +11,9 @@ module.metadata = {
|
||||
const { Cu } = require("chrome");
|
||||
|
||||
// Passing an empty object as second argument to avoid scope's pollution
|
||||
const { atob, btoa } = Cu.import("resource://gre/modules/Services.jsm", {});
|
||||
// (devtools loader injects these symbols as global and prevent using
|
||||
// const here)
|
||||
var { atob, btoa } = Cu.import("resource://gre/modules/Services.jsm", {});
|
||||
|
||||
function isUTF8(charset) {
|
||||
let type = typeof charset;
|
||||
|
@ -283,17 +283,31 @@ const load = iced(function load(loader, module) {
|
||||
}
|
||||
});
|
||||
|
||||
let sandbox = sandboxes[module.uri] = Sandbox({
|
||||
name: module.uri,
|
||||
prototype: create(globals, descriptors),
|
||||
wantXrays: false,
|
||||
wantGlobalProperties: module.id == "sdk/indexed-db" ? ["indexedDB"] : [],
|
||||
invisibleToDebugger: loader.invisibleToDebugger,
|
||||
metadata: {
|
||||
addonID: loader.id,
|
||||
URI: module.uri
|
||||
}
|
||||
});
|
||||
let sandbox;
|
||||
if (loader.sharedGlobalSandbox &&
|
||||
loader.sharedGlobalBlacklist.indexOf(module.id) == -1) {
|
||||
// Create a new object in this sandbox, that will be used as
|
||||
// the scope object for this particular module
|
||||
sandbox = new loader.sharedGlobalSandbox.Object();
|
||||
// Inject all expected globals in the scope object
|
||||
getOwnPropertyNames(globals).forEach(function(name) {
|
||||
descriptors[name] = getOwnPropertyDescriptor(globals, name)
|
||||
});
|
||||
define(sandbox, descriptors);
|
||||
} else {
|
||||
sandbox = Sandbox({
|
||||
name: module.uri,
|
||||
prototype: create(globals, descriptors),
|
||||
wantXrays: false,
|
||||
wantGlobalProperties: module.id == "sdk/indexed-db" ? ["indexedDB"] : [],
|
||||
invisibleToDebugger: loader.invisibleToDebugger,
|
||||
metadata: {
|
||||
addonID: loader.id,
|
||||
URI: module.uri
|
||||
}
|
||||
});
|
||||
}
|
||||
sandboxes[module.uri] = sandbox;
|
||||
|
||||
try {
|
||||
evaluate(sandbox, module.uri);
|
||||
@ -691,8 +705,8 @@ const Loader = iced(function Loader(options) {
|
||||
});
|
||||
|
||||
let {
|
||||
modules, globals, resolve, paths, rootURI,
|
||||
manifest, requireMap, isNative, metadata
|
||||
modules, globals, resolve, paths, rootURI, manifest, requireMap, isNative,
|
||||
metadata, sharedGlobal, sharedGlobalBlacklist
|
||||
} = override({
|
||||
paths: {},
|
||||
modules: {},
|
||||
@ -702,6 +716,7 @@ const Loader = iced(function Loader(options) {
|
||||
resolve: options.isNative ?
|
||||
exports.nodeResolve :
|
||||
exports.resolve,
|
||||
sharedGlobalBlacklist: ["sdk/indexed-db"]
|
||||
}, options);
|
||||
|
||||
// We create an identity object that will be dispatched on an unload
|
||||
@ -738,6 +753,24 @@ const Loader = iced(function Loader(options) {
|
||||
return result;
|
||||
}, {});
|
||||
|
||||
let sharedGlobalSandbox;
|
||||
if (sharedGlobal) {
|
||||
// Create the unique sandbox we will be using for all modules,
|
||||
// so that we prevent creating a new comportment per module.
|
||||
// The side effect is that all modules will share the same
|
||||
// global objects.
|
||||
sharedGlobalSandbox = Sandbox({
|
||||
name: "Addon-SDK",
|
||||
wantXrays: false,
|
||||
wantGlobalProperties: [],
|
||||
invisibleToDebugger: options.invisibleToDebugger || false,
|
||||
metadata: {
|
||||
addonID: options.id,
|
||||
URI: "Addon-SDK"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Loader object is just a representation of a environment
|
||||
// state. We freeze it and mark make it's properties non-enumerable
|
||||
// as they are pure implementation detail that no one should rely upon.
|
||||
@ -748,6 +781,8 @@ const Loader = iced(function Loader(options) {
|
||||
// Map of module objects indexed by module URIs.
|
||||
modules: { enumerable: false, value: modules },
|
||||
metadata: { enumerable: false, value: metadata },
|
||||
sharedGlobalSandbox: { enumerable: false, value: sharedGlobalSandbox },
|
||||
sharedGlobalBlacklist: { enumerable: false, value: sharedGlobalBlacklist },
|
||||
// Map of module sandboxes indexed by module URIs.
|
||||
sandboxes: { enumerable: false, value: {} },
|
||||
resolve: { enumerable: false, value: resolve },
|
||||
|
@ -343,4 +343,27 @@ exports['test console global by default'] = function (assert) {
|
||||
function fakeConsole () {};
|
||||
};
|
||||
|
||||
exports['test shared globals'] = function(assert) {
|
||||
let uri = root + '/fixtures/loader/cycles/';
|
||||
let loader = Loader({ paths: { '': uri }, sharedGlobal: true,
|
||||
sharedGlobalBlacklist: ['b'] });
|
||||
|
||||
let program = main(loader, 'main');
|
||||
|
||||
// As it is hard to verify what is the global of an object
|
||||
// (due to wrappers) we check that we see the `foo` symbol
|
||||
// being manually injected into the shared global object
|
||||
loader.sharedGlobalSandbox.foo = true;
|
||||
|
||||
let m = loader.sandboxes[uri + 'main.js'];
|
||||
let a = loader.sandboxes[uri + 'a.js'];
|
||||
let b = loader.sandboxes[uri + 'b.js'];
|
||||
|
||||
assert.ok(Cu.getGlobalForObject(m).foo, "main is shared");
|
||||
assert.ok(Cu.getGlobalForObject(a).foo, "a is shared");
|
||||
assert.ok(!Cu.getGlobalForObject(b).foo, "b isn't shared");
|
||||
|
||||
unload(loader);
|
||||
}
|
||||
|
||||
require('test').run(exports);
|
||||
|
@ -14,14 +14,13 @@ const { indexedDB } = require("sdk/indexed-db");
|
||||
* a unique `location` object.
|
||||
*/
|
||||
|
||||
const global = this;
|
||||
const IDB = {
|
||||
_db: null,
|
||||
|
||||
open: function () {
|
||||
let deferred = promise.defer();
|
||||
|
||||
let request = global.indexedDB.open("AppProjects", 5);
|
||||
let request = indexedDB.open("AppProjects", 5);
|
||||
request.onerror = function(event) {
|
||||
deferred.reject("Unable to open AppProjects indexedDB. " +
|
||||
"Error code: " + event.target.errorCode);
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
const {Cu, Cc, Ci} = require("chrome");
|
||||
const Services = require("Services");
|
||||
const promise = require("promise");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "gDevTools", "resource:///modules/devtools/gDevTools.jsm");
|
||||
|
||||
|
@ -10,6 +10,7 @@ const { EventTarget } = require("sdk/event/target");
|
||||
const { emit } = require("sdk/event/core");
|
||||
const { EditorTypeForResource } = require("projecteditor/editors");
|
||||
const NetworkHelper = require("devtools/toolkit/webconsole/network-helper");
|
||||
const promise = require("promise");
|
||||
|
||||
/**
|
||||
* The Shell is the object that manages the editor for a single resource.
|
||||
|
@ -9,6 +9,7 @@ const {Simulator} = Cu.import("resource://gre/modules/devtools/Simulator.jsm");
|
||||
const {ConnectionManager, Connection} = require("devtools/client/connection-manager");
|
||||
const {DebuggerServer} = require("resource://gre/modules/devtools/dbg-server.jsm");
|
||||
const discovery = require("devtools/toolkit/discovery/discovery");
|
||||
const promise = require("promise");
|
||||
|
||||
const Strings = Services.strings.createBundle("chrome://webide/content/webide.properties");
|
||||
|
||||
|
@ -6,10 +6,10 @@
|
||||
|
||||
/* General utilities used throughout devtools. */
|
||||
|
||||
// hasChrome is provided as a global by the loader. It is true if we are running
|
||||
// on the main thread, and false if we are running on a worker thread.
|
||||
var { Ci, Cu } = require("chrome");
|
||||
var Services = require("Services");
|
||||
var promise = require("promise");
|
||||
var { setTimeout } = require("Timer");
|
||||
|
||||
/**
|
||||
* Turn the error |aError| into a string, without fail.
|
||||
|
@ -44,19 +44,11 @@ let Timer = Cu.import("resource://gre/modules/Timer.jsm", {});
|
||||
|
||||
let loaderGlobals = {
|
||||
isWorker: false,
|
||||
Debugger: Debugger,
|
||||
promise: promise,
|
||||
reportError: Cu.reportError,
|
||||
setInterval: Timer.setInterval,
|
||||
setTimeout: Timer.setTimeout,
|
||||
clearInterval: Timer.clearInterval,
|
||||
clearTimeout: Timer.clearTimeout,
|
||||
xpcInspector: xpcInspector,
|
||||
|
||||
btoa: btoa,
|
||||
console: console,
|
||||
_Iterator: Iterator,
|
||||
ChromeWorker: ChromeWorker,
|
||||
loader: {
|
||||
lazyGetter: XPCOMUtils.defineLazyGetter.bind(XPCOMUtils),
|
||||
lazyImporter: XPCOMUtils.defineLazyModuleGetter.bind(XPCOMUtils),
|
||||
@ -64,16 +56,30 @@ let loaderGlobals = {
|
||||
},
|
||||
};
|
||||
|
||||
let loaderModules = {
|
||||
"Debugger": Debugger,
|
||||
"Services": Object.create(Services),
|
||||
"Timer": Object.create(Timer),
|
||||
"toolkit/loader": loader,
|
||||
"xpcInspector": xpcInspector,
|
||||
"promise": promise,
|
||||
};
|
||||
try {
|
||||
let { indexedDB } = Cu.Sandbox(this, {wantGlobalProperties:["indexedDB"]});
|
||||
loaderModules.indexedDB = indexedDB;
|
||||
} catch(e) {
|
||||
// On xpcshell, we can't instantiate indexedDB without crashing
|
||||
}
|
||||
|
||||
let sharedGlobalBlacklist = ["sdk/indexed-db", "devtools/toolkit/qrcode/decoder/index"];
|
||||
|
||||
// Used when the tools should be loaded from the Firefox package itself (the default)
|
||||
function BuiltinProvider() {}
|
||||
BuiltinProvider.prototype = {
|
||||
load: function() {
|
||||
this.loader = new loader.Loader({
|
||||
id: "fx-devtools",
|
||||
modules: {
|
||||
"Services": Object.create(Services),
|
||||
"toolkit/loader": loader,
|
||||
},
|
||||
modules: loaderModules,
|
||||
paths: {
|
||||
// When you add a line to this mapping, don't forget to make a
|
||||
// corresponding addition to the SrcdirProvider mapping below as well.
|
||||
@ -103,7 +109,9 @@ BuiltinProvider.prototype = {
|
||||
"xpcshell-test": "resource://test"
|
||||
},
|
||||
globals: loaderGlobals,
|
||||
invisibleToDebugger: this.invisibleToDebugger
|
||||
invisibleToDebugger: this.invisibleToDebugger,
|
||||
sharedGlobal: true,
|
||||
sharedGlobalBlacklist: sharedGlobalBlacklist
|
||||
});
|
||||
|
||||
return promise.resolve(undefined);
|
||||
@ -153,10 +161,7 @@ SrcdirProvider.prototype = {
|
||||
let sourceMapURI = this.fileURI(OS.Path.join(toolkitDir), "SourceMap.jsm");
|
||||
this.loader = new loader.Loader({
|
||||
id: "fx-devtools",
|
||||
modules: {
|
||||
"Services": Object.create(Services),
|
||||
"toolkit/loader": loader,
|
||||
},
|
||||
modules: loaderModules,
|
||||
paths: {
|
||||
"": "resource://gre/modules/commonjs/",
|
||||
"main": mainURI,
|
||||
@ -181,7 +186,9 @@ SrcdirProvider.prototype = {
|
||||
"source-map": sourceMapURI,
|
||||
},
|
||||
globals: loaderGlobals,
|
||||
invisibleToDebugger: this.invisibleToDebugger
|
||||
invisibleToDebugger: this.invisibleToDebugger,
|
||||
sharedGlobal: true,
|
||||
sharedGlobalBlacklist: sharedGlobalBlacklist
|
||||
});
|
||||
|
||||
return this._writeManifest(devtoolsDir).then(null, Cu.reportError);
|
||||
|
@ -24,6 +24,7 @@ module.exports = EventEmitter;
|
||||
|
||||
const { Cu, components } = require("chrome");
|
||||
const Services = require("Services");
|
||||
const promise = require("promise");
|
||||
|
||||
/**
|
||||
* Decorate an object with event emitter functionality.
|
||||
|
@ -7,12 +7,16 @@
|
||||
"use strict";
|
||||
|
||||
const Services = require("Services");
|
||||
const { Cc, Ci, Cu, components } = require("chrome");
|
||||
const { Cc, Ci, Cu, components, ChromeWorker } = require("chrome");
|
||||
const { ActorPool } = require("devtools/server/actors/common");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
const DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
|
||||
const { dbg_assert, dumpn, update } = DevToolsUtils;
|
||||
const { SourceMapConsumer, SourceMapGenerator } = require("source-map");
|
||||
const promise = require("promise");
|
||||
const Debugger = require("Debugger");
|
||||
const xpcInspector = require("xpcInspector");
|
||||
|
||||
const { defer, resolve, reject, all } = require("devtools/toolkit/deprecated-sync-thenables");
|
||||
const { CssLogic } = require("devtools/styleinspector/css-logic");
|
||||
|
||||
|
@ -1184,7 +1184,7 @@ StorageActors.createActor({
|
||||
principal = Services.scriptSecurityManager.getCodebasePrincipal(uri);
|
||||
}
|
||||
|
||||
return indexedDB.openForPrincipal(principal, name);
|
||||
return require("indexedDB").openForPrincipal(principal, name);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -7,9 +7,7 @@
|
||||
const { Cu } = require("chrome");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
const { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
|
||||
|
||||
Cu.import("resource://gre/modules/jsdebugger.jsm");
|
||||
addDebuggerToGlobal(this);
|
||||
const Debugger = require("Debugger");
|
||||
|
||||
// TODO bug 943125: remove this polyfill and use Debugger.Frame.prototype.depth
|
||||
// once it is implemented.
|
||||
|
@ -10,6 +10,7 @@ const { Cc, Ci, Cu } = require("chrome");
|
||||
const { DebuggerServer, ActorPool } = require("devtools/server/main");
|
||||
const { EnvironmentActor, LongStringActor, ObjectActor, ThreadActor } = require("devtools/server/actors/script");
|
||||
const { update } = require("devtools/toolkit/DevToolsUtils");
|
||||
const Debugger = require("Debugger");
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
|
@ -19,6 +19,7 @@ let DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
|
||||
let { dumpn, dumpv, dbg_assert } = DevToolsUtils;
|
||||
let Services = require("Services");
|
||||
let EventEmitter = require("devtools/toolkit/event-emitter");
|
||||
let Debugger = require("Debugger");
|
||||
|
||||
// Until all Debugger server code is converted to SDK modules,
|
||||
// imports Components.* alias from chrome module.
|
||||
@ -843,6 +844,15 @@ if (this.exports) {
|
||||
// Needed on B2G (See header note)
|
||||
this.DebuggerServer = DebuggerServer;
|
||||
|
||||
// When using DebuggerServer.addActors, some symbols are expected to be in
|
||||
// the scope of the added actor even before the corresponding modules are
|
||||
// loaded, so let's explicitly bind the expected symbols here.
|
||||
let includes = ["Components", "Ci", "Cu", "require", "Services", "DebuggerServer",
|
||||
"ActorPool", "DevToolsUtils"];
|
||||
includes.forEach(name => {
|
||||
DebuggerServer[name] = this[name];
|
||||
});
|
||||
|
||||
// Export ActorPool for requirers of main.js
|
||||
if (this.exports) {
|
||||
exports.ActorPool = ActorPool;
|
||||
|
@ -5,6 +5,7 @@ const { ActorPool, appendExtraActors, createExtraActors } = require("devtools/se
|
||||
const { RootActor } = require("devtools/server/actors/root");
|
||||
const { ThreadActor } = require("devtools/server/actors/script");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
const promise = require("promise");
|
||||
|
||||
var gTestGlobals = [];
|
||||
DebuggerServer.addTestGlobal = function(aGlobal) {
|
||||
|
@ -21,7 +21,7 @@ function visible_loader() {
|
||||
loader.require("devtools/css-color");
|
||||
|
||||
let dbg = new Debugger();
|
||||
let sandbox = loader._provider.loader.sandboxes[COLOR_URI];
|
||||
let sandbox = loader._provider.loader.sharedGlobalSandbox;
|
||||
|
||||
try {
|
||||
dbg.addDebuggee(sandbox);
|
||||
@ -37,7 +37,7 @@ function invisible_loader() {
|
||||
loader.require("devtools/css-color");
|
||||
|
||||
let dbg = new Debugger();
|
||||
let sandbox = loader._provider.loader.sandboxes[COLOR_URI];
|
||||
let sandbox = loader._provider.loader.sharedGlobalSandbox;
|
||||
|
||||
try {
|
||||
dbg.addDebuggee(sandbox);
|
||||
|
@ -28,7 +28,7 @@ const { Cc, Ci, Cu } = require("chrome");
|
||||
const DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
|
||||
const { dumpn, dumpv } = DevToolsUtils;
|
||||
const StreamUtils = require("devtools/toolkit/transport/stream-utils");
|
||||
const EventEmitter = require("devtools/toolkit/event-emitter");
|
||||
const promise = require("promise");
|
||||
|
||||
DevToolsUtils.defineLazyGetter(this, "unicodeConverter", () => {
|
||||
const unicodeConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
|
||||
|
@ -9,6 +9,7 @@ const Services = require("Services");
|
||||
const DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
|
||||
const { dumpv } = DevToolsUtils;
|
||||
const EventEmitter = require("devtools/toolkit/event-emitter");
|
||||
const promise = require("promise");
|
||||
|
||||
DevToolsUtils.defineLazyGetter(this, "IOUtil", () => {
|
||||
return Cc["@mozilla.org/io-util;1"].getService(Ci.nsIIOUtil);
|
||||
|
@ -6,6 +6,7 @@ const { ActorPool, appendExtraActors, createExtraActors } =
|
||||
const { RootActor } = require("devtools/server/actors/root");
|
||||
const { ThreadActor } = require("devtools/server/actors/script");
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
const promise = require("promise");
|
||||
|
||||
var gTestGlobals = [];
|
||||
DebuggerServer.addTestGlobal = function(aGlobal) {
|
||||
|
@ -29,6 +29,7 @@ const { dumpn, dumpv } = DevToolsUtils;
|
||||
const StreamUtils = require("devtools/toolkit/transport/stream-utils");
|
||||
const { Packet, JSONPacket, BulkPacket } =
|
||||
require("devtools/toolkit/transport/packets");
|
||||
const promise = require("promise");
|
||||
|
||||
DevToolsUtils.defineLazyGetter(this, "Pipe", () => {
|
||||
return CC("@mozilla.org/pipe;1", "nsIPipe", "init");
|
||||
|
@ -311,18 +311,16 @@ if (typeof Components === "object") {
|
||||
createSandbox: createSandbox,
|
||||
globals: {
|
||||
"isWorker": true,
|
||||
"Debugger": Debugger,
|
||||
"setInterval": Timer.setInterval,
|
||||
"setTimeout": Timer.setTimeout,
|
||||
"clearInterval": Timer.clearInterval,
|
||||
"clearTimeout": Timer.clearTimeout,
|
||||
"xpcInspector": xpcInspector,
|
||||
"reportError": Cu.reportError,
|
||||
},
|
||||
loadInSandbox: loadInSandbox,
|
||||
modules: {
|
||||
"Services": {},
|
||||
"chrome": chrome,
|
||||
"promise": Promise,
|
||||
"Debugger": Debugger,
|
||||
"xpcInspector": xpcInspector,
|
||||
"Timer": Object.create(Timer)
|
||||
},
|
||||
paths: {
|
||||
"": "resource://gre/modules/commonjs/",
|
||||
|
Loading…
Reference in New Issue
Block a user