Avoid infinite recursion when lazy-loading devtools modules and stepping into promise code in chrome debugging (bug 1149910). r=jlongster,fitzgen
authorPanos Astithas <past@mozilla.com>
Tue, 21 Apr 2015 09:11:44 +0300
changeset 240165 899ae22ef02a9d259a54cc6c5e42f4902a77372f
parent 240164 19519ebc76bccff422ace0e19c9ff0facad751ce
child 240166 3de89bd361c3c68adc7b959823e34d5ca29abf2d
child 240300 c8d12213943f54770284aa4cf6c12d0e16a75869
push id58752
push usercbook@mozilla.com
push dateTue, 21 Apr 2015 10:39:00 +0000
treeherdermozilla-inbound@b8d59286a581 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjlongster, fitzgen
bugs1149910
milestone40.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
Avoid infinite recursion when lazy-loading devtools modules and stepping into promise code in chrome debugging (bug 1149910). r=jlongster,fitzgen
toolkit/devtools/Loader.jsm
toolkit/devtools/server/actors/utils/TabSources.js
toolkit/devtools/server/actors/webbrowser.js
--- a/toolkit/devtools/Loader.jsm
+++ b/toolkit/devtools/Loader.jsm
@@ -311,20 +311,35 @@ DevToolsLoader.prototype = {
    *    The property name.
    * @param String module
    *    The module path.
    * @param Boolean destructure
    *    Pass true if the property name is a member of the module's exports.
    */
   lazyRequireGetter: function (obj, property, module, destructure) {
     Object.defineProperty(obj, property, {
-      get: () => destructure
-        ? this.require(module)[property]
-        : this.require(module || property),
-      configurable: true
+      get: () => {
+        // Redefine this accessor property as a data property.
+        // Delete it first, to rule out "too much recursion" in case obj is
+        // a proxy whose defineProperty handler might unwittingly trigger this
+        // getter again.
+        delete obj[property];
+        let value = destructure
+          ? this.require(module)[property]
+          : this.require(module || property);
+        Object.defineProperty(obj, property, {
+          value,
+          writable: true,
+          configurable: true,
+          enumerable: true
+        });
+        return value;
+      },
+      configurable: true,
+      enumerable: true
     });
   },
 
   /**
    * Add a URI to the loader.
    * @param string id
    *    The module id that can be used within the loader to refer to this module.
    * @param string uri
--- a/toolkit/devtools/server/actors/utils/TabSources.js
+++ b/toolkit/devtools/server/actors/utils/TabSources.js
@@ -1,15 +1,21 @@
-const Services = require("Services");
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
 const { Ci, Cu } = require("chrome");
+const Services = require("Services");
 const DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
+const { dbg_assert, fetch } = DevToolsUtils;
 const EventEmitter = require("devtools/toolkit/event-emitter");
-const { dbg_assert, fetch } = require("devtools/toolkit/DevToolsUtils");
 const { OriginalLocation, GeneratedLocation, getOffsetColumn } = require("devtools/server/actors/common");
-const { resolve } = require("promise");
+const { resolve } = Promise;
 
 loader.lazyRequireGetter(this, "SourceActor", "devtools/server/actors/script", true);
 loader.lazyRequireGetter(this, "isEvalSource", "devtools/server/actors/script", true);
 loader.lazyRequireGetter(this, "SourceMapConsumer", "source-map", true);
 loader.lazyRequireGetter(this, "SourceMapGenerator", "source-map", true);
 
 /**
  * Manages the sources for a thread. Handles source maps, locations in the
--- a/toolkit/devtools/server/actors/webbrowser.js
+++ b/toolkit/devtools/server/actors/webbrowser.js
@@ -3,24 +3,24 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 let { Ci, Cu } = require("chrome");
 let Services = require("Services");
+let promise = require("promise");
 let { ActorPool, createExtraActors, appendExtraActors } = require("devtools/server/actors/common");
 let { DebuggerServer } = require("devtools/server/main");
 let DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
 let { dbg_assert } = DevToolsUtils;
 let { TabSources, isHiddenSource } = require("./utils/TabSources");
 let makeDebugger = require("./utils/make-debugger");
 
-let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 loader.lazyRequireGetter(this, "RootActor", "devtools/server/actors/root", true);
 loader.lazyRequireGetter(this, "AddonThreadActor", "devtools/server/actors/script", true);
 loader.lazyRequireGetter(this, "ThreadActor", "devtools/server/actors/script", true);
 loader.lazyRequireGetter(this, "mapURIToAddonID", "devtools/server/actors/utils/map-uri-to-addon-id");
 loader.lazyImporter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm");