Merge inbound to mozilla-central. a=merge
authorGurzau Raul <rgurzau@mozilla.com>
Wed, 10 Oct 2018 00:59:57 +0300
changeset 440313 6f8701d1be0ccf42a8e22bfce6f40056a4f58a1b
parent 440302 4845f02cf3545f00f4a6887a92455b3917296dee (current diff)
parent 440312 fb0c2bcc9bc616cc20d193969e0f4c14c7166600 (diff)
child 440340 f4978846e9c9918b9f8a21e7b4ba1453fa2891fe
child 440374 38890d8fa2542082eafe6e16dfc26b87d42ade94
push id34813
push userrgurzau@mozilla.com
push dateTue, 09 Oct 2018 22:01:11 +0000
treeherdermozilla-central@6f8701d1be0c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone64.0a1
first release with
nightly linux32
6f8701d1be0c / 64.0a1 / 20181009220508 / files
nightly linux64
6f8701d1be0c / 64.0a1 / 20181009220508 / files
nightly mac
6f8701d1be0c / 64.0a1 / 20181009220508 / files
nightly win32
6f8701d1be0c / 64.0a1 / 20181009220508 / files
nightly win64
6f8701d1be0c / 64.0a1 / 20181009220508 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
devtools/client/aboutdebugging-new/src/modules/usb-runtimes.js
devtools/client/webide/content/addons.js
devtools/shared/adb/adb-addon.js
devtools/shared/apps/Devices.jsm
--- a/browser/base/content/test/static/browser_all_files_referenced.js
+++ b/browser/base/content/test/static/browser_all_files_referenced.js
@@ -36,16 +36,19 @@ var gExceptionPaths = [
   "resource://pdf.js/web/images/",
 
   // Exclude all the metadata paths under the country metadata folder because these
   // paths will be concatenated in FormAutofillUtils.jsm based on different country/region.
   "resource://formautofill/addressmetadata/",
 
   // Exclude all search-plugins because they aren't referenced by filename
   "resource://search-plugins/",
+
+  // This is only in Nightly, and accessed using a direct chrome URL
+  "chrome://browser/content/aboutconfig/",
 ];
 
 // These are not part of the omni.ja file, so we find them only when running
 // the test on a non-packaged build.
 if (AppConstants.platform == "macosx")
   gExceptionPaths.push("resource://gre/res/cursors/");
 
 var whitelist = [
new file mode 100644
--- /dev/null
+++ b/browser/components/aboutconfig/content/aboutconfig.css
@@ -0,0 +1,5 @@
+/* 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/. */
+
+/* aboutconfig.css */
new file mode 100644
--- /dev/null
+++ b/browser/components/aboutconfig/content/aboutconfig.html
@@ -0,0 +1,20 @@
+<!-- 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/. -->
+
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <link rel="stylesheet" media="screen, projection" type="text/css"
+          href="chrome://global/skin/in-content/common.css"/>
+    <link rel="stylesheet" type="text/css" 
+          href="chrome://browser/content/aboutconfig/aboutconfig.css"/>
+    <script type="application/javascript" 
+            src="chrome://browser/content/aboutconfig/aboutconfig.js"></script>
+    <title>about:config</title>
+  </head>
+
+  <body>
+  </body>
+ </html>
new file mode 100644
--- /dev/null
+++ b/browser/components/aboutconfig/content/aboutconfig.js
@@ -0,0 +1,5 @@
+/* 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/. */
+
+/* aboutconfig.js */
new file mode 100644
--- /dev/null
+++ b/browser/components/aboutconfig/jar.mn
@@ -0,0 +1,8 @@
+# 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/.
+
+browser.jar:
+   content/browser/aboutconfig/aboutconfig.css          (content/aboutconfig.css)
+   content/browser/aboutconfig/aboutconfig.html         (content/aboutconfig.html)
+   content/browser/aboutconfig/aboutconfig.js           (content/aboutconfig.js)
new file mode 100644
--- /dev/null
+++ b/browser/components/aboutconfig/moz.build
@@ -0,0 +1,9 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
+
+JAR_MANIFESTS += ['jar.mn']
new file mode 100644
--- /dev/null
+++ b/browser/components/aboutconfig/test/browser/.eslintrc.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = {
+  "extends": [
+    "plugin:mozilla/browser-test",
+  ],
+};
new file mode 100644
--- /dev/null
+++ b/browser/components/aboutconfig/test/browser/browser.ini
@@ -0,0 +1,3 @@
+[DEFAULT]
+
+[browser_basic.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/aboutconfig/test/browser/browser_basic.js
@@ -0,0 +1,14 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+add_task(async function test_load_title() {
+  await BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: "chrome://browser/content/aboutconfig/aboutconfig.html",
+  }, browser => {
+    info("about:config loaded");
+    return ContentTask.spawn(browser, null, () => {
+      Assert.equal(content.document.title, "about:config");
+    });
+  });
+});
--- a/browser/components/moz.build
+++ b/browser/components/moz.build
@@ -54,17 +54,20 @@ DIRS += [
     'uitour',
     'urlbar',
     'translation',
 ]
 
 DIRS += ['build']
 
 if CONFIG['NIGHTLY_BUILD']:
