author | J. Ryan Stinnett <jryans@gmail.com> |
Wed, 18 Dec 2013 12:48:38 -0600 | |
changeset 161341 | 89c1a04bede15e4c9536eb789de595268e53db4b |
parent 161340 | 29a40a25a938ff599628cec8608e4958e8361966 |
child 161342 | af9e8e63fc8b2e254d2ab3d3b0bdace63db1babb |
push id | 25878 |
push user | kwierso@gmail.com |
push date | Fri, 20 Dec 2013 03:09:21 +0000 |
treeherder | mozilla-central@599100c4ebfe [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bustage |
bugs | 946813, 941012 |
milestone | 29.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/toolkit/devtools/Loader.jsm +++ b/toolkit/devtools/Loader.jsm @@ -30,17 +30,16 @@ this.EXPORTED_SYMBOLS = ["DevToolsLoader /** * Providers are different strategies for loading the devtools. */ let loaderGlobals = { btoa: btoa, console: console, _Iterator: Iterator, - ChromeWorker: ChromeWorker, loader: { lazyGetter: XPCOMUtils.defineLazyGetter.bind(XPCOMUtils), lazyImporter: XPCOMUtils.defineLazyModuleGetter.bind(XPCOMUtils), lazyServiceGetter: XPCOMUtils.defineLazyServiceGetter.bind(XPCOMUtils) } }; // Used when the tools should be loaded from the Firefox package itself (the default)
--- a/toolkit/devtools/server/dbg-server.jsm +++ b/toolkit/devtools/server/dbg-server.jsm @@ -10,16 +10,36 @@ * shield it from the debuggee. This way, when debugging chrome globals, * debugger and debuggee will be in separate compartments. */ const Ci = Components.interfaces; const Cc = Components.classes; const Cu = Components.utils; -const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}); - this.EXPORTED_SYMBOLS = ["DebuggerServer", "ActorPool"]; -let server = devtools.require("devtools/server/main"); +var loadSubScript = + "function loadSubScript(aURL)\n" + + "{\n" + + "const Ci = Components.interfaces;\n" + + "const Cc = Components.classes;\n" + + " try {\n" + + " let loader = Cc[\"@mozilla.org/moz/jssubscript-loader;1\"]\n" + + " .getService(Ci.mozIJSSubScriptLoader);\n" + + " loader.loadSubScript(aURL, this);\n" + + " } catch(e) {\n" + + " dump(\"Error loading: \" + aURL + \": \" + e + \" - \" + e.stack + \"\\n\");\n" + + " throw e;\n" + + " }\n" + + "}"; -this.DebuggerServer = server.DebuggerServer; -this.ActorPool = server.ActorPool; +// Load the debugging server in a sandbox with its own compartment. +var systemPrincipal = Cc["@mozilla.org/systemprincipal;1"] + .createInstance(Ci.nsIPrincipal); + +var gGlobal = Cu.Sandbox(systemPrincipal); +gGlobal.ChromeWorker = ChromeWorker; +Cu.evalInSandbox(loadSubScript, gGlobal, "1.8"); +gGlobal.loadSubScript("resource://gre/modules/devtools/server/main.js"); + +this.DebuggerServer = gGlobal.DebuggerServer; +this.ActorPool = gGlobal.ActorPool;
--- a/toolkit/devtools/server/main.js +++ b/toolkit/devtools/server/main.js @@ -5,32 +5,46 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; /** * Toolkit glue for the remote debugging protocol, loaded into the * debugging global. */ -// Until all Debugger server code is converted to SDK modules, -// imports Components.* alias from chrome module. -var { Ci, Cc, CC, Cu, Cr } = require("chrome"); -// On B2G, `this` != Global scope, so `Ci` won't be binded on `this` -// (i.e. this.Ci is undefined) Then later, when using loadSubScript, -// Ci,... won't be defined for sub scripts. -this.Ci = Ci; -this.Cc = Cc; -this.CC = CC; -this.Cu = Cu; -this.Cr = Cr; -// Overload `Components` to prevent SDK loader exception on Components -// object usage -Object.defineProperty(this, "Components", { - get: function () require("chrome").components -}); +// |this.require| is used to test if this file was loaded via the devtools +// loader (as it is in DebuggerProcess.jsm) or via loadSubScript (as it is from +// dbg-server.jsm). Note that testing |require| is not safe in either +// situation, as it causes a ReferenceError. +var Ci, Cc, CC, Cu, Cr, Components; +if (this.require) { + ({ Ci, Cc, CC, Cu, Cr, components: Components }) = require("chrome"); +} else { + ({ + interfaces: Ci, + classes: Cc, + Constructor: CC, + utils: Cu, + results: Cr + }) = Components; +} + +// On B2G, if |this.require| is undefined at this point, it remains undefined +// later on when |DebuggerServer.registerModule| is called. On desktop (and +// perhaps other places), if |this.require| starts out undefined, it ends up +// being set to some native code by the time we get to |registerModule|. Here +// we perform a test early on, and then cache the correct require function for +// later use. +var localRequire; +if (this.require) { + localRequire = id => require(id); +} else { + let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}); + localRequire = id => devtools.require(id); +} const DBG_STRINGS_URI = "chrome://global/locale/devtools/debugger.properties"; const nsFile = CC("@mozilla.org/file/local;1", "nsIFile", "initWithPath"); Cu.import("resource://gre/modules/reflect.jsm"); Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); @@ -49,40 +63,36 @@ function loadSubScript(aURL) } catch(e) { let errorStr = "Error loading: " + aURL + ": " + e + " - " + e.stack + "\n"; dump(errorStr); Cu.reportError(errorStr); throw e; } } -let {defer, resolve, reject, promised, all} = require("sdk/core/promise"); -this.defer = defer; -this.resolve = resolve; -this.reject = reject; -this.promised = promised; -this.all = all; +let loaderRequire = this.require; +this.require = null; +loadSubScript.call(this, "resource://gre/modules/commonjs/sdk/core/promise.js"); +this.require = loaderRequire; Cu.import("resource://gre/modules/devtools/SourceMap.jsm"); loadSubScript.call(this, "resource://gre/modules/devtools/DevToolsUtils.js"); function dumpn(str) { if (wantLogging) { dump("DBG-SERVER: " + str + "\n"); } } -this.dumpn = dumpn; function dbg_assert(cond, e) { if (!cond) { return e; } } -this.dbg_assert = dbg_assert; loadSubScript.call(this, "resource://gre/modules/devtools/server/transport.js"); // XPCOM constructors const ServerSocket = CC("@mozilla.org/network/server-socket;1", "nsIServerSocket", "initSpecialConnection"); const UnixDomainServerSocket = CC("@mozilla.org/network/server-socket;1", @@ -309,17 +319,17 @@ var DebuggerServer = { * 'register' and 'unregister' functions. */ registerModule: function(id) { if (id in gRegisteredModules) { throw new Error("Tried to register a module twice: " + id + "\n"); } let moduleAPI = ModuleAPI(); - let mod = require(id); + let mod = localRequire(id); mod.register(moduleAPI); gRegisteredModules[id] = { module: mod, api: moduleAPI }; }, /** * Returns true if a module id has been registered. */ isModuleRegistered: function(id) { @@ -673,18 +683,16 @@ var DebuggerServer = { } } } }; if (this.exports) { exports.DebuggerServer = DebuggerServer; } -// Needed on B2G (See header note) -this.DebuggerServer = DebuggerServer; /** * Construct an ActorPool. * * ActorPools are actorID -> actor mapping and storage. These are * used to accumulate and quickly dispose of groups of actors that * share a lifetime. */ @@ -693,18 +701,16 @@ function ActorPool(aConnection) this.conn = aConnection; this._cleanups = {}; this._actors = {}; } if (this.exports) { exports.ActorPool = ActorPool; } -// Needed on B2G (See header note) -this.ActorPool = ActorPool; ActorPool.prototype = { /** * Add an actor to the actor pool. If the actor doesn't have an ID, * allocate one from the connection. * * @param aActor object * The actor implementation. If the object has a