Bug 941012 - Always use SDK loader to load DebuggerServer. r=jryans
☠☠ backed out by 861caea2762b ☠ ☠
authorAlexandre Poirot <poirot.alex@gmail.com>
Mon, 02 Dec 2013 11:34:47 -0500
changeset 173026 c50cca7d248a7039fceade04032c401781ed521b
parent 173025 29dd3fb48a443a43d2da5757319e691c38beac86
child 173027 236a0eba3a8afdbb6e72085b19cbbd6941b83397
push id3224
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:06:49 +0000
treeherdermozilla-beta@60c04d0987f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjryans
bugs941012
milestone28.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
Bug 941012 - Always use SDK loader to load DebuggerServer. r=jryans
toolkit/devtools/Loader.jsm
toolkit/devtools/server/dbg-server.jsm
toolkit/devtools/server/main.js
--- a/toolkit/devtools/Loader.jsm
+++ b/toolkit/devtools/Loader.jsm
@@ -30,16 +30,17 @@ 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,36 +10,16 @@
  * 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"];
 
-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" +
-  "}";
+let server = devtools.require("devtools/server/main");
 
-// 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;
+this.DebuggerServer = server.DebuggerServer;
+this.ActorPool = server.ActorPool;
--- a/toolkit/devtools/server/main.js
+++ b/toolkit/devtools/server/main.js
@@ -5,46 +5,32 @@
  * 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.
  */
 
-// |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);
-}
+// 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
+});
 
 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");
@@ -63,36 +49,40 @@ function loadSubScript(aURL)
   } catch(e) {
     let errorStr = "Error loading: " + aURL + ": " + e + " - " + e.stack + "\n";
     dump(errorStr);
     Cu.reportError(errorStr);
     throw e;
   }
 }
 
-let loaderRequire = this.require;
-this.require = null;
-loadSubScript.call(this, "resource://gre/modules/commonjs/sdk/core/promise.js");
-this.require = loaderRequire;
+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;
 
 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",
@@ -319,17 +309,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 = localRequire(id);
+    let mod = require(id);
     mod.register(moduleAPI);
     gRegisteredModules[id] = { module: mod, api: moduleAPI };
   },
 
   /**
    * Returns true if a module id has been registered.
    */
   isModuleRegistered: function(id) {
@@ -683,16 +673,18 @@ 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.
  */
@@ -701,16 +693,18 @@ 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