-    DIRS += ['payments']
+    DIRS += [
+        'aboutconfig',
+        'payments',
+    ]
 
 XPIDL_SOURCES += [
     'nsIBrowserHandler.idl',
 ]
 
 XPIDL_MODULE = 'browsercompsbase'
 
 EXTRA_COMPONENTS += [
--- a/devtools/client/aboutdebugging-new/src/modules/usb-runtimes.js
+++ b/devtools/client/aboutdebugging-new/src/modules/usb-runtimes.js
@@ -1,33 +1,34 @@
 /* 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 { ADBScanner } = require("devtools/shared/adb/adb-scanner");
 loader.lazyRequireGetter(this, "adbAddon", "devtools/shared/adb/adb-addon", true);
+loader.lazyRequireGetter(this, "ADB_ADDON_STATES", "devtools/shared/adb/adb-addon", true);
 
 /**
  * This module provides a collection of helper methods to detect USB runtimes whom Firefox
  * is running on.
  */
 function addUSBRuntimesObserver(listener) {
   ADBScanner.on("runtime-list-updated", listener);
 }
 exports.addUSBRuntimesObserver = addUSBRuntimesObserver;
 
 function disableUSBRuntimes() {
   ADBScanner.disable();
 }
 exports.disableUSBRuntimes = disableUSBRuntimes;
 
 async function enableUSBRuntimes() {
-  if (adbAddon.status !== "installed") {
+  if (adbAddon.status !== ADB_ADDON_STATES.INSTALLED) {
     console.error("ADB extension is not installed");
     return;
   }
 
   ADBScanner.enable();
 }
 exports.enableUSBRuntimes = enableUSBRuntimes;
 
--- a/devtools/client/webide/content/addons.js
+++ b/devtools/client/webide/content/addons.js
@@ -7,16 +7,17 @@ const {loader, require} = ChromeUtils.im
 const Services = require("Services");
 const Strings = Services.strings.createBundle("chrome://devtools/locale/webide.properties");
 
 const {gDevTools} = require("devtools/client/framework/devtools");
 const {ADBScanner} = require("devtools/shared/adb/adb-scanner");
 const {RuntimeScanners} = require("devtools/client/webide/modules/runtimes");
 
 loader.lazyRequireGetter(this, "adbAddon", "devtools/shared/adb/adb-addon", true);
+loader.lazyRequireGetter(this, "ADB_ADDON_STATES", "devtools/shared/adb/adb-addon", true);
 
 window.addEventListener("load", function() {
   document.querySelector("#aboutaddons").onclick = function() {
     const browserWin = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
     if (browserWin && browserWin.BrowserOpenAddonsMgr) {
       browserWin.BrowserOpenAddonsMgr("addons://list/extension");
     }
   };
@@ -28,19 +29,19 @@ function CloseUI() {
   window.parent.UI.openProject();
 }
 
 function BuildUI() {
   function onAddonUpdate(arg) {
     progress.removeAttribute("value");
     li.setAttribute("status", adbAddon.status);
     status.textContent = Strings.GetStringFromName("addons_status_" + adbAddon.status);
-    if (adbAddon.status == "installed") {
+    if (adbAddon.status == ADB_ADDON_STATES.INSTALLED) {
       RuntimeScanners.add(ADBScanner);
-    } else if (adbAddon.status == "uninstalled") {
+    } else if (adbAddon.status == ADB_ADDON_STATES.UNINSTALLED) {
       RuntimeScanners.remove(ADBScanner);
     }
   }
 
   function onAddonFailure(arg) {
     window.parent.UI.reportError("error_operationFail", arg);
   }
 
--- a/devtools/shared/adb/adb-addon.js
+++ b/devtools/shared/adb/adb-addon.js
@@ -9,145 +9,180 @@ const Services = require("Services");
 const EventEmitter = require("devtools/shared/event-emitter");
 
 const ADB_LINK = Services.prefs.getCharPref("devtools.remote.adb.extensionURL");
 const ADB_ADDON_ID = Services.prefs.getCharPref("devtools.remote.adb.extensionID");
 
 // Extension ID for adb helper extension that might be installed on Firefox 63 or older.
 const OLD_ADB_ADDON_ID = "adbhelper@mozilla.org";
 
-const platform = Services.appShell.hiddenDOMWindow.navigator.platform;
-let OS = "";
-if (platform.includes("Win")) {
-  OS = "win32";
-} else if (platform.includes("Mac")) {
-  OS = "mac64";
-} else if (platform.includes("Linux")) {
-  if (platform.includes("x86_64")) {
-    OS = "linux64";
-  } else {
-    OS = "linux32";
-  }
-}
-
-function ADBAddon() {
-  EventEmitter.decorate(this);
-
-  this._status = "unknown";
+// Possible values for ADBAddon::state. WebIDE relies on the exact values for localization
+// and styles, so they should not be updated until WebIDE is removed.
+const ADB_ADDON_STATES = {
+  DOWNLOADING: "downloading",
+  INSTALLED: "installed",
+  INSTALLING: "installing",
+  PREPARING: "preparing",
+  UNINSTALLED: "uninstalled",
+  UNKNOWN: "unknown",
+};
+exports.ADB_ADDON_STATES = ADB_ADDON_STATES;
 
-  // This addon uses the string "linux" for "linux32"
-  const fixedOS = OS == "linux32" ? "linux" : OS;
-  this.xpiLink = ADB_LINK.replace(/#OS#/g, fixedOS);
-
-  // Uninstall old version of the extension that might be installed on this profile.
-  this.uninstallOldExtension();
-
-  this.updateInstallStatus();
+/**
+ * Wrapper around the ADB Extension providing ADB binaries for devtools remote debugging.
+ * Fires the following events:
+ * - "update": the status of the addon was updated
+ * - "failure": addon installation failed
+ * - "progress": addon download in progress
+ *
+ * AdbAddon::state can take any of the values from ADB_ADDON_STATES.
+ */
+class ADBAddon extends EventEmitter {
+  constructor() {
+    super();
 
-  const addonsListener = {};
-  addonsListener.onEnabled =
-  addonsListener.onDisabled =
-  addonsListener.onInstalled =
-  addonsListener.onUninstalled = () => this.updateInstallStatus();
-  AddonManager.addAddonListener(addonsListener);
-}
+    this._status = ADB_ADDON_STATES.UNKNOWN;
+
+    // Uninstall old version of the extension that might be installed on this profile.
+    this.uninstallOldExtension();
 
-ADBAddon.prototype = {
+    const addonsListener = {};
+    addonsListener.onEnabled =
+    addonsListener.onDisabled =
+    addonsListener.onInstalled =
+    addonsListener.onUninstalled = () => this.updateInstallStatus();
+    AddonManager.addAddonListener(addonsListener);
+
+    this.updateInstallStatus();
+  }
+
   set status(value) {
     if (this._status != value) {
       this._status = value;
       this.emit("update");
     }
-  },
+  }
 
   get status() {
     return this._status;
-  },
+  }
 
-  updateInstallStatus: async function() {
+  async updateInstallStatus() {
     const addon = await AddonManager.getAddonByID(ADB_ADDON_ID);
     if (addon && !addon.userDisabled) {
-      this.status = "installed";
+      this.status = ADB_ADDON_STATES.INSTALLED;
     } else {
-      this.status = "uninstalled";
+      this.status = ADB_ADDON_STATES.UNINSTALLED;
     }
-  },
+  }
+
+  /**
+   * Returns the platform specific download link for the ADB extension.
+   */
+  _getXpiLink() {
+    const platform = Services.appShell.hiddenDOMWindow.navigator.platform;
+    let OS = "";
+    if (platform.includes("Win")) {
+      OS = "win32";
+    } else if (platform.includes("Mac")) {
+      OS = "mac64";
+    } else if (platform.includes("Linux")) {
+      if (platform.includes("x86_64")) {
+        OS = "linux64";
+      } else {
+        OS = "linux";
+      }
+    }
+
+    return ADB_LINK.replace(/#OS#/g, OS);
+  }
 
   /**
    * Install and enable the adb extension. Returns a promise that resolves when ADB is
    * enabled.
    *
    * @param {String} source
    *        String passed to the AddonManager for telemetry.
    */
-  install: async function(source) {
+  async install(source) {
     const addon = await AddonManager.getAddonByID(ADB_ADDON_ID);
     if (addon && !addon.userDisabled) {
-      this.status = "installed";
+      this.status = ADB_ADDON_STATES.INSTALLED;
       return;
     }
-    this.status = "preparing";
+    this.status = ADB_ADDON_STATES.PREPARING;
     if (addon && addon.userDisabled) {
       await addon.enable();
     } else {
       const install = await AddonManager.getInstallForURL(
-        this.xpiLink,
+        this._getXpiLink(),
         "application/x-xpinstall",
         null, null, null, null, null,
         { source }
       );
       install.addListener(this);
       install.install();
     }
-  },
+  }
 
-  uninstall: async function() {
+  async uninstall() {
     const addon = await AddonManager.getAddonByID(ADB_ADDON_ID);
     addon.uninstall();
-  },
+  }
 
-  uninstallOldExtension: async function() {
+  async uninstallOldExtension() {
     const oldAddon = await AddonManager.getAddonByID(OLD_ADB_ADDON_ID);
     if (oldAddon) {
       oldAddon.uninstall();
     }
-  },
+  }
 
-  installFailureHandler: function(install, message) {
-    this.status = "uninstalled";
+  installFailureHandler(install, message) {
+    this.status = ADB_ADDON_STATES.UNINSTALLED;
     this.emit("failure", message);
-  },
+  }
 
-  onDownloadStarted: function() {
-    this.status = "downloading";
-  },
+  // Expected AddonManager install listener.
+  onDownloadStarted() {
+    this.status = ADB_ADDON_STATES.DOWNLOADING;
+  }
 
-  onInstallStarted: function() {
-    this.status = "installing";
-  },
-
-  onDownloadProgress: function(install) {
+  // Expected AddonManager install listener.
+  onDownloadProgress(install) {
     if (install.maxProgress == -1) {
       this.emit("progress", -1);
     } else {
       this.emit("progress", install.progress / install.maxProgress);
     }
-  },
+  }
 
-  onInstallEnded: function({addon}) {
-    addon.enable();
-  },
-
-  onDownloadCancelled: function(install) {
+  // Expected AddonManager install listener.
+  onDownloadCancelled(install) {
     this.installFailureHandler(install, "Download cancelled");
-  },
-  onDownloadFailed: function(install) {
+  }
+
+  // Expected AddonManager install listener.
+  onDownloadFailed(install) {
     this.installFailureHandler(install, "Download failed");
-  },
-  onInstallCancelled: function(install) {
+  }
+
+  // Expected AddonManager install listener.
+  onInstallStarted() {
+    this.status = ADB_ADDON_STATES.INSTALLING;
+  }
+
+  // Expected AddonManager install listener.
+  onInstallCancelled(install) {
     this.installFailureHandler(install, "Install cancelled");
-  },
-  onInstallFailed: function(install) {
+  }
+
+  // Expected AddonManager install listener.
+  onInstallFailed(install) {
     this.installFailureHandler(install, "Install failed");
-  },
-};
+  }
+
+  // Expected AddonManager install listener.
+  onInstallEnded({addon}) {
+    addon.enable();
+  }
+}
 
 exports.adbAddon = new ADBAddon();
--- a/devtools/shared/apps/Devices.jsm
+++ b/devtools/shared/apps/Devices.jsm
@@ -1,23 +1,23 @@
 /* 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 { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
 const EventEmitter = require("devtools/shared/event-emitter");
-const { adbAddon } = require("devtools/shared/adb/adb-addon");
+const { adbAddon, ADB_ADDON_STATES } = require("devtools/shared/adb/adb-addon");
 
 /* exported EXPORTED_SYMBOLS */
 
 const EXPORTED_SYMBOLS = ["Devices"];
 
-var addonInstalled = adbAddon.status === "installed";
+var addonInstalled = adbAddon.status === ADB_ADDON_STATES.INSTALLED;
 
 const Devices = {
   _devices: {},
 
   get adbExtensionInstalled() {
     return addonInstalled;
   },
   set adbExtensionInstalled(v) {
@@ -44,17 +44,17 @@ const Devices = {
     return Object.keys(this._devices).sort();
   },
 
   getByName: function(name) {
     return this._devices[name];
   },
 
   updateAdbAddonStatus: function() {
-    this.adbExtensionInstalled = adbAddon.status === "installed";
+    this.adbExtensionInstalled = adbAddon.status === ADB_ADDON_STATES.INSTALLED;
   },
 };
 
 Object.defineProperty(this, "Devices", {
   value: Devices,
   enumerable: true,
   writable: false
 });
--- a/gfx/layers/wr/ClipManager.cpp
+++ b/gfx/layers/wr/ClipManager.cpp
@@ -157,49 +157,25 @@ ClipManager::BeginItem(nsDisplayItem* aI
     asr = static_cast<nsDisplayStickyPosition*>(aItem)->GetContainerASR();
   }
 
   // In most cases we can combine the leaf of the clip chain with the clip rect
   // of the display item. This reduces the number of clip items, which avoids
   // some overhead further down the pipeline.
   bool separateLeaf = false;
   if (clip && clip->mASR == asr && clip->mClip.GetRoundedRectCount() == 0) {
-    switch (type) {
-      case DisplayItemType::TYPE_BLEND_CONTAINER:
-      case DisplayItemType::TYPE_BLEND_MODE:
-      case DisplayItemType::TYPE_FILTER:
-      case DisplayItemType::TYPE_FIXED_POSITION:
-      case DisplayItemType::TYPE_MASK:
-      case DisplayItemType::TYPE_OPACITY:
-      case DisplayItemType::TYPE_OWN_LAYER:
-      case DisplayItemType::TYPE_PERSPECTIVE:
-      case DisplayItemType::TYPE_RESOLUTION:
-      case DisplayItemType::TYPE_SCROLL_INFO_LAYER:
-      case DisplayItemType::TYPE_STICKY_POSITION:
-      case DisplayItemType::TYPE_SUBDOCUMENT:
-      case DisplayItemType::TYPE_SVG_WRAPPER:
-      case DisplayItemType::TYPE_TABLE_BLEND_CONTAINER:
-      case DisplayItemType::TYPE_TABLE_BLEND_MODE:
-      case DisplayItemType::TYPE_TABLE_FIXED_POSITION:
-      case DisplayItemType::TYPE_TRANSFORM:
-      case DisplayItemType::TYPE_WRAP_LIST:
-        // Container display items are not currently supported because the clip
-        // rect of a stacking context is not handled the same as normal display
-        // items.
-        break;
-      case DisplayItemType::TYPE_TEXT:
-        // Text with shadows interprets the text display item clip rect and
-        // clips from the clip chain differently.
-        if (aItem->Frame()->StyleText()->HasTextShadow()) {
-          break;
-        }
-        MOZ_FALLTHROUGH;
-      default:
-        separateLeaf = true;
-        break;
+    if (type == DisplayItemType::TYPE_TEXT) {
+      // Text with shadows interprets the text display item clip rect and
+      // clips from the clip chain differently.
+      separateLeaf = !aItem->Frame()->StyleText()->HasTextShadow();
+    } else {
+      // Container display items are not currently supported because the clip
+      // rect of a stacking context is not handled the same as normal display
+      // items.
+      separateLeaf = aItem->GetChildren() == nullptr;
     }
   }
 
   ItemClips clips(asr, clip, separateLeaf);
   MOZ_ASSERT(!mItemClipStack.empty());
   if (clips.HasSameInputs(mItemClipStack.top())) {
     // Early-exit because if the clips are the same as aItem's previous sibling,
     // then we don't need to do do the work of popping the old stuff and then
--- a/gfx/qcms/fuzztest/qcms_fuzzer.cpp
+++ b/gfx/qcms/fuzztest/qcms_fuzzer.cpp
@@ -46,16 +46,18 @@ transform(qcms_profile* src_profile, qcm
   qcms_transform* transform =
     qcms_transform_create(src_profile, src_type, dst_profile, dst_type, intent);
   if (!transform) {
     return;
   }
 
   static uint8_t src[] = {
     0x7F, 0x7F, 0x7F, 0x00, 0x00, 0x7F, 0x7F, 0xFF, 0x7F, 0x10, 0x20, 0x30,
+    0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, 0xBF, 0xEF, 0x6F,
+    0x3F, 0xC0, 0x9F, 0xE0, 0x90, 0xCF, 0x40, 0xAF, 0x0F, 0x01, 0x60, 0xF0,
   };
   static uint8_t dst[sizeof(src) * 4]; // 4x in case of GRAY to RGBA
 
   int src_bytes_per_pixel = 4; // QCMS_DATA_RGBA_8
   if (src_type == QCMS_DATA_RGB_8) {
     src_bytes_per_pixel = 3;
   } else if (src_type == QCMS_DATA_GRAYA_8) {
     src_bytes_per_pixel = 2;
--- a/js/src/vm/JSContext.h
+++ b/js/src/vm/JSContext.h
@@ -439,23 +439,19 @@ struct JSContext : public JS::RootingCon
     }
 
 #ifdef DEBUG
     static size_t offsetOfInUnsafeCallWithABI() {
         return offsetof(JSContext, inUnsafeCallWithABI);
     }
 #endif
 
-  private:
-    /* Space for interpreter frames. */
-    js::ThreadData<js::InterpreterStack> interpreterStack_;
-
   public:
     js::InterpreterStack& interpreterStack() {
-        return interpreterStack_.ref();
+        return runtime()->interpreterStack();
     }
 
     /* Base address of the native stack for the current thread. */
     const uintptr_t     nativeStackBase;
 
     /* The native stack size limit that runtime should not exceed. */
     js::ThreadData<size_t> nativeStackQuota[JS::StackKindCount];
 
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -225,17 +225,24 @@ class AutoLockScriptData;
 struct JSRuntime : public js::MallocProvider<JSRuntime>
 {
   private:
     friend class js::Activation;
     friend class js::ActivationIterator;
     friend class js::jit::JitActivation;
     friend class js::jit::CompileRuntime;
 
+    /* Space for interpreter frames. */
+    js::MainThreadData<js::InterpreterStack> interpreterStack_;
+
   public:
+    js::InterpreterStack& interpreterStack() {
+        return interpreterStack_.ref();
+    }
+
     /*
      * If non-null, another runtime guaranteed to outlive this one and whose
      * permanent data may be used by this one where possible.
      */
     JSRuntime* const parentRuntime;
 
 #ifdef DEBUG
     /* The number of child runtimes that have this runtime as their parent. */
--- a/testing/web-platform/meta/payment-request/payment-request-id-attribute.https.html.ini
+++ b/testing/web-platform/meta/payment-request/payment-request-id-attribute.https.html.ini
@@ -5,10 +5,9 @@
 
   [PaymentRequest's id attribute's value can be set via PaymentDetailsInit dictionary]
     expected: 
       if not e10s: FAIL
 
   [PaymentRequest's id attribute must be a UUID when PaymentDetailsInit.id is missing]
     expected: 
       if not e10s: FAIL
-      if (os == "mac"): FAIL