merge mozilla-central to b2g-inbound
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 10 Sep 2013 10:44:21 +0200
changeset 146342 36d500768a21f315e64988c204c10cb5393cdcc3
parent 146341 f353bb8650e7b937b2c4cf71ec1d9978466b4e10 (current diff)
parent 146334 680c89c761007e26015ac3450820d28463b97dff (diff)
child 146343 e33614e3aea08388206b2636cf390921092d5ecd
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
milestone26.0a1
merge mozilla-central to b2g-inbound
ipc/chromium/src/base/foundation_utils_mac.h
ipc/chromium/src/base/string_escape.cc
ipc/chromium/src/base/string_escape.h
js/src/builtin/Iterator-inl.h
js/src/vm/RegExpObject-inl.h
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -302,19 +302,17 @@
 #endif
 @BINPATH@/components/txtsvc.xpt
 @BINPATH@/components/txmgr.xpt
 #ifdef MOZ_USE_NATIVE_UCONV
 @BINPATH@/components/ucnative.xpt
 #endif
 @BINPATH@/components/uconv.xpt
 @BINPATH@/components/unicharutil.xpt
-#ifdef MOZ_UPDATER
 @BINPATH@/components/update.xpt
-#endif
 @BINPATH@/components/uriloader.xpt
 @BINPATH@/components/urlformatter.xpt
 @BINPATH@/components/webBrowser_core.xpt
 @BINPATH@/components/webbrowserpersist.xpt
 @BINPATH@/components/webshell_idls.xpt
 @BINPATH@/components/widget.xpt
 #ifdef XP_MACOSX
 @BINPATH@/components/widget_cocoa.xpt
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -5,17 +5,18 @@
 // the "exported" symbols
 let SocialUI,
     SocialChatBar,
     SocialFlyout,
     SocialMarks,
     SocialShare,
     SocialMenu,
     SocialToolbar,
-    SocialSidebar;
+    SocialSidebar,
+    SocialStatus;
 
 (function() {
 
 // The minimum sizes for the auto-resize panel code.
 const PANEL_MIN_HEIGHT = 100;
 const PANEL_MIN_WIDTH = 330;
 
 XPCOMUtils.defineLazyModuleGetter(this, "SharedFrame",
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -6363,17 +6363,17 @@ function formatURL(aFormat, aIsPref) {
  */
 var gIdentityHandler = {
   // Mode strings used to control CSS display
   IDENTITY_MODE_IDENTIFIED                             : "verifiedIdentity", // High-quality identity information
   IDENTITY_MODE_DOMAIN_VERIFIED                        : "verifiedDomain",   // Minimal SSL CA-signed domain verification
   IDENTITY_MODE_UNKNOWN                                : "unknownIdentity",  // No trusted identity information
   IDENTITY_MODE_MIXED_DISPLAY_LOADED                   : "unknownIdentity mixedContent mixedDisplayContent",  // SSL with unauthenticated display content
   IDENTITY_MODE_MIXED_ACTIVE_LOADED                    : "unknownIdentity mixedContent mixedActiveContent",  // SSL with unauthenticated active (and perhaps also display) content
-  IDENTITY_MODE_MIXED_DISPLAY_LOADED_ACTIVE_BLOCKED    : "unknownIdentity mixedContent mixedDisplayContent",  // SSL with unauthenticated display content; unauthenticated active content is blocked.
+  IDENTITY_MODE_MIXED_DISPLAY_LOADED_ACTIVE_BLOCKED    : "unknownIdentity mixedContent mixedDisplayContentLoadedActiveBlocked",  // SSL with unauthenticated display content; unauthenticated active content is blocked.
   IDENTITY_MODE_CHROMEUI                               : "chromeUI",         // Part of the product's UI
 
   // Cache the most recent SSLStatus and Location seen in checkIdentity
   _lastStatus : null,
   _lastUri : null,
   _mode : "unknownIdentity",
 
   // smart getters
--- a/browser/base/content/newtab/newTab.js
+++ b/browser/base/content/newtab/newTab.js
@@ -5,16 +5,19 @@
 "use strict";
 
 let Cu = Components.utils;
 let Ci = Components.interfaces;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/PageThumbs.jsm");
+#ifndef RELEASE_BUILD
+Cu.import("resource://gre/modules/BackgroundPageThumbs.jsm");
+#endif
 Cu.import("resource://gre/modules/NewTabUtils.jsm");
 Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Rect",
   "resource://gre/modules/Geometry.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
   "resource://gre/modules/PrivateBrowsingUtils.jsm");
 
--- a/browser/base/content/newtab/sites.js
+++ b/browser/base/content/newtab/sites.js
@@ -126,20 +126,22 @@ Site.prototype = {
 
     let link = this._querySelector(".newtab-link");
     link.setAttribute("title", tooltip);
     link.setAttribute("href", url);
     this._querySelector(".newtab-title").textContent = title;
 
     if (this.isPinned())
       this._updateAttributes(true);
+#ifndef RELEASE_BUILD
     // request a staleness check for the thumbnail, which will cause page.js
     // to be notified and call our refreshThumbnail() method.
-    PageThumbs.captureIfStale(this.url);
+    BackgroundPageThumbs.captureIfStale(this.url);
     // but still display whatever thumbnail might be available now.
+#endif
     this.refreshThumbnail();
   },
 
   /**
    * Refreshes the thumbnail for the site.
    */
   refreshThumbnail: function Site_refreshThumbnail() {
     let thumbnailURL = PageThumbs.getThumbnailURL(this.url);
--- a/browser/components/downloads/content/downloads.js
+++ b/browser/components/downloads/content/downloads.js
@@ -186,22 +186,29 @@ const DownloadsPanel = {
     DownloadsSummary.active = false;
     DownloadsCommon.log("DownloadsPanel terminated.");
   },
 
   //////////////////////////////////////////////////////////////////////////////
   //// Panel interface
 
   /**
-   * Main panel element in the browser window.
+   * Main panel element in the browser window, or null if the panel overlay
+   * hasn't been loaded yet.
    */
   get panel()
   {
+    // If the downloads panel overlay hasn't loaded yet, just return null
+    // without reseting this.panel.
+    let downloadsPanel = document.getElementById("downloadsPanel");
+    if (!downloadsPanel)
+      return null;
+
     delete this.panel;
-    return this.panel = document.getElementById("downloadsPanel");
+    return this.panel = downloadsPanel;
   },
 
   /**
    * Starts opening the downloads panel interface, anchored to the downloads
    * button of the browser window.  The list of downloads to display is
    * initialized the first time this method is called, and the panel is shown
    * only when data is ready.
    */
--- a/browser/components/downloads/test/browser/browser_basic_functionality.js
+++ b/browser/components/downloads/test/browser/browser_basic_functionality.js
@@ -14,16 +14,19 @@ function test_task()
     { state: nsIDM.DOWNLOAD_NOTSTARTED },
     { state: nsIDM.DOWNLOAD_PAUSED },
     { state: nsIDM.DOWNLOAD_FINISHED },
     { state: nsIDM.DOWNLOAD_FAILED },
     { state: nsIDM.DOWNLOAD_CANCELED },
   ];
 
   try {
+    // Wait for focus first
+    yield promiseFocus();
+
     // Ensure that state is reset in case previous tests didn't finish.
     yield task_resetState();
 
     // For testing purposes, show all the download items at once.
     var originalCountLimit = DownloadsView.kItemCountLimit;
     DownloadsView.kItemCountLimit = DownloadData.length;
     registerCleanupFunction(function () {
       DownloadsView.kItemCountLimit = originalCountLimit;
--- a/browser/components/downloads/test/browser/browser_first_download_panel.js
+++ b/browser/components/downloads/test/browser/browser_first_download_panel.js
@@ -5,16 +5,24 @@
 
 /**
  * Make sure the downloads panel only opens automatically on the first
  * download it notices. All subsequent downloads, even across sessions, should
  * not open the panel automatically.
  */
 function test_task()
 {
+  // Clear the download panel has shown preference first as this test is used to
+  // verify this preference's behaviour.
+  let oldPrefValue = true;
+  try {
+    oldPrefValue = Services.prefs.getBoolPref("browser.download.panel.shown");
+  } catch(ex) { }
+  Services.prefs.setBoolPref("browser.download.panel.shown", false);
+
   try {
     // Ensure that state is reset in case previous tests didn't finish.
     yield task_resetState();
 
     // With this set to false, we should automatically open the panel the first
     // time a download is started.
     DownloadsCommon.getData(window).panelHasShownBefore = false;
 
@@ -44,10 +52,14 @@ function test_task()
       setTimeout(deferTimeout.resolve, 2000);
       yield deferTimeout.promise;
     } finally {
       DownloadsPanel.onPopupShown = originalOnPopupShown;
     }
   } finally {
     // Clean up when the test finishes.
     yield task_resetState();
+    // Set the preference instead of clearing it afterwards to ensure the
+    // right value is used no matter what the default was. This ensures the
+    // panel doesn't appear and affect other tests.
+    Services.prefs.setBoolPref("browser.download.panel.shown", oldPrefValue);
   }
 }
--- a/browser/components/downloads/test/browser/head.js
+++ b/browser/components/downloads/test/browser/head.js
@@ -46,16 +46,20 @@ function promiseFocus()
   waitForFocus(deferred.resolve);
   return deferred.promise;
 }
 
 function promisePanelOpened()
 {
   let deferred = Promise.defer();
 
+  if (DownloadsPanel.panel && DownloadsPanel.panel.state == "open") {
+    return deferred.resolve();
+  }
+
   // Hook to wait until the panel is shown.
   let originalOnPopupShown = DownloadsPanel.onPopupShown;
   DownloadsPanel.onPopupShown = function () {
     DownloadsPanel.onPopupShown = originalOnPopupShown;
     originalOnPopupShown.apply(this, arguments);
 
     // Defer to the next tick of the event loop so that we don't continue
     // processing during the DOM event handler itself.
@@ -70,19 +74,16 @@ function task_resetState()
   // Remove all downloads.
   let publicList = yield Downloads.getPublicDownloadList();
   let downloads = yield publicList.getAll();
   for (let download of downloads) {
     publicList.remove(download);
     yield download.finalize(true);
   }
 
-  // Reset any prefs that might have been changed.
-  Services.prefs.clearUserPref("browser.download.panel.shown");
-
   DownloadsPanel.hidePanel();
 
   yield promiseFocus();
 }
 
 function task_addDownloads(aItems)
 {
   let startTimeMs = Date.now();
--- a/browser/devtools/shared/test/browser_observableobject.js
+++ b/browser/devtools/shared/test/browser_observableobject.js
@@ -44,16 +44,19 @@ function test() {
     {type: "get", path: "bar", value: {}},
     {type: "set", path: "foo.1", value: {}},
   ];
 
   function callback(event, path, value) {
     oe.off("get", callback);
     ok(event, "event defined");
     ok(path, "path defined");
+    if (index >= expected.length) {
+      return;
+    }
     let e = expected[index];
     is(event, e.type, "[" + index + "] Right event received");
     is(path.join("."), e.path, "[" + index + "] Path valid");
     is(str(value), str(e.value), "[" + index + "] Value valid");
     index++;
     areObjectsSynced();
     oe.on("get", callback);
   }
--- a/browser/metro/base/content/downloads.js
+++ b/browser/metro/base/content/downloads.js
@@ -57,28 +57,50 @@ var Downloads = {
     Services.obs.addObserver(this, "dl-request", true);
 
     this._notificationBox = Browser.getNotificationBox();
 
     this._progress = new DownloadProgressListener(this);
     this.manager.addListener(this._progress);
 
     this._downloadProgressIndicator = document.getElementById("download-progress");
+
+    if (this.manager.activeDownloadCount) {
+      setTimeout (this._restartWithActiveDownloads.bind(this), 0);
+    }
   },
 
   uninit: function dh_uninit() {
     if (this._inited) {
       Services.obs.removeObserver(this, "dl-start");
       Services.obs.removeObserver(this, "dl-done");
       Services.obs.removeObserver(this, "dl-run");
       Services.obs.removeObserver(this, "dl-failed");
       Services.obs.removeObserver(this, "dl-request");
     }
   },
 
+  _restartWithActiveDownloads: function() {
+    let activeDownloads = this.manager.activeDownloads;
+
+    while (activeDownloads.hasMoreElements()) {
+      let dl = activeDownloads.getNext();
+      switch (dl.state) {
+        case 0: // Downloading
+        case 5: // Queued
+          this.watchDownload(dl);
+          this.updateInfobar(dl);
+          break;
+      }
+    }
+    if (this.manager.activeDownloadCount) {
+      Services.obs.notifyObservers(null, "dl-request", "");
+    }
+  },
+
   openDownload: function dh_openDownload(aDownload) {
     let fileURI = aDownload.target
 
     if (!(fileURI && fileURI.spec)) {
       Util.dumpLn("Cant open download "+id+", fileURI is invalid");
       return;
     }
 
@@ -126,18 +148,18 @@ var Downloads = {
     } catch (ex) {
       Util.dumpLn("Failed to cancel download, with id: "+aDownload.id+", download target URI spec: " + fileURI.spec);
       Util.dumpLn("Failed download source:"+(aDownload.source && aDownload.source.spec));
     }
   },
 
   // Cancels all downloads.
   cancelDownloads: function dh_cancelDownloads() {
-    for (let info of this._progressNotificationInfo) {
-      this.cancelDownload(info[1].download);
+    for (let [guid, info] of this._progressNotificationInfo) {
+      this.cancelDownload(info.download);
     }
     this._downloadCount = 0;
     this._progressNotificationInfo.clear();
     this._runDownloadBooleanMap.clear();
   },
 
   pauseDownload: function dh_pauseDownload(aDownload) {
     let id = aDownload.getAttribute("downloadId");
@@ -167,21 +189,22 @@ var Downloads = {
     if (!aIcon)
       aIcon = TOAST_URI_GENERIC_ICON_DOWNLOAD;
 
     notifier.showAlertNotification(aIcon, aTitle, aMessage, true, "", aObserver, aName);
   },
 
   showNotification: function dh_showNotification(title, msg, buttons, priority) {
     this._notificationBox.notificationsHidden = false;
-    return this._notificationBox.appendNotification(msg,
+    let notification = this._notificationBox.appendNotification(msg,
                                               title,
                                               URI_GENERIC_ICON_DOWNLOAD,
                                               priority,
                                               buttons);
+    return notification;
   },
 
   _showDownloadFailedNotification: function (aDownload) {
     let tryAgainButtonText =
       Strings.browser.GetStringFromName("downloadTryAgain");
     let cancelButtonText =
       Strings.browser.GetStringFromName("downloadCancel");
 
@@ -296,32 +319,31 @@ var Downloads = {
   },
 
   _updateCircularProgressMeter: function dv_updateCircularProgressMeter() {
     if (!this._progressNotificationInfo) {
       return;
     }
 
     let totPercent = 0;
-    for (let info of this._progressNotificationInfo) {
-      // info[0]          => download guid
-      // info[1].download => nsIDownload
-      totPercent += info[1].download.percentComplete;
+    for (let [guid, info] of this._progressNotificationInfo) {
+      // info.download => nsIDownload
+      totPercent += info.download.percentComplete;
     }
 
     let percentComplete = totPercent / this._progressNotificationInfo.size;
     this._downloadProgressIndicator.updateProgress(percentComplete);
   },
 
   _computeDownloadProgressString: function dv_computeDownloadProgressString(aDownload) {
     let totTransferred = 0, totSize = 0, totSecondsLeft = 0;
-    for (let info of this._progressNotificationInfo) {
-      let size = info[1].download.size;
-      let amountTransferred = info[1].download.amountTransferred;
-      let speed = info[1].download.speed;
+    for (let [guid, info] of this._progressNotificationInfo) {
+      let size = info.download.size;
+      let amountTransferred = info.download.amountTransferred;
+      let speed = info.download.speed;
 
       totTransferred += amountTransferred;
       totSize += size;
       totSecondsLeft += ((size - amountTransferred) / speed);
     }
 
     // Compute progress in bytes.
     let amountTransferred = Util.getDownloadSize(totTransferred);
@@ -352,23 +374,24 @@ var Downloads = {
       this._progressNotificationInfo.set(aDownload.guid, {});
     }
     let infoObj = this._progressNotificationInfo.get(aDownload.guid);
     infoObj.download = aDownload;
     this._progressNotificationInfo.set(aDownload.guid, infoObj);
   },
 
   updateInfobar: function dv_updateInfobar(aDownload) {
-    this._saveDownloadData(aDownload);
     let message = this._computeDownloadProgressString(aDownload);
     this._updateCircularProgressMeter();
 
+    if (this._notificationBox && this._notificationBox.notificationsHidden)
+      this._notificationBox.notificationsHidden = false;
+
     if (this._progressNotification == null ||
         !this._notificationBox.getNotificationWithValue("download-progress")) {
-
       let cancelButtonText =
               Strings.browser.GetStringFromName("downloadCancel");
 
       let buttons = [
         {
           isDefault: false,
           label: cancelButtonText,
           accessKey: "",
@@ -390,36 +413,41 @@ var Downloads = {
     if (this._progressNotification != null) {
       this._saveDownloadData(aDownload);
       this._progressNotification.label =
         this._computeDownloadProgressString(aDownload);
       this._updateCircularProgressMeter();
     }
   },
 
+  watchDownload: function dv_watchDownload(aDownload) {
+    this._saveDownloadData(aDownload);
+    this._downloadCount++;
+    this._downloadsInProgress++;
+    if (!this._progressNotificationInfo.get(aDownload.guid)) {
+      this._progressNotificationInfo.set(aDownload.guid, {});
+    }
+    if (!this._progressAlert) {
+      this._progressAlert = new AlertDownloadProgressListener();
+      this.manager.addListener(this._progressAlert);
+    }
+  },
+
   observe: function (aSubject, aTopic, aData) {
     let message = "";
     let msgTitle = "";
 
     switch (aTopic) {
       case "dl-run":
         let file = aSubject.QueryInterface(Ci.nsIFile);
         this._runDownloadBooleanMap.set(file.path, (aData == 'true'));
         break;
       case "dl-start":
-        this._downloadCount++;
-        this._downloadsInProgress++;
         let download = aSubject.QueryInterface(Ci.nsIDownload);
-        if (!this._progressNotificationInfo.get(download.guid)) {
-          this._progressNotificationInfo.set(download.guid, {});
-        }
-        if (!this._progressAlert) {
-          this._progressAlert = new AlertDownloadProgressListener();
-          this.manager.addListener(this._progressAlert);
-        }
+        this.watchDownload(download);
         this.updateInfobar(download);
         break;
       case "dl-done":
         this._downloadsInProgress--;
         download = aSubject.QueryInterface(Ci.nsIDownload);
         let runAfterDownload = this._runDownloadBooleanMap.get(download.targetFile.path);
         if (runAfterDownload) {
           this.openDownload(download);
--- a/browser/metro/components/HelperAppDialog.js
+++ b/browser/metro/components/HelperAppDialog.js
@@ -39,17 +39,17 @@ HelperAppLauncherDialog.prototype = {
     } else {
       let wasClicked = false;
       this._showDownloadInfobar(aLauncher);
     }
   },
 
   _getDownloadSize: function dv__getDownloadSize (aSize) {
     let displaySize = DownloadUtils.convertByteUnits(aSize);
-    if (displaySize[0] > 0) // [0] is size, [1] is units
+    if (!isNaN(displaySize[0]) && displaySize[0] > 0) // [0] is size, [1] is units
       return displaySize.join("");
     else {
       let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
       return browserBundle.GetStringFromName("downloadsUnknownSize");
     }
   },
 
   _getChromeWindow: function (aWindow) {
--- a/browser/metro/modules/CrossSlide.jsm
+++ b/browser/metro/modules/CrossSlide.jsm
@@ -235,24 +235,30 @@ CrossSlideHandler.prototype = {
 
   /**
    * Dispatches a custom Event on the drag node.
    * @param aEvent The source event.
    * @param aType The event type.
    */
   _fireProgressEvent: function CrossSliding_fireEvent(aState, aEvent) {
     if (!this.drag)
-        return;
+      return;
     let event = this.node.ownerDocument.createEvent("Events");
-    let crossAxis = this.drag.crossAxis;
+    let crossAxisName = this.drag.crossAxis;
     event.initEvent("MozCrossSliding", true, true);
     event.crossSlidingState = aState;
-    event.position = this.drag.position;
-    event.direction = this.drag.crossAxis;
-    event.delta = this.drag.position[crossAxis] - this.drag.origin[crossAxis];
+    if ('position' in this.drag) {
+      event.position = this.drag.position;
+      if (crossAxisName) {
+        event.direction = crossAxisName;
+        if('origin' in this.drag) {
+          event.delta = this.drag.position[crossAxisName] - this.drag.origin[crossAxisName];
+        }
+      }
+    }
     aEvent.target.dispatchEvent(event);
   },
 
   /**
    * Dispatches a custom Event on the given target node.
    * @param aEvent The source event.
    */
   _fireSelectEvent: function SelectTarget_fireEvent(aEvent) {
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -1399,16 +1399,20 @@ toolbar[mode="icons"] #zoom-in-button {
   .mixedActiveContent > #page-proxy-favicon[pageproxystate="valid"] {
     list-style-image: url(chrome://browser/skin/identity-icons-https-mixed-active@2x.png);
   }
 
   .mixedDisplayContent > #page-proxy-favicon[pageproxystate="valid"] {
     list-style-image: url(chrome://browser/skin/identity-icons-https-mixed-display@2x.png);
   }
 
+  .mixedDisplayContentLoadedActiveBlocked > #page-proxy-favicon[pageproxystate="valid"] {
+    list-style-image: url(chrome://browser/skin/identity-icons-https-mixed-display@2x.png);
+  }
+
   #identity-box:hover:active > #page-proxy-favicon,
   #identity-box[open=true] > #page-proxy-favicon {
     -moz-image-region: rect(0, 64px, 32px, 32px);
   }
 
   /* The chromeUI identity-icon set includes three states,
      but OS X only uses two of them. */
   #identity-box.chromeUI:hover:active > #page-proxy-favicon,
--- a/browser/themes/shared/identity-block.inc.css
+++ b/browser/themes/shared/identity-block.inc.css
@@ -71,16 +71,20 @@
 .mixedActiveContent > #page-proxy-favicon[pageproxystate="valid"] {
   list-style-image: url(chrome://browser/skin/identity-icons-https-mixed-active.png);
 }
 
 .mixedDisplayContent > #page-proxy-favicon[pageproxystate="valid"] {
   list-style-image: url(chrome://browser/skin/identity-icons-https-mixed-display.png);
 }
 
+.mixedDisplayContentLoadedActiveBlocked > #page-proxy-favicon[pageproxystate="valid"] {
+  list-style-image: url(chrome://browser/skin/identity-icons-https-mixed-display.png);
+}
+
 #page-proxy-favicon[pageproxystate="invalid"] {
   opacity: 0.3;
 }
 
 #identity-popup.chromeUI > #identity-popup-container > #identity-popup-icon {
   list-style-image: url("chrome://branding/content/icon64.png");
 }
 
--- a/build/mach_bootstrap.py
+++ b/build/mach_bootstrap.py
@@ -61,16 +61,17 @@ MACH_MODULES = [
     'addon-sdk/mach_commands.py',
     'layout/tools/reftest/mach_commands.py',
     'python/mach_commands.py',
     'python/mach/mach/commands/commandinfo.py',
     'python/mozboot/mozboot/mach_commands.py',
     'python/mozbuild/mozbuild/config.py',
     'python/mozbuild/mozbuild/mach_commands.py',
     'python/mozbuild/mozbuild/frontend/mach_commands.py',
+    'testing/mach_commands.py',
     'testing/marionette/mach_commands.py',
     'testing/mochitest/mach_commands.py',
     'testing/xpcshell/mach_commands.py',
     'testing/talos/mach_commands.py',
     'testing/xpcshell/mach_commands.py',
     'tools/mercurial/mach_commands.py',
     'tools/mach_commands.py',
 ]
--- a/config/nspr/Makefile.in
+++ b/config/nspr/Makefile.in
@@ -18,16 +18,20 @@ ABS_DIST = $(call core_abspath,$(DIST))
 ifdef MOZ_FOLD_LIBS
 # Trick the nspr build system into not building shared libraries.
 # bug #851869.
 EXTRA_MAKE_FLAGS := SHARED_LIBRARY= IMPORT_LIBRARY= SHARED_LIB_PDB=
 
 # Work around libVersionPoint conflict between all three libraries.
 # See bug #838566.
 EXTRA_MAKE_FLAGS += XP_DEFINE=-DlibVersionPoint='libVersionPoint$$(LIBRARY_NAME)'
+else
+# nspr's make export compiles and links everything, but linking can't happen
+# during export on platforms where nspr is linked against mozcrt/mozglue.
+export:: EXTRA_MAKE_FLAGS := SHARED_LIBRARY= IMPORT_LIBRARY= SHARED_LIB_PDB=
 endif
 
 libs export clean distclean::
 	$(MAKE) -C $(DEPTH)/nsprpub $@ $(EXTRA_MAKE_FLAGS)
 
 libs::
 	$(MAKE) -C $(DEPTH)/nsprpub install prefix=$(ABS_DIST)/sdk exec_prefix=$(ABS_DIST)/sdk bindir=$(ABS_DIST)/sdk/dummy includedir=$(ABS_DIST)/include/nspr libdir=$(ABS_DIST)/sdk/lib datadir=$(ABS_DIST)/sdk/dummy DESTDIR= $(EXTRA_MAKE_FLAGS)
 	$(INSTALL) $(DEPTH)/nsprpub/config/nspr-config $(DIST)/sdk/bin
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1529,16 +1529,17 @@ public:
   static nsresult ProcessViewportInfo(nsIDocument *aDocument,
                                       const nsAString &viewportInfo);
 
   static nsIScriptContext* GetContextForEventHandlers(nsINode* aNode,
                                                       nsresult* aRv);
 
   static JSContext *GetCurrentJSContext();
   static JSContext *GetSafeJSContext();
+  static JSContext *GetDefaultJSContextForThread();
 
   /**
    * Case insensitive comparison between two strings. However it only ignores
    * case for ASCII characters a-z.
    */
   static bool EqualsIgnoreASCIICase(const nsAString& aStr1,
                                     const nsAString& aStr2);
 
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -1761,16 +1761,17 @@ nsContentUtils::IsCallerChrome()
   // If the check failed, look for UniversalXPConnect on the cx compartment.
   return xpc::IsUniversalXPConnectEnabled(GetCurrentJSContext());
 }
 
 namespace mozilla {
 namespace dom {
 namespace workers {
 extern bool IsCurrentThreadRunningChromeWorker();
+extern JSContext* GetCurrentThreadJSContext();
 }
 }
 }
 
 bool
 nsContentUtils::ThreadsafeIsCallerChrome()
 {
   return NS_IsMainThread() ?
@@ -5193,16 +5194,27 @@ nsContentUtils::GetCurrentJSContext()
 JSContext *
 nsContentUtils::GetSafeJSContext()
 {
   MOZ_ASSERT(NS_IsMainThread());
   return sXPConnect->GetSafeJSContext();
 }
 
 /* static */
+JSContext *
+nsContentUtils::GetDefaultJSContextForThread()
+{
+  if (MOZ_LIKELY(NS_IsMainThread())) {
+    return GetSafeJSContext();
+  } else {
+    return workers::GetCurrentThreadJSContext();
+  }
+}
+
+/* static */
 nsresult
 nsContentUtils::ASCIIToLower(nsAString& aStr)
 {
   PRUnichar* iter = aStr.BeginWriting();
   PRUnichar* end = aStr.EndWriting();
   if (MOZ_UNLIKELY(!iter || !end)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
--- a/content/base/src/nsDOMBlobBuilder.cpp
+++ b/content/base/src/nsDOMBlobBuilder.cpp
@@ -10,16 +10,17 @@
 #include "nsAutoPtr.h"
 #include "nsDOMClassInfoID.h"
 #include "nsIMultiplexInputStream.h"
 #include "nsStringStream.h"
 #include "nsTArray.h"
 #include "nsJSUtils.h"
 #include "nsContentUtils.h"
 #include "nsIScriptError.h"
+#include "nsIXPConnect.h"
 #include <algorithm>
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsDOMMultipartFile, nsDOMFile,
                              nsIJSNativeInitializer)
 
--- a/content/base/src/nsDOMMutationObserver.cpp
+++ b/content/base/src/nsDOMMutationObserver.cpp
@@ -1,23 +1,23 @@
 /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
 /* vim: set sw=4 ts=8 et tw=80 : */
 /* 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/. */
 
-#include "nsDOMMutationObserver.h"        
-#include "nsDOMClassInfoID.h"
+#include "nsDOMMutationObserver.h"
+
+#include "mozilla/dom/OwningNonNull.h"
 #include "nsError.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsContentUtils.h"
 #include "nsThreadUtils.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsTextFragment.h"
-#include "jsapi.h"
 #include "nsServiceManagerUtils.h"
 
 nsTArray<nsRefPtr<nsDOMMutationObserver> >*
   nsDOMMutationObserver::sScheduledMutationObservers = nullptr;
 
 nsDOMMutationObserver* nsDOMMutationObserver::sCurrentObserver = nullptr;
 
 uint32_t nsDOMMutationObserver::sMutationLevel = 0;
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -185,21 +185,22 @@
 
 #include "imgILoader.h"
 #include "imgRequestProxy.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsSandboxFlags.h"
 #include "nsIAppsService.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/DocumentFragment.h"
-#include "mozilla/dom/WebComponentsBinding.h"
 #include "mozilla/dom/HTMLBodyElement.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "mozilla/dom/NodeFilterBinding.h"
+#include "mozilla/dom/OwningNonNull.h"
 #include "mozilla/dom/UndoManager.h"
+#include "mozilla/dom/WebComponentsBinding.h"
 #include "nsFrame.h"
 #include "nsDOMCaretPosition.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsViewportInfo.h"
 #include "nsDOMEvent.h"
 #include "nsIContentPermissionPrompt.h"
 #include "mozilla/StaticPtr.h"
 #include "nsITextControlElement.h"
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -1,54 +1,47 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * 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/. */
 
-#include "base/basictypes.h"
 #include "CanvasRenderingContext2D.h"
 
 #include "nsXULElement.h"
 
-#include "prenv.h"
-
 #include "nsIServiceManager.h"
 #include "nsMathUtils.h"
 
 #include "nsContentUtils.h"
 
 #include "nsIDocument.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "nsSVGEffects.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
-#include "nsIVariant.h"
 
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIFrame.h"
 #include "nsError.h"
-#include "nsIScriptError.h"
 
 #include "nsCSSParser.h"
 #include "mozilla/css/StyleRule.h"
 #include "mozilla/css/Declaration.h"
 #include "nsComputedDOMStyle.h"
 #include "nsStyleSet.h"
 
 #include "nsPrintfCString.h"
 
 #include "nsReadableUtils.h"
 
 #include "nsColor.h"
 #include "nsGfxCIID.h"
-#include "nsIScriptSecurityManager.h"
 #include "nsIDocShell.h"
 #include "nsIDOMWindow.h"
 #include "nsPIDOMWindow.h"
-#include "nsIXPConnect.h"
 #include "nsDisplayList.h"
 
 #include "nsTArray.h"
 
 #include "imgIEncoder.h"
 
 #include "gfxContext.h"
 #include "gfxASurface.h"
@@ -85,19 +78,16 @@
 #include "mozilla/ipc/DocumentRendererParent.h"
 #include "mozilla/ipc/PDocumentRendererParent.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/unused.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsWrapperCacheInlines.h"
-#include "nsJSUtils.h"
-#include "XPCQuickStubs.h"
-#include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 #include "mozilla/dom/HTMLImageElement.h"
 #include "mozilla/dom/HTMLVideoElement.h"
 #include "mozilla/dom/TextMetrics.h"
 #include "mozilla/dom/UnionTypes.h"
 
 #ifdef USE_SKIA_GPU
 #undef free // apparently defined by some windows header, clashing with a free()
--- a/content/events/src/Touch.h
+++ b/content/events/src/Touch.h
@@ -3,16 +3,17 @@
  * 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/. */
 
 #ifndef mozilla_dom_Touch_h
 #define mozilla_dom_Touch_h
 
 #include "mozilla/Attributes.h"
 #include "nsWrapperCache.h"
+#include "nsAutoPtr.h"
 #include "Units.h"
 
 class nsPresContext;
 class nsEvent;
 
 namespace mozilla {
 namespace dom {
 
--- a/content/html/content/src/HTMLOptionsCollection.cpp
+++ b/content/html/content/src/HTMLOptionsCollection.cpp
@@ -2,16 +2,17 @@
 /* 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/. */
 
 #include "mozilla/dom/HTMLOptionsCollection.h"
 
 #include "HTMLOptGroupElement.h"
 #include "mozAutoDocUpdate.h"
+#include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLOptionElement.h"
 #include "mozilla/dom/HTMLOptionsCollectionBinding.h"
 #include "mozilla/dom/HTMLSelectElement.h"
 #include "mozilla/Util.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsError.h"
 #include "nsEventDispatcher.h"
--- a/content/media/AbstractMediaDecoder.h
+++ b/content/media/AbstractMediaDecoder.h
@@ -70,17 +70,17 @@ public:
   virtual int64_t GetMediaDuration() = 0;
 
   // Set the duration of the media in microseconds.
   virtual void SetMediaDuration(int64_t aDuration) = 0;
 
   // Sets the duration of the media in microseconds. The MediaDecoder
   // fires a durationchange event to its owner (e.g., an HTML audio
   // tag).
-  virtual void UpdateMediaDuration(int64_t aDuration) = 0;
+  virtual void UpdateEstimatedMediaDuration(int64_t aDuration) = 0;
 
   // Set the media as being seekable or not.
   virtual void SetMediaSeekable(bool aMediaSeekable) = 0;
 
   // Set the transport level as being seekable or not.
   virtual void SetTransportSeekable(bool aTransportSeekable) = 0;
 
   virtual VideoFrameContainer* GetVideoFrameContainer() = 0;
--- a/content/media/BufferDecoder.cpp
+++ b/content/media/BufferDecoder.cpp
@@ -104,17 +104,17 @@ BufferDecoder::GetMediaDuration()
 
 void
 BufferDecoder::SetMediaDuration(int64_t aDuration)
 {
   // ignore
 }
 
 void
-BufferDecoder::UpdateMediaDuration(int64_t aDuration)
+BufferDecoder::UpdateEstimatedMediaDuration(int64_t aDuration)
 {
   // ignore
 }
 
 void
 BufferDecoder::SetMediaSeekable(bool aMediaSeekable)
 {
   // ignore
--- a/content/media/BufferDecoder.h
+++ b/content/media/BufferDecoder.h
@@ -45,17 +45,17 @@ public:
   void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded) MOZ_FINAL MOZ_OVERRIDE;
 
   int64_t GetEndMediaTime() const MOZ_FINAL MOZ_OVERRIDE;
 
   int64_t GetMediaDuration() MOZ_FINAL MOZ_OVERRIDE;
 
   void SetMediaDuration(int64_t aDuration) MOZ_OVERRIDE;
 
-  void UpdateMediaDuration(int64_t aDuration) MOZ_OVERRIDE;
+  void UpdateEstimatedMediaDuration(int64_t aDuration) MOZ_OVERRIDE;
 
   void SetMediaSeekable(bool aMediaSeekable) MOZ_OVERRIDE;
 
   void SetTransportSeekable(bool aTransportSeekable) MOZ_OVERRIDE;
 
   VideoFrameContainer* GetVideoFrameContainer() MOZ_FINAL MOZ_OVERRIDE;
   layers::ImageContainer* GetImageContainer() MOZ_OVERRIDE;
 
--- a/content/media/MediaDecoder.cpp
+++ b/content/media/MediaDecoder.cpp
@@ -1267,20 +1267,24 @@ void MediaDecoder::SetDuration(double aD
 }
 
 void MediaDecoder::SetMediaDuration(int64_t aDuration)
 {
   NS_ENSURE_TRUE_VOID(GetStateMachine());
   GetStateMachine()->SetDuration(aDuration);
 }
 
-void MediaDecoder::UpdateMediaDuration(int64_t aDuration)
+void MediaDecoder::UpdateEstimatedMediaDuration(int64_t aDuration)
 {
+  MOZ_ASSERT(NS_IsMainThread());
+  if (mPlayState <= PLAY_STATE_LOADING) {
+    return;
+  }
   NS_ENSURE_TRUE_VOID(GetStateMachine());
-  GetStateMachine()->UpdateDuration(aDuration);
+  GetStateMachine()->UpdateEstimatedDuration(aDuration);
 }
 
 void MediaDecoder::SetMediaSeekable(bool aMediaSeekable) {
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   MOZ_ASSERT(NS_IsMainThread() || OnDecodeThread());
   mMediaSeekable = aMediaSeekable;
   if (mDecoderStateMachine) {
     mDecoderStateMachine->SetMediaSeekable(aMediaSeekable);
--- a/content/media/MediaDecoder.h
+++ b/content/media/MediaDecoder.h
@@ -492,18 +492,28 @@ public:
   // Call on the main thread only.
   virtual bool IsEnded() const;
 
   // Set the duration of the media resource in units of seconds.
   // This is called via a channel listener if it can pick up the duration
   // from a content header. Must be called from the main thread only.
   virtual void SetDuration(double aDuration);
 
+  // Sets the initial duration of the media. Called while the media metadata
+  // is being read and the decode is being setup.
   void SetMediaDuration(int64_t aDuration) MOZ_OVERRIDE;
-  void UpdateMediaDuration(int64_t aDuration) MOZ_OVERRIDE;
+  // Updates the media duration. This is called while the media is being
+  // played, calls before the media has reached loaded metadata are ignored.
+  // The duration is assumed to be an estimate, and so a degree of
+  // instability is expected; if the incoming duration is not significantly
+  // different from the existing duration, the change request is ignored.
+  // If the incoming duration is significantly different, the duration is
+  // changed, this causes a durationchanged event to fire to the media
+  // element.
+  void UpdateEstimatedMediaDuration(int64_t aDuration) MOZ_OVERRIDE;
 
   // Set a flag indicating whether seeking is supported
   virtual void SetMediaSeekable(bool aMediaSeekable) MOZ_OVERRIDE;
   virtual void SetTransportSeekable(bool aTransportSeekable) MOZ_FINAL MOZ_OVERRIDE;
   // Returns true if this media supports seeking. False for example for WebM
   // files without an index and chained ogg files.
   virtual bool IsMediaSeekable() MOZ_FINAL MOZ_OVERRIDE;
   // Returns true if seeking is supported on a transport level (e.g. the server
--- a/content/media/MediaDecoderStateMachine.cpp
+++ b/content/media/MediaDecoderStateMachine.cpp
@@ -113,16 +113,22 @@ static const uint32_t QUICK_BUFFERING_LO
 // quick buffering in a timely fashion, as the decode pauses when it
 // reaches AMPLE_AUDIO_USECS decoded data, and thus we'll never reach
 // QUICK_BUFFERING_LOW_DATA_USECS.
 PR_STATIC_ASSERT(QUICK_BUFFERING_LOW_DATA_USECS <= AMPLE_AUDIO_USECS);
 
 // This value has been chosen empirically.
 static const uint32_t AUDIOSTREAM_MIN_WRITE_BEFORE_START_USECS = 200000;
 
+// The amount of instability we tollerate in calls to
+// MediaDecoderStateMachine::UpdateEstimatedDuration(); changes of duration
+// less than this are ignored, as they're assumed to be the result of
+// instability in the duration estimation.
+static const int64_t ESTIMATED_DURATION_FUZZ_FACTOR_USECS = USECS_PER_S / 2;
+
 static TimeDuration UsecsToDuration(int64_t aUsecs) {
   return TimeDuration::FromMilliseconds(static_cast<double>(aUsecs) / USECS_PER_MS);
 }
 
 static int64_t DurationToUsecs(TimeDuration aDuration) {
   return static_cast<int64_t>(aDuration.ToSeconds() * USECS_PER_S);
 }
 
@@ -1439,19 +1445,22 @@ void MediaDecoderStateMachine::SetDurati
   if (mStartTime != -1) {
     mEndTime = mStartTime + aDuration;
   } else {
     mStartTime = 0;
     mEndTime = aDuration;
   }
 }
 
-void MediaDecoderStateMachine::UpdateDuration(int64_t aDuration)
+void MediaDecoderStateMachine::UpdateEstimatedDuration(int64_t aDuration)
 {
-  if (aDuration != GetDuration()) {
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
+  int64_t duration = GetDuration();
+  if (aDuration != duration &&
+      abs(aDuration - duration) > ESTIMATED_DURATION_FUZZ_FACTOR_USECS) {
     SetDuration(aDuration);
     nsCOMPtr<nsIRunnable> event =
       NS_NewRunnableMethod(mDecoder, &MediaDecoder::DurationChanged);
     NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
   }
 }
 
 void MediaDecoderStateMachine::SetMediaEndTime(int64_t aEndTime)
--- a/content/media/MediaDecoderStateMachine.h
+++ b/content/media/MediaDecoderStateMachine.h
@@ -155,19 +155,22 @@ public:
   // aDuration is in microseconds.
   void SetDuration(int64_t aDuration);
 
   // Called while decoding metadata to set the end time of the media
   // resource. The decoder monitor must be obtained before calling this.
   // aEndTime is in microseconds.
   void SetMediaEndTime(int64_t aEndTime);
 
-  // Called from decode thread to update the duration. Can result in
-  // a durationchangeevent. aDuration is in microseconds.
-  void UpdateDuration(int64_t aDuration);
+  // Called from main thread to update the duration with an estimated value.
+  // The duration is only changed if its significantly different than the
+  // the current duration, as the incoming duration is an estimate and so
+  // often is unstable as more data is read and the estimate is updated.
+  // Can result in a durationchangeevent. aDuration is in microseconds.
+  void UpdateEstimatedDuration(int64_t aDuration);
 
   // Functions used by assertions to ensure we're calling things
   // on the appropriate threads.
   bool OnDecodeThread() const {
     return IsCurrentThread(mDecodeThread);
   }
   bool OnStateMachineThread() const;
   bool OnAudioThread() const {
--- a/content/media/directshow/DirectShowReader.cpp
+++ b/content/media/directshow/DirectShowReader.cpp
@@ -31,22 +31,24 @@ GetDirectShowLog() {
 #define LOG(...) PR_LOG(GetDirectShowLog(), PR_LOG_DEBUG, (__VA_ARGS__))
 
 #else
 #define LOG(...)
 #endif
 
 DirectShowReader::DirectShowReader(AbstractMediaDecoder* aDecoder)
   : MediaDecoderReader(aDecoder),
+    mMP3FrameParser(aDecoder->GetResource()->GetLength()),
 #ifdef DEBUG
     mRotRegister(0),
 #endif
     mNumChannels(0),
     mAudioRate(0),
-    mBytesPerSample(0)
+    mBytesPerSample(0),
+    mDuration(0)
 {
   MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
   MOZ_COUNT_CTOR(DirectShowReader);
 }
 
 DirectShowReader::~DirectShowReader()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
@@ -361,9 +363,26 @@ DirectShowReader::OnDecodeThreadStart()
 
 void
 DirectShowReader::OnDecodeThreadFinish()
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
   CoUninitialize();
 }
 
+void
+DirectShowReader::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  if (!mMP3FrameParser.IsMP3()) {
+    return;
+  }
+  mMP3FrameParser.Parse(aBuffer, aLength, aOffset);
+  int64_t duration = mMP3FrameParser.GetDuration();
+  if (duration != mDuration) {
+    mDuration = duration;
+    MOZ_ASSERT(mDecoder);
+    ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
+    mDecoder->UpdateEstimatedMediaDuration(mDuration);
+  }
+}
+
 } // namespace mozilla
--- a/content/media/directshow/DirectShowReader.h
+++ b/content/media/directshow/DirectShowReader.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #if !defined(DirectShowReader_h_)
 #define DirectShowReader_h_
 
 #include "Windows.h" // HRESULT, DWORD
 #include "MediaDecoderReader.h"
 #include "mozilla/RefPtr.h"
+#include "MP3FrameParser.h"
 
 class IGraphBuilder;
 class IMediaControl;
 class IMediaSeeking;
 class IMediaEventEx;
 
 namespace mozilla {
 
@@ -65,16 +66,20 @@ public:
                 int64_t aCurrentTime) MOZ_OVERRIDE;
 
   nsresult GetBuffered(mozilla::dom::TimeRanges* aBuffered,
                        int64_t aStartTime) MOZ_OVERRIDE;
 
   void OnDecodeThreadStart() MOZ_OVERRIDE;
   void OnDecodeThreadFinish() MOZ_OVERRIDE;
 
+  void NotifyDataArrived(const char* aBuffer,
+                         uint32_t aLength,
+                         int64_t aOffset) MOZ_OVERRIDE;
+
 private:
 
   // Calls mAudioQueue.Finish(), and notifies the filter graph that playback
   // is complete. aStatus is the code to send to the filter graph.
   // Always returns false, so that we can just "return Finish()" from
   // DecodeAudioData().
   bool Finish(HRESULT aStatus);
 
@@ -86,28 +91,36 @@ private:
 
   // Wraps the MediaResource, and feeds undecoded data into the filter graph.
   RefPtr<SourceFilter> mSourceFilter;
 
   // Sits at the end of the graph, removing decoded samples from the graph.
   // The graph will block while this is blocked, i.e. it will pause decoding.
   RefPtr<AudioSinkFilter> mAudioSinkFilter;
 
+  // Some MP3s are variable bitrate, so DirectShow's duration estimation
+  // can make its duration estimation based on the wrong bitrate. So we parse
+  // the MP3 frames to get a more accuate estimate of the duration.
+  MP3FrameParser mMP3FrameParser;
+
 #ifdef DEBUG
   // Used to add/remove the filter graph to the Running Object Table. You can
   // connect GraphEdit/GraphStudio to the graph to observe and/or debug its
   // topology and state.
   DWORD mRotRegister;
 #endif
 
   // Number of channels in the audio stream.
   uint32_t mNumChannels;
 
   // Samples per second in the audio stream.
   uint32_t mAudioRate;
 
   // Number of bytes per sample. Can be either 1 or 2.
   uint32_t mBytesPerSample;
+
+  // Duration of the stream, in microseconds.
+  int64_t mDuration;
 };
 
 } // namespace mozilla
 
 #endif
--- a/content/media/omx/OmxDecoder.cpp
+++ b/content/media/omx/OmxDecoder.cpp
@@ -627,17 +627,17 @@ void OmxDecoder::NotifyDataArrived(const
 
   int64_t durationUs = mMP3FrameParser.GetDuration();
 
   if (durationUs != mDurationUs) {
     mDurationUs = durationUs;
 
     MOZ_ASSERT(mDecoder);
     ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-    mDecoder->UpdateMediaDuration(mDurationUs);
+    mDecoder->UpdateEstimatedMediaDuration(mDurationUs);
   }
 }
 
 void OmxDecoder::ReleaseVideoBuffer() {
   if (mVideoBuffer) {
     mVideoBuffer->release();
     mVideoBuffer = nullptr;
   }
--- a/content/media/webaudio/AudioContext.cpp
+++ b/content/media/webaudio/AudioContext.cpp
@@ -1,21 +1,23 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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/. */
 
 #include "AudioContext.h"
+
 #include "nsPIDOMWindow.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/AnalyserNode.h"
 #include "mozilla/dom/AudioContextBinding.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/OfflineAudioContextBinding.h"
+#include "mozilla/dom/OwningNonNull.h"
 #include "MediaStreamGraph.h"
 #include "AudioDestinationNode.h"
 #include "AudioBufferSourceNode.h"
 #include "AudioBuffer.h"
 #include "GainNode.h"
 #include "MediaElementAudioSourceNode.h"
 #include "MediaStreamAudioSourceNode.h"
 #include "DelayNode.h"
--- a/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp
+++ b/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp
@@ -30,16 +30,17 @@
 #include "txXSLTProcessor.h"
 #include "nsIPrincipal.h"
 #include "nsThreadUtils.h"
 #include "jsapi.h"
 #include "txExprParser.h"
 #include "nsIErrorService.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsJSUtils.h"
+#include "nsIXPConnect.h"
 
 using namespace mozilla::dom;
 
 static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
 
 /**
  * Output Handler Factories
  */
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -7,16 +7,17 @@
 #ifndef nsDOMClassInfo_h___
 #define nsDOMClassInfo_h___
 
 #include "mozilla/Attributes.h"
 #include "nsIXPCScriptable.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIDOMScriptObjectFactory.h"
 #include "js/Id.h"
+#include "nsIXPConnect.h"
 
 #ifdef XP_WIN
 #undef GetClassName
 #endif
 
 class nsContentList;
 class nsDocument;
 class nsGlobalWindow;
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -668,16 +668,38 @@ bool
 NativeInterface2JSObjectAndThrowIfFailed(JSContext* aCx,
                                          JS::Handle<JSObject*> aScope,
                                          JS::Value* aRetval,
                                          xpcObjectHelper& aHelper,
                                          const nsIID* aIID,
                                          bool aAllowNativeWrapper)
 {
   nsresult rv;
+  // Inline some logic from XPCConvert::NativeInterfaceToJSObject that we need
+  // on all threads.
+  nsWrapperCache *cache = aHelper.GetWrapperCache();
+
+  if (cache && cache->IsDOMBinding()) {
+      JS::RootedObject obj(aCx, cache->GetWrapper());
+      if (!obj) {
+          obj = cache->WrapObject(aCx, aScope);
+      }
+
+      if (obj && aAllowNativeWrapper && !JS_WrapObject(aCx, obj.address())) {
+        return false;
+      }
+
+      if (obj) {
+        *aRetval = JS::ObjectValue(*obj);
+        return true;
+      }
+  }
+
+  MOZ_ASSERT(NS_IsMainThread());
+
   if (!XPCConvert::NativeInterface2JSObject(aRetval, NULL, aHelper, aIID,
                                             NULL, aAllowNativeWrapper, &rv)) {
     // I can't tell if NativeInterface2JSObject throws JS exceptions
     // or not.  This is a sloppy stab at the right semantics; the
     // method really ought to be fixed to behave consistently.
     if (!JS_IsExceptionPending(aCx)) {
       Throw(aCx, NS_FAILED(rv) ? rv : NS_ERROR_UNEXPECTED);
     }
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -1418,70 +1418,16 @@ HasPropertyOnPrototype(JSContext* cx, JS
 // shadowPrototypeProperties is false then skip properties that are also
 // present on the proto chain of proxy.  If shadowPrototypeProperties is true,
 // then the "proxy" argument is ignored.
 bool
 AppendNamedPropertyIds(JSContext* cx, JS::Handle<JSObject*> proxy,
                        nsTArray<nsString>& names,
                        bool shadowPrototypeProperties, JS::AutoIdVector& props);
 
-template<class T>
-class OwningNonNull
-{
-public:
-  OwningNonNull()
-#ifdef DEBUG
-    : inited(false)
-#endif
-  {}
-
-  operator T&() {
-    MOZ_ASSERT(inited);
-    MOZ_ASSERT(ptr, "OwningNonNull<T> was set to null");
-    return *ptr;
-  }
-
-  void operator=(T* t) {
-    init(t);
-  }
-
-  void operator=(const already_AddRefed<T>& t) {
-    init(t);
-  }
-
-  already_AddRefed<T> forget() {
-#ifdef DEBUG
-    inited = false;
-#endif
-    return ptr.forget();
-  }
-
-  // Make us work with smart-ptr helpers that expect a get()
-  T* get() const {
-    MOZ_ASSERT(inited);
-    MOZ_ASSERT(ptr);
-    return ptr;
-  }
-
-protected:
-  template<typename U>
-  void init(U t) {
-    ptr = t;
-    MOZ_ASSERT(ptr);
-#ifdef DEBUG
-    inited = true;
-#endif
-  }
-
-  nsRefPtr<T> ptr;
-#ifdef DEBUG
-  bool inited;
-#endif
-};
-
 // A struct that has the same layout as an nsDependentString but much
 // faster constructor and destructor behavior
 struct FakeDependentString {
   FakeDependentString() :
     mFlags(nsDependentString::F_TERMINATED)
   {
   }
 
@@ -1607,47 +1553,16 @@ ConvertJSValueToString(JSContext* cx, JS
   return true;
 }
 
 bool
 ConvertJSValueToByteString(JSContext* cx, JS::Handle<JS::Value> v,
                            JS::MutableHandle<JS::Value> pval, bool nullable,
                            nsACString& result);
 
-// Class for holding the type of members of a union. The union type has an enum
-// to keep track of which of its UnionMembers has been constructed.
-template<class T>
-class UnionMember {
-    AlignedStorage2<T> storage;
-
-public:
-    T& SetValue() {
-      new (storage.addr()) T();
-      return *storage.addr();
-    }
-    template <typename T1>
-    T& SetValue(const T1 &t1)
-    {
-      new (storage.addr()) T(t1);
-      return *storage.addr();
-    }
-    template <typename T1, typename T2>
-    T& SetValue(const T1 &t1, const T2 &t2)
-    {
-      new (storage.addr()) T(t1, t2);
-      return *storage.addr();
-    }
-    const T& Value() const {
-      return *storage.addr();
-    }
-    void Destroy() {
-      storage.addr()->~T();
-    }
-};
-
 template<typename T>
 void DoTraceSequence(JSTracer* trc, FallibleTArray<T>& seq);
 template<typename T>
 void DoTraceSequence(JSTracer* trc, InfallibleTArray<T>& seq);
 
 // Class for simple sequence arguments, only used internally by codegen.
 template<typename T>
 class AutoSequence : public AutoFallibleTArray<T, 16>
--- a/dom/bindings/CallbackObject.cpp
+++ b/dom/bindings/CallbackObject.cpp
@@ -12,16 +12,17 @@
 #include "nsIScriptGlobalObject.h"
 #include "nsIXPConnect.h"
 #include "nsIScriptContext.h"
 #include "nsPIDOMWindow.h"
 #include "nsJSUtils.h"
 #include "nsCxPusher.h"
 #include "nsIScriptSecurityManager.h"
 #include "xpcprivate.h"
+#include "WorkerPrivate.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CallbackObject)
   NS_INTERFACE_MAP_ENTRY(mozilla::dom::CallbackObject)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
@@ -44,86 +45,96 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
 CallbackObject::CallSetup::CallSetup(JS::Handle<JSObject*> aCallback,
                                      ErrorResult& aRv,
                                      ExceptionHandling aExceptionHandling,
                                      JSCompartment* aCompartment)
   : mCx(nullptr)
   , mCompartment(aCompartment)
   , mErrorResult(aRv)
   , mExceptionHandling(aExceptionHandling)
+  , mIsMainThread(NS_IsMainThread())
 {
+  if (mIsMainThread) {
+    nsContentUtils::EnterMicroTask();
+  }
   // We need to produce a useful JSContext here.  Ideally one that the callback
   // is in some sense associated with, so that we can sort of treat it as a
   // "script entry point".  Though once we actually have script entry points,
   // we'll need to do the script entry point bits once we have an actual
   // callable.
 
   // First, find the real underlying callback.
   JSObject* realCallback = js::UncheckedUnwrap(aCallback);
+  JSContext* cx = nullptr;
 
-  // Now get the nsIScriptGlobalObject for this callback.
-  JSContext* cx = nullptr;
-  nsIScriptContext* ctx = nullptr;
-  nsIScriptGlobalObject* sgo = nsJSUtils::GetStaticScriptGlobal(realCallback);
-  if (sgo) {
-    // Make sure that if this is a window it's the current inner, since the
-    // nsIScriptContext and hence JSContext are associated with the outer
-    // window.  Which means that if someone holds on to a function from a
-    // now-unloaded document we'd have the new document as the script entry
-    // point...
-    nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(sgo);
-    if (win) {
-      MOZ_ASSERT(win->IsInnerWindow());
-      nsPIDOMWindow* outer = win->GetOuterWindow();
-      if (!outer || win != outer->GetCurrentInnerWindow()) {
-        // Just bail out from here
-        return;
+  if (mIsMainThread) {
+    // Now get the nsIScriptGlobalObject for this callback.
+    nsIScriptContext* ctx = nullptr;
+    nsIScriptGlobalObject* sgo = nsJSUtils::GetStaticScriptGlobal(realCallback);
+    if (sgo) {
+      // Make sure that if this is a window it's the current inner, since the
+      // nsIScriptContext and hence JSContext are associated with the outer
+      // window.  Which means that if someone holds on to a function from a
+      // now-unloaded document we'd have the new document as the script entry
+      // point...
+      nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(sgo);
+      if (win) {
+        MOZ_ASSERT(win->IsInnerWindow());
+        nsPIDOMWindow* outer = win->GetOuterWindow();
+        if (!outer || win != outer->GetCurrentInnerWindow()) {
+          // Just bail out from here
+          return;
+        }
+      }
+      // if not a window at all, just press on
+
+      ctx = sgo->GetContext();
+      if (ctx) {
+        // We don't check whether scripts are enabled on ctx, because
+        // CheckFunctionAccess will do that anyway... and because we ignore them
+        // being disabled if the callee is system.
+        cx = ctx->GetNativeContext();
       }
     }
-    // if not a window at all, just press on
 
-    ctx = sgo->GetContext();
-    if (ctx) {
-      // We don't check whether scripts are enabled on ctx, because
-      // CheckFunctionAccess will do that anyway... and because we ignore them
-      // being disabled if the callee is system.
-      cx = ctx->GetNativeContext();
+    if (!cx) {
+      // We didn't manage to hunt down a script global to work with.  Just fall
+      // back on using the safe context.
+      cx = nsContentUtils::GetSafeJSContext();
     }
+
+    // Make sure our JSContext is pushed on the stack.
+    mCxPusher.Push(cx);
+  } else {
+    cx = workers::GetCurrentThreadJSContext();
   }
 
-  if (!cx) {
-    // We didn't manage to hunt down a script global to work with.  Just fall
-    // back on using the safe context.
-    cx = nsContentUtils::GetSafeJSContext();
-  }
-
-  // Make sure our JSContext is pushed on the stack.
-  mCxPusher.Push(cx);
-
   // Unmark the callable, and stick it in a Rooted before it can go gray again.
   // Nothing before us in this function can trigger a CC, so it's safe to wait
   // until here it do the unmark. This allows us to order the following two
   // operations _after_ the Push() above, which lets us take advantage of the
   // JSAutoRequest embedded in the pusher.
   //
   // We can do this even though we're not in the right compartment yet, because
   // Rooted<> does not care about compartments.
   JS::ExposeObjectToActiveJS(aCallback);
   mRootedCallable.construct(cx, aCallback);
 
-  // Check that it's ok to run this callback at all.
-  // FIXME: Bug 807371: we want a less silly check here.
-  // Make sure to unwrap aCallback before passing it in, because
-  // getting principals from wrappers is silly.
-  nsresult rv = nsContentUtils::GetSecurityManager()->
-    CheckFunctionAccess(cx, js::UncheckedUnwrap(aCallback), nullptr);
+  if (mIsMainThread) {
+    // Check that it's ok to run this callback at all.
+    // FIXME: Bug 807371: we want a less silly check here.
+    // Make sure to unwrap aCallback before passing it in, because
+    // getting principals from wrappers is silly.
+    nsresult rv = nsContentUtils::GetSecurityManager()->
+      CheckFunctionAccess(cx, js::UncheckedUnwrap(aCallback), nullptr);
 
-  if (NS_FAILED(rv)) {
-    // Security check failed.  We're done here.
-    return;
+    if (NS_FAILED(rv)) {
+      // Security check failed.  We're done here.
+      return;
+    }
   }
 
   // Enter the compartment of our callback, so we can actually work with it.
   mAc.construct(cx, aCallback);
 
   // And now we're ready to go.
   mCx = cx;
 
@@ -199,22 +210,29 @@ CallbackObject::CallSetup::~CallSetup()
   // XXXbz For that matter why do we need to manually call ScriptEvaluated at
   // all?  nsCxPusher::Pop will do that nowadays if !mScriptIsRunning, so the
   // concerns from bug 295983 don't seem relevant anymore.  Do we want to make
   // sure it's still called when !mScriptIsRunning?  I guess play it safe for
   // now and do what CallEventHandler did, which is call always.
 
   // Popping an nsCxPusher is safe even if it never got pushed.
   mCxPusher.Pop();
+
+  // It is important that this is the last thing we do, after leaving the
+  // compartment and popping the context.
+  if (mIsMainThread) {
+    nsContentUtils::LeaveMicroTask();
+  }
 }
 
 already_AddRefed<nsISupports>
 CallbackObjectHolderBase::ToXPCOMCallback(CallbackObject* aCallback,
                                           const nsIID& aIID) const
 {
+  MOZ_ASSERT(NS_IsMainThread());
   if (!aCallback) {
     return nullptr;
   }
 
   AutoSafeJSContext cx;
 
   JS::Rooted<JSObject*> callback(cx, aCallback->Callback());
 
--- a/dom/bindings/CallbackObject.h
+++ b/dom/bindings/CallbackObject.h
@@ -146,20 +146,16 @@ protected:
     JSContext* mCx;
 
     // Caller's compartment. This will only have a sensible value if
     // mExceptionHandling == eRethrowContentExceptions.
     JSCompartment* mCompartment;
 
     // And now members whose construction/destruction order we need to control.
 
-    // Put our nsAutoMicrotask first, so it gets destroyed after everything else
-    // is gone
-    nsAutoMicroTask mMt;
-
     nsCxPusher mCxPusher;
 
     // Constructed the rooter within the scope of mCxPusher above, so that it's
     // always within a request during its lifetime.
     Maybe<JS::Rooted<JSObject*> > mRootedCallable;
 
     // Can't construct a JSAutoCompartment without a JSContext either.  Also,
     // Put mAc after mCxPusher so that we exit the compartment before we pop the
@@ -167,16 +163,17 @@ protected:
     // things.
     Maybe<JSAutoCompartment> mAc;
 
     // An ErrorResult to possibly re-throw exceptions on and whether
     // we should re-throw them.
     ErrorResult& mErrorResult;
     const ExceptionHandling mExceptionHandling;
     uint32_t mSavedJSContextOptions;
+    const bool mIsMainThread;
   };
 };
 
 template<class WebIDLCallbackT, class XPCOMCallbackT>
 class CallbackObjectHolder;
 
 template<class T, class U>
 void ImplCycleCollectionUnlink(CallbackObjectHolder<T, U>& aField);
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -6,17 +6,17 @@
 
 import operator
 import os
 import re
 import string
 import math
 import itertools
 
-from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType
+from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType, IDLAttribute
 from Configuration import NoSuchDescriptorError, getTypesFromDescriptor, getTypesFromDictionary, getTypesFromCallback, Descriptor
 
 AUTOGENERATED_WARNING_COMMENT = \
     "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n"
 ADDPROPERTY_HOOK_NAME = '_addProperty'
 FINALIZE_HOOK_NAME = '_finalize'
 TRACE_HOOK_NAME = '_trace'
 CONSTRUCT_HOOK_NAME = '_constructor'
@@ -2892,24 +2892,21 @@ for (uint32_t i = 0; i < length; ++i) {
             holderArgs = None
 
         return JSToNativeConversionInfo(templateBody, declType=typeName,
                                         holderType=holderType,
                                         dealWithOptional=isOptional,
                                         holderArgs=holderArgs)
 
     if type.isUnion():
-        if isMember:
-            raise TypeError("Can't handle unions as members, we have a "
-                            "holderType")
         nullable = type.nullable();
         if nullable:
             type = type.inner
 
-        unionArgumentObj = "${holderName}"
+        unionArgumentObj = "${declName}" if isMember else "${holderName}"
         if nullable:
             unionArgumentObj += ".ref()"
 
         memberTypes = type.flatMemberTypes
         names = []
 
         interfaceMemberTypes = filter(lambda t: t.isNonCallbackInterface(), memberTypes)
         if len(interfaceMemberTypes) > 0:
@@ -3062,33 +3059,33 @@ for (uint32_t i = 0; i < length; ++i) {
                           '  ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "%s", "%s");\n'
                           "%s\n"
                           "}" % (exceptionCodeIndented.define(),
                                  firstCap(sourceDescription),
                                  ", ".join(names),
                                  exceptionCodeIndented.define()))
         templateBody = CGWrapper(CGIndenter(CGList([templateBody, throw], "\n")), pre="{\n", post="\n}")
 
-        typeName = type.name
+        typeName = type.name + ("ReturnValue" if isMember else "")
         argumentTypeName = typeName + "Argument"
         if nullable:
             typeName = "Nullable<" + typeName + " >"
 
         def handleNull(templateBody, setToNullVar, extraConditionForNull=""):
             null = CGGeneric("if (%s${val}.isNullOrUndefined()) {\n"
                              "  %s.SetNull();\n"
                              "}" % (extraConditionForNull, setToNullVar))
             templateBody = CGWrapper(CGIndenter(templateBody), pre="{\n", post="\n}")
             return CGList([null, templateBody], " else ")
 
         if type.hasNullableType:
             templateBody = handleNull(templateBody, unionArgumentObj)
 
         declType = CGGeneric(typeName)
-        holderType = CGGeneric(argumentTypeName)
+        holderType = CGGeneric(argumentTypeName) if not isMember else None
 
         # If we're isOptional and not nullable the normal optional handling will
         # handle lazy construction of our holder.  If we're nullable we do it
         # all by hand because we do not want our holder constructed if we're
         # null.
         declLoc = "${declName}"
         constructDecl = None
         if nullable:
@@ -3152,20 +3149,18 @@ for (uint32_t i = 0; i < length; ++i) {
             type.unroll().inner.identifier.name)
 
         if descriptor.nativeType == 'JSObject':
             # XXXbz Workers code does this sometimes
             assert descriptor.workers
             return handleJSObjectType(type, isMember, failureCode)
 
         if (descriptor.interface.isCallback() and
-            descriptor.interface.identifier.name != "EventListener"):
-            if descriptor.workers:
-                return handleJSObjectType(type, isMember, failureCode)
-
+            (descriptor.interface.identifier.name != "EventListener" or
+             descriptorProvider.workers)):
             name = descriptor.interface.identifier.name
             if type.nullable() or isCallbackReturnValue:
                 declType = CGGeneric("nsRefPtr<%s>" % name);
             else:
                 declType = CGGeneric("OwningNonNull<%s>" % name)
             conversion = (
                 "  ${declName} = new %s(&${val}.toObject());\n" % name)
 
@@ -3411,20 +3406,26 @@ for (uint32_t i = 0; i < length; ++i) {
         if isOptional:
             declType = "Optional<nsAString>"
         elif isInUnionReturnValue:
             declType = "nsString"
         else:
             declType = "NonNull<nsAString>"
 
         # No need to deal with optional here; we handled it already
+        decl = ""
+        if isInUnionReturnValue:
+            decl += "FakeDependentString str;\n"
         return JSToNativeConversionInfo(
+            "%s"
             "%s\n"
-            "${declName} = &${holderName};" %
-            getConversionCode("${holderName}"),
+            "${declName} = %s" %
+              (decl,
+               getConversionCode("str" if isInUnionReturnValue else "${holderName}"),
+               ("str;" if isInUnionReturnValue else "&${holderName};")),
             declType=CGGeneric(declType),
             holderType=CGGeneric("FakeDependentString"))
 
     if type.isByteString():
         assert not isEnforceRange and not isClamp
 
         nullable = toStringBool(type.nullable())
 
@@ -4117,17 +4118,18 @@ if (!returnArray) {
 }\n""" % (result, exceptionCodeIndented.define(),
           index, index, index,
           innerTemplate, index,
           CGIndenter(exceptionCodeIndented, 4).define())) +
                 setValue("JS::ObjectValue(*returnArray)"), False)
 
     if (type.isGeckoInterface() and
         (not type.isCallbackInterface() or
-         type.unroll().inner.identifier.name == "EventListener")):
+         (type.unroll().inner.identifier.name == "EventListener" and
+          not descriptorProvider.workers))):
         descriptor = descriptorProvider.getDescriptor(type.unroll().inner.identifier.name)
         if type.nullable():
             wrappingCode = ("if (!%s) {\n" % (result) +
                             CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define() + "\n" +
                             "}\n")
         else:
             wrappingCode = ""
 
@@ -4623,16 +4625,25 @@ class CGCallGenerator(CGThing):
             self.cgRoot.append(CGGeneric("rv.WouldReportJSException();"))
             self.cgRoot.append(CGGeneric("if (rv.Failed()) {"))
             self.cgRoot.append(CGIndenter(errorReport))
             self.cgRoot.append(CGGeneric("}"))
 
     def define(self):
         return self.cgRoot.define()
 
+def getUnionMemberName(type):
+    if type.isGeckoInterface():
+        return type.inner.identifier.name
+    if type.isEnum():
+        return type.inner.identifier.name
+    if type.isArray() or type.isSequence():
+        return str(type)
+    return type.name
+
 class MethodNotCreatorError(Exception):
     def __init__(self, typename):
         self.typename = typename
 
 # A counter for making sure that when we're wrapping up things in
 # nested sequences we don't use the same variable name to iterate over
 # different sequences.
 sequenceWrapLevel = 0
@@ -4705,18 +4716,25 @@ def wrapTypeIntoCurrentCompartment(type,
                     member,
                     "%s.%s" % (value, CGDictionary.makeMemberName(member.identifier.name)))
                 if memberWrap:
                     memberWraps.append(memberWrap)
             myDict = myDict.parent
         return CGList(memberWraps, "\n") if len(memberWraps) != 0 else None
 
     if type.isUnion():
-        raise TypeError("Can't handle wrapping of unions in constructor "
-                        "arguments yet")
+        memberWraps = []
+        for member in type.flatMemberTypes:
+            memberWrap = wrapTypeIntoCurrentCompartment(
+               member,
+               "%s.%s" % (value, getUnionMemberName(member)))
+            if memberWrap:
+                memberWrap = CGIfWrapper(memberWrap, "mType == %s" % member)
+                memberWraps.append(memberWrap)
+        return CGList(memberWraps, "else ") if len(memberWraps) != 0 else None
 
     if (type.isString() or type.isPrimitive() or type.isEnum() or
         type.isGeckoInterface() or type.isCallback() or type.isDate()):
         # All of these don't need wrapping
         return None
 
     raise TypeError("Unknown type; we don't know how to wrap it in constructor "
                     "arguments: %s" % type)
@@ -5328,18 +5346,22 @@ class FakeArgument():
     """
     def __init__(self, type, interfaceMember, name="arg"):
         self.type = type
         self.optional = False
         self.variadic = False
         self.defaultValue = None
         self.treatNullAs = interfaceMember.treatNullAs
         self.treatUndefinedAs = interfaceMember.treatUndefinedAs
-        self.enforceRange = False
-        self.clamp = False
+        if isinstance(interfaceMember, IDLAttribute):
+            self.enforceRange = interfaceMember.enforceRange
+            self.clamp = interfaceMember.clamp
+        else:
+            self.enforceRange = False
+            self.clamp = False
         class FakeIdentifier():
             def __init__(self):
                 self.name = name
         self.identifier = FakeIdentifier()
 
 class CGSetterCall(CGPerSignatureCall):
     """
     A class to generate a native object setter call for a particular IDL
@@ -6117,86 +6139,75 @@ def getUnionAccessorSignatureType(type, 
 def getUnionTypeTemplateVars(unionType, type, descriptorProvider, isReturnValue=False):
     # For dictionaries and sequences we need to pass None as the failureCode
     # for getJSToNativeConversionInfo.
     # Also, for dictionaries we would need to handle conversion of
     # null/undefined to the dictionary correctly.
     if type.isDictionary() or type.isSequence():
         raise TypeError("Can't handle dictionaries or sequences in unions")
 
-    if type.isGeckoInterface():
-        name = type.inner.identifier.name
-    elif type.isEnum():
-        name = type.inner.identifier.name
-    elif type.isArray() or type.isSequence():
-        name = str(type)
-    else:
-        name = type.name
+    name = getUnionMemberName(type)
 
     ctorArgs = "cx" if type.isSpiderMonkeyInterface() else ""
 
     tryNextCode = ("tryNext = true;\n"
                    "return true;")
     if type.isGeckoInterface():
-         tryNextCode = ("if (mUnion.mType != mUnion.eUninitialized) {"
-                        "  mUnion.Destroy%s();"
-                        "}" % name) + tryNextCode
+         prefix = "" if isReturnValue else "mUnion."
+         tryNextCode = ("if (%smType != %seUninitialized) {"
+                        "  %sDestroy%s();"
+                        "}") % (prefix, prefix, prefix, name) + tryNextCode
     conversionInfo = getJSToNativeConversionInfo(
         type, descriptorProvider, failureCode=tryNextCode,
         isDefinitelyObject=True, isInUnionReturnValue=isReturnValue,
         sourceDescription="member of %s" % unionType)
 
     # This is ugly, but UnionMember needs to call a constructor with no
     # arguments so the type can't be const.
     structType = conversionInfo.declType.define()
     if structType.startswith("const "):
         structType = structType[6:]
     externalType = getUnionAccessorSignatureType(type, descriptorProvider).define()
 
     if type.isObject():
         body = ("mUnion.mValue.mObject.SetValue(cx, obj);\n"
                 "mUnion.mType = mUnion.eObject;")
-        setters = [ClassMethod("SetToObject", "void",
-                               [Argument("JSContext*", "cx"),
-                                Argument("JSObject*", "obj")],
-                               inline=True, bodyInHeader=True,
-                               body=body)]
+        setter = ClassMethod("SetToObject", "void",
+                             [Argument("JSContext*", "cx"),
+                              Argument("JSObject*", "obj")],
+                             inline=True, bodyInHeader=True,
+                             body=body)
 
     else:
         jsConversion = string.Template(conversionInfo.template).substitute(
             {
                 "val": "value",
                 "mutableVal": "pvalue",
                 "declName": "SetAs" + name + "(%s)" % ctorArgs,
                 "holderName": "m" + name + "Holder",
                 }
             )
         jsConversion = CGWrapper(CGGeneric(jsConversion),
                                  pre="tryNext = false;\n",
                                  post="\n"
                                       "return true;")
-        setters = [ClassMethod("TrySetTo" + name, "bool",
-                               [Argument("JSContext*", "cx"),
-                                Argument("JS::Handle<JS::Value>", "value"),
-                                Argument("JS::MutableHandle<JS::Value>", "pvalue"),
-                                Argument("bool&", "tryNext")],
-                               inline=True, bodyInHeader=True,
-                               body=jsConversion.define())]
-        if type.isString():
-            setters.append(ClassMethod("SetStringData", "void",
-                [Argument("const nsDependentString::char_type*", "aData"),
-                 Argument("nsDependentString::size_type", "aLength")],
-                inline=True, bodyInHeader=True,
-                body="mStringHolder.SetData(aData, aLength);"))
+        setter = ClassMethod("TrySetTo" + name, "bool",
+                              [Argument("JSContext*", "cx"),
+                               Argument("JS::Handle<JS::Value>", "value"),
+                               Argument("JS::MutableHandle<JS::Value>", "pvalue"),
+                               Argument("bool&", "tryNext")],
+                              inline=not isReturnValue,
+                              bodyInHeader=not isReturnValue,
+                              body=jsConversion.define())
 
     return {
                 "name": name,
                 "structType": structType,
                 "externalType": externalType,
-                "setters": setters,
+                "setter": setter,
                 "holderType": conversionInfo.holderType.define() if conversionInfo.holderType else None,
                 "ctorArgs": ctorArgs,
                 "ctorArgList": [Argument("JSContext*", "cx")] if type.isSpiderMonkeyInterface() else []
                 }
 
 def mapTemplate(template, templateVarArray):
     return map(lambda v: string.Template(template).substitute(v),
                templateVarArray)
@@ -6249,16 +6260,26 @@ class CGUnionStruct(CGThing):
                 # bodyInHeader must be false for return values because they own
                 # their union members and we don't want include headers in
                 # UnionTypes.h just to call Addref/Release
                 methods.append(ClassMethod("SetAs" + vars["name"],
                                            vars["structType"] + "&",
                                            vars["ctorArgList"],
                                            bodyInHeader=not self.isReturnValue,
                                            body=body))
+                if self.isReturnValue:
+                    methods.append(vars["setter"])
+                    if t.isString():
+                        methods.append(
+                            ClassMethod("SetStringData", "void",
+                                [Argument("const nsString::char_type*", "aData"),
+                                 Argument("nsString::size_type", "aLength")],
+                                inline=True, bodyInHeader=True,
+                                body="mValue.mString.Value().Assign(aData, aLength);"))
+
             body = string.Template('MOZ_ASSERT(Is${name}(), "Wrong type!");\n'
                                    'mValue.m${name}.Destroy();\n'
                                    'mType = eUninitialized;').substitute(vars)
             methods.append(ClassMethod("Destroy" + vars["name"],
                                        "void",
                                        [],
                                        visibility="private",
                                        bodyInHeader=not self.isReturnValue,
@@ -6347,26 +6368,33 @@ class CGUnionConversionStruct(CGThing):
             methods.append(ClassMethod("SetNull", "bool", [],
                                        body=("mUnion.mType = mUnion.eNull;\n"
                                              "return true;"),
                                        inline=True, bodyInHeader=True))
 
         for t in self.type.flatMemberTypes:
             vars = getUnionTypeTemplateVars(self.type,
                                             t, self.descriptorProvider)
-            methods.extend(vars["setters"])
+            methods.append(vars["setter"])
             if vars["name"] != "Object":
                 body=string.Template("mUnion.mType = mUnion.e${name};\n"
                                      "return mUnion.mValue.m${name}.SetValue(${ctorArgs});").substitute(vars)
                 methods.append(ClassMethod("SetAs" + vars["name"],
                                            vars["structType"] + "&",
                                            vars["ctorArgList"],
                                            bodyInHeader=True,
                                            body=body,
                                            visibility="private"))
+                if t.isString():
+                    methods.append(ClassMethod("SetStringData", "void",
+                                     [Argument("const nsDependentString::char_type*", "aData"),
+                                      Argument("nsDependentString::size_type", "aLength")],
+                                     inline=True, bodyInHeader=True,
+                                     body="mStringHolder.SetData(aData, aLength);"))
+
             if vars["holderType"] is not None:
                 members.append(ClassMember("m%sHolder" % vars["name"],
                                            vars["holderType"]))
 
         return CGClass(structName + "Argument",
                        members=members,
                        constructors=[ctor],
                        methods=methods,
@@ -8110,18 +8138,22 @@ class CGDictionary(CGThing):
         self.dictionary = dictionary
         self.descriptorProvider = descriptorProvider
         self.needToInitIds = len(dictionary.members) > 0
         self.memberInfo = [
             (member,
              getJSToNativeConversionInfo(
                             member.type,
                             descriptorProvider,
+                            isEnforceRange=member.enforceRange,
+                            isClamp=member.clamp,
                             isMember="Dictionary",
                             isOptional=(not member.defaultValue),
+                            # Set this to true so that we get an owning union.
+                            isInUnionReturnValue=True,
                             defaultValue=member.defaultValue,
                             sourceDescription=("'%s' member of %s" %
                                                (member.identifier.name,
                                                 dictionary.identifier.name))))
             for member in dictionary.members ]
         self.structs = self.getStructs()
 
     def declare(self):
@@ -8798,21 +8830,22 @@ class CGBindingRoot(CGThing):
                 return False
             return typeDesc.hasXPConnectImpls
         addHeaderBasedOnTypes("nsDOMQS.h", checkForXPConnectImpls)
 
         # Do codegen for all the enums
         enums = config.getEnums(webIDLFile)
         cgthings = [ CGEnum(e) for e in enums ]
 
-        bindingHeaders["mozilla/dom/BindingUtils.h"] = (
-            descriptors or callbackDescriptors or dictionaries or
-            mainCallbacks or workerCallbacks)
+        hasCode = (descriptors or callbackDescriptors or dictionaries or
+                   mainCallbacks or workerCallbacks)
+        bindingHeaders["mozilla/dom/BindingUtils.h"] = hasCode
+        bindingHeaders["mozilla/dom/OwningNonNull.h"] = hasCode
         bindingHeaders["mozilla/dom/BindingDeclarations.h"] = (
-            not bindingHeaders["mozilla/dom/BindingUtils.h"] and enums)
+            not hasCode and enums)
 
         bindingHeaders["WrapperFactory.h"] = descriptors
         bindingHeaders["mozilla/dom/DOMJSClass.h"] = descriptors
 
         # Do codegen for all the dictionaries.  We have to be a bit careful
         # here, because we have to generate these in order from least derived
         # to most derived so that class inheritance works out.  We also have to
         # generate members before the dictionary that contains them.
@@ -10516,17 +10549,19 @@ struct PrototypeTraits;
     @staticmethod
     def UnionTypes(config):
 
         (includes, implincludes,
          declarations, unions) = UnionTypes(config.getDescriptors(),
                                             config.getDictionaries(),
                                             config.getCallbacks(),
                                             config)
-        includes.add("mozilla/dom/BindingUtils.h")
+        includes.add("mozilla/dom/OwningNonNull.h")
+        includes.add("mozilla/dom/UnionMember.h")
+        implincludes.add("mozilla/dom/PrimitiveConversions.h")
 
         # Wrap all of that in our namespaces.
         curr = CGNamespace.build(['mozilla', 'dom'], unions)
 
         curr = CGWrapper(curr, post='\n')
 
         namespaces = []
         stack = [CGList([])]
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -204,20 +204,17 @@ class Descriptor(DescriptorProvider):
         # Read the desc, and fill in the relevant defaults.
         ifaceName = self.interface.identifier.name
         if self.interface.isExternal():
             if self.workers:
                 nativeTypeDefault = "JSObject"
             else:
                 nativeTypeDefault = "nsIDOM" + ifaceName
         elif self.interface.isCallback():
-            if self.workers:
-                nativeTypeDefault = "JSObject"
-            else:
-                nativeTypeDefault = "mozilla::dom::" + ifaceName
+            nativeTypeDefault = "mozilla::dom::" + ifaceName
         else:
             if self.workers:
                 nativeTypeDefault = "mozilla::dom::workers::" + ifaceName
             else:
                 nativeTypeDefault = "mozilla::dom::" + ifaceName
 
         self.nativeType = desc.get('nativeType', nativeTypeDefault)
         self.jsImplParent = desc.get('jsImplParent', self.nativeType)
copy from dom/bindings/BindingUtils.h
copy to dom/bindings/OwningNonNull.h
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/OwningNonNull.h
@@ -1,2344 +1,80 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
-/* vim: set ts=2 sw=2 et tw=79: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
-
-#ifndef mozilla_dom_BindingUtils_h__
-#define mozilla_dom_BindingUtils_h__
-
-#include <algorithm>
+ * 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/. */
 
-#include "jsfriendapi.h"
-#include "jswrapper.h"
-#include "mozilla/Alignment.h"
-#include "mozilla/dom/BindingDeclarations.h"
-#include "mozilla/dom/CallbackObject.h"
-#include "mozilla/dom/DOMJSClass.h"
-#include "mozilla/dom/DOMJSProxyHandler.h"
-#include "mozilla/dom/Exceptions.h"
-#include "mozilla/dom/NonRefcountedDOMObject.h"
-#include "mozilla/dom/Nullable.h"
-#include "mozilla/dom/workers/Workers.h"
-#include "mozilla/ErrorResult.h"
-#include "mozilla/Likely.h"
-#include "mozilla/Util.h"
-#include "nsCycleCollector.h"
-#include "nsIXPConnect.h"
-#include "nsThreadUtils.h" // Hacky work around for some bindings needing NS_IsMainThread.
-#include "nsTraceRefcnt.h"
-#include "qsObjectHelper.h"
-#include "xpcpublic.h"
-#include "nsIVariant.h"
+/* A class for non-null strong pointers to reference-counted objects. */
 
-#include "nsWrapperCacheInlines.h"
-
-class nsPIDOMWindow;
+#ifndef mozilla_dom_OwningNonNull_h
+#define mozilla_dom_OwningNonNull_h
 
-extern nsresult
-xpc_qsUnwrapArgImpl(JSContext* cx, jsval v, const nsIID& iid, void** ppArg,
-                    nsISupports** ppArgRef, jsval* vp);
+#include "nsAutoPtr.h"
 
 namespace mozilla {
 namespace dom {
 
-struct SelfRef
-{
-  SelfRef() : ptr(nullptr) {}
-  explicit SelfRef(nsISupports *p) : ptr(p) {}
-  ~SelfRef() { NS_IF_RELEASE(ptr); }
-
-  nsISupports* ptr;
-};
-
-/** Convert a jsval to an XPCOM pointer. */
-template <class Interface, class StrongRefType>
-inline nsresult
-UnwrapArg(JSContext* cx, jsval v, Interface** ppArg,
-          StrongRefType** ppArgRef, jsval* vp)
-{
-  nsISupports* argRef = *ppArgRef;
-  nsresult rv = xpc_qsUnwrapArgImpl(cx, v, NS_GET_TEMPLATE_IID(Interface),
-                                    reinterpret_cast<void**>(ppArg), &argRef,
-                                    vp);
-  *ppArgRef = static_cast<StrongRefType*>(argRef);
-  return rv;
-}
-
-bool
-ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs,
-                 const ErrNum aErrorNumber,
-                 const char* aInterfaceName);
-
-inline bool
-ThrowMethodFailedWithDetails(JSContext* cx, ErrorResult& rv,
-                             const char* ifaceName,
-                             const char* memberName,
-                             bool reportJSContentExceptions = false)
-{
-  if (rv.IsTypeError()) {
-    rv.ReportTypeError(cx);
-    return false;
-  }
-  if (rv.IsJSException()) {
-    if (reportJSContentExceptions) {
-      rv.ReportJSExceptionFromJSImplementation(cx);
-    } else {
-      rv.ReportJSException(cx);
-    }
-    return false;
-  }
-  if (rv.IsNotEnoughArgsError()) {
-    rv.ReportNotEnoughArgsError(cx, ifaceName, memberName);
-  }
-  return Throw(cx, rv.ErrorCode());
-}
-
-// Returns true if the JSClass is used for DOM objects.
-inline bool
-IsDOMClass(const JSClass* clasp)
-{
-  return clasp->flags & JSCLASS_IS_DOMJSCLASS;
-}
-
-inline bool
-IsDOMClass(const js::Class* clasp)
-{
-  return IsDOMClass(Jsvalify(clasp));
-}
-
-// Returns true if the JSClass is used for DOM interface and interface 
-// prototype objects.
-inline bool
-IsDOMIfaceAndProtoClass(const JSClass* clasp)
-{
-  return clasp->flags & JSCLASS_IS_DOMIFACEANDPROTOJSCLASS;
-}
-
-inline bool
-IsDOMIfaceAndProtoClass(const js::Class* clasp)
-{
-  return IsDOMIfaceAndProtoClass(Jsvalify(clasp));
-}
-
-static_assert(DOM_OBJECT_SLOT == js::PROXY_PRIVATE_SLOT,
-              "js::PROXY_PRIVATE_SLOT doesn't match DOM_OBJECT_SLOT.  "
-              "Expect bad things");
-template <class T>
-inline T*
-UnwrapDOMObject(JSObject* obj)
-{
-  MOZ_ASSERT(IsDOMClass(js::GetObjectClass(obj)) || IsDOMProxy(obj),
-             "Don't pass non-DOM objects to this function");
-
-  JS::Value val = js::GetReservedSlot(obj, DOM_OBJECT_SLOT);
-  return static_cast<T*>(val.toPrivate());
-}
-
-inline const DOMClass*
-GetDOMClass(JSObject* obj)
-{
-  js::Class* clasp = js::GetObjectClass(obj);
-  if (IsDOMClass(clasp)) {
-    return &DOMJSClass::FromJSClass(clasp)->mClass;
-  }
-
-  if (js::IsProxyClass(clasp)) {
-    js::BaseProxyHandler* handler = js::GetProxyHandler(obj);
-    if (handler->family() == ProxyFamily()) {
-      return &static_cast<DOMProxyHandler*>(handler)->mClass;
-    }
-  }
-
-  return nullptr;
-}
-
-inline nsISupports*
-UnwrapDOMObjectToISupports(JSObject* aObject)
-{
-  const DOMClass* clasp = GetDOMClass(aObject);
-  if (!clasp || !clasp->mDOMObjectIsISupports) {
-    return nullptr;
-  }
- 
-  return UnwrapDOMObject<nsISupports>(aObject);
-}
-
-inline bool
-IsDOMObject(JSObject* obj)
-{
-  js::Class* clasp = js::GetObjectClass(obj);
-  return IsDOMClass(clasp) || IsDOMProxy(obj, clasp);
-}
-
-#define UNWRAP_OBJECT(Interface, cx, obj, value)                             \
-  mozilla::dom::UnwrapObject<mozilla::dom::prototypes::id::Interface,        \
-    mozilla::dom::Interface##Binding::NativeType>(cx, obj, value)
-
-// Some callers don't want to set an exception when unwrapping fails
-// (for example, overload resolution uses unwrapping to tell what sort
-// of thing it's looking at).
-// U must be something that a T* can be assigned to (e.g. T* or an nsRefPtr<T>).
-template <prototypes::ID PrototypeID, class T, typename U>
-MOZ_ALWAYS_INLINE nsresult
-UnwrapObject(JSContext* cx, JSObject* obj, U& value)
-{
-  /* First check to see whether we have a DOM object */
-  const DOMClass* domClass = GetDOMClass(obj);
-  if (!domClass) {
-    /* Maybe we have a security wrapper or outer window? */
-    if (!js::IsWrapper(obj)) {
-      /* Not a DOM object, not a wrapper, just bail */
-      return NS_ERROR_XPC_BAD_CONVERT_JS;
-    }
-
-    obj = js::CheckedUnwrap(obj, /* stopAtOuter = */ false);
-    if (!obj) {
-      return NS_ERROR_XPC_SECURITY_MANAGER_VETO;
-    }
-    MOZ_ASSERT(!js::IsWrapper(obj));
-    domClass = GetDOMClass(obj);
-    if (!domClass) {
-      /* We don't have a DOM object */
-      return NS_ERROR_XPC_BAD_CONVERT_JS;
-    }
-  }
-
-  /* This object is a DOM object.  Double-check that it is safely
-     castable to T by checking whether it claims to inherit from the
-     class identified by protoID. */
-  if (domClass->mInterfaceChain[PrototypeTraits<PrototypeID>::Depth] ==
-      PrototypeID) {
-    value = UnwrapDOMObject<T>(obj);
-    return NS_OK;
-  }
-
-  /* It's the wrong sort of DOM object */
-  return NS_ERROR_XPC_BAD_CONVERT_JS;
-}
-
-inline bool
-IsNotDateOrRegExp(JSContext* cx, JS::Handle<JSObject*> obj)
-{
-  MOZ_ASSERT(obj);
-  return !JS_ObjectIsDate(cx, obj) && !JS_ObjectIsRegExp(cx, obj);
-}
-
-MOZ_ALWAYS_INLINE bool
-IsArrayLike(JSContext* cx, JS::Handle<JSObject*> obj)
-{
-  return IsNotDateOrRegExp(cx, obj);
-}
-
-MOZ_ALWAYS_INLINE bool
-IsObjectValueConvertibleToDictionary(JSContext* cx,
-                                     JS::Handle<JS::Value> objVal)
-{
-  JS::Rooted<JSObject*> obj(cx, &objVal.toObject());
-  return IsNotDateOrRegExp(cx, obj);
-}
-
-MOZ_ALWAYS_INLINE bool
-IsConvertibleToDictionary(JSContext* cx, JS::Handle<JS::Value> val)
-{
-  return val.isNullOrUndefined() ||
-    (val.isObject() && IsObjectValueConvertibleToDictionary(cx, val));
-}
-
-MOZ_ALWAYS_INLINE bool
-IsConvertibleToCallbackInterface(JSContext* cx, JS::Handle<JSObject*> obj)
-{
-  return IsNotDateOrRegExp(cx, obj);
-}
-
-// The items in the protoAndIfaceArray are indexed by the prototypes::id::ID and
-// constructors::id::ID enums, in that order. The end of the prototype objects
-// should be the start of the interface objects.
-static_assert((size_t)constructors::id::_ID_Start ==
-              (size_t)prototypes::id::_ID_Count,
-              "Overlapping or discontiguous indexes.");
-const size_t kProtoAndIfaceCacheCount = constructors::id::_ID_Count;
-
-inline void
-AllocateProtoAndIfaceCache(JSObject* obj)
-{
-  MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL);
-  MOZ_ASSERT(js::GetReservedSlot(obj, DOM_PROTOTYPE_SLOT).isUndefined());
-
-  JS::Heap<JSObject*>* protoAndIfaceArray = new JS::Heap<JSObject*>[kProtoAndIfaceCacheCount];
-
-  js::SetReservedSlot(obj, DOM_PROTOTYPE_SLOT,
-                      JS::PrivateValue(protoAndIfaceArray));
-}
-
-inline void
-TraceProtoAndIfaceCache(JSTracer* trc, JSObject* obj)
-{
-  MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL);
-
-  if (!HasProtoAndIfaceArray(obj))
-    return;
-  JS::Heap<JSObject*>* protoAndIfaceArray = GetProtoAndIfaceArray(obj);
-  for (size_t i = 0; i < kProtoAndIfaceCacheCount; ++i) {
-    if (protoAndIfaceArray[i]) {
-      JS_CallHeapObjectTracer(trc, &protoAndIfaceArray[i], "protoAndIfaceArray[i]");
-    }
-  }
-}
-
-inline void
-DestroyProtoAndIfaceCache(JSObject* obj)
-{
-  MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL);
-
-  JS::Heap<JSObject*>* protoAndIfaceArray = GetProtoAndIfaceArray(obj);
-
-  delete [] protoAndIfaceArray;
-}
-
-/**
- * Add constants to an object.
- */
-bool
-DefineConstants(JSContext* cx, JS::Handle<JSObject*> obj,
-                const ConstantSpec* cs);
-
-struct JSNativeHolder
-{
-  JSNative mNative;
-  const NativePropertyHooks* mPropertyHooks;
-};
-
-struct NamedConstructor
-{
-  const char* mName;
-  const JSNativeHolder mHolder;
-  unsigned mNargs;
-};
-
-/*
- * Create a DOM interface object (if constructorClass is non-null) and/or a
- * DOM interface prototype object (if protoClass is non-null).
- *
- * global is used as the parent of the interface object and the interface
- *        prototype object
- * protoProto is the prototype to use for the interface prototype object.
- * interfaceProto is the prototype to use for the interface object.
- * protoClass is the JSClass to use for the interface prototype object.
- *            This is null if we should not create an interface prototype
- *            object.
- * protoCache a pointer to a JSObject pointer where we should cache the
- *            interface prototype object. This must be null if protoClass is and
- *            vice versa.
- * constructorClass is the JSClass to use for the interface object.
- *                  This is null if we should not create an interface object or
- *                  if it should be a function object.
- * constructor holds the JSNative to back the interface object which should be a
- *             Function, unless constructorClass is non-null in which case it is
- *             ignored. If this is null and constructorClass is also null then
- *             we should not create an interface object at all.
- * ctorNargs is the length of the constructor function; 0 if no constructor
- * constructorCache a pointer to a JSObject pointer where we should cache the
- *                  interface object. This must be null if both constructorClass
- *                  and constructor are null, and non-null otherwise.
- * domClass is the DOMClass of instance objects for this class.  This can be
- *          null if this is not a concrete proto.
- * properties contains the methods, attributes and constants to be defined on
- *            objects in any compartment.
- * chromeProperties contains the methods, attributes and constants to be defined
- *                  on objects in chrome compartments. This must be null if the
- *                  interface doesn't have any ChromeOnly properties or if the
- *                  object is being created in non-chrome compartment.
- * defineOnGlobal controls whether properties should be defined on the given
- *                global for the interface object (if any) and named
- *                constructors (if any) for this interface.  This can be
- *                false in situations where we want the properties to only
- *                appear on privileged Xrays but not on the unprivileged
- *                underlying global.
- *
- * At least one of protoClass, constructorClass or constructor should be
- * non-null. If constructorClass or constructor are non-null, the resulting
- * interface object will be defined on the given global with property name
- * |name|, which must also be non-null.
- */
-void
-CreateInterfaceObjects(JSContext* cx, JS::Handle<JSObject*> global,
-                       JS::Handle<JSObject*> protoProto,
-                       JSClass* protoClass, JS::Heap<JSObject*>* protoCache,
-                       JS::Handle<JSObject*> interfaceProto,
-                       JSClass* constructorClass, const JSNativeHolder* constructor,
-                       unsigned ctorNargs, const NamedConstructor* namedConstructors,
-                       JS::Heap<JSObject*>* constructorCache, const DOMClass* domClass,
-                       const NativeProperties* regularProperties,
-                       const NativeProperties* chromeOnlyProperties,
-                       const char* name, bool defineOnGlobal);
-
-/*
- * Define the unforgeable attributes on an object.
- */
-bool
-DefineUnforgeableAttributes(JSContext* cx, JS::Handle<JSObject*> obj,
-                            const Prefable<const JSPropertySpec>* props);
-
-bool
-DefineWebIDLBindingPropertiesOnXPCProto(JSContext* cx,
-                                        JS::Handle<JSObject*> proto,
-                                        const NativeProperties* properties);
-
-#ifdef _MSC_VER
-#define HAS_MEMBER_CHECK(_name)                                           \
-  template<typename V> static yes& Check(char (*)[(&V::_name == 0) + 1])
-#else
-#define HAS_MEMBER_CHECK(_name)                                           \
-  template<typename V> static yes& Check(char (*)[sizeof(&V::_name) + 1])
-#endif
-
-#define HAS_MEMBER(_name)                                                 \
-template<typename T>                                                      \
-class Has##_name##Member {                                                \
-  typedef char yes[1];                                                    \
-  typedef char no[2];                                                     \
-  HAS_MEMBER_CHECK(_name);                                                \
-  template<typename V> static no& Check(...);                             \
-                                                                          \
-public:                                                                   \
-  static bool const Value = sizeof(Check<T>(nullptr)) == sizeof(yes);     \
-};
-
-HAS_MEMBER(WrapObject)
-
-// HasWrapObject<T>::Value will be true if T has a WrapObject member but it's
-// not nsWrapperCache::WrapObject.
-template<typename T>
-struct HasWrapObject
-{
-private:
-  typedef char yes[1];
-  typedef char no[2];
-  typedef JSObject* (nsWrapperCache::*WrapObject)(JSContext*,
-                                                  JS::Handle<JSObject*>);
-  template<typename U, U> struct SFINAE;
-  template <typename V> static no& Check(SFINAE<WrapObject, &V::WrapObject>*);
-  template <typename V> static yes& Check(...);
-
-public:
-  static bool const Value = HasWrapObjectMember<T>::Value &&
-                            sizeof(Check<T>(nullptr)) == sizeof(yes);
-};
-
-#ifdef DEBUG
-template <class T, bool isISupports=IsBaseOf<nsISupports, T>::value>
-struct
-CheckWrapperCacheCast
-{
-  static bool Check()
-  {
-    return reinterpret_cast<uintptr_t>(
-      static_cast<nsWrapperCache*>(
-        reinterpret_cast<T*>(1))) == 1;
-  }
-};
-template <class T>
-struct
-CheckWrapperCacheCast<T, true>
-{
-  static bool Check()
-  {
-    return true;
-  }
-};
-#endif
-
-MOZ_ALWAYS_INLINE bool
-CouldBeDOMBinding(void*)
-{
-  return true;
-}
-
-MOZ_ALWAYS_INLINE bool
-CouldBeDOMBinding(nsWrapperCache* aCache)
-{
-  return aCache->IsDOMBinding();
-}
-
-// The DOM_OBJECT_SLOT_SOW slot contains a JS::ObjectValue which points to the
-// cached system object wrapper (SOW) or JS::UndefinedValue if this class
-// doesn't need SOWs.
-
-inline const JS::Value&
-GetSystemOnlyWrapperSlot(JSObject* obj)
-{
-  MOZ_ASSERT(IsDOMClass(js::GetObjectJSClass(obj)) &&
-             !(js::GetObjectJSClass(obj)->flags & JSCLASS_DOM_GLOBAL));
-  return js::GetReservedSlot(obj, DOM_OBJECT_SLOT_SOW);
-}
-inline void
-SetSystemOnlyWrapperSlot(JSObject* obj, const JS::Value& v)
-{
-  MOZ_ASSERT(IsDOMClass(js::GetObjectJSClass(obj)) &&
-             !(js::GetObjectJSClass(obj)->flags & JSCLASS_DOM_GLOBAL));
-  js::SetReservedSlot(obj, DOM_OBJECT_SLOT_SOW, v);
-}
-
-inline bool
-GetSameCompartmentWrapperForDOMBinding(JSObject*& obj)
-{
-  js::Class* clasp = js::GetObjectClass(obj);
-  if (dom::IsDOMClass(clasp)) {
-    if (!(clasp->flags & JSCLASS_DOM_GLOBAL)) {
-      JS::Value v = GetSystemOnlyWrapperSlot(obj);
-      if (v.isObject()) {
-        obj = &v.toObject();
-      }
-    }
-    return true;
-  }
-  return IsDOMProxy(obj, clasp);
-}
-
-inline void
-SetSystemOnlyWrapper(JSObject* obj, nsWrapperCache* cache, JSObject& wrapper)
-{
-  SetSystemOnlyWrapperSlot(obj, JS::ObjectValue(wrapper));
-  cache->SetHasSystemOnlyWrapper();
-}
-
-// Make sure to wrap the given string value into the right compartment, as
-// needed.
-MOZ_ALWAYS_INLINE
-bool
-MaybeWrapStringValue(JSContext* cx, JS::MutableHandle<JS::Value> rval)
-{
-  MOZ_ASSERT(rval.isString());
-  JSString* str = rval.toString();
-  if (JS::GetGCThingZone(str) != js::GetContextZone(cx)) {
-    return JS_WrapValue(cx, rval.address());
-  }
-  return true;
-}
-
-// Make sure to wrap the given object value into the right compartment as
-// needed.  This will work correctly, but possibly slowly, on all objects.
-MOZ_ALWAYS_INLINE
-bool
-MaybeWrapObjectValue(JSContext* cx, JS::MutableHandle<JS::Value> rval)
-{
-  MOZ_ASSERT(rval.isObject());
-
-  JSObject* obj = &rval.toObject();
-  if (js::GetObjectCompartment(obj) != js::GetContextCompartment(cx)) {
-    return JS_WrapValue(cx, rval.address());
-  }
-
-  // We're same-compartment, but even then we might need to wrap
-  // objects specially.  Check for that.
-  if (GetSameCompartmentWrapperForDOMBinding(obj)) {
-    // We're a new-binding object, and "obj" now points to the right thing
-    rval.set(JS::ObjectValue(*obj));
-    return true;
-  }
-
-  // It's not a WebIDL object.  But it might be an XPConnect one, in which case
-  // we may need to outerize here, so make sure to call JS_WrapValue.
-  return JS_WrapValue(cx, rval.address());
-}
-
-// Like MaybeWrapObjectValue, but also allows null
-MOZ_ALWAYS_INLINE
-bool
-MaybeWrapObjectOrNullValue(JSContext* cx, JS::MutableHandle<JS::Value> rval)
-{
-  MOZ_ASSERT(rval.isObjectOrNull());
-  if (rval.isNull()) {
-    return true;
-  }
-  return MaybeWrapObjectValue(cx, rval);
-}
-
-// Wrapping for objects that are known to not be DOM or XPConnect objects
-MOZ_ALWAYS_INLINE
-bool
-MaybeWrapNonDOMObjectValue(JSContext* cx, JS::MutableHandle<JS::Value> rval)
-{
-  MOZ_ASSERT(rval.isObject());
-  MOZ_ASSERT(!GetDOMClass(&rval.toObject()));
-  MOZ_ASSERT(!(js::GetObjectClass(&rval.toObject())->flags &
-               JSCLASS_PRIVATE_IS_NSISUPPORTS));
-
-  JSObject* obj = &rval.toObject();
-  if (js::GetObjectCompartment(obj) == js::GetContextCompartment(cx)) {
-    return true;
-  }
-  return JS_WrapValue(cx, rval.address());
-}
-
-// Like MaybeWrapNonDOMObjectValue but allows null
-MOZ_ALWAYS_INLINE
-bool
-MaybeWrapNonDOMObjectOrNullValue(JSContext* cx, JS::MutableHandle<JS::Value> rval)
-{
-  MOZ_ASSERT(rval.isObjectOrNull());
-  if (rval.isNull()) {
-    return true;
-  }
-  return MaybeWrapNonDOMObjectValue(cx, rval);
-}
-
-// If rval is a gcthing and is not in the compartment of cx, wrap rval
-// into the compartment of cx (typically by replacing it with an Xray or
-// cross-compartment wrapper around the original object).
-MOZ_ALWAYS_INLINE bool
-MaybeWrapValue(JSContext* cx, JS::MutableHandle<JS::Value> rval)
-{
-  if (rval.isString()) {
-    return MaybeWrapStringValue(cx, rval);
-  }
-
-  if (!rval.isObject()) {
-    return true;
-  }
-
-  return MaybeWrapObjectValue(cx, rval);
-}
-
-static inline void
-WrapNewBindingForSameCompartment(JSContext* cx, JSObject* obj, void* value,
-                                 JS::MutableHandle<JS::Value> rval)
-{
-  rval.set(JS::ObjectValue(*obj));
-}
-
-static inline void
-WrapNewBindingForSameCompartment(JSContext* cx, JSObject* obj,
-                                 nsWrapperCache* value,
-                                 JS::MutableHandle<JS::Value> rval)
-{
-  if (value->HasSystemOnlyWrapper()) {
-    rval.set(GetSystemOnlyWrapperSlot(obj));
-    MOZ_ASSERT(rval.isObject());
-  } else {
-    rval.set(JS::ObjectValue(*obj));
-  }
-}
-
-// Create a JSObject wrapping "value", if there isn't one already, and store it
-// in rval.  "value" must be a concrete class that implements a
-// GetWrapperPreserveColor() which can return its existing wrapper, if any, and
-// a WrapObject() which will try to create a wrapper. Typically, this is done by
-// having "value" inherit from nsWrapperCache.
-template <class T>
-MOZ_ALWAYS_INLINE bool
-WrapNewBindingObject(JSContext* cx, JS::Handle<JSObject*> scope, T* value,
-                     JS::MutableHandle<JS::Value> rval)
-{
-  MOZ_ASSERT(value);
-  JSObject* obj = value->GetWrapperPreserveColor();
-  bool couldBeDOMBinding = CouldBeDOMBinding(value);
-  if (obj) {
-    JS::ExposeObjectToActiveJS(obj);
-  } else {
-    // Inline this here while we have non-dom objects in wrapper caches.
-    if (!couldBeDOMBinding) {
-      return false;
-    }
-
-    obj = value->WrapObject(cx, scope);
-    if (!obj) {
-      // At this point, obj is null, so just return false.
-      // Callers seem to be testing JS_IsExceptionPending(cx) to
-      // figure out whether WrapObject() threw.
-      return false;
-    }
-  }
-
-#ifdef DEBUG
-  const DOMClass* clasp = GetDOMClass(obj);
-  // clasp can be null if the cache contained a non-DOM object from a
-  // different compartment than scope.
-  if (clasp) {
-    // Some sanity asserts about our object.  Specifically:
-    // 1)  If our class claims we're nsISupports, we better be nsISupports
-    //     XXXbz ideally, we could assert that reinterpret_cast to nsISupports
-    //     does the right thing, but I don't see a way to do it.  :(
-    // 2)  If our class doesn't claim we're nsISupports we better be
-    //     reinterpret_castable to nsWrapperCache.
-    MOZ_ASSERT(clasp, "What happened here?");
-    MOZ_ASSERT_IF(clasp->mDOMObjectIsISupports, (IsBaseOf<nsISupports, T>::value));
-    MOZ_ASSERT(CheckWrapperCacheCast<T>::Check());
-  }
-
-  // When called via XrayWrapper, we end up here while running in the
-  // chrome compartment.  But the obj we have would be created in
-  // whatever the content compartment is.  So at this point we need to
-  // make sure it's correctly wrapped for the compartment of |scope|.
-  // cx should already be in the compartment of |scope| here.
-  MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
-#endif
-
-  bool sameCompartment =
-    js::GetObjectCompartment(obj) == js::GetContextCompartment(cx);
-  if (sameCompartment && couldBeDOMBinding) {
-    WrapNewBindingForSameCompartment(cx, obj, value, rval);
-    return true;
-  }
-
-  rval.set(JS::ObjectValue(*obj));
-  return JS_WrapValue(cx, rval.address());
-}
-
-// Create a JSObject wrapping "value", for cases when "value" is a
-// non-wrapper-cached object using WebIDL bindings.  "value" must implement a
-// WrapObject() method taking a JSContext and a scope.
-template <class T>
-inline bool
-WrapNewBindingNonWrapperCachedObject(JSContext* cx,
-                                     JS::Handle<JSObject*> scopeArg,
-                                     T* value,
-                                     JS::MutableHandle<JS::Value> rval)
-{
-  MOZ_ASSERT(value);
-  // We try to wrap in the compartment of the underlying object of "scope"
-  JS::Rooted<JSObject*> obj(cx);
-  {
-    // scope for the JSAutoCompartment so that we restore the compartment
-    // before we call JS_WrapValue.
-    Maybe<JSAutoCompartment> ac;
-    // Maybe<Handle> doesn't so much work, and in any case, adding
-    // more Maybe (one for a Rooted and one for a Handle) adds more
-    // code (and branches!) than just adding a single rooted.
-    JS::Rooted<JSObject*> scope(cx, scopeArg);
-    if (js::IsWrapper(scope)) {
-      scope = js::CheckedUnwrap(scope, /* stopAtOuter = */ false);
-      if (!scope)
-        return false;
-      ac.construct(cx, scope);
-    }
-
-    obj = value->WrapObject(cx, scope);
-  }
-
-  if (!obj) {
-    return false;
-  }
-
-  // We can end up here in all sorts of compartments, per above.  Make
-  // sure to JS_WrapValue!
-  rval.set(JS::ObjectValue(*obj));
-  return JS_WrapValue(cx, rval.address());
-}
-
-// Create a JSObject wrapping "value", for cases when "value" is a
-// non-wrapper-cached owned object using WebIDL bindings.  "value" must implement a
-// WrapObject() method taking a JSContext, a scope, and a boolean outparam that
-// is true if the JSObject took ownership
-template <class T>
-inline bool
-WrapNewBindingNonWrapperCachedOwnedObject(JSContext* cx,
-                                          JS::Handle<JSObject*> scopeArg,
-                                          nsAutoPtr<T>& value,
-                                          JS::MutableHandle<JS::Value> rval)
-{
-  // We do a runtime check on value, because otherwise we might in
-  // fact end up wrapping a null and invoking methods on it later.
-  if (!value) {
-    NS_RUNTIMEABORT("Don't try to wrap null objects");
-  }
-  // We try to wrap in the compartment of the underlying object of "scope"
-  JS::Rooted<JSObject*> obj(cx);
-  {
-    // scope for the JSAutoCompartment so that we restore the compartment
-    // before we call JS_WrapValue.
-    Maybe<JSAutoCompartment> ac;
-    // Maybe<Handle> doesn't so much work, and in any case, adding
-    // more Maybe (one for a Rooted and one for a Handle) adds more
-    // code (and branches!) than just adding a single rooted.
-    JS::Rooted<JSObject*> scope(cx, scopeArg);
-    if (js::IsWrapper(scope)) {
-      scope = js::CheckedUnwrap(scope, /* stopAtOuter = */ false);
-      if (!scope)
-        return false;
-      ac.construct(cx, scope);
-    }
-
-    bool tookOwnership = false;
-    obj = value->WrapObject(cx, scope, &tookOwnership);
-    MOZ_ASSERT_IF(obj, tookOwnership);
-    if (tookOwnership) {
-      value.forget();
-    }
-  }
-
-  if (!obj) {
-    return false;
-  }
-
-  // We can end up here in all sorts of compartments, per above.  Make
-  // sure to JS_WrapValue!
-  rval.set(JS::ObjectValue(*obj));
-  return JS_WrapValue(cx, rval.address());
-}
-
-// Helper for smart pointers (nsAutoPtr/nsRefPtr/nsCOMPtr).
-template <template <typename> class SmartPtr, typename T>
-inline bool
-WrapNewBindingNonWrapperCachedObject(JSContext* cx, JS::Handle<JSObject*> scope,
-                                     const SmartPtr<T>& value,
-                                     JS::MutableHandle<JS::Value> rval)
-{
-  return WrapNewBindingNonWrapperCachedObject(cx, scope, value.get(), rval);
-}
-
-// Only set allowNativeWrapper to false if you really know you need it, if in
-// doubt use true. Setting it to false disables security wrappers.
-bool
-NativeInterface2JSObjectAndThrowIfFailed(JSContext* aCx,
-                                         JS::Handle<JSObject*> aScope,
-                                         JS::Value* aRetval,
-                                         xpcObjectHelper& aHelper,
-                                         const nsIID* aIID,
-                                         bool aAllowNativeWrapper);
-
-/**
- * A method to handle new-binding wrap failure, by possibly falling back to
- * wrapping as a non-new-binding object.
- */
-template <class T>
-MOZ_ALWAYS_INLINE bool
-HandleNewBindingWrappingFailure(JSContext* cx, JS::Handle<JSObject*> scope,
-                                T* value, JS::MutableHandle<JS::Value> rval)
-{
-  if (JS_IsExceptionPending(cx)) {
-    return false;
-  }
-
-  qsObjectHelper helper(value, GetWrapperCache(value));
-  return NativeInterface2JSObjectAndThrowIfFailed(cx, scope, rval.address(),
-                                                  helper, nullptr, true);
-}
-
-// Helper for calling HandleNewBindingWrappingFailure with smart pointers
-// (nsAutoPtr/nsRefPtr/nsCOMPtr) or references.
-HAS_MEMBER(get)
-
-template <class T, bool isSmartPtr=HasgetMember<T>::Value>
-struct HandleNewBindingWrappingFailureHelper
-{
-  static inline bool Wrap(JSContext* cx, JS::Handle<JSObject*> scope,
-                          const T& value, JS::MutableHandle<JS::Value> rval)
-  {
-    return HandleNewBindingWrappingFailure(cx, scope, value.get(), rval);
-  }
-};
-
-template <class T>
-struct HandleNewBindingWrappingFailureHelper<T, false>
-{
-  static inline bool Wrap(JSContext* cx, JS::Handle<JSObject*> scope, T& value,
-                          JS::MutableHandle<JS::Value> rval)
-  {
-    return HandleNewBindingWrappingFailure(cx, scope, &value, rval);
-  }
-};
-
-template<class T>
-inline bool
-HandleNewBindingWrappingFailure(JSContext* cx, JS::Handle<JSObject*> scope,
-                                T& value, JS::MutableHandle<JS::Value> rval)
-{
-  return HandleNewBindingWrappingFailureHelper<T>::Wrap(cx, scope, value, rval);
-}
-
-template<bool Fatal>
-inline bool
-EnumValueNotFound(JSContext* cx, const jschar* chars, size_t length,
-                  const char* type, const char* sourceDescription)
-{
-  return false;
-}
-
-template<>
-inline bool
-EnumValueNotFound<false>(JSContext* cx, const jschar* chars, size_t length,
-                         const char* type, const char* sourceDescription)
-{
-  // TODO: Log a warning to the console.
-  return true;
-}
-
-template<>
-inline bool
-EnumValueNotFound<true>(JSContext* cx, const jschar* chars, size_t length,
-                        const char* type, const char* sourceDescription)
-{
-  NS_LossyConvertUTF16toASCII deflated(static_cast<const PRUnichar*>(chars),
-                                       length);
-  return ThrowErrorMessage(cx, MSG_INVALID_ENUM_VALUE, sourceDescription,
-                           deflated.get(), type);
-}
-
-
-template<bool InvalidValueFatal>
-inline int
-FindEnumStringIndex(JSContext* cx, JS::Value v, const EnumEntry* values,
-                    const char* type, const char* sourceDescription, bool* ok)
-{
-  // JS_StringEqualsAscii is slow as molasses, so don't use it here.
-  JSString* str = JS_ValueToString(cx, v);
-  if (!str) {
-    *ok = false;
-    return 0;
-  }
-  JS::Anchor<JSString*> anchor(str);
-  size_t length;
-  const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
-  if (!chars) {
-    *ok = false;
-    return 0;
-  }
-  int i = 0;
-  for (const EnumEntry* value = values; value->value; ++value, ++i) {
-    if (length != value->length) {
-      continue;
-    }
-
-    bool equal = true;
-    const char* val = value->value;
-    for (size_t j = 0; j != length; ++j) {
-      if (unsigned(val[j]) != unsigned(chars[j])) {
-        equal = false;
-        break;
-      }
-    }
-
-    if (equal) {
-      *ok = true;
-      return i;
-    }
-  }
-
-  *ok = EnumValueNotFound<InvalidValueFatal>(cx, chars, length, type,
-                                             sourceDescription);
-  return -1;
-}
-
-inline nsWrapperCache*
-GetWrapperCache(const ParentObject& aParentObject)
-{
-  return aParentObject.mWrapperCache;
-}
-
-template<class T>
-inline T*
-GetParentPointer(T* aObject)
-{
-  return aObject;
-}
-
-inline nsISupports*
-GetParentPointer(const ParentObject& aObject)
-{
-  return aObject.mObject;
-}
-
-template<class T>
-inline void
-ClearWrapper(T* p, nsWrapperCache* cache)
-{
-  cache->ClearWrapper();
-}
-
-template<class T>
-inline void
-ClearWrapper(T* p, void*)
-{
-  nsWrapperCache* cache;
-  CallQueryInterface(p, &cache);
-  ClearWrapper(p, cache);
-}
-
-// Attempt to preserve the wrapper, if any, for a Paris DOM bindings object.
-// Return true if we successfully preserved the wrapper, or there is no wrapper
-// to preserve. In the latter case we don't need to preserve the wrapper, because
-// the object can only be obtained by JS once, or they cannot be meaningfully
-// owned from the native side.
-//
-// This operation will return false only for non-nsISupports cycle-collected
-// objects, because we cannot determine if they are wrappercached or not.
-bool
-TryPreserveWrapper(JSObject* obj);
-
-// Can only be called with the immediate prototype of the instance object. Can
-// only be called on the prototype of an object known to be a DOM instance.
-bool
-InstanceClassHasProtoAtDepth(JS::Handle<JSObject*> protoObject, uint32_t protoID,
-                             uint32_t depth);
-
-// Only set allowNativeWrapper to false if you really know you need it, if in
-// doubt use true. Setting it to false disables security wrappers.
-bool
-XPCOMObjectToJsval(JSContext* cx, JS::Handle<JSObject*> scope,
-                   xpcObjectHelper& helper, const nsIID* iid,
-                   bool allowNativeWrapper, JS::Value* rval);
-
-// Special-cased wrapping for variants
-bool
-VariantToJsval(JSContext* aCx, JS::Handle<JSObject*> aScope,
-               nsIVariant* aVariant, JS::Value* aRetval);
-
-// Wrap an object "p" which is not using WebIDL bindings yet.  This _will_
-// actually work on WebIDL binding objects that are wrappercached, but will be
-// much slower than WrapNewBindingObject.  "cache" must either be null or be the
-// nsWrapperCache for "p".
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, T* p,
-           nsWrapperCache* cache, const nsIID* iid,
-           JS::MutableHandle<JS::Value> rval)
-{
-  if (xpc_FastGetCachedWrapper(cache, scope, rval.address()))
-    return true;
-  qsObjectHelper helper(p, cache);
-  return XPCOMObjectToJsval(cx, scope, helper, iid, true, rval.address());
-}
-
-// A specialization of the above for nsIVariant, because that needs to
-// do something different.
-template<>
-inline bool
-WrapObject<nsIVariant>(JSContext* cx, JS::Handle<JSObject*> scope, nsIVariant* p,
-                       nsWrapperCache* cache, const nsIID* iid,
-                       JS::MutableHandle<JS::Value> rval)
-{
-  MOZ_ASSERT(iid);
-  MOZ_ASSERT(iid->Equals(NS_GET_IID(nsIVariant)));
-  return VariantToJsval(cx, scope, p, rval.address());
-}
-
-// Wrap an object "p" which is not using WebIDL bindings yet.  Just like the
-// variant that takes an nsWrapperCache above, but will try to auto-derive the
-// nsWrapperCache* from "p".
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, T* p, const nsIID* iid,
-           JS::MutableHandle<JS::Value> rval)
-{
-  return WrapObject(cx, scope, p, GetWrapperCache(p), iid, rval);
-}
-
-// Just like the WrapObject above, but without requiring you to pick which
-// interface you're wrapping as.  This should only be used for objects that have
-// classinfo, for which it doesn't matter what IID is used to wrap.
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, T* p,
-           JS::MutableHandle<JS::Value> rval)
-{
-  return WrapObject(cx, scope, p, NULL, rval);
-}
-
-// Helper to make it possible to wrap directly out of an nsCOMPtr
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, const nsCOMPtr<T>& p,
-           const nsIID* iid, JS::MutableHandle<JS::Value> rval)
-{
-  return WrapObject(cx, scope, p.get(), iid, rval);
-}
-
-// Helper to make it possible to wrap directly out of an nsCOMPtr
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, const nsCOMPtr<T>& p,
-           JS::MutableHandle<JS::Value> rval)
-{
-  return WrapObject(cx, scope, p, NULL, rval);
-}
-
-// Helper to make it possible to wrap directly out of an nsRefPtr
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, const nsRefPtr<T>& p,
-           const nsIID* iid, JS::MutableHandle<JS::Value> rval)
-{
-  return WrapObject(cx, scope, p.get(), iid, rval);
-}
-
-// Helper to make it possible to wrap directly out of an nsRefPtr
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, const nsRefPtr<T>& p,
-           JS::MutableHandle<JS::Value> rval)
-{
-  return WrapObject(cx, scope, p, NULL, rval);
-}
-
-// Specialization to make it easy to use WrapObject in codegen.
-template<>
-inline bool
-WrapObject<JSObject>(JSContext* cx, JS::Handle<JSObject*> scope, JSObject* p,
-                     JS::MutableHandle<JS::Value> rval)
-{
-  rval.set(JS::ObjectOrNullValue(p));
-  return true;
-}
-
-inline bool
-WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, JSObject& p,
-           JS::MutableHandle<JS::Value> rval)
-{
-  rval.set(JS::ObjectValue(p));
-  return true;
-}
-
-// Given an object "p" that inherits from nsISupports, wrap it and return the
-// result.  Null is returned on wrapping failure.  This is somewhat similar to
-// WrapObject() above, but does NOT allow Xrays around the result, since we
-// don't want those for our parent object.
-template<typename T>
-static inline JSObject*
-WrapNativeISupportsParent(JSContext* cx, JS::Handle<JSObject*> scope, T* p,
-                          nsWrapperCache* cache)
-{
-  qsObjectHelper helper(ToSupports(p), cache);
-  JS::Rooted<JS::Value> v(cx);
-  return XPCOMObjectToJsval(cx, scope, helper, nullptr, false, v.address()) ?
-         JSVAL_TO_OBJECT(v) :
-         nullptr;
-}
-
-
-// Fallback for when our parent is not a WebIDL binding object.
-template<typename T, bool isISupports=IsBaseOf<nsISupports, T>::value>
-struct WrapNativeParentFallback
-{
-  static inline JSObject* Wrap(JSContext* cx, JS::Handle<JSObject*> scope,
-                               T* parent, nsWrapperCache* cache)
-  {
-    return nullptr;
-  }
-};
-
-// Fallback for when our parent is not a WebIDL binding object but _is_ an
-// nsISupports object.
-template<typename T >
-struct WrapNativeParentFallback<T, true >
-{
-  static inline JSObject* Wrap(JSContext* cx, JS::Handle<JSObject*> scope,
-                               T* parent, nsWrapperCache* cache)
-  {
-    return WrapNativeISupportsParent(cx, scope, parent, cache);
-  }
-};
-
-// Wrapping of our native parent, for cases when it's a WebIDL object (though
-// possibly preffed off).
-template<typename T, bool hasWrapObject=HasWrapObject<T>::Value >
-struct WrapNativeParentHelper
-{
-  static inline JSObject* Wrap(JSContext* cx, JS::Handle<JSObject*> scope,
-                               T* parent, nsWrapperCache* cache)
-  {
-    MOZ_ASSERT(cache);
-
-    JSObject* obj;
-    if ((obj = cache->GetWrapper())) {
-      return obj;
-    }
-
-    // Inline this here while we have non-dom objects in wrapper caches.
-    if (!CouldBeDOMBinding(parent)) {
-      obj = WrapNativeParentFallback<T>::Wrap(cx, scope, parent, cache);
-    } else {
-      obj = parent->WrapObject(cx, scope);
-    }
-
-    return obj;
-  }
-};
-
-// Wrapping of our native parent, for cases when it's not a WebIDL object.  In
-// this case it must be nsISupports.
-template<typename T>
-struct WrapNativeParentHelper<T, false >
-{
-  static inline JSObject* Wrap(JSContext* cx, JS::Handle<JSObject*> scope,
-                               T* parent, nsWrapperCache* cache)
-  {
-    JSObject* obj;
-    if (cache && (obj = cache->GetWrapper())) {
-#ifdef DEBUG
-      NS_ASSERTION(WrapNativeISupportsParent(cx, scope, parent, cache) == obj,
-                   "Unexpected object in nsWrapperCache");
-#endif
-      return obj;
-    }
-
-    return WrapNativeISupportsParent(cx, scope, parent, cache);
-  }
-};
-
-// Wrapping of our native parent.
-template<typename T>
-static inline JSObject*
-WrapNativeParent(JSContext* cx, JS::Handle<JSObject*> scope, T* p,
-                 nsWrapperCache* cache)
-{
-  if (!p) {
-    return scope;
-  }
-
-  return WrapNativeParentHelper<T>::Wrap(cx, scope, p, cache);
-}
-
-// Wrapping of our native parent, when we don't want to explicitly pass in
-// things like the nsWrapperCache for it.
-template<typename T>
-static inline JSObject*
-WrapNativeParent(JSContext* cx, JS::Handle<JSObject*> scope, const T& p)
-{
-  return WrapNativeParent(cx, scope, GetParentPointer(p), GetWrapperCache(p));
-}
-
-// A way to differentiate between nodes, which use the parent object
-// returned by native->GetParentObject(), and all other objects, which
-// just use the parent's global.
-static inline JSObject*
-GetRealParentObject(void* aParent, JSObject* aParentObject)
-{
-  return aParentObject ?
-    js::GetGlobalForObjectCrossCompartment(aParentObject) : nullptr;
-}
-
-static inline JSObject*
-GetRealParentObject(Element* aParent, JSObject* aParentObject)
-{
-  return aParentObject;
-}
-
-HAS_MEMBER(GetParentObject)
-
-template<typename T, bool WrapperCached=HasGetParentObjectMember<T>::Value>
-struct GetParentObject
-{
-  static JSObject* Get(JSContext* cx, JS::Handle<JSObject*> obj)
-  {
-    T* native = UnwrapDOMObject<T>(obj);
-    return
-      GetRealParentObject(native,
-                          WrapNativeParent(cx, obj, native->GetParentObject()));
-  }
-};
-
-template<typename T>
-struct GetParentObject<T, false>
-{
-  static JSObject* Get(JSContext* cx, JS::Handle<JSObject*> obj)
-  {
-    MOZ_CRASH();
-    return nullptr;
-  }
-};
-
-MOZ_ALWAYS_INLINE
-JSObject* GetJSObjectFromCallback(CallbackObject* callback)
-{
-  return callback->Callback();
-}
-
-MOZ_ALWAYS_INLINE
-JSObject* GetJSObjectFromCallback(void* noncallback)
-{
-  return nullptr;
-}
-
-template<typename T>
-static inline JSObject*
-WrapCallThisObject(JSContext* cx, JS::Handle<JSObject*> scope, const T& p)
-{
-  // Callbacks are nsISupports, so WrapNativeParent will just happily wrap them
-  // up as an nsISupports XPCWrappedNative... which is not at all what we want.
-  // So we need to special-case them.
-  JS::Rooted<JSObject*> obj(cx, GetJSObjectFromCallback(p));
-  if (!obj) {
-    // WrapNativeParent is a bit of a Swiss army knife that will
-    // wrap anything for us.
-    obj = WrapNativeParent(cx, scope, p);
-    if (!obj) {
-      return nullptr;
-    }
-  }
-
-  // But all that won't necessarily put things in the compartment of cx.
-  if (!JS_WrapObject(cx, obj.address())) {
-    return nullptr;
-  }
-
-  return obj;
-}
-
-// Helper for calling WrapNewBindingObject with smart pointers
-// (nsAutoPtr/nsRefPtr/nsCOMPtr) or references.
-template <class T, bool isSmartPtr=HasgetMember<T>::Value>
-struct WrapNewBindingObjectHelper
-{
-  static inline bool Wrap(JSContext* cx, JS::Handle<JSObject*> scope,
-                          const T& value, JS::MutableHandle<JS::Value> rval)
-  {
-    return WrapNewBindingObject(cx, scope, value.get(), rval);
-  }
-};
-
-template <class T>
-struct WrapNewBindingObjectHelper<T, false>
-{
-  static inline bool Wrap(JSContext* cx, JS::Handle<JSObject*> scope, T& value,
-                          JS::MutableHandle<JS::Value> rval)
-  {
-    return WrapNewBindingObject(cx, scope, &value, rval);
-  }
-};
-
-template<class T>
-inline bool
-WrapNewBindingObject(JSContext* cx, JS::Handle<JSObject*> scope, T& value,
-                     JS::MutableHandle<JS::Value> rval)
-{
-  return WrapNewBindingObjectHelper<T>::Wrap(cx, scope, value, rval);
-}
-
-template <class T>
-inline JSObject*
-GetCallbackFromCallbackObject(T* aObj)
-{
-  return aObj->Callback();
-}
-
-// Helper for getting the callback JSObject* of a smart ptr around a
-// CallbackObject or a reference to a CallbackObject or something like
-// that.
-template <class T, bool isSmartPtr=HasgetMember<T>::Value>
-struct GetCallbackFromCallbackObjectHelper
-{
-  static inline JSObject* Get(const T& aObj)
-  {
-    return GetCallbackFromCallbackObject(aObj.get());
-  }
-};
-
-template <class T>
-struct GetCallbackFromCallbackObjectHelper<T, false>
-{
-  static inline JSObject* Get(T& aObj)
-  {
-    return GetCallbackFromCallbackObject(&aObj);
-  }
-};
-
-template<class T>
-inline JSObject*
-GetCallbackFromCallbackObject(T& aObj)
-{
-  return GetCallbackFromCallbackObjectHelper<T>::Get(aObj);
-}
-
-static inline bool
-InternJSString(JSContext* cx, jsid& id, const char* chars)
-{
-  if (JSString *str = ::JS_InternString(cx, chars)) {
-    id = INTERNED_STRING_TO_JSID(cx, str);
-    return true;
-  }
-  return false;
-}
-
-// Spec needs a name property
-template <typename Spec>
-static bool
-InitIds(JSContext* cx, const Prefable<Spec>* prefableSpecs, jsid* ids)
-{
-  MOZ_ASSERT(prefableSpecs);
-  MOZ_ASSERT(prefableSpecs->specs);
-  do {
-    // We ignore whether the set of ids is enabled and just intern all the IDs,
-    // because this is only done once per application runtime.
-    Spec* spec = prefableSpecs->specs;
-    do {
-      if (!InternJSString(cx, *ids, spec->name)) {
-        return false;
-      }
-    } while (++ids, (++spec)->name);
-
-    // We ran out of ids for that pref.  Put a JSID_VOID in on the id
-    // corresponding to the list terminator for the pref.
-    *ids = JSID_VOID;
-    ++ids;
-  } while ((++prefableSpecs)->specs);
-
-  return true;
-}
-
-bool
-QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp);
-
-template <class T, bool isISupports=IsBaseOf<nsISupports, T>::value>
-struct
-WantsQueryInterface
-{
-  static bool Enabled(JSContext* aCx, JSObject* aGlobal)
-  {
-    return false;
-  }
-};
-template <class T>
-struct
-WantsQueryInterface<T, true>
-{
-  static bool Enabled(JSContext* aCx, JSObject* aGlobal)
-  {
-    return IsChromeOrXBL(aCx, aGlobal);
-  }
-};
-
-bool
-ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp);
-
-// vp is allowed to be null; in that case no get will be attempted,
-// and *found will simply indicate whether the property exists.
-bool
-GetPropertyOnPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
-                       JS::Handle<jsid> id, bool* found,
-                       JS::Value* vp);
-
-bool
-HasPropertyOnPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
-                       JS::Handle<jsid> id);
-
-
-// Append the property names in "names" to "props". If
-// shadowPrototypeProperties is false then skip properties that are also
-// present on the proto chain of proxy.  If shadowPrototypeProperties is true,
-// then the "proxy" argument is ignored.
-bool
-AppendNamedPropertyIds(JSContext* cx, JS::Handle<JSObject*> proxy,
-                       nsTArray<nsString>& names,
-                       bool shadowPrototypeProperties, JS::AutoIdVector& props);
-
 template<class T>
 class OwningNonNull
 {
 public:
   OwningNonNull()
 #ifdef DEBUG
-    : inited(false)
+    : mInited(false)
 #endif
   {}
 
-  operator T&() {
-    MOZ_ASSERT(inited);
-    MOZ_ASSERT(ptr, "OwningNonNull<T> was set to null");
-    return *ptr;
+  operator T&()
+  {
+    MOZ_ASSERT(mInited);
+    MOZ_ASSERT(mPtr, "OwningNonNull<T> was set to null");
+    return *mPtr;
   }
 
-  void operator=(T* t) {
-    init(t);
+  void operator=(T* aValue)
+  {
+    init(aValue);
   }
 
-  void operator=(const already_AddRefed<T>& t) {
-    init(t);
+  void operator=(const already_AddRefed<T>& aValue)
+  {
+    init(aValue);
   }
 
-  already_AddRefed<T> forget() {
+  already_AddRefed<T> forget()
+  {
 #ifdef DEBUG
-    inited = false;
+    mInited = false;
 #endif
-    return ptr.forget();
+    return mPtr.forget();
   }
 
-  // Make us work with smart-ptr helpers that expect a get()
-  T* get() const {
-    MOZ_ASSERT(inited);
-    MOZ_ASSERT(ptr);
-    return ptr;
+  // Make us work with smart pointer helpers that expect a get().
+  T* get() const
+  {
+    MOZ_ASSERT(mInited);
+    MOZ_ASSERT(mPtr);
+    return mPtr;
   }
 
 protected:
   template<typename U>
-  void init(U t) {
-    ptr = t;
-    MOZ_ASSERT(ptr);
+  void init(U aValue)
+  {
+    mPtr = aValue;
+    MOZ_ASSERT(mPtr);
 #ifdef DEBUG
-    inited = true;
+    mInited = true;
 #endif
   }
 
-  nsRefPtr<T> ptr;
+  nsRefPtr<T> mPtr;
 #ifdef DEBUG
-  bool inited;
+  bool mInited;
 #endif
 };
 
-// A struct that has the same layout as an nsDependentString but much
-// faster constructor and destructor behavior
-struct FakeDependentString {
-  FakeDependentString() :
-    mFlags(nsDependentString::F_TERMINATED)
-  {
-  }
-
-  void SetData(const nsDependentString::char_type* aData,
-               nsDependentString::size_type aLength) {
-    MOZ_ASSERT(mFlags == nsDependentString::F_TERMINATED);
-    mData = aData;
-    mLength = aLength;
-  }
-
-  void Truncate() {
-    mData = nsDependentString::char_traits::sEmptyBuffer;
-    mLength = 0;
-  }
-
-  void SetNull() {
-    Truncate();
-    mFlags |= nsDependentString::F_VOIDED;
-  }
-
-  const nsDependentString::char_type* Data() const
-  {
-    return mData;
-  }
-
-  nsDependentString::size_type Length() const
-  {
-    return mLength;
-  }
-
-  // If this ever changes, change the corresponding code in the
-  // Optional<nsAString> specialization as well.
-  const nsAString* ToAStringPtr() const {
-    return reinterpret_cast<const nsDependentString*>(this);
-  }
-
-  nsAString* ToAStringPtr() {
-    return reinterpret_cast<nsDependentString*>(this);
-  }
-
-  operator const nsAString& () const {
-    return *reinterpret_cast<const nsDependentString*>(this);
-  }
-
-private:
-  const nsDependentString::char_type* mData;
-  nsDependentString::size_type mLength;
-  uint32_t mFlags;
-
-  // A class to use for our static asserts to ensure our object layout
-  // matches that of nsDependentString.
-  class DependentStringAsserter;
-  friend class DependentStringAsserter;
-
-  class DepedentStringAsserter : public nsDependentString {
-  public:
-    static void StaticAsserts() {
-      static_assert(sizeof(FakeDependentString) == sizeof(nsDependentString),
-                    "Must have right object size");
-      static_assert(offsetof(FakeDependentString, mData) ==
-                      offsetof(DepedentStringAsserter, mData),
-                    "Offset of mData should match");
-      static_assert(offsetof(FakeDependentString, mLength) ==
-                      offsetof(DepedentStringAsserter, mLength),
-                    "Offset of mLength should match");
-      static_assert(offsetof(FakeDependentString, mFlags) ==
-                      offsetof(DepedentStringAsserter, mFlags),
-                    "Offset of mFlags should match");
-    }
-  };
-};
-
-enum StringificationBehavior {
-  eStringify,
-  eEmpty,
-  eNull
-};
-
-// pval must not be null and must point to a rooted JS::Value
-static inline bool
-ConvertJSValueToString(JSContext* cx, JS::Handle<JS::Value> v,
-                       JS::MutableHandle<JS::Value> pval,
-                       StringificationBehavior nullBehavior,
-                       StringificationBehavior undefinedBehavior,
-                       FakeDependentString& result)
-{
-  JSString *s;
-  if (v.isString()) {
-    s = v.toString();
-  } else {
-    StringificationBehavior behavior;
-    if (v.isNull()) {
-      behavior = nullBehavior;
-    } else if (v.isUndefined()) {
-      behavior = undefinedBehavior;
-    } else {
-      behavior = eStringify;
-    }
-
-    if (behavior != eStringify) {
-      if (behavior == eEmpty) {
-        result.Truncate();
-      } else {
-        result.SetNull();
-      }
-      return true;
-    }
-
-    s = JS_ValueToString(cx, v);
-    if (!s) {
-      return false;
-    }
-    pval.set(JS::StringValue(s));  // Root the new string.
-  }
-
-  size_t len;
-  const jschar *chars = JS_GetStringCharsZAndLength(cx, s, &len);
-  if (!chars) {
-    return false;
-  }
-
-  result.SetData(chars, len);
-  return true;
-}
-
-bool
-ConvertJSValueToByteString(JSContext* cx, JS::Handle<JS::Value> v,
-                           JS::MutableHandle<JS::Value> pval, bool nullable,
-                           nsACString& result);
-
-// Class for holding the type of members of a union. The union type has an enum
-// to keep track of which of its UnionMembers has been constructed.
-template<class T>
-class UnionMember {
-    AlignedStorage2<T> storage;
-
-public:
-    T& SetValue() {
-      new (storage.addr()) T();
-      return *storage.addr();
-    }
-    template <typename T1>
-    T& SetValue(const T1 &t1)
-    {
-      new (storage.addr()) T(t1);
-      return *storage.addr();
-    }
-    template <typename T1, typename T2>
-    T& SetValue(const T1 &t1, const T2 &t2)
-    {
-      new (storage.addr()) T(t1, t2);
-      return *storage.addr();
-    }
-    const T& Value() const {
-      return *storage.addr();
-    }
-    void Destroy() {
-      storage.addr()->~T();
-    }
-};
-
-template<typename T>
-void DoTraceSequence(JSTracer* trc, FallibleTArray<T>& seq);
-template<typename T>
-void DoTraceSequence(JSTracer* trc, InfallibleTArray<T>& seq);
-
-// Class for simple sequence arguments, only used internally by codegen.
-template<typename T>
-class AutoSequence : public AutoFallibleTArray<T, 16>
-{
-public:
-  AutoSequence() : AutoFallibleTArray<T, 16>()
-  {}
-
-  // Allow converting to const sequences as needed
-  operator const Sequence<T>&() const {
-    return *reinterpret_cast<const Sequence<T>*>(this);
-  }
-};
-
-// Class used to trace sequences, with specializations for various
-// sequence types.
-template<typename T,
-         bool isDictionary=IsBaseOf<DictionaryBase, T>::value,
-         bool isTypedArray=IsBaseOf<AllTypedArraysBase, T>::value>
-class SequenceTracer
-{
-  explicit SequenceTracer() MOZ_DELETE; // Should never be instantiated
-};
-
-// sequence<object> or sequence<object?>
-template<>
-class SequenceTracer<JSObject*, false, false>
-{
-  explicit SequenceTracer() MOZ_DELETE; // Should never be instantiated
-
-public:
-  static void TraceSequence(JSTracer* trc, JSObject** objp, JSObject** end) {
-    for (; objp != end; ++objp) {
-      JS_CallObjectTracer(trc, objp, "sequence<object>");
-    }
-  }
-};
-
-// sequence<any>
-template<>
-class SequenceTracer<JS::Value, false, false>
-{
-  explicit SequenceTracer() MOZ_DELETE; // Should never be instantiated
-
-public:
-  static void TraceSequence(JSTracer* trc, JS::Value* valp, JS::Value* end) {
-    for (; valp != end; ++valp) {
-      JS_CallValueTracer(trc, valp, "sequence<any>");
-    }
-  }
-};
-
-// sequence<sequence<T>>
-template<typename T>
-class SequenceTracer<Sequence<T>, false, false>
-{
-  explicit SequenceTracer() MOZ_DELETE; // Should never be instantiated
-
-public:
-  static void TraceSequence(JSTracer* trc, Sequence<T>* seqp, Sequence<T>* end) {
-    for (; seqp != end; ++seqp) {
-      DoTraceSequence(trc, *seqp);
-    }
-  }
-};
-
-// sequence<sequence<T>> as return value
-template<typename T>
-class SequenceTracer<nsTArray<T>, false, false>
-{
-  explicit SequenceTracer() MOZ_DELETE; // Should never be instantiated
-
-public:
-  static void TraceSequence(JSTracer* trc, nsTArray<T>* seqp, nsTArray<T>* end) {
-    for (; seqp != end; ++seqp) {
-      DoTraceSequence(trc, *seqp);
-    }
-  }
-};
-
-// sequence<someDictionary>
-template<typename T>
-class SequenceTracer<T, true, false>
-{
-  explicit SequenceTracer() MOZ_DELETE; // Should never be instantiated
-
-public:
-  static void TraceSequence(JSTracer* trc, T* dictp, T* end) {
-    for (; dictp != end; ++dictp) {
-      dictp->TraceDictionary(trc);
-    }
-  }
-};
-
-// sequence<SomeTypedArray>
-template<typename T>
-class SequenceTracer<T, false, true>
-{
-  explicit SequenceTracer() MOZ_DELETE; // Should never be instantiated
-
-public:
-  static void TraceSequence(JSTracer* trc, T* arrayp, T* end) {
-    for (; arrayp != end; ++arrayp) {
-      arrayp->TraceSelf(trc);
-    }
-  }
-};
-
-// sequence<T?> with T? being a Nullable<T>
-template<typename T>
-class SequenceTracer<Nullable<T>, false, false>
-{
-  explicit SequenceTracer() MOZ_DELETE; // Should never be instantiated
-
-public:
-  static void TraceSequence(JSTracer* trc, Nullable<T>* seqp,
-                            Nullable<T>* end) {
-    for (; seqp != end; ++seqp) {
-      if (!seqp->IsNull()) {
-        // Pretend like we actually have a length-one sequence here so
-        // we can do template instantiation correctly for T.
-        T& val = seqp->Value();
-        T* ptr = &val;
-        SequenceTracer<T>::TraceSequence(trc, ptr, ptr+1);
-      }
-    }
-  }
-};
-
-template<typename T>
-void DoTraceSequence(JSTracer* trc, FallibleTArray<T>& seq)
-{
-  SequenceTracer<T>::TraceSequence(trc, seq.Elements(),
-                                   seq.Elements() + seq.Length());
-}
-
-template<typename T>
-void DoTraceSequence(JSTracer* trc, InfallibleTArray<T>& seq)
-{
-  SequenceTracer<T>::TraceSequence(trc, seq.Elements(),
-                                   seq.Elements() + seq.Length());
-}
-
-// Rooter class for sequences; this is what we mostly use in the codegen
-template<typename T>
-class MOZ_STACK_CLASS SequenceRooter : private JS::CustomAutoRooter
-{
-public:
-  SequenceRooter(JSContext *aCx, FallibleTArray<T>* aSequence
-                 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-    : JS::CustomAutoRooter(aCx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
-      mFallibleArray(aSequence),
-      mSequenceType(eFallibleArray)
-  {
-  }
-
-  SequenceRooter(JSContext *aCx, InfallibleTArray<T>* aSequence
-                 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-    : JS::CustomAutoRooter(aCx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
-      mInfallibleArray(aSequence),
-      mSequenceType(eInfallibleArray)
-  {
-  }
-
-  SequenceRooter(JSContext *aCx, Nullable<nsTArray<T> >* aSequence
-                 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-    : JS::CustomAutoRooter(aCx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
-      mNullableArray(aSequence),
-      mSequenceType(eNullableArray)
-  {
-  }
-
- private:
-  enum SequenceType {
-    eInfallibleArray,
-    eFallibleArray,
-    eNullableArray
-  };
-
-  virtual void trace(JSTracer *trc) MOZ_OVERRIDE
-  {
-    if (mSequenceType == eFallibleArray) {
-      DoTraceSequence(trc, *mFallibleArray);
-    } else if (mSequenceType == eInfallibleArray) {
-      DoTraceSequence(trc, *mInfallibleArray);
-    } else {
-      MOZ_ASSERT(mSequenceType == eNullableArray);
-      if (!mNullableArray->IsNull()) {
-        DoTraceSequence(trc, mNullableArray->Value());
-      }
-    }
-  }
-
-  union {
-    InfallibleTArray<T>* mInfallibleArray;
-    FallibleTArray<T>* mFallibleArray;
-    Nullable<nsTArray<T> >* mNullableArray;
-  };
-
-  SequenceType mSequenceType;
-};
-
-template<typename T>
-class MOZ_STACK_CLASS RootedDictionary : public T,
-                                         private JS::CustomAutoRooter
-{
-public:
-  RootedDictionary(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
-    T(),
-    JS::CustomAutoRooter(cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)
-  {
-  }
-
-  virtual void trace(JSTracer *trc) MOZ_OVERRIDE
-  {
-    this->TraceDictionary(trc);
-  }
-};
-
-template<typename T>
-class MOZ_STACK_CLASS NullableRootedDictionary : public Nullable<T>,
-                                                 private JS::CustomAutoRooter
-{
-public:
-  NullableRootedDictionary(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
-    Nullable<T>(),
-    JS::CustomAutoRooter(cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)
-  {
-  }
-
-  virtual void trace(JSTracer *trc) MOZ_OVERRIDE
-  {
-    if (!this->IsNull()) {
-      this->Value().TraceDictionary(trc);
-    }
-  }
-};
-
-inline bool
-IdEquals(jsid id, const char* string)
-{
-  return JSID_IS_STRING(id) &&
-         JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), string);
-}
-
-inline bool
-AddStringToIDVector(JSContext* cx, JS::AutoIdVector& vector, const char* name)
-{
-  return vector.growBy(1) &&
-         InternJSString(cx, vector[vector.length() - 1], name);
-}
-
-// Implementation of the bits that XrayWrapper needs
-
-/**
- * This resolves indexed or named properties of obj.
- *
- * wrapper is the Xray JS object.
- * obj is the target object of the Xray, a binding's instance object or a
- *     interface or interface prototype object.
- */
-bool
-XrayResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
-                       JS::Handle<JSObject*> obj,
-                       JS::Handle<jsid> id,
-                       JS::MutableHandle<JSPropertyDescriptor> desc, unsigned flags);
-
-/**
- * This resolves operations, attributes and constants of the interfaces for obj.
- *
- * wrapper is the Xray JS object.
- * obj is the target object of the Xray, a binding's instance object or a
- *     interface or interface prototype object.
- */
-bool
-XrayResolveNativeProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
-                          JS::Handle<JSObject*> obj,
-                          JS::Handle<jsid> id, JS::MutableHandle<JSPropertyDescriptor> desc);
-
-/**
- * Define a property on obj through an Xray wrapper.
- *
- * wrapper is the Xray JS object.
- * obj is the target object of the Xray, a binding's instance object or a
- *     interface or interface prototype object.
- * defined will be set to true if a property was set as a result of this call.
- */
-bool
-XrayDefineProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
-                   JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
-                   JS::MutableHandle<JSPropertyDescriptor> desc, bool* defined);
-
-/**
- * This enumerates indexed or named properties of obj and operations, attributes
- * and constants of the interfaces for obj.
- *
- * wrapper is the Xray JS object.
- * obj is the target object of the Xray, a binding's instance object or a
- *     interface or interface prototype object.
- * flags are JSITER_* flags.
- */
-bool
-XrayEnumerateProperties(JSContext* cx, JS::Handle<JSObject*> wrapper,
-                        JS::Handle<JSObject*> obj,
-                        unsigned flags, JS::AutoIdVector& props);
-
-extern NativePropertyHooks sWorkerNativePropertyHooks;
-
-// We use one constructor JSNative to represent all DOM interface objects (so
-// we can easily detect when we need to wrap them in an Xray wrapper). We store
-// the real JSNative in the mNative member of a JSNativeHolder in the
-// CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT slot of the JSFunction object for a
-// specific interface object. We also store the NativeProperties in the
-// JSNativeHolder. The CONSTRUCTOR_XRAY_EXPANDO_SLOT is used to store the
-// expando chain of the Xray for the interface object.
-// Note that some interface objects are not yet a JSFunction but a normal
-// JSObject with a DOMJSClass, those do not use these slots.
-
-enum {
-  CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT = 0,
-  CONSTRUCTOR_XRAY_EXPANDO_SLOT
-};
-
-bool
-Constructor(JSContext* cx, unsigned argc, JS::Value* vp);
-
-inline bool
-UseDOMXray(JSObject* obj)
-{
-  const js::Class* clasp = js::GetObjectClass(obj);
-  return IsDOMClass(clasp) ||
-         IsDOMProxy(obj, clasp) ||
-         JS_IsNativeFunction(obj, Constructor) ||
-         IsDOMIfaceAndProtoClass(clasp);
-}
-
-#ifdef DEBUG
-inline bool
-HasConstructor(JSObject* obj)
-{
-  return JS_IsNativeFunction(obj, Constructor) ||
-         js::GetObjectClass(obj)->construct;
-}
- #endif
- 
-// Transfer reference in ptr to smartPtr.
-template<class T>
-inline void
-Take(nsRefPtr<T>& smartPtr, T* ptr)
-{
-  smartPtr = dont_AddRef(ptr);
-}
-
-// Transfer ownership of ptr to smartPtr.
-template<class T>
-inline void
-Take(nsAutoPtr<T>& smartPtr, T* ptr)
-{
-  smartPtr = ptr;
-}
-
-inline void
-MustInheritFromNonRefcountedDOMObject(NonRefcountedDOMObject*)
-{
-}
-
-// Set the chain of expando objects for various consumers of the given object.
-// For Paris Bindings only. See the relevant infrastructure in XrayWrapper.cpp.
-JSObject* GetXrayExpandoChain(JSObject *obj);
-void SetXrayExpandoChain(JSObject *obj, JSObject *chain);
-
-/**
- * This creates a JSString containing the value that the toString function for
- * obj should create according to the WebIDL specification, ignoring any
- * modifications by script. The value is prefixed with pre and postfixed with
- * post, unless this is called for an object that has a stringifier. It is
- * specifically for use by Xray code.
- *
- * wrapper is the Xray JS object.
- * obj is the target object of the Xray, a binding's instance object or a
- *     interface or interface prototype object.
- * pre is a string that should be prefixed to the value.
- * post is a string that should be prefixed to the value.
- * v contains the JSString for the value if the function returns true.
- */
-bool
-NativeToString(JSContext* cx, JS::Handle<JSObject*> wrapper,
-               JS::Handle<JSObject*> obj, const char* pre,
-               const char* post, JS::Value* v);
-
-HAS_MEMBER(JSBindingFinalized)
-
-template<class T, bool hasCallback=HasJSBindingFinalizedMember<T>::Value>
-struct JSBindingFinalized
-{
-  static void Finalized(T* self)
-  {
-  }
-};
-
-template<class T>
-struct JSBindingFinalized<T, true>
-{
-  static void Finalized(T* self)
-  {
-    self->JSBindingFinalized();
-  }
-};
-
-// Helpers for creating a const version of a type.
-template<typename T>
-const T& Constify(T& arg)
-{
-  return arg;
-}
-
-// Helper for turning (Owning)NonNull<T> into T&
-template<typename T>
-T& NonNullHelper(T& aArg)
-{
-  return aArg;
-}
-
-template<typename T>
-T& NonNullHelper(NonNull<T>& aArg)
-{
-  return aArg;
-}
-
-template<typename T>
-const T& NonNullHelper(const NonNull<T>& aArg)
-{
-  return aArg;
-}
-
-template<typename T>
-T& NonNullHelper(OwningNonNull<T>& aArg)
-{
-  return aArg;
-}
-
-template<typename T>
-const T& NonNullHelper(const OwningNonNull<T>& aArg)
-{
-  return aArg;
-}
-
-// Reparent the wrapper of aObj to whatever its native now thinks its
-// parent should be.
-nsresult
-ReparentWrapper(JSContext* aCx, JS::HandleObject aObj);
-
-/**
- * Used to implement the hasInstance hook of an interface object.
- *
- * instance should not be a security wrapper.
- */
-bool
-InterfaceHasInstance(JSContext* cx, JS::Handle<JSObject*> obj,
-                     JS::Handle<JSObject*> instance,
-                     bool* bp);
-bool
-InterfaceHasInstance(JSContext* cx, JS::Handle<JSObject*> obj, JS::MutableHandle<JS::Value> vp,
-                     bool* bp);
-bool
-InterfaceHasInstance(JSContext* cx, int prototypeID, int depth,
-                     JS::Handle<JSObject*> instance,
-                     bool* bp);
-
-// Helper for lenient getters/setters to report to console.  If this
-// returns false, we couldn't even get a global.
-bool
-ReportLenientThisUnwrappingFailure(JSContext* cx, JS::Handle<JSObject*> obj);
-
-inline JSObject*
-GetUnforgeableHolder(JSObject* aGlobal, prototypes::ID aId)
-{
-  JS::Heap<JSObject*>* protoAndIfaceArray = GetProtoAndIfaceArray(aGlobal);
-  JSObject* interfaceProto = protoAndIfaceArray[aId];
-  return &js::GetReservedSlot(interfaceProto,
-                              DOM_INTERFACE_PROTO_SLOTS_BASE).toObject();
-}
-
-// Given a JSObject* that represents the chrome side of a JS-implemented WebIDL
-// interface, get the nsPIDOMWindow corresponding to the content side, if any.
-// A false return means an exception was thrown.
-bool
-GetWindowForJSImplementedObject(JSContext* cx, JS::Handle<JSObject*> obj,
-                                nsPIDOMWindow** window);
-
-already_AddRefed<nsPIDOMWindow>
-ConstructJSImplementation(JSContext* aCx, const char* aContractId,
-                          const GlobalObject& aGlobal,
-                          JS::MutableHandle<JSObject*> aObject,
-                          ErrorResult& aRv);
-
-/**
- * Convert an nsCString to jsval, returning true on success.
- * These functions are intended for ByteString implementations.
- * As such, the string is not UTF-8 encoded.  Any UTF8 strings passed to these
- * methods will be mangled.
- */
-bool NonVoidByteStringToJsval(JSContext *cx, const nsACString &str,
-                              JS::MutableHandle<JS::Value> rval);
-inline bool ByteStringToJsval(JSContext *cx, const nsACString &str,
-                              JS::MutableHandle<JS::Value> rval)
-{
-    if (str.IsVoid()) {
-        rval.setNull();
-        return true;
-    }
-    return NonVoidByteStringToJsval(cx, str, rval);
-}
-
-template<class T, bool isISupports=IsBaseOf<nsISupports, T>::value>
-struct PreserveWrapperHelper
-{
-  static void PreserveWrapper(T* aObject)
-  {
-    aObject->PreserveWrapper(aObject, NS_CYCLE_COLLECTION_PARTICIPANT(T));
-  }
-};
-
-template<class T>
-struct PreserveWrapperHelper<T, true>
-{
-  static void PreserveWrapper(T* aObject)
-  {
-    aObject->PreserveWrapper(reinterpret_cast<nsISupports*>(aObject));
-  }
-};
-
-template<class T>
-void PreserveWrapper(T* aObject)
-{
-  PreserveWrapperHelper<T>::PreserveWrapper(aObject);
-}
-
-template<class T, bool isISupports=IsBaseOf<nsISupports, T>::value>
-struct CastingAssertions
-{
-  static bool ToSupportsIsCorrect(T*)
-  {
-    return true;
-  }
-  static bool ToSupportsIsOnPrimaryInheritanceChain(T*, nsWrapperCache*)
-  {
-    return true;
-  }
-};
-
-template<class T>
-struct CastingAssertions<T, true>
-{
-  static bool ToSupportsIsCorrect(T* aObject)
-  {
-    return ToSupports(aObject) ==  reinterpret_cast<nsISupports*>(aObject);
-  }
-  static bool ToSupportsIsOnPrimaryInheritanceChain(T* aObject,
-                                                    nsWrapperCache* aCache)
-  {
-    return reinterpret_cast<void*>(aObject) != aCache;
-  }
-};
-
-template<class T>
-bool
-ToSupportsIsCorrect(T* aObject)
-{
-  return CastingAssertions<T>::ToSupportsIsCorrect(aObject);
-}
-
-template<class T>
-bool
-ToSupportsIsOnPrimaryInheritanceChain(T* aObject, nsWrapperCache* aCache)
-{
-  return CastingAssertions<T>::ToSupportsIsOnPrimaryInheritanceChain(aObject,
-                                                                     aCache);
-}
-
-template<class T, template <typename> class SmartPtr,
-         bool isISupports=IsBaseOf<nsISupports, T>::value>
-class DeferredFinalizer
-{
-  typedef nsTArray<SmartPtr<T> > SmartPtrArray;
-
-  static void*
-  AppendDeferredFinalizePointer(void* aData, void* aObject)
-  {
-    SmartPtrArray* pointers = static_cast<SmartPtrArray*>(aData);
-    if (!pointers) {
-      pointers = new SmartPtrArray();
-    }
-
-    T* self = static_cast<T*>(aObject);
-
-    SmartPtr<T>* defer = pointers->AppendElement();
-    Take(*defer, self);
-    return pointers;
-  }
-  static bool
-  DeferredFinalize(uint32_t aSlice, void* aData)
-  {
-    MOZ_ASSERT(aSlice > 0, "nonsensical/useless call with aSlice == 0");
-    SmartPtrArray* pointers = static_cast<SmartPtrArray*>(aData);
-    uint32_t oldLen = pointers->Length();
-    aSlice = std::min(oldLen, aSlice);
-    uint32_t newLen = oldLen - aSlice;
-    pointers->RemoveElementsAt(newLen, aSlice);
-    if (newLen == 0) {
-      delete pointers;
-      return true;
-    }
-    return false;
-  }
-
-public:
-  static void
-  AddForDeferredFinalization(T* aObject)
-  {
-    cyclecollector::DeferredFinalize(AppendDeferredFinalizePointer,
-                                     DeferredFinalize, aObject);
-  }
-};
-
-template<class T, template <typename> class SmartPtr>
-class DeferredFinalizer<T, SmartPtr, true>
-{
-public:
-  static void
-  AddForDeferredFinalization(T* aObject)
-  {
-    cyclecollector::DeferredFinalize(reinterpret_cast<nsISupports*>(aObject));
-  }
-};
-
-template<class T, template <typename> class SmartPtr>
-static void
-AddForDeferredFinalization(T* aObject)
-{
-  DeferredFinalizer<T, SmartPtr>::AddForDeferredFinalization(aObject);
-}
-
-// This returns T's CC participant if it participates in CC or null if it
-// doesn't. This also returns null for classes that don't inherit from
-// nsISupports (QI should be used to get the participant for those).
-template<class T, bool isISupports=IsBaseOf<nsISupports, T>::value>
-class GetCCParticipant
-{
-  // Helper for GetCCParticipant for classes that participate in CC.
-  template<class U>
-  static MOZ_CONSTEXPR nsCycleCollectionParticipant*
-  GetHelper(int, typename U::NS_CYCLE_COLLECTION_INNERCLASS* dummy=nullptr)
-  {
-    return T::NS_CYCLE_COLLECTION_INNERCLASS::GetParticipant();
-  }
-  // Helper for GetCCParticipant for classes that don't participate in CC.
-  template<class U>
-  static MOZ_CONSTEXPR nsCycleCollectionParticipant*
-  GetHelper(double)
-  {
-    return nullptr;
-  }
-
-public:
-  static MOZ_CONSTEXPR nsCycleCollectionParticipant*
-  Get()
-  {
-    // Passing int() here will try to call the GetHelper that takes an int as
-    // its firt argument. If T doesn't participate in CC then substitution for
-    // the second argument (with a default value) will fail and because of
-    // SFINAE the next best match (the variant taking a double) will be called.
-    return GetHelper<T>(int());
-  }
-};
-
-template<class T>
-class GetCCParticipant<T, true>
-{
-public:
-  static MOZ_CONSTEXPR nsCycleCollectionParticipant*
-  Get()
-  {
-    return nullptr;
-  }
-};
-
-bool
-ThreadsafeCheckIsChrome(JSContext* aCx, JSObject* aObj);
-
 } // namespace dom
 } // namespace mozilla
 
-#endif /* mozilla_dom_BindingUtils_h__ */
+#endif // mozilla_dom_OwningNonNull_h
new file mode 100644
--- /dev/null
+++ b/dom/bindings/UnionMember.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+/* A class for holding the members of a union. */
+
+#ifndef mozilla_dom_UnionMember_h
+#define mozilla_dom_UnionMember_h
+
+#include "mozilla/Alignment.h"
+
+namespace mozilla {
+namespace dom {
+
+// The union type has an enum to keep track of which of its UnionMembers has
+// been constructed.
+template<class T>
+class UnionMember
+{
+  AlignedStorage2<T> mStorage;
+
+public:
+  T& SetValue()
+  {
+    new (mStorage.addr()) T();
+    return *mStorage.addr();
+  }
+  template <typename T1>
+  T& SetValue(const T1& aValue)
+  {
+    new (mStorage.addr()) T(aValue);
+    return *mStorage.addr();
+  }
+  template<typename T1, typename T2>
+  T& SetValue(const T1& aValue1, const T2& aValue2)
+  {
+    new (mStorage.addr()) T(aValue1, aValue2);
+    return *mStorage.addr();
+  }
+  T& Value()
+  {
+    return *mStorage.addr();
+  }
+  const T& Value() const
+  {
+    return *mStorage.addr();
+  }
+  void Destroy()
+  {
+    mStorage.addr()->~T();
+  }
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_UnionMember_h
--- a/dom/bindings/moz.build
+++ b/dom/bindings/moz.build
@@ -20,18 +20,20 @@ EXPORTS.mozilla.dom += [
     'DOMJSClass.h',
     'DOMJSProxyHandler.h',
     'Date.h',
     'Errors.msg',
     'Exceptions.h',
     'JSSlots.h',
     'NonRefcountedDOMObject.h',
     'Nullable.h',
+    'OwningNonNull.h',
     'PrimitiveConversions.h',
     'TypedArray.h',
+    'UnionMember.h',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 MSVC_ENABLE_PGO = True
 
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -2559,16 +2559,18 @@ class IDLAttribute(IDLInterfaceMember):
         assert isinstance(type, IDLType)
         self.type = type
         self.readonly = readonly
         self.inherit = inherit
         self.static = static
         self.lenientThis = False
         self._unforgeable = False
         self.stringifier = stringifier
+        self.enforceRange = False
+        self.clamp = False
 
         if static and identifier.name == "prototype":
             raise WebIDLError("The identifier of a static attribute must not be 'prototype'",
                               [location])
 
         if readonly and inherit:
             raise WebIDLError("An attribute cannot be both 'readonly' and 'inherit'",
                               [self.location])
@@ -2682,16 +2684,26 @@ class IDLAttribute(IDLInterfaceMember):
         elif identifier == "LenientFloat":
             if self.readonly:
                 raise WebIDLError("[LenientFloat] used on a readonly attribute",
                                   [attr.location, self.location])
             if not self.type.includesRestrictedFloat():
                 raise WebIDLError("[LenientFloat] used on an attribute with a "
                                   "non-restricted-float type",
                                   [attr.location, self.location])
+        elif identifier == "EnforceRange":
+            if self.readonly:
+                raise WebIDLError("[EnforceRange] used on a readonly attribute",
+                                  [attr.location, self.location])
+            self.enforceRange = True
+        elif identifier == "Clamp":
+            if self.readonly:
+                raise WebIDLError("[Clamp] used on a readonly attribute",
+                                  [attr.location, self.location])
+            self.clamp = True
         elif (identifier == "Pref" or
               identifier == "SetterThrows" or
               identifier == "Pure" or
               identifier == "Throws" or
               identifier == "GetterThrows" or
               identifier == "ChromeOnly" or
               identifier == "SameObject" or
               identifier == "Constant" or
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -681,16 +681,20 @@ public:
   void SetIndirectlyImplementedProperty(bool);
   void IndirectlyImplementedMethod();
   uint32_t DiamondImplementedProperty();
 
   // Test EnforceRange/Clamp
   void DontEnforceRangeOrClamp(int8_t);
   void DoEnforceRange(int8_t);
   void DoClamp(int8_t);
+  void SetEnforcedByte(int8_t);
+  int8_t EnforcedByte();
+  void SetClampedByte(int8_t);
+  int8_t ClampedByte();
 
 private:
   // We add signatures here that _could_ start matching if the codegen
   // got data types wrong.  That way if it ever does we'll have a call
   // to these private deleted methods and compilation will fail.
   void SetReadonlyByte(int8_t) MOZ_DELETE;
   template<typename T>
   void SetWritableByte(T) MOZ_DELETE;
--- a/dom/bindings/test/TestCodeGen.webidl
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -531,16 +531,18 @@ interface TestInterface {
   void passDictContainingDict(optional DictContainingDict arg);
   void passDictContainingSequence(optional DictContainingSequence arg);
   DictContainingSequence receiveDictContainingSequence();
 
   // EnforceRange/Clamp tests
   void dontEnforceRangeOrClamp(byte arg);
   void doEnforceRange([EnforceRange] byte arg);
   void doClamp([Clamp] byte arg);
+  [EnforceRange] attribute byte enforcedByte;
+  [Clamp] attribute byte clampedByte;
 
   // Typedefs
   const myLong myLongConstant = 5;
   void exerciseTypedefInterfaces1(AnotherNameForTestInterface arg);
   AnotherNameForTestInterface exerciseTypedefInterfaces2(NullableTestInterface arg);
   void exerciseTypedefInterfaces3(YetAnotherNameForTestInterface arg);
 
   // Static methods and attributes
@@ -702,16 +704,18 @@ DiamondBranch1A implements DiamondImplem
 DiamondBranch1B implements DiamondImplements;
 
 dictionary Dict : ParentDict {
   TestEnum someEnum;
   long x;
   long a;
   long b = 8;
   long z = 9;
+  [EnforceRange] unsigned long enforcedUnsignedLong;
+  [Clamp] unsigned long clampedUnsignedLong;
   DOMString str;
   DOMString empty = "";
   TestEnum otherEnum = "b";
   DOMString otherStr = "def";
   DOMString? yetAnotherStr = null;
   DOMString template;
   object someObj;
   boolean prototype;
@@ -731,16 +735,18 @@ dictionary Dict : ParentDict {
   unrestricted double  urDouble = 0;
   unrestricted double  urDouble2 = 1.1;
   unrestricted double  urDouble3 = -1.1;
   unrestricted double? urDouble4 = null;
   unrestricted double  infUrDouble = Infinity;
   unrestricted double  negativeInfUrDouble = -Infinity;
   unrestricted double  nanUrDouble = NaN;
 
+  (float or DOMString) floatOrString = "str";
+
   ArrayBuffer arrayBuffer;
   ArrayBuffer? nullableArrayBuffer;
   Uint8Array uint8Array;
   Float64Array? float64Array = null;
 };
 
 dictionary ParentDict : GrandparentDict {
   long c = 5;
@@ -759,16 +765,17 @@ dictionary DictContainingSequence {
   sequence<TestInterface> ourSequence2;
   sequence<any> ourSequence3;
   sequence<object> ourSequence4;
   sequence<object?> ourSequence5;
   sequence<object>? ourSequence6;
   sequence<object?>? ourSequence7;
   sequence<object>? ourSequence8 = null;
   sequence<object?>? ourSequence9 = null;
+  sequence<(float or DOMString)> ourSequence10;
 };
 
 dictionary DictForConstructor {
   Dict dict;
   DictContainingDict dict2;
   sequence<Dict> seq1;
   sequence<sequence<Dict>>? seq2;
   sequence<sequence<Dict>?> seq3;
--- a/dom/bindings/test/TestExampleGen.webidl
+++ b/dom/bindings/test/TestExampleGen.webidl
@@ -428,16 +428,18 @@ interface TestExampleInterface {
   void passDictContainingDict(optional DictContainingDict arg);
   void passDictContainingSequence(optional DictContainingSequence arg);
   //UNSUPPORTED DictContainingSequence receiveDictContainingSequence();
 
   // EnforceRange/Clamp tests
   void dontEnforceRangeOrClamp(byte arg);
   void doEnforceRange([EnforceRange] byte arg);
   void doClamp([Clamp] byte arg);
+  [EnforceRange] attribute byte enforcedByte;
+  [Clamp] attribute byte clampedByte;
 
   // Typedefs
   const myLong myLongConstant = 5;
   void exerciseTypedefInterfaces1(AnotherNameForTestInterface arg);
   AnotherNameForTestInterface exerciseTypedefInterfaces2(NullableTestInterface arg);
   void exerciseTypedefInterfaces3(YetAnotherNameForTestInterface arg);
 
   // Static methods and attributes
--- a/dom/bindings/test/TestJSImplGen.webidl
+++ b/dom/bindings/test/TestJSImplGen.webidl
@@ -453,16 +453,18 @@ interface TestJSImplInterface {
   void passDictContainingSequence(optional DictContainingSequence arg);
   // FIXME: Bug 863949 no dictionary return values
   //   DictContainingSequence receiveDictContainingSequence();
 
   // EnforceRange/Clamp tests
   void dontEnforceRangeOrClamp(byte arg);
   void doEnforceRange([EnforceRange] byte arg);
   void doClamp([Clamp] byte arg);
+  [EnforceRange] attribute byte enforcedByte;
+  [Clamp] attribute byte clampedByte;
 
   // Typedefs
   const myLong myLongConstant = 5;
   void exerciseTypedefInterfaces1(AnotherNameForTestJSImplInterface arg);
   AnotherNameForTestJSImplInterface exerciseTypedefInterfaces2(NullableTestJSImplInterface arg);
   void exerciseTypedefInterfaces3(YetAnotherNameForTestJSImplInterface arg);
 
   // Static methods and attributes
--- a/dom/promise/Promise.cpp
+++ b/dom/promise/Promise.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #include "mozilla/dom/Promise.h"
 
 #include "jsfriendapi.h"
+#include "mozilla/dom/OwningNonNull.h"
 #include "mozilla/dom/PromiseBinding.h"
 #include "mozilla/dom/PromiseResolver.h"
 #include "mozilla/Preferences.h"
 #include "PromiseCallback.h"
 #include "nsContentUtils.h"
 #include "nsPIDOMWindow.h"
 #include "WorkerPrivate.h"
 #include "nsJSPrincipals.h"
--- a/dom/src/notification/Notification.cpp
+++ b/dom/src/notification/Notification.cpp
@@ -1,14 +1,15 @@
 /* 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/. */
 
 #include "PCOMContentPermissionRequestChild.h"
 #include "mozilla/dom/Notification.h"
+#include "mozilla/dom/OwningNonNull.h"
 #include "mozilla/Preferences.h"
 #include "TabChild.h"
 #include "nsContentUtils.h"
 #include "nsDOMEvent.h"
 #include "nsIAlertsService.h"
 #include "nsIContentPermissionPrompt.h"
 #include "nsIDocument.h"
 #include "nsIPermissionManager.h"
--- a/dom/workers/EventTarget.cpp
+++ b/dom/workers/EventTarget.cpp
@@ -1,18 +1,20 @@
 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
 /* 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/. */
 
 #include "EventTarget.h"
+#include "mozilla/dom/EventListenerBinding.h"
 
 USING_WORKERS_NAMESPACE
 using mozilla::ErrorResult;
-using namespace mozilla::dom;
+using mozilla::dom::EventListener;
+using mozilla::dom::Nullable;
 
 void
 EventTarget::_trace(JSTracer* aTrc)
 {
   mListenerManager._trace(aTrc);
   DOMBindingBase::_trace(aTrc);
 }
 
@@ -53,17 +55,17 @@ EventTarget::SetEventListener(const nsAS
   }
 
   mListenerManager.SetEventListener(cx, INTERNED_STRING_TO_JSID(cx, type),
                                     aListener, aRv);
 }
 
 void
 EventTarget::AddEventListener(const nsAString& aType,
-                              JS::Handle<JSObject*> aListener,
+                              EventListener* aListener,
                               bool aCapturing, Nullable<bool> aWantsUntrusted,
                               ErrorResult& aRv)
 {
   if (!aListener) {
     return;
   }
 
   JSContext* cx = GetJSContext();
@@ -72,33 +74,33 @@ EventTarget::AddEventListener(const nsAS
     JS_NewUCStringCopyN(cx, aType.BeginReading(), aType.Length());
   if (!type || !(type = JS_InternJSString(cx, type))) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
 
   bool wantsUntrusted = !aWantsUntrusted.IsNull() && aWantsUntrusted.Value();
   mListenerManager.AddEventListener(cx, INTERNED_STRING_TO_JSID(cx, type),
-                                    aListener, aCapturing, wantsUntrusted,
-                                    aRv);
+                                    aListener->Callback(), aCapturing,
+                                    wantsUntrusted, aRv);
 }
 
 void
 EventTarget::RemoveEventListener(const nsAString& aType,
-                                 JS::Handle<JSObject*> aListener,
+                                 EventListener* aListener,
                                  bool aCapturing, ErrorResult& aRv)
 {
   if (!aListener) {
     return;
   }
 
   JSContext* cx = GetJSContext();
 
   JSString* type =
     JS_NewUCStringCopyN(cx, aType.BeginReading(), aType.Length());
   if (!type || !(type = JS_InternJSString(cx, type))) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
 
   mListenerManager.RemoveEventListener(cx, INTERNED_STRING_TO_JSID(cx, type),
-                                       aListener, aCapturing);
+                                       aListener->Callback(), aCapturing);
 }
--- a/dom/workers/EventTarget.h
+++ b/dom/workers/EventTarget.h
@@ -9,16 +9,21 @@
 #include "mozilla/dom/workers/bindings/DOMBindingBase.h"
 
 // I hate having to export this...
 #include "mozilla/dom/workers/bindings/EventListenerManager.h"
 
 #include "mozilla/dom/Nullable.h"
 #include "mozilla/ErrorResult.h"
 
+namespace mozilla {
+namespace dom {
+class EventListener;
+} // namespace mozilla
+} // namespace dom
 
 BEGIN_WORKERS_NAMESPACE
 
 class EventTarget : public DOMBindingBase
 {
   EventListenerManager mListenerManager;
 
 protected:
@@ -32,22 +37,22 @@ protected:
 public:
   virtual void
   _trace(JSTracer* aTrc) MOZ_OVERRIDE;
 
   virtual void
   _finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
 
   void
-  AddEventListener(const nsAString& aType, JS::Handle<JSObject*> aListener,
+  AddEventListener(const nsAString& aType, EventListener* aListener,
                    bool aCapture, Nullable<bool> aWantsUntrusted,
                    ErrorResult& aRv);
 
   void
-  RemoveEventListener(const nsAString& aType, JS::Handle<JSObject*> aListener,
+  RemoveEventListener(const nsAString& aType, EventListener* aListener,
                       bool aCapture, ErrorResult& aRv);
 
   bool
   DispatchEvent(JS::Handle<JSObject*> aEvent, ErrorResult& aRv) const
   {
     return mListenerManager.DispatchEvent(GetJSContext(), *this, aEvent, aRv);
   }
 
--- a/dom/workers/Events.cpp
+++ b/dom/workers/Events.cpp
@@ -2,47 +2,42 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #include "mozilla/Util.h"
 
 #include "Events.h"
+#include "mozilla/dom/BindingUtils.h"
 
 #include "jsapi.h"
 #include "jsfriendapi.h"
 
 #include "nsTraceRefcnt.h"
 
 #include "WorkerInlines.h"
 #include "WorkerPrivate.h"
 
-#define PROPERTY_FLAGS \
-  (JSPROP_ENUMERATE | JSPROP_SHARED)
-
 #define FUNCTION_FLAGS \
   JSPROP_ENUMERATE
 
-#define CONSTANT_FLAGS \
-  JSPROP_ENUMERATE | JSPROP_SHARED | JSPROP_PERMANENT | JSPROP_READONLY
-
 using namespace mozilla;
 USING_WORKERS_NAMESPACE
 
 namespace {
 
 class Event : public PrivatizableBase
 {
   static JSClass sClass;
   static JSClass sMainRuntimeClass;
 
   static const JSPropertySpec sProperties[];
   static const JSFunctionSpec sFunctions[];
-  static const JSPropertySpec sStaticProperties[];
+  static const dom::ConstantSpec sStaticConstants[];
 
 protected:
   bool mStopPropagationCalled;
   bool mStopImmediatePropagationCalled;
 
 public:
   static bool
   IsThisClass(JSClass* aClass)
@@ -72,19 +67,28 @@ public:
           parentProto = JSVAL_TO_OBJECT(protoVal);
         }
       }
     }
 
     JSClass* clasp = parentProto ? &sMainRuntimeClass : &sClass;
 
     JS::Rooted<JSObject*> proto(aCx, JS_InitClass(aCx, aObj, parentProto, clasp, Construct, 0,
-                                                  sProperties, sFunctions, sStaticProperties,
-                                                  nullptr));
-    if (proto && !JS_DefineProperties(aCx, proto, sStaticProperties)) {
+                                                  sProperties, sFunctions, nullptr, nullptr));
+    if (!proto) {
+      return NULL;
+    }
+
+    JS::Rooted<JSObject*> ctor(aCx, JS_GetConstructor(aCx, proto));
+    if (!ctor) {
+      return NULL;
+    }
+
+    if (!dom::DefineConstants(aCx, ctor, sStaticConstants) ||
+        !dom::DefineConstants(aCx, proto, sStaticConstants)) {
       return NULL;
     }
 
     return proto;
   }
 
   static JSObject*
   Create(JSContext* aCx, JS::Handle<JSObject*> aParent, JS::Handle<JSString*> aType,
@@ -140,17 +144,17 @@ protected:
     MOZ_COUNT_CTOR(mozilla::dom::workers::Event);
   }
 
   virtual ~Event()
   {
     MOZ_COUNT_DTOR(mozilla::dom::workers::Event);
   }
 
-  enum {
+  enum EventPhase {
     CAPTURING_PHASE = 1,
     AT_TARGET = 2,
     BUBBLING_PHASE = 3
   };
 
   enum SLOT {
     SLOT_type = 0,
     SLOT_target,
@@ -215,43 +219,43 @@ private:
   static void
   Finalize(JSFreeOp* aFop, JSObject* aObj)
   {
     JS_ASSERT(IsThisClass(JS_GetClass(aObj)));
     delete GetJSPrivateSafeish<Event>(aObj);
   }
 
   static bool
-  GetProperty(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-              JS::MutableHandle<JS::Value> aVp)
+  IsEvent(JS::Handle<JS::Value> v)
   {
-    JS_ASSERT(JSID_IS_INT(aIdval));
-
-    int32_t slot = JSID_TO_INT(aIdval);
+    return v.isObject() && GetPrivate(&v.toObject()) != nullptr;
+  }
 
-    const char* name = sProperties[slot - SLOT_FIRST].name;
-    if (!GetInstancePrivate(aCx, aObj, name)) {
-      return false;
-    }
-
-    aVp.set(JS_GetReservedSlot(aObj, slot));
+  template<SLOT Slot>
+  static bool
+  GetPropertyImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    aArgs.rval().set(JS_GetReservedSlot(&aArgs.thisv().toObject(), Slot));
     return true;
   }
 
-  static bool
-  GetConstant(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> idval,
-              JS::MutableHandle<JS::Value> aVp)
+  // This struct (versus just templating the method directly) is needed only for
+  // gcc 4.4 (and maybe 4.5 -- 4.6 is okay) being too braindead to allow
+  // GetProperty<Slot> and friends in the JSPropertySpec[] below.
+  template<SLOT Slot>
+  struct Property
   {
-    JS_ASSERT(JSID_IS_INT(idval));
-    JS_ASSERT(JSID_TO_INT(idval) >= CAPTURING_PHASE &&
-              JSID_TO_INT(idval) <= BUBBLING_PHASE);
-
-    aVp.set(INT_TO_JSVAL(JSID_TO_INT(idval)));
-    return true;
-  }
+    static bool
+    Get(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
+    {
+      static_assert(SLOT_FIRST <= Slot && Slot < SLOT_COUNT, "bad slot");
+      JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+      return JS::CallNonGenericMethod<IsEvent, GetPropertyImpl<Slot> >(aCx, args);
+    }
+  };
 
   static bool
   StopPropagation(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
@@ -338,52 +342,50 @@ private:
   };
 
 DECL_EVENT_CLASS(Event::sClass, "WorkerEvent")
 DECL_EVENT_CLASS(Event::sMainRuntimeClass, "WorkerEvent")
 
 #undef DECL_EVENT_CLASS
 
 const JSPropertySpec Event::sProperties[] = {
-  { "type", SLOT_type, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "target", SLOT_target, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "currentTarget", SLOT_currentTarget, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "eventPhase", SLOT_eventPhase, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "bubbles", SLOT_bubbles, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "cancelable", SLOT_cancelable, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "timeStamp", SLOT_timeStamp, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "defaultPrevented", SLOT_defaultPrevented, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "isTrusted", SLOT_isTrusted, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
+  JS_PSGS("type", Property<SLOT_type>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PSGS("target", Property<SLOT_target>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PSGS("currentTarget", Property<SLOT_currentTarget>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PSGS("eventPhase", Property<SLOT_eventPhase>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PSGS("bubbles", Property<SLOT_bubbles>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PSGS("cancelable", Property<SLOT_cancelable>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PSGS("timeStamp", Property<SLOT_timeStamp>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PSGS("defaultPrevented", Property<SLOT_defaultPrevented>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PSGS("isTrusted", Property<SLOT_isTrusted>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PS_END
 };
 
 const JSFunctionSpec Event::sFunctions[] = {
   JS_FN("stopPropagation", StopPropagation, 0, FUNCTION_FLAGS),
   JS_FN("preventDefault", PreventDefault, 0, FUNCTION_FLAGS),
   JS_FN("initEvent", InitEvent, 3, FUNCTION_FLAGS),
   JS_FN("stopImmediatePropagation", StopImmediatePropagation, 0, FUNCTION_FLAGS),
   JS_FS_END
 };
 
-const JSPropertySpec Event::sStaticProperties[] = {
-  { "CAPTURING_PHASE", CAPTURING_PHASE, CONSTANT_FLAGS,
-    JSOP_WRAPPER(GetConstant), JSOP_NULLWRAPPER },
-  { "AT_TARGET", AT_TARGET, CONSTANT_FLAGS, JSOP_WRAPPER(GetConstant), JSOP_NULLWRAPPER },
-  { "BUBBLING_PHASE", BUBBLING_PHASE, CONSTANT_FLAGS,
-    JSOP_WRAPPER(GetConstant), JSOP_NULLWRAPPER },
-  { 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
+const dom::ConstantSpec Event::sStaticConstants[] = {
+  { "CAPTURING_PHASE", JS::Int32Value(CAPTURING_PHASE) },
+  { "AT_TARGET", JS::Int32Value(AT_TARGET) },
+  { "BUBBLING_PHASE", JS::Int32Value(BUBBLING_PHASE) },
+  { nullptr, JS::UndefinedValue() }
 };
 
 class MessageEvent : public Event
 {
   static JSClass sClass;
   static JSClass sMainRuntimeClass;
 
   static const JSPropertySpec sProperties[];
@@ -502,56 +504,75 @@ private:
   Finalize(JSFreeOp* aFop, JSObject* aObj)
   {
     JS_ASSERT(IsThisClass(JS_GetClass(aObj)));
     MessageEvent* priv = GetJSPrivateSafeish<MessageEvent>(aObj);
     delete priv;
   }
 
   static bool
-  GetProperty(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-              JS::MutableHandle<JS::Value> aVp)
+  IsMessageEvent(JS::Handle<JS::Value> v)
   {
-    JS_ASSERT(JSID_IS_INT(aIdval));
-
-    int32_t slot = JSID_TO_INT(aIdval);
+    if (!v.isObject())
+      return false;
+    JSObject* obj = &v.toObject();
+    return IsThisClass(JS_GetClass(obj)) &&
+           GetJSPrivateSafeish<MessageEvent>(obj) != nullptr;
+  }
 
-    JS_ASSERT(slot >= SLOT_data && slot < SLOT_COUNT);
+  template<SLOT Slot>
+  static bool
+  GetPropertyImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
 
-    const char* name = sProperties[slot - SLOT_FIRST].name;
-    MessageEvent* event = GetInstancePrivate(aCx, aObj, name);
-    if (!event) {
-      return false;
-    }
+    const char* name = sProperties[Slot - SLOT_FIRST].name;
+    MessageEvent* event = GetInstancePrivate(aCx, obj, name);
+    MOZ_ASSERT(event);
 
     // Deserialize and save the data value if we can.
-    if (slot == SLOT_data && event->mBuffer.data()) {
+    if (Slot == SLOT_data && event->mBuffer.data()) {
       JSAutoStructuredCloneBuffer buffer;
       buffer.swap(event->mBuffer);
 
       // Release reference to objects that were AddRef'd for
       // cloning into worker when array goes out of scope.
       nsTArray<nsCOMPtr<nsISupports> > clonedObjects;
       clonedObjects.SwapElements(event->mClonedObjects);
 
       JS::Rooted<JS::Value> data(aCx);
       if (!buffer.read(aCx, data.address(),
                        WorkerStructuredCloneCallbacks(event->mMainRuntime))) {
         return false;
       }
-      JS_SetReservedSlot(aObj, slot, data);
+      JS_SetReservedSlot(obj, Slot, data);
 
-      aVp.set(data);
+      aArgs.rval().set(data);
       return true;
     }
 
-    aVp.set(JS_GetReservedSlot(aObj, slot));
+    aArgs.rval().set(JS_GetReservedSlot(obj, Slot));
     return true;
   }
 
+  // This struct (versus just templating the method directly) is needed only for
+  // gcc 4.4 (and maybe 4.5 -- 4.6 is okay) being too braindead to allow
+  // GetProperty<Slot> and friends in the JSPropertySpec[] below.
+  template<SLOT Slot>
+  struct Property
+  {
+    static bool
+    Get(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
+    {
+      static_assert(SLOT_FIRST <= Slot && Slot < SLOT_COUNT, "bad slot");
+      JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+      return JS::CallNonGenericMethod<IsMessageEvent, GetPropertyImpl<Slot> >(aCx, args);
+    }
+  };
+
   static bool
   InitMessageEvent(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS::Rooted<JSObject*> obj(aCx, JS_THIS_OBJECT(aCx, aVp));
     if (!obj) {
       return false;
     }
 
@@ -584,23 +605,23 @@ private:
   };
 
 DECL_MESSAGEEVENT_CLASS(MessageEvent::sClass, "WorkerMessageEvent")
 DECL_MESSAGEEVENT_CLASS(MessageEvent::sMainRuntimeClass, "WorkerMessageEvent")
 
 #undef DECL_MESSAGEEVENT_CLASS
 
 const JSPropertySpec MessageEvent::sProperties[] = {
-  { "data", SLOT_data, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "origin", SLOT_origin, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "source", SLOT_source, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
+  JS_PSGS("data", Property<SLOT_data>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PSGS("origin", Property<SLOT_origin>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PSGS("source", Property<SLOT_source>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PS_END
 };
 
 const JSFunctionSpec MessageEvent::sFunctions[] = {
   JS_FN("initMessageEvent", InitMessageEvent, 6, FUNCTION_FLAGS),
   JS_FS_END
 };
 
 class ErrorEvent : public Event
@@ -710,35 +731,48 @@ private:
   static void
   Finalize(JSFreeOp* aFop, JSObject* aObj)
   {
     JS_ASSERT(IsThisClass(JS_GetClass(aObj)));
     delete GetJSPrivateSafeish<ErrorEvent>(aObj);
   }
 
   static bool
-  GetProperty(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-              JS::MutableHandle<JS::Value> aVp)
+  IsErrorEvent(JS::Handle<JS::Value> v)
   {
-    JS_ASSERT(JSID_IS_INT(aIdval));
-
-    int32_t slot = JSID_TO_INT(aIdval);
+    if (!v.isObject())
+      return false;
+    JSObject* obj = &v.toObject();
+    return IsThisClass(JS_GetClass(obj)) &&
+           GetJSPrivateSafeish<ErrorEvent>(obj) != nullptr;
+  }
 
-    JS_ASSERT(slot >= SLOT_message && slot < SLOT_COUNT);
-
-    const char* name = sProperties[slot - SLOT_FIRST].name;
-    ErrorEvent* event = GetInstancePrivate(aCx, aObj, name);
-    if (!event) {
-      return false;
-    }
-
-    aVp.set(JS_GetReservedSlot(aObj, slot));
+  template<SLOT Slot>
+  static bool
+  GetPropertyImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    aArgs.rval().set(JS_GetReservedSlot(&aArgs.thisv().toObject(), Slot));
     return true;
   }
 
+  // This struct (versus just templating the method directly) is needed only for
+  // gcc 4.4 (and maybe 4.5 -- 4.6 is okay) being too braindead to allow
+  // GetProperty<Slot> and friends in the JSPropertySpec[] below.
+  template<SLOT Slot>
+  struct Property
+  {
+    static bool
+    Get(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
+    {
+      static_assert(SLOT_FIRST <= Slot && Slot < SLOT_COUNT, "bad slot");
+      JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+      return JS::CallNonGenericMethod<IsErrorEvent, GetPropertyImpl<Slot> >(aCx, args);
+    }
+  };
+
   static bool
   InitErrorEvent(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS::Rooted<JSObject*> obj(aCx, JS_THIS_OBJECT(aCx, aVp));
     if (!obj) {
       return false;
     }
 
@@ -771,23 +805,23 @@ private:
   };
 
 DECL_ERROREVENT_CLASS(ErrorEvent::sClass, "WorkerErrorEvent")
 DECL_ERROREVENT_CLASS(ErrorEvent::sMainRuntimeClass, "WorkerErrorEvent")
 
 #undef DECL_ERROREVENT_CLASS
 
 const JSPropertySpec ErrorEvent::sProperties[] = {
-  { "message", SLOT_message, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "filename", SLOT_filename, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "lineno", SLOT_lineno, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
+  JS_PSGS("message", Property<SLOT_message>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PSGS("filename", Property<SLOT_filename>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PSGS("lineno", Property<SLOT_lineno>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PS_END
 };
 
 const JSFunctionSpec ErrorEvent::sFunctions[] = {
   JS_FN("initErrorEvent", InitErrorEvent, 6, FUNCTION_FLAGS),
   JS_FS_END
 };
 
 class ProgressEvent : public Event
@@ -890,51 +924,64 @@ private:
   static void
   Finalize(JSFreeOp* aFop, JSObject* aObj)
   {
     JS_ASSERT(JS_GetClass(aObj) == &sClass);
     delete GetJSPrivateSafeish<ProgressEvent>(aObj);
   }
 
   static bool
-  GetProperty(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-              JS::MutableHandle<JS::Value> aVp)
+  IsProgressEvent(JS::Handle<JS::Value> v)
   {
-    JS_ASSERT(JSID_IS_INT(aIdval));
-
-    int32_t slot = JSID_TO_INT(aIdval);
+    if (!v.isObject())
+      return false;
+    JSObject* obj = &v.toObject();
+    return JS_GetClass(obj) == &sClass &&
+           GetJSPrivateSafeish<ProgressEvent>(obj) != nullptr;
+  }
 
-    JS_ASSERT(slot >= SLOT_lengthComputable && slot < SLOT_COUNT);
-
-    const char* name = sProperties[slot - SLOT_FIRST].name;
-    ProgressEvent* event = GetInstancePrivate(aCx, aObj, name);
-    if (!event) {
-      return false;
-    }
-
-    aVp.set(JS_GetReservedSlot(aObj, slot));
+  template<SLOT Slot>
+  static bool
+  GetPropertyImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    aArgs.rval().set(JS_GetReservedSlot(&aArgs.thisv().toObject(), Slot));
     return true;
   }
+
+  // This struct (versus just templating the method directly) is needed only for
+  // gcc 4.4 (and maybe 4.5 -- 4.6 is okay) being too braindead to allow
+  // GetProperty<Slot> and friends in the JSPropertySpec[] below.
+  template<SLOT Slot>
+  struct Property
+  {
+    static bool
+    Get(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
+    {
+      static_assert(SLOT_FIRST <= Slot && Slot < SLOT_COUNT, "bad slot");
+      JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+      return JS::CallNonGenericMethod<IsProgressEvent, GetPropertyImpl<Slot> >(aCx, args);
+    }
+  };
 };
 
 JSClass ProgressEvent::sClass = {
   "WorkerProgressEvent",
   JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(SLOT_COUNT),
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize
 };
 
 const JSPropertySpec ProgressEvent::sProperties[] = {
-  { "lengthComputable", SLOT_lengthComputable, PROPERTY_FLAGS,
-    JSOP_WRAPPER(GetProperty), JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "loaded", SLOT_loaded, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "total", SLOT_total, PROPERTY_FLAGS, JSOP_WRAPPER(GetProperty),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
+  JS_PSGS("lengthComputable", Property<SLOT_lengthComputable>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PSGS("loaded", Property<SLOT_loaded>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PSGS("total", Property<SLOT_total>::Get, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PS_END
 };
 
 Event*
 Event::GetPrivate(JSObject* aObj)
 {
   if (aObj) {
     JSClass* classPtr = JS_GetClass(aObj);
     if (IsThisClass(classPtr) ||
--- a/dom/workers/File.cpp
+++ b/dom/workers/File.cpp
@@ -15,19 +15,16 @@
 #include "nsCOMPtr.h"
 #include "nsJSUtils.h"
 #include "nsStringGlue.h"
 
 #include "mozilla/dom/Exceptions.h"
 #include "WorkerInlines.h"
 #include "WorkerPrivate.h"
 
-#define PROPERTY_FLAGS \
-  (JSPROP_ENUMERATE | JSPROP_SHARED)
-
 USING_WORKERS_NAMESPACE
 using mozilla::dom::Throw;
 
 namespace {
 
 class Blob
 {
   // Blob should never be instantiated.
@@ -106,56 +103,70 @@ private:
   {
     JS_ASSERT(JS_GetClass(aObj) == &sClass);
 
     nsIDOMBlob* blob = GetPrivate(aObj);
     NS_IF_RELEASE(blob);
   }
 
   static bool
-  GetSize(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-          JS::MutableHandle<JS::Value> aVp)
+  IsBlob(JS::Handle<JS::Value> v)
   {
-    nsIDOMBlob* blob = GetInstancePrivate(aCx, aObj, "size");
-    if (!blob) {
-      return false;
-    }
+    return v.isObject() && GetPrivate(&v.toObject()) != nullptr;
+  }
+
+  static bool
+  GetSizeImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
+    nsIDOMBlob* blob = GetInstancePrivate(aCx, obj, "size");
+    MOZ_ASSERT(blob);
 
     uint64_t size;
     if (NS_FAILED(blob->GetSize(&size))) {
       return Throw(aCx, NS_ERROR_DOM_FILE_NOT_READABLE_ERR);
     }
 
-    aVp.set(JS_NumberValue(double(size)));
-
+    aArgs.rval().setNumber(double(size));
     return true;
   }
 
   static bool
-  GetType(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-          JS::MutableHandle<JS::Value> aVp)
+  GetSize(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
   {
-    nsIDOMBlob* blob = GetInstancePrivate(aCx, aObj, "type");
-    if (!blob) {
-      return false;
-    }
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsBlob, GetSizeImpl>(aCx, args);
+  }
+
+  static bool
+  GetTypeImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
+    nsIDOMBlob* blob = GetInstancePrivate(aCx, obj, "type");
+    MOZ_ASSERT(blob);
 
     nsString type;
     if (NS_FAILED(blob->GetType(type))) {
       return Throw(aCx, NS_ERROR_DOM_FILE_NOT_READABLE_ERR);
     }
 
     JSString* jsType = JS_NewUCStringCopyN(aCx, type.get(), type.Length());
     if (!jsType) {
       return false;
     }
 
-    aVp.set(STRING_TO_JSVAL(jsType));
+    aArgs.rval().setString(jsType);
+    return true;
+  }
 
-    return true;
+  static bool
+  GetType(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
+  {
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsBlob, GetTypeImpl>(aCx, args);
   }
 
   static bool
   Slice(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS::Rooted<JSObject*> obj(aCx, JS_THIS_OBJECT(aCx, aVp));
     if (!obj) {
       return false;
@@ -200,19 +211,19 @@ private:
 JSClass Blob::sClass = {
   "Blob",
   JSCLASS_HAS_PRIVATE,
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize
 };
 
 const JSPropertySpec Blob::sProperties[] = {
-  { "size", 0, PROPERTY_FLAGS, JSOP_WRAPPER(GetSize), JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "type", 0, PROPERTY_FLAGS, JSOP_WRAPPER(GetType), JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
+  JS_PSGS("size", GetSize, GetterOnlyJSNative, JSPROP_ENUMERATE),
+  JS_PSGS("type", GetType, GetterOnlyJSNative, JSPROP_ENUMERATE),
+  JS_PS_END
 };
 
 const JSFunctionSpec Blob::sFunctions[] = {
   JS_FN("slice", Slice, 1, JSPROP_ENUMERATE),
   JS_FS_END
 };
 
 class File : public Blob
@@ -294,123 +305,146 @@ private:
   {
     JS_ASSERT(JS_GetClass(aObj) == &sClass);
 
     nsIDOMFile* file = GetPrivate(aObj);
     NS_IF_RELEASE(file);
   }
 
   static bool
-  GetMozFullPath(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-                 JS::MutableHandle<JS::Value> aVp)
+  IsFile(JS::Handle<JS::Value> v)
   {
-    nsIDOMFile* file = GetInstancePrivate(aCx, aObj, "mozFullPath");
-    if (!file) {
-      return false;
-    }
+    return v.isObject() && GetPrivate(&v.toObject()) != nullptr;
+  }
+
+  static bool
+  GetMozFullPathImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
+    nsIDOMFile* file = GetInstancePrivate(aCx, obj, "mozFullPath");
+    MOZ_ASSERT(file);
 
     nsString fullPath;
 
     if (GetWorkerPrivateFromContext(aCx)->UsesSystemPrincipal() &&
         NS_FAILED(file->GetMozFullPathInternal(fullPath))) {
       return Throw(aCx, NS_ERROR_DOM_FILE_NOT_READABLE_ERR);
     }
 
     JSString* jsFullPath = JS_NewUCStringCopyN(aCx, fullPath.get(),
                                                fullPath.Length());
     if (!jsFullPath) {
       return false;
     }
 
-    aVp.set(STRING_TO_JSVAL(jsFullPath));
+    aArgs.rval().setString(jsFullPath);
     return true;
   }
 
   static bool
-  GetName(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-          JS::MutableHandle<JS::Value> aVp)
+  GetMozFullPath(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
   {
-    nsIDOMFile* file = GetInstancePrivate(aCx, aObj, "name");
-    if (!file) {
-      return false;
-    }
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsFile, GetMozFullPathImpl>(aCx, args);
+  }
+
+  static bool
+  GetNameImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
+    nsIDOMFile* file = GetInstancePrivate(aCx, obj, "name");
+    MOZ_ASSERT(file);
 
     nsString name;
     if (NS_FAILED(file->GetName(name))) {
       name.Truncate();
     }
 
     JSString* jsName = JS_NewUCStringCopyN(aCx, name.get(), name.Length());
     if (!jsName) {
       return false;
     }
 
-    aVp.set(STRING_TO_JSVAL(jsName));
+    aArgs.rval().setString(jsName);
     return true;
   }
 
   static bool
-  GetPath(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-          JS::MutableHandle<JS::Value> aVp)
+  GetName(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
   {
-    nsIDOMFile* file = GetInstancePrivate(aCx, aObj, "path");
-    if (!file) {
-      return false;
-    }
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsFile, GetNameImpl>(aCx, args);
+  }
+
+  static bool
+  GetPathImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
+    nsIDOMFile* file = GetInstancePrivate(aCx, obj, "path");
+    MOZ_ASSERT(file);
 
     nsString path;
     if (NS_FAILED(file->GetPath(path))) {
       path.Truncate();
     }
 
     JSString* jsPath = JS_NewUCStringCopyN(aCx, path.get(), path.Length());
     if (!jsPath) {
       return false;
     }
 
-    aVp.set(STRING_TO_JSVAL(jsPath));
+    aArgs.rval().setString(jsPath);
     return true;
   }
 
   static bool
-  GetLastModifiedDate(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-                      JS::MutableHandle<JS::Value> aVp)
+  GetPath(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
   {
-    nsIDOMFile* file = GetInstancePrivate(aCx, aObj, "lastModifiedDate");
-    if (!file) {
-      return false;
-    }
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsFile, GetPathImpl>(aCx, args);
+  }
+
+  static bool
+  GetLastModifiedDateImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
+    nsIDOMFile* file = GetInstancePrivate(aCx, obj, "lastModifiedDate");
+    MOZ_ASSERT(file);
 
     JS::Rooted<JS::Value> value(aCx);
     if (NS_FAILED(file->GetLastModifiedDate(aCx, value.address()))) {
       return false;
     }
 
-    aVp.set(value);
+    aArgs.rval().set(value);
     return true;
   }
+
+  static bool
+  GetLastModifiedDate(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
+  {
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsFile, GetLastModifiedDateImpl>(aCx, args);
+  }
 };
 
 JSClass File::sClass = {
   "File",
   JSCLASS_HAS_PRIVATE,
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize
 };
 
 const JSPropertySpec File::sProperties[] = {
-  { "name", 0, PROPERTY_FLAGS, JSOP_WRAPPER(GetName),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "path", 0, PROPERTY_FLAGS, JSOP_WRAPPER(GetPath),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "lastModifiedDate", 0, PROPERTY_FLAGS, JSOP_WRAPPER(GetLastModifiedDate),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "mozFullPath", 0, PROPERTY_FLAGS, JSOP_WRAPPER(GetMozFullPath),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
+  JS_PSGS("name", GetName, GetterOnlyJSNative, JSPROP_ENUMERATE),
+  JS_PSGS("path", GetPath, GetterOnlyJSNative, JSPROP_ENUMERATE),
+  JS_PSGS("lastModifiedDate", GetLastModifiedDate, GetterOnlyJSNative,
+          JSPROP_ENUMERATE),
+  JS_PSGS("mozFullPath", GetMozFullPath, GetterOnlyJSNative, JSPROP_ENUMERATE),
+  JS_PS_END
 };
 
 nsIDOMBlob*
 Blob::GetPrivate(JSObject* aObj)
 {
   if (aObj) {
     JSClass* classPtr = JS_GetClass(aObj);
     if (classPtr == &sClass || classPtr == File::Class()) {
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -1506,16 +1506,19 @@ RuntimeService::Init()
 
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   NS_ENSURE_TRUE(obs, NS_ERROR_FAILURE);
 
   nsresult rv =
     obs->AddObserver(this, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   mObserved = true;
 
   if (NS_FAILED(obs->AddObserver(this, GC_REQUEST_OBSERVER_TOPIC, false))) {
     NS_WARNING("Failed to register for GC request notifications!");
   }
 
   if (NS_FAILED(obs->AddObserver(this, MEMORY_PRESSURE_OBSERVER_TOPIC,
                                  false))) {
@@ -1593,67 +1596,85 @@ RuntimeService::Init()
   rv = InitOSFileConstants();
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   return NS_OK;
 }
 
-// This spins the event loop until all workers are finished and their threads
-// have been joined.
 void
-RuntimeService::Cleanup()
+RuntimeService::Shutdown()
 {
   AssertIsOnMainThread();
 
+  MOZ_ASSERT(!mShuttingDown);
+  // That's it, no more workers.
+  mShuttingDown = true;
+
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   NS_WARN_IF_FALSE(obs, "Failed to get observer service?!");
 
   // Tell anyone that cares that they're about to lose worker support.
   if (obs && NS_FAILED(obs->NotifyObservers(nullptr, WORKERS_SHUTDOWN_TOPIC,
                                             nullptr))) {
     NS_WARNING("NotifyObservers failed!");
   }
 
-  // That's it, no more workers.
-  mShuttingDown = true;
+  {
+    MutexAutoLock lock(mMutex);
+
+    nsAutoTArray<WorkerPrivate*, 100> workers;
+    mDomainMap.EnumerateRead(AddAllTopLevelWorkersToArray, &workers);
+
+    if (!workers.IsEmpty()) {
+
+      // Cancel all top-level workers.
+      {
+        MutexAutoUnlock unlock(mMutex);
+
+        AutoSafeJSContext cx;
+        JSAutoRequest ar(cx);
+
+        for (uint32_t index = 0; index < workers.Length(); index++) {
+          if (!workers[index]->Kill(cx)) {
+            NS_WARNING("Failed to cancel worker!");
+          }
+        }
+      }
+    }
+  }
+}
+
+// This spins the event loop until all workers are finished and their threads
+// have been joined.
+void
+RuntimeService::Cleanup()
+{
+  AssertIsOnMainThread();
+
+  nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
+  NS_WARN_IF_FALSE(obs, "Failed to get observer service?!");
 
   if (mIdleThreadTimer) {
     if (NS_FAILED(mIdleThreadTimer->Cancel())) {
       NS_WARNING("Failed to cancel idle timer!");
     }
     mIdleThreadTimer = nullptr;
   }
 
   {
     MutexAutoLock lock(mMutex);
 
     nsAutoTArray<WorkerPrivate*, 100> workers;
     mDomainMap.EnumerateRead(AddAllTopLevelWorkersToArray, &workers);
 
     if (!workers.IsEmpty()) {
-      nsIThread* currentThread;
-
-      // Cancel all top-level workers.
-      {
-        MutexAutoUnlock unlock(mMutex);
-
-        currentThread = NS_GetCurrentThread();
-        NS_ASSERTION(currentThread, "This should never be null!");
-
-        AutoSafeJSContext cx;
-        JSAutoRequest ar(cx);
-
-        for (uint32_t index = 0; index < workers.Length(); index++) {
-          if (!workers[index]->Kill(cx)) {
-            NS_WARNING("Failed to cancel worker!");
-          }
-        }
-      }
+      nsIThread* currentThread = NS_GetCurrentThread();
+      NS_ASSERTION(currentThread, "This should never be null!");
 
       // Shut down any idle threads.
       if (!mIdleThreadArray.IsEmpty()) {
         nsAutoTArray<nsCOMPtr<nsIThread>, 20> idleThreads;
 
         uint32_t idleThreadCount = mIdleThreadArray.Length();
         idleThreads.SetLength(idleThreadCount);
 
@@ -1729,19 +1750,19 @@ RuntimeService::Cleanup()
         NS_WARNING("Failed to unregister for GC request notifications!");
       }
 
       if (NS_FAILED(obs->RemoveObserver(this,
                                         MEMORY_PRESSURE_OBSERVER_TOPIC))) {
         NS_WARNING("Failed to unregister for memory pressure notifications!");
       }
 
-      nsresult rv =
-        obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID);
-      mObserved = NS_FAILED(rv);
+      obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID);
+      obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
+      mObserved = false;
     }
   }
 
   CleanupOSFileConstants();
   nsLayoutStatics::Release();
 }
 
 // static
@@ -1930,16 +1951,20 @@ NS_IMPL_ISUPPORTS1(RuntimeService, nsIOb
 
 // nsIObserver
 NS_IMETHODIMP
 RuntimeService::Observe(nsISupports* aSubject, const char* aTopic,
                         const PRUnichar* aData)
 {
   AssertIsOnMainThread();
 
+  if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
+    Shutdown();
+    return NS_OK;
+  }
   if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID)) {
     Cleanup();
     return NS_OK;
   }
   if (!strcmp(aTopic, GC_REQUEST_OBSERVER_TOPIC)) {
     GarbageCollectAllWorkers(false);
     return NS_OK;
   }
--- a/dom/workers/RuntimeService.h
+++ b/dom/workers/RuntimeService.h
@@ -204,16 +204,19 @@ public:
 private:
   RuntimeService();
   ~RuntimeService();
 
   nsresult
   Init();
 
   void
+  Shutdown();
+
+  void
   Cleanup();
 
   static PLDHashOperator
   AddAllTopLevelWorkersToArray(const nsACString& aKey,
                                WorkerDomainInfo* aData,
                                void* aUserArg);
 
   void
--- a/dom/workers/Worker.cpp
+++ b/dom/workers/Worker.cpp
@@ -3,25 +3,23 @@
  * 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/. */
 
 #include "Worker.h"
 
 #include "mozilla/dom/DOMJSClass.h"
 #include "mozilla/dom/BindingUtils.h"
 
+#include "jsapi.h"
 #include "EventTarget.h"
 #include "RuntimeService.h"
 #include "WorkerPrivate.h"
 
 #include "WorkerInlines.h"
 
-#define PROPERTY_FLAGS \
-  (JSPROP_ENUMERATE | JSPROP_SHARED)
-
 #define FUNCTION_FLAGS \
   JSPROP_ENUMERATE
 
 USING_WORKERS_NAMESPACE
 
 using namespace mozilla::dom;
 using mozilla::ErrorResult;
 
@@ -29,26 +27,16 @@ namespace {
 
 class Worker
 {
   static DOMJSClass sClass;
   static DOMIfaceAndProtoJSClass sProtoClass;
   static const JSPropertySpec sProperties[];
   static const JSFunctionSpec sFunctions[];
 
-  enum
-  {
-    STRING_onerror = 0,
-    STRING_onmessage,
-
-    STRING_COUNT
-  };
-
-  static const char* const sEventStrings[STRING_COUNT];
-
 protected:
   enum {
     // The constructor function holds a WorkerPrivate* in its first reserved
     // slot.
     CONSTRUCTOR_SLOT_PARENT = 0
   };
 
 public:
@@ -171,71 +159,121 @@ protected:
 private:
   // No instance of this class should ever be created so these are explicitly
   // left without an implementation to prevent linking in case someone tries to
   // make one.
   Worker();
   ~Worker();
 
   static bool
-  GetEventListener(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-                   JS::MutableHandle<JS::Value> aVp)
+  IsWorker(JS::Handle<JS::Value> v)
   {
-    JS_ASSERT(JSID_IS_INT(aIdval));
-    JS_ASSERT(JSID_TO_INT(aIdval) >= 0 && JSID_TO_INT(aIdval) < STRING_COUNT);
+    return v.isObject() && ClassIsWorker(JS_GetClass(&v.toObject()));
+  }
 
-    const char* name = sEventStrings[JSID_TO_INT(aIdval)];
-    WorkerPrivate* worker = GetInstancePrivate(aCx, aObj, name);
-    if (!worker) {
-      return !JS_IsExceptionPending(aCx);
-    }
+  static bool
+  GetEventListener(JSContext* aCx, const JS::CallArgs aArgs,
+                   const nsAString &aNameStr)
+  {
+    WorkerPrivate* worker =
+      GetInstancePrivate(aCx, &aArgs.thisv().toObject(),
+                         NS_ConvertUTF16toUTF8(aNameStr).get());
+    MOZ_ASSERT(worker);
 
-    NS_ConvertASCIItoUTF16 nameStr(name + 2);
     ErrorResult rv;
-    JS::Rooted<JSObject*> listener(aCx, worker->GetEventListener(nameStr, rv));
+    JS::Rooted<JSObject*> listener(aCx, worker->GetEventListener(Substring(aNameStr, 2), rv));
 
     if (rv.Failed()) {
       JS_ReportError(aCx, "Failed to get listener!");
+      return false;
     }
 
-    aVp.set(listener ? OBJECT_TO_JSVAL(listener) : JSVAL_NULL);
+    aArgs.rval().setObjectOrNull(listener);
     return true;
   }
 
   static bool
-  SetEventListener(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-                   bool aStrict, JS::MutableHandle<JS::Value> aVp)
+  GetOnerrorImpl(JSContext* aCx, JS::CallArgs aArgs)
   {
-    JS_ASSERT(JSID_IS_INT(aIdval));
-    JS_ASSERT(JSID_TO_INT(aIdval) >= 0 && JSID_TO_INT(aIdval) < STRING_COUNT);
+    return GetEventListener(aCx, aArgs, NS_LITERAL_STRING("onerror"));
+  }
+
+  static bool
+  GetOnerror(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
+  {
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsWorker, GetOnerrorImpl>(aCx, args);
+  }
 
-    const char* name = sEventStrings[JSID_TO_INT(aIdval)];
-    WorkerPrivate* worker = GetInstancePrivate(aCx, aObj, name);
-    if (!worker) {
-      return !JS_IsExceptionPending(aCx);
-    }
+  static bool
+  GetOnmessageImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    return GetEventListener(aCx, aArgs, NS_LITERAL_STRING("onmessage"));
+  }
+
+  static bool
+  GetOnmessage(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
+  {
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsWorker, GetOnmessageImpl>(aCx, args);
+  }
+
+  static bool
+  SetEventListener(JSContext* aCx, JS::CallArgs aArgs,
+                   const nsAString& aNameStr)
+  {
+    WorkerPrivate* worker =
+      GetInstancePrivate(aCx, &aArgs.thisv().toObject(),
+                         NS_ConvertUTF16toUTF8(aNameStr).get());
+    MOZ_ASSERT(worker);
 
     JS::Rooted<JSObject*> listener(aCx);
-    if (!JS_ValueToObject(aCx, aVp, listener.address())) {
+    if (!JS_ValueToObject(aCx, aArgs.get(0), listener.address())) {
       return false;
     }
 
-    NS_ConvertASCIItoUTF16 nameStr(name + 2);
     ErrorResult rv;
-    worker->SetEventListener(nameStr, listener, rv);
+    worker->SetEventListener(Substring(aNameStr, 2), listener, rv);
 
     if (rv.Failed()) {
       JS_ReportError(aCx, "Failed to set listener!");
       return false;
     }
 
+    aArgs.rval().setUndefined();
     return true;
   }
 
   static bool
+  SetOnerrorImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    return SetEventListener(aCx, aArgs, NS_LITERAL_STRING("onerror"));
+  }
+
+  static bool
+  SetOnerror(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
+  {
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsWorker, SetOnerrorImpl>(aCx, args);
+  }
+
+  static bool
+  SetOnmessageImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    return SetEventListener(aCx, aArgs, NS_LITERAL_STRING("onmessage"));
+  }
+
+  static bool
+  SetOnmessage(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
+  {
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsWorker, SetOnmessageImpl>(aCx, args);
+  }
+
+  static bool
   Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     return ConstructInternal(aCx, aArgc, aVp, false, Class());
   }
 
   static void
   Finalize(JSFreeOp* aFop, JSObject* aObj)
   {
@@ -350,34 +388,27 @@ DOMIfaceAndProtoJSClass Worker::sProtoCl
   eInterfacePrototype,
   &sWorkerNativePropertyHooks,
   "[object Worker]",
   prototypes::id::_ID_Count,
   0
 };
 
 const JSPropertySpec Worker::sProperties[] = {
-  { sEventStrings[STRING_onerror], STRING_onerror, PROPERTY_FLAGS,
-    JSOP_WRAPPER(GetEventListener), JSOP_WRAPPER(SetEventListener) },
-  { sEventStrings[STRING_onmessage], STRING_onmessage, PROPERTY_FLAGS,
-    JSOP_WRAPPER(GetEventListener), JSOP_WRAPPER(SetEventListener) },
-  { 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
+  JS_PSGS("onerror", GetOnerror, SetOnerror, JSPROP_ENUMERATE),
+  JS_PSGS("onmessage", GetOnmessage, SetOnmessage, JSPROP_ENUMERATE),
+  JS_PS_END
 };
 
 const JSFunctionSpec Worker::sFunctions[] = {
   JS_FN("terminate", Terminate, 0, FUNCTION_FLAGS),
   JS_FN("postMessage", PostMessage, 1, FUNCTION_FLAGS),
   JS_FS_END
 };
 
-const char* const Worker::sEventStrings[STRING_COUNT] = {
-  "onerror",
-  "onmessage"
-};
-
 class ChromeWorker : public Worker
 {
   static DOMJSClass sClass;
   static DOMIfaceAndProtoJSClass sProtoClass;
 
 public:
   static JSClass*
   Class()
@@ -517,17 +548,17 @@ DOMIfaceAndProtoJSClass ChromeWorker::sP
   0
 };
 
 WorkerPrivate*
 Worker::GetInstancePrivate(JSContext* aCx, JSObject* aObj,
                            const char* aFunctionName)
 {
   JSClass* classPtr = JS_GetClass(aObj);
-  if (classPtr == Class() || classPtr == ChromeWorker::Class()) {
+  if (ClassIsWorker(classPtr)) {
     return UnwrapDOMObject<WorkerPrivate>(aObj);
   }
 
   JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
                        Class()->name, aFunctionName, classPtr->name);
   return NULL;
 }
 
@@ -575,9 +606,16 @@ InitClass(JSContext* aCx, JSObject* aGlo
 } // namespace chromeworker
 
 bool
 ClassIsWorker(JSClass* aClass)
 {
   return Worker::Class() == aClass || ChromeWorker::Class() == aClass;
 }
 
+bool
+GetterOnlyJSNative(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
+{
+    JS_ReportErrorNumber(aCx, js_GetErrorMessage, nullptr, JSMSG_GETTER_ONLY);
+    return false;
+}
+
 END_WORKERS_NAMESPACE
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -43,19 +43,16 @@
 #include "Principal.h"
 #include "ScriptLoader.h"
 #include "Worker.h"
 #include "WorkerPrivate.h"
 #include "XMLHttpRequest.h"
 
 #include "WorkerInlines.h"
 
-#define PROPERTY_FLAGS \
-  (JSPROP_ENUMERATE | JSPROP_SHARED)
-
 #define FUNCTION_FLAGS \
   JSPROP_ENUMERATE
 
 using namespace mozilla;
 using namespace mozilla::dom;
 USING_WORKERS_NAMESPACE
 
 namespace {
@@ -150,123 +147,136 @@ protected:
 
   virtual void
   _finalize(JSFreeOp* aFop) MOZ_OVERRIDE
   {
     EventTarget::_finalize(aFop);
   }
 
 private:
+  static bool IsWorkerGlobalScope(JS::Handle<JS::Value> v);
+
   static bool
-  GetEventListener(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-                   JS::MutableHandle<JS::Value> aVp)
+  GetOnCloseImpl(JSContext* aCx, JS::CallArgs aArgs)
   {
-    JS_ASSERT(JSID_IS_INT(aIdval));
-    JS_ASSERT(JSID_TO_INT(aIdval) >= 0 && JSID_TO_INT(aIdval) < STRING_COUNT);
-
-    const char* name = sEventStrings[JSID_TO_INT(aIdval)];
-    WorkerGlobalScope* scope = GetInstancePrivate(aCx, aObj, name);
-    if (!scope) {
-      return false;
-    }
+    const char* name = sEventStrings[STRING_onclose];
+    WorkerGlobalScope* scope = GetInstancePrivate(aCx, &aArgs.thisv().toObject(), name);
+    MOZ_ASSERT(scope);
 
     ErrorResult rv;
 
     JSObject* listener =
       scope->GetEventListener(NS_ConvertASCIItoUTF16(name + 2), rv);
 
     if (rv.Failed()) {
       JS_ReportError(aCx, "Failed to get event listener!");
       return false;
     }
 
-    aVp.set(listener ? OBJECT_TO_JSVAL(listener) : JSVAL_NULL);
+    aArgs.rval().setObjectOrNull(listener);
     return true;
   }
 
   static bool
-  SetEventListener(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-                   bool aStrict, JS::MutableHandle<JS::Value> aVp)
+  GetOnClose(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
   {
-    JS_ASSERT(JSID_IS_INT(aIdval));
-    JS_ASSERT(JSID_TO_INT(aIdval) >= 0 && JSID_TO_INT(aIdval) < STRING_COUNT);
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsWorkerGlobalScope, GetOnCloseImpl>(aCx, args);
+  }
 
-    const char* name = sEventStrings[JSID_TO_INT(aIdval)];
-    WorkerGlobalScope* scope = GetInstancePrivate(aCx, aObj, name);
-    if (!scope) {
-      return false;
-    }
+  static bool
+  SetOnCloseImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    const char* name = sEventStrings[STRING_onclose];
+    WorkerGlobalScope* scope =
+      GetInstancePrivate(aCx, &aArgs.thisv().toObject(), name);
+    MOZ_ASSERT(scope);
 
-    if (JSVAL_IS_PRIMITIVE(aVp)) {
+    if (aArgs.length() == 0 || !aArgs[0].isObject()) {
       JS_ReportError(aCx, "Not an event listener!");
       return false;
     }
 
     ErrorResult rv;
-    JS::Rooted<JSObject*> listenerObj(aCx, JSVAL_TO_OBJECT(aVp));
+    JS::Rooted<JSObject*> listenerObj(aCx, &aArgs[0].toObject());
     scope->SetEventListener(NS_ConvertASCIItoUTF16(name + 2),
                             listenerObj, rv);
     if (rv.Failed()) {
       JS_ReportError(aCx, "Failed to set event listener!");
       return false;
     }
 
+    aArgs.rval().setUndefined();
     return true;
   }
 
+  static bool
+  SetOnClose(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
+  {
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsWorkerGlobalScope, SetOnCloseImpl>(aCx, args);
+  }
+
   static WorkerGlobalScope*
   GetInstancePrivate(JSContext* aCx, JSObject* aObj, const char* aFunctionName);
 
   static bool
   Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_WRONG_CONSTRUCTOR,
                          sClass.name);
     return false;
   }
 
   static bool
-  GetSelf(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-          JS::MutableHandle<JS::Value> aVp)
+  GetSelfImpl(JSContext* aCx, JS::CallArgs aArgs)
   {
-    if (!GetInstancePrivate(aCx, aObj, "self")) {
-      return false;
-    }
-
-    aVp.set(OBJECT_TO_JSVAL(aObj));
+    aArgs.rval().setObject(aArgs.thisv().toObject());
     return true;
   }
 
   static bool
-  GetLocation(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-              JS::MutableHandle<JS::Value> aVp)
+  GetSelf(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
   {
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsWorkerGlobalScope, GetSelfImpl>(aCx, args);
+  }
+
+  static bool
+  GetLocationImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
     WorkerGlobalScope* scope =
-      GetInstancePrivate(aCx, aObj, sProperties[SLOT_location].name);
-    if (!scope) {
-      return false;
-    }
+      GetInstancePrivate(aCx, obj, sProperties[SLOT_location].name);
+    MOZ_ASSERT(scope);
 
-    if (JSVAL_IS_VOID(scope->mSlots[SLOT_location])) {
+    if (scope->mSlots[SLOT_location].isUndefined()) {
       WorkerPrivate::LocationInfo& info = scope->mWorker->GetLocationInfo();
 
       nsRefPtr<WorkerLocation> location =
-        WorkerLocation::Create(aCx, aObj, info);
+        WorkerLocation::Create(aCx, obj, info);
       if (!location) {
         return false;
       }
 
       scope->mSlots[SLOT_location] = OBJECT_TO_JSVAL(location->GetJSObject());
     }
 
-    aVp.set(scope->mSlots[SLOT_location]);
+    aArgs.rval().set(scope->mSlots[SLOT_location]);
     return true;
   }
 
   static bool
+  GetLocation(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
+  {
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsWorkerGlobalScope, GetLocationImpl>(aCx, args);
+  }
+
+  static bool
   UnwrapErrorEvent(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JS_ASSERT(aArgc == 1);
     JS_ASSERT((JS_ARGV(aCx, aVp)[0]).isObject());
 
     JSObject* wrapper = &JS_CALLEE(aCx, aVp).toObject();
     JS_ASSERT(JS_ObjectIsFunction(aCx, wrapper));
 
@@ -296,58 +306,58 @@ private:
         !JS_CallFunctionName(aCx, event, "preventDefault", 0, NULL, rval.address())) {
       return false;
     }
 
     return true;
   }
 
   static bool
-  GetOnErrorListener(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-                     JS::MutableHandle<JS::Value> aVp)
+  GetOnErrorListenerImpl(JSContext* aCx, JS::CallArgs aArgs)
   {
     const char* name = sEventStrings[STRING_onerror];
-    WorkerGlobalScope* scope = GetInstancePrivate(aCx, aObj, name);
-    if (!scope) {
-      return false;
-    }
+    WorkerGlobalScope* scope = GetInstancePrivate(aCx, &aArgs.thisv().toObject(), name);
+    MOZ_ASSERT(scope);
 
     ErrorResult rv;
 
     JSObject* adaptor =
       scope->GetEventListener(NS_ConvertASCIItoUTF16(name + 2), rv);
 
     if (rv.Failed()) {
       JS_ReportError(aCx, "Failed to get event listener!");
       return false;
     }
 
     if (!adaptor) {
-      aVp.setNull();
+      aArgs.rval().setNull();
       return true;
     }
 
-    aVp.set(js::GetFunctionNativeReserved(adaptor, SLOT_wrappedFunction));
-
-    JS_ASSERT(!JSVAL_IS_PRIMITIVE(aVp));
-
+    aArgs.rval().set(js::GetFunctionNativeReserved(adaptor, SLOT_wrappedFunction));
+    MOZ_ASSERT(aArgs.rval().isObject());
     return true;
   }
 
   static bool
-  SetOnErrorListener(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-                     bool aStrict, JS::MutableHandle<JS::Value> aVp)
+  GetOnErrorListener(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
   {
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsWorkerGlobalScope, GetOnErrorListenerImpl>(aCx, args);
+  }
+
+  static bool
+  SetOnErrorListenerImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
     const char* name = sEventStrings[STRING_onerror];
-    WorkerGlobalScope* scope = GetInstancePrivate(aCx, aObj, name);
-    if (!scope) {
-      return false;
-    }
+    WorkerGlobalScope* scope = GetInstancePrivate(aCx, obj, name);
+    MOZ_ASSERT(scope);
 
-    if (JSVAL_IS_PRIMITIVE(aVp)) {
+    if (aArgs.length() == 0 || !aArgs[0].isObject()) {
       JS_ReportError(aCx, "Not an event listener!");
       return false;
     }
 
     JSFunction* adaptor =
       js::NewFunctionWithReserved(aCx, UnwrapErrorEvent, 1, 0,
                                   JS::CurrentGlobalOrNull(aCx), "unwrap");
     if (!adaptor) {
@@ -355,55 +365,68 @@ private:
     }
 
     JS::Rooted<JSObject*> listener(aCx, JS_GetFunctionObject(adaptor));
     if (!listener) {
       return false;
     }
 
     js::SetFunctionNativeReserved(listener, SLOT_wrappedScope,
-                                  OBJECT_TO_JSVAL(aObj));
-    js::SetFunctionNativeReserved(listener, SLOT_wrappedFunction, aVp);
+                                  JS::ObjectValue(*obj));
+    js::SetFunctionNativeReserved(listener, SLOT_wrappedFunction, aArgs[0]);
 
     ErrorResult rv;
 
     scope->SetEventListener(NS_ConvertASCIItoUTF16(name + 2), listener, rv);
 
     if (rv.Failed()) {
       JS_ReportError(aCx, "Failed to set event listener!");
       return false;
     }
 
+    aArgs.rval().setUndefined();
     return true;
   }
 
   static bool
-  GetNavigator(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-               JS::MutableHandle<JS::Value> aVp)
+  SetOnErrorListener(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
   {
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsWorkerGlobalScope, SetOnErrorListenerImpl>(aCx, args);
+  }
+
+  static bool
+  GetNavigatorImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    JS::Rooted<JSObject*> obj(aCx, &aArgs.thisv().toObject());
     WorkerGlobalScope* scope =
-      GetInstancePrivate(aCx, aObj, sProperties[SLOT_navigator].name);
-    if (!scope) {
-      return false;
-    }
+      GetInstancePrivate(aCx, obj, sProperties[SLOT_navigator].name);
+    MOZ_ASSERT(scope);
 
-    if (JSVAL_IS_VOID(scope->mSlots[SLOT_navigator])) {
-      nsRefPtr<WorkerNavigator> navigator = WorkerNavigator::Create(aCx, aObj);
+    if (scope->mSlots[SLOT_navigator].isUndefined()) {
+      nsRefPtr<WorkerNavigator> navigator = WorkerNavigator::Create(aCx, obj);
       if (!navigator) {
         return false;
       }
 
       scope->mSlots[SLOT_navigator] = OBJECT_TO_JSVAL(navigator->GetJSObject());
     }
 
-    aVp.set(scope->mSlots[SLOT_navigator]);
+    aArgs.rval().set(scope->mSlots[SLOT_navigator]);
     return true;
   }
 
   static bool
+  GetNavigator(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
+  {
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsWorkerGlobalScope, GetNavigatorImpl>(aCx, args);
+  }
+
+  static bool
   Close(JSContext* aCx, unsigned aArgc, jsval* aVp)
   {
     JSObject* obj = JS_THIS_OBJECT(aCx, aVp);
     if (!obj) {
       return false;
     }
 
     WorkerGlobalScope* scope = GetInstancePrivate(aCx, obj, sFunctions[0].name);
@@ -632,26 +655,24 @@ NS_INTERFACE_MAP_END
 JSClass WorkerGlobalScope::sClass = {
   "WorkerGlobalScope",
   0,
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
 };
 
 const JSPropertySpec WorkerGlobalScope::sProperties[] = {
-  { "location", SLOT_location, PROPERTY_FLAGS, JSOP_WRAPPER(GetLocation),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { sEventStrings[STRING_onerror], STRING_onerror, PROPERTY_FLAGS,
-    JSOP_WRAPPER(GetOnErrorListener), JSOP_WRAPPER(SetOnErrorListener) },
-  { sEventStrings[STRING_onclose], STRING_onclose, PROPERTY_FLAGS,
-    JSOP_WRAPPER(GetEventListener), JSOP_WRAPPER(SetEventListener) },
-  { "navigator", SLOT_navigator, PROPERTY_FLAGS, JSOP_WRAPPER(GetNavigator),
-    JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { "self", 0, PROPERTY_FLAGS, JSOP_WRAPPER(GetSelf), JSOP_WRAPPER(js_GetterOnlyPropertyStub) },
-  { 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
+  JS_PSGS("location", GetLocation, GetterOnlyJSNative, JSPROP_ENUMERATE),
+  JS_PSGS(sEventStrings[STRING_onerror], GetOnErrorListener, SetOnErrorListener,
+          JSPROP_ENUMERATE),
+  JS_PSGS(sEventStrings[STRING_onclose], GetOnClose, SetOnClose,
+          JSPROP_ENUMERATE),
+  JS_PSGS("navigator", GetNavigator, GetterOnlyJSNative, JSPROP_ENUMERATE),
+  JS_PSGS("self", GetSelf, GetterOnlyJSNative, JSPROP_ENUMERATE),
+  JS_PS_END
 };
 
 const JSFunctionSpec WorkerGlobalScope::sFunctions[] = {
   JS_FN("close", Close, 0, FUNCTION_FLAGS),
   JS_FN("importScripts", ImportScripts, 1, FUNCTION_FLAGS),
   JS_FN("setTimeout", SetTimeout, 1, FUNCTION_FLAGS),
   JS_FN("clearTimeout", ClearTimeout, 1, FUNCTION_FLAGS),
   JS_FN("setInterval", SetInterval, 1, FUNCTION_FLAGS),
@@ -746,74 +767,85 @@ protected:
     MOZ_COUNT_DTOR(mozilla::dom::workers::DedicatedWorkerGlobalScope);
   }
 
 private:
   using EventTarget::GetEventListener;
   using EventTarget::SetEventListener;
 
   static bool
-  GetEventListener(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-                   JS::MutableHandle<JS::Value> aVp)
+  IsDedicatedWorkerGlobalScope(JS::Handle<JS::Value> v)
   {
-    JS_ASSERT(JSID_IS_INT(aIdval));
-    JS_ASSERT(JSID_TO_INT(aIdval) >= 0 && JSID_TO_INT(aIdval) < STRING_COUNT);
+    return v.isObject() && JS_GetClass(&v.toObject()) == Class();
+  }
 
-    const char* name = sEventStrings[JSID_TO_INT(aIdval)];
-    DedicatedWorkerGlobalScope* scope = GetInstancePrivate(aCx, aObj, name);
-    if (!scope) {
-      return false;
-    }
+  static bool
+  GetOnMessageImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    const char* name = sEventStrings[STRING_onmessage];
+    DedicatedWorkerGlobalScope* scope =
+      GetInstancePrivate(aCx, &aArgs.thisv().toObject(), name);
+    MOZ_ASSERT(scope);
 
     ErrorResult rv;
 
     JSObject* listener =
       scope->GetEventListener(NS_ConvertASCIItoUTF16(name + 2), rv);
 
     if (rv.Failed()) {
       JS_ReportError(aCx, "Failed to get event listener!");
       return false;
     }
 
-    aVp.set(listener ? OBJECT_TO_JSVAL(listener) : JSVAL_NULL);
+    aArgs.rval().setObjectOrNull(listener);
     return true;
   }
 
   static bool
-  SetEventListener(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aIdval,
-                   bool aStrict, JS::MutableHandle<JS::Value> aVp)
+  GetOnMessage(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
   {
-    JS_ASSERT(JSID_IS_INT(aIdval));
-    JS_ASSERT(JSID_TO_INT(aIdval) >= 0 && JSID_TO_INT(aIdval) < STRING_COUNT);
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsDedicatedWorkerGlobalScope, GetOnMessageImpl>(aCx, args);
+  }
 
-    const char* name = sEventStrings[JSID_TO_INT(aIdval)];
-    DedicatedWorkerGlobalScope* scope = GetInstancePrivate(aCx, aObj, name);
-    if (!scope) {
-      return false;
-    }
+  static bool
+  SetOnMessageImpl(JSContext* aCx, JS::CallArgs aArgs)
+  {
+    const char* name = sEventStrings[STRING_onmessage];
+    DedicatedWorkerGlobalScope* scope =
+      GetInstancePrivate(aCx, &aArgs.thisv().toObject(), name);
+    MOZ_ASSERT(scope);
 
-    if (JSVAL_IS_PRIMITIVE(aVp)) {
+    if (aArgs.length() == 0 || !aArgs[0].isObject()) {
       JS_ReportError(aCx, "Not an event listener!");
       return false;
     }
 
     ErrorResult rv;
 
-    JS::Rooted<JSObject*> listenerObj(aCx, JSVAL_TO_OBJECT(aVp));
+    JS::Rooted<JSObject*> listenerObj(aCx, &aArgs[0].toObject());
     scope->SetEventListener(NS_ConvertASCIItoUTF16(name + 2),
                             listenerObj, rv);
 
     if (rv.Failed()) {
       JS_ReportError(aCx, "Failed to set event listener!");
       return false;
     }
 
+    aArgs.rval().setUndefined();
     return true;
   }
 
+  static bool
+  SetOnMessage(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
+  {
+    JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
+    return JS::CallNonGenericMethod<IsDedicatedWorkerGlobalScope, SetOnMessageImpl>(aCx, args);
+  }
+
   static DedicatedWorkerGlobalScope*
   GetInstancePrivate(JSContext* aCx, JSObject* aObj, const char* aFunctionName)
   {
     JSClass* classPtr = JS_GetClass(aObj);
     if (classPtr == Class()) {
       return UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj);
     }
 
@@ -942,19 +974,19 @@ DOMIfaceAndProtoJSClass DedicatedWorkerG
   eInterfacePrototype,
   &sWorkerNativePropertyHooks,
   "[object DedicatedWorkerGlobalScope]",
   prototypes::id::_ID_Count,
   0
 };
 
 const JSPropertySpec DedicatedWorkerGlobalScope::sProperties[] = {
-  { sEventStrings[STRING_onmessage], STRING_onmessage, PROPERTY_FLAGS,
-    JSOP_WRAPPER(GetEventListener), JSOP_WRAPPER(SetEventListener) },
-  { 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
+  JS_PSGS(sEventStrings[STRING_onmessage], GetOnMessage, SetOnMessage,
+          JSPROP_ENUMERATE),
+  JS_PS_END
 };
 
 const JSFunctionSpec DedicatedWorkerGlobalScope::sFunctions[] = {
   JS_FN("postMessage", PostMessage, 1, FUNCTION_FLAGS),
   JS_FS_END
 };
 
 const char* const DedicatedWorkerGlobalScope::sEventStrings[STRING_COUNT] = {
@@ -975,16 +1007,22 @@ WorkerGlobalScope::GetInstancePrivate(JS
     return UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj);
   }
 
   JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
                        sClass.name, aFunctionName, classPtr->name);
   return NULL;
 }
 
+bool
+WorkerGlobalScope::IsWorkerGlobalScope(JS::Handle<JS::Value> v)
+{
+  return v.isObject() && JS_GetClass(&v.toObject()) == DedicatedWorkerGlobalScope::Class();
+}
+
 } /* anonymous namespace */
 
 BEGIN_WORKERS_NAMESPACE
 
 JSObject*
 CreateDedicatedWorkerGlobalScope(JSContext* aCx)
 {
   using namespace mozilla::dom;
--- a/dom/workers/Workers.h
+++ b/dom/workers/Workers.h
@@ -220,11 +220,19 @@ const uint32_t kJSPrincipalsDebugToken =
 namespace exceptions {
 
 // Implemented in Exceptions.cpp
 void
 ThrowDOMExceptionForNSResult(JSContext* aCx, nsresult aNSResult);
 
 } // namespace exceptions
 
+// Throws the JSMSG_GETTER_ONLY exception.  This shouldn't be used going
+// forward -- getter-only properties should just use JS_PSG for the setter
+// (implying no setter at all), which will not throw when set in non-strict
+// code but will in strict code.  Old code should use this only for temporary
+// compatibility reasons.
+extern bool
+GetterOnlyJSNative(JSContext* aCx, unsigned aArgc, JS::Value* aVp);
+
 END_WORKERS_NAMESPACE
 
 #endif // mozilla_dom_workers_workers_h__
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -475,21 +475,19 @@ BasicCompositor::EndFrame()
     mCopyTarget->SetOperator(gfxContext::OPERATOR_SOURCE);
     mCopyTarget->SetSource(thebes);
     mCopyTarget->Paint();
     mCopyTarget = nullptr;
   } else {
     // Most platforms require us to buffer drawing to the widget surface.
     // That's why we don't draw to mDrawTarget directly.
     RefPtr<SourceSurface> source = mRenderTarget->mDrawTarget->Snapshot();
-    mDrawTarget->DrawSurface(source,
-                             Rect(0, 0, mWidgetSize.width, mWidgetSize.height),
-                             Rect(0, 0, mWidgetSize.width, mWidgetSize.height),
-                             DrawSurfaceOptions(),
-                             DrawOptions());
+    mDrawTarget->CopySurface(source,
+	                     IntRect(0, 0, mWidgetSize.width, mWidgetSize.height),
+			     IntPoint(0, 0));
     mWidget->EndRemoteDrawing();
   }
   mDrawTarget = nullptr;
   mRenderTarget = nullptr;
 }
 
 void
 BasicCompositor::AbortFrame()
new file mode 100644
--- /dev/null
+++ b/gfx/src/AppUnits.h
@@ -0,0 +1,11 @@
+/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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/. */
+
+#ifndef _NS_APPUNITS_H_
+#define _NS_APPUNITS_H_
+namespace mozilla {
+static int32_t AppUnitsPerCSSPixel() { return 60; }
+}
+#endif /* _NS_APPUNITS_H_ */
--- a/gfx/src/moz.build
+++ b/gfx/src/moz.build
@@ -29,16 +29,20 @@ EXPORTS += [
     'nsRect.h',
     'nsRegion.h',
     'nsRenderingContext.h',
     'nsSize.h',
     'nsThemeConstants.h',
     'nsTransform2D.h',
 ]
 
+EXPORTS.mozilla += [
+    'AppUnits.h',
+]
+
 if CONFIG['MOZ_X11']:
     EXPORTS.mozilla += ['X11Util.h']
     CPP_SOURCES += [
         'X11Util.cpp',
     ]
 
 CPP_SOURCES += [
     'gfxCrashReporterUtils.cpp',
--- a/gfx/src/nsDeviceContext.h
+++ b/gfx/src/nsDeviceContext.h
@@ -12,16 +12,17 @@
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT_HELPER2
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMPtr.h"                   // for nsCOMPtr
 #include "nsCoord.h"                    // for nscoord
 #include "nsError.h"                    // for nsresult
 #include "nsISupports.h"                // for NS_INLINE_DECL_REFCOUNTING
 #include "nsMathUtils.h"                // for NS_round
 #include "nscore.h"                     // for PRUnichar, nsAString
+#include "mozilla/AppUnits.h"           // for AppUnits
 
 class gfxASurface;
 class gfxUserFontSet;
 class nsFont;
 class nsFontCache;
 class nsFontMetrics;
 class nsIAtom;
 class nsIDeviceContextSpec;
@@ -60,17 +61,17 @@ public:
      * @return error status
      */
     nsresult CreateRenderingContext(nsRenderingContext *&aContext);
 
     /**
      * Gets the number of app units in one CSS pixel; this number is global,
      * not unique to each device context.
      */
-    static int32_t AppUnitsPerCSSPixel() { return 60; }
+    static int32_t AppUnitsPerCSSPixel() { return mozilla::AppUnitsPerCSSPixel(); }
 
     /**
      * Gets the number of app units in one device pixel; this number
      * is usually a factor of AppUnitsPerCSSPixel(), although that is
      * not guaranteed.
      */
     int32_t AppUnitsPerDevPixel() const { return mAppUnitsPerDevPixel; }
 
--- a/ipc/chromium/moz.build
+++ b/ipc/chromium/moz.build
@@ -70,17 +70,16 @@ CPP_SOURCES += [
     'path_service.cc',
     'pickle.cc',
     'rand_util.cc',
     'ref_counted.cc',
     'revocable_store.cc',
     'scoped_temp_dir.cc',
     'simple_thread.cc',
     'stats_table.cc',
-    'string_escape.cc',
     'string_piece.cc',
     'string_util.cc',
     'system_monitor.cc',
     'task_queue.cc',
     'thread.cc',
     'thread_collision_warner.cc',
     'time.cc',
     'timer.cc',
deleted file mode 100644
--- a/ipc/chromium/src/base/foundation_utils_mac.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_FOUNDATION_UTILS_MAC_H_
-#define BASE_FOUNDATION_UTILS_MAC_H_
-
-#include <CoreFoundation/CoreFoundation.h>
-#import <Foundation/Foundation.h>
-
-// CFTypeRefToNSObjectAutorelease transfers ownership of a Core Foundation
-// object (one derived from CFTypeRef) to the Foundation memory management
-// system.  In a traditional managed-memory environment, cf_object is
-// autoreleased and returned as an NSObject.  In a garbage-collected
-// environment, cf_object is marked as eligible for garbage collection.
-//
-// This function should only be used to convert a concrete CFTypeRef type to
-// its equivalent "toll-free bridged" NSObject subclass, for example,
-// converting a CFStringRef to NSString.
-//
-// By calling this function, callers relinquish any ownership claim to
-// cf_object.  In a managed-memory environment, the object's ownership will be
-// managed by the innermost NSAutoreleasePool, so after this function returns,
-// callers should not assume that cf_object is valid any longer than the
-// returned NSObject.
-static inline id CFTypeRefToNSObjectAutorelease(CFTypeRef cf_object) {
-  // When GC is on, NSMakeCollectable marks cf_object for GC and autorelease
-  // is a no-op.
-  //
-  // In the traditional GC-less environment, NSMakeCollectable is a no-op,
-  // and cf_object is autoreleased, balancing out the caller's ownership claim.
-  //
-  // NSMakeCollectable returns nil when used on a NULL object.
-  return [NSMakeCollectable(cf_object) autorelease];
-}
-
-#endif  // BASE_FOUNDATION_UTILS_MAC_H_
--- a/ipc/chromium/src/base/mac_util.h
+++ b/ipc/chromium/src/base/mac_util.h
@@ -1,39 +1,15 @@
 // Copyright (c) 2008 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #ifndef BASE_MAC_UTIL_H_
 #define BASE_MAC_UTIL_H_
 
-struct FSRef;
-class FilePath;
-
-#ifdef __OBJC__
-@class NSBundle;
-#else
-class NSBundle;
-#endif
-
-#include <string>
-
 namespace mac_util {
 
-std::string PathFromFSRef(const FSRef& ref);
-bool FSRefFromPath(const std::string& path, FSRef* ref);
-
 // Returns true if the application is running from a bundle
 bool AmIBundled();
 
-// Returns the main bundle or the override, used for code that needs
-// to fetch resources from bundles, but work within a unittest where we
-// aren't a bundle.
-NSBundle* MainAppBundle();
-
-// Set the bundle that MainAppBundle will return, overriding the default value
-// (Restore the default by calling SetOverrideAppBundle(nil)).
-void SetOverrideAppBundle(NSBundle* bundle);
-void SetOverrideAppBundlePath(const FilePath& file_path);
-
 }  // namespace mac_util
 
 #endif  // BASE_MAC_UTIL_H_
--- a/ipc/chromium/src/base/mac_util.mm
+++ b/ipc/chromium/src/base/mac_util.mm
@@ -9,29 +9,16 @@
 
 #include "base/file_path.h"
 #include "base/logging.h"
 #include "base/scoped_cftyperef.h"
 #include "base/sys_string_conversions.h"
 
 namespace mac_util {
 
-std::string PathFromFSRef(const FSRef& ref) {
-  scoped_cftyperef<CFURLRef> url(
-      CFURLCreateFromFSRef(kCFAllocatorDefault, &ref));
-  NSString *path_string = [(NSURL *)url.get() path];
-  return [path_string fileSystemRepresentation];
-}
-
-bool FSRefFromPath(const std::string& path, FSRef* ref) {
-  OSStatus status = FSPathMakeRef((const UInt8*)path.c_str(),
-                                  ref, nil);
-  return status == noErr;
-}
-
 // Adapted from http://developer.apple.com/carbon/tipsandtricks.html#AmIBundled
 bool AmIBundled() {
   ProcessSerialNumber psn = {0, kCurrentProcess};
 
   FSRef fsref;
   if (GetProcessBundleLocation(&psn, &fsref) != noErr)
     return false;
 
@@ -39,31 +26,9 @@ bool AmIBundled() {
   if (FSGetCatalogInfo(&fsref, kFSCatInfoNodeFlags, &info,
                        NULL, NULL, NULL) != noErr) {
     return false;
   }
 
   return info.nodeFlags & kFSNodeIsDirectoryMask;
 }
 
-// No threading worries since NSBundle isn't thread safe.
-static NSBundle* g_override_app_bundle = nil;
-
-NSBundle* MainAppBundle() {
-  if (g_override_app_bundle)
-    return g_override_app_bundle;
-  return [NSBundle mainBundle];
-}
-
-void SetOverrideAppBundle(NSBundle* bundle) {
-  [g_override_app_bundle release];
-  g_override_app_bundle = [bundle retain];
-}
-
-void SetOverrideAppBundlePath(const FilePath& file_path) {
-  NSString* path = base::SysUTF8ToNSString(file_path.value());
-  NSBundle* bundle = [NSBundle bundleWithPath:path];
-  DCHECK(bundle) << "failed to load the bundle: " << file_path.value();
-
-  SetOverrideAppBundle(bundle);
-}
-
 }  // namespace mac_util
--- a/ipc/chromium/src/base/process.h
+++ b/ipc/chromium/src/base/process.h
@@ -60,30 +60,16 @@ class Process {
 
   // Set a prcess as backgrounded.  If value is true, the priority
   // of the process will be lowered.  If value is false, the priority
   // of the process will be made "normal" - equivalent to default
   // process priority.
   // Returns true if the priority was changed, false otherwise.
   bool SetProcessBackgrounded(bool value);
 
-  // Reduces the working set of memory used by the process.
-  // The algorithm used by this function is intentionally vague.  Repeated calls
-  // to this function consider the process' previous required Working Set sizes
-  // to determine a reasonable reduction.  This helps give memory back to the OS
-  // in increments without over releasing memory.
-  // When the WorkingSet is reduced, it is permanent, until the caller calls
-  // UnReduceWorkingSet.
-  // Returns true if successful, false otherwise.
-  bool ReduceWorkingSet();
-
-  // Undoes the effects of prior calls to ReduceWorkingSet().
-  // Returns true if successful, false otherwise.
-  bool UnReduceWorkingSet();
-
   // Releases as much of the working set back to the OS as possible.
   // Returns true if successful, false otherwise.
   bool EmptyWorkingSet();
 
  private:
   ProcessHandle process_;
   size_t last_working_set_size_;
 };
--- a/ipc/chromium/src/base/process_posix.cc
+++ b/ipc/chromium/src/base/process_posix.cc
@@ -31,26 +31,16 @@ bool Process::IsProcessBackgrounded() co
 bool Process::SetProcessBackgrounded(bool value) {
   // http://code.google.com/p/chromium/issues/detail?id=8083
   // Just say we did it to keep renderer happy at the moment.  Need to finish
   // cleaning this up w/in higher layers since windows is probably the only
   // one that can raise priorities w/o privileges.
   return true;
 }
 
-bool Process::ReduceWorkingSet() {
-  // http://code.google.com/p/chromium/issues/detail?id=8083
-  return false;
-}
-
-bool Process::UnReduceWorkingSet() {
-  // http://code.google.com/p/chromium/issues/detail?id=8083
-  return false;
-}
-
 bool Process::EmptyWorkingSet() {
   // http://code.google.com/p/chromium/issues/detail?id=8083
   return false;
 }
 
 ProcessId Process::pid() const {
   if (process_ == 0)
     return 0;
--- a/ipc/chromium/src/base/process_util.h
+++ b/ipc/chromium/src/base/process_util.h
@@ -185,97 +185,40 @@ bool LaunchApp(const std::vector<std::st
 // returns if privileges were successfully adjusted.
 void SetCurrentProcessPrivileges(ChildPrivileges privs);
 
 // Executes the application specified by cl. This function delegates to one
 // of the above two platform-specific functions.
 bool LaunchApp(const CommandLine& cl,
                bool wait, bool start_hidden, ProcessHandle* process_handle);
 
-#if defined(OS_WIN)
-// Executes the application specified by |cmd_line| and copies the contents
-// printed to the standard output to |output|, which should be non NULL.
-// Blocks until the started process terminates.
-// Returns true if the application was run successfully, false otherwise.
-bool GetAppOutput(const std::wstring& cmd_line, std::string* output);
-#elif defined(OS_POSIX)
-// Executes the application specified by |cl| and wait for it to exit. Stores
-// the output (stdout) in |output|. Redirects stderr to /dev/null. Returns true
-// on success (application launched and exited cleanly, with exit code
-// indicating success). |output| is modified only when the function finished
-// successfully.
-bool GetAppOutput(const CommandLine& cl, std::string* output);
-#endif
-
 // Used to filter processes by process ID.
 class ProcessFilter {
  public:
   // Returns true to indicate set-inclusion and false otherwise.  This method
   // should not have side-effects and should be idempotent.
   virtual bool Includes(ProcessId pid, ProcessId parent_pid) const = 0;
   virtual ~ProcessFilter() { }
 };
 
-// Returns the number of processes on the machine that are running from the
-// given executable name.  If filter is non-null, then only processes selected
-// by the filter will be counted.
-int GetProcessCount(const std::wstring& executable_name,
-                    const ProcessFilter* filter);
-
-// Attempts to kill all the processes on the current machine that were launched
-// from the given executable name, ending them with the given exit code.  If
-// filter is non-null, then only processes selected by the filter are killed.
-// Returns false if all processes were able to be killed off, false if at least
-// one couldn't be killed.
-bool KillProcesses(const std::wstring& executable_name, int exit_code,
-                   const ProcessFilter* filter);
-
 // Attempts to kill the process identified by the given process
 // entry structure, giving it the specified exit code. If |wait| is true, wait
 // for the process to be actually terminated before returning.
 // Returns true if this is successful, false otherwise.
 bool KillProcess(ProcessHandle process, int exit_code, bool wait);
-#if defined(OS_WIN)
-bool KillProcessById(ProcessId process_id, int exit_code, bool wait);
-#endif
 
 // Get the termination status (exit code) of the process and return true if the
 // status indicates the process crashed. |child_exited| is set to true iff the
 // child process has terminated. (|child_exited| may be NULL.)
 //
 // On Windows, it is an error to call this if the process hasn't terminated
 // yet. On POSIX, |child_exited| is set correctly since we detect terminate in
 // a different manner on POSIX.
 bool DidProcessCrash(bool* child_exited, ProcessHandle handle);
 
-// Waits for process to exit. In POSIX systems, if the process hasn't been
-// signaled then puts the exit code in |exit_code|; otherwise it's considered
-// a failure. On Windows |exit_code| is always filled. Returns true on success,
-// and closes |handle| in any case.
-bool WaitForExitCode(ProcessHandle handle, int* exit_code);
-
-// Wait for all the processes based on the named executable to exit.  If filter
-// is non-null, then only processes selected by the filter are waited on.
-// Returns after all processes have exited or wait_milliseconds have expired.
-// Returns true if all the processes exited, false otherwise.
-bool WaitForProcessesToExit(const std::wstring& executable_name,
-                            int wait_milliseconds,
-                            const ProcessFilter* filter);
-
-// Waits a certain amount of time (can be 0) for all the processes with a given
-// executable name to exit, then kills off any of them that are still around.
-// If filter is non-null, then only processes selected by the filter are waited
-// on.  Killed processes are ended with the given exit code.  Returns false if
-// any processes needed to be killed, true if they all exited cleanly within
-// the wait_milliseconds delay.
-bool CleanupProcesses(const std::wstring& executable_name,
-                      int wait_milliseconds,
-                      int exit_code,
-                      const ProcessFilter* filter);
-
 // This class provides a way to iterate through the list of processes
 // on the current machine that were started from the given executable
 // name.  To use, create an instance and then call NextProcessEntry()
 // until it returns false.
 class NamedProcessIterator {
  public:
   NamedProcessIterator(const std::wstring& executable_name,
                        const ProcessFilter* filter);
@@ -319,81 +262,28 @@ class NamedProcessIterator {
 #if !defined(OS_BSD) || defined(__GLIBC__)
   ProcessEntry entry_;
   const ProcessFilter* filter_;
 #endif
 
   DISALLOW_EVIL_CONSTRUCTORS(NamedProcessIterator);
 };
 
-// Working Set (resident) memory usage broken down by
-// priv (private): These pages (kbytes) cannot be shared with any other process.
-// shareable:      These pages (kbytes) can be shared with other processes under
-//                 the right circumstances.
-// shared :        These pages (kbytes) are currently shared with at least one
-//                 other process.
-struct WorkingSetKBytes {
-  size_t priv;
-  size_t shareable;
-  size_t shared;
-};
-
-// Committed (resident + paged) memory usage broken down by
-// private: These pages cannot be shared with any other process.
-// mapped:  These pages are mapped into the view of a section (backed by
-//          pagefile.sys)
-// image:   These pages are mapped into the view of an image section (backed by
-//          file system)
-struct CommittedKBytes {
-  size_t priv;
-  size_t mapped;
-  size_t image;
-};
-
-// Free memory (Megabytes marked as free) in the 2G process address space.
-// total : total amount in megabytes marked as free. Maximum value is 2048.
-// largest : size of the largest contiguous amount of memory found. It is
-//   always smaller or equal to FreeMBytes::total.
-// largest_ptr: starting address of the largest memory block.
-struct FreeMBytes {
-  size_t total;
-  size_t largest;
-  void* largest_ptr;
-};
-
 // Provides performance metrics for a specified process (CPU usage, memory and
 // IO counters). To use it, invoke CreateProcessMetrics() to get an instance
 // for a specific process, then access the information with the different get
 // methods.
 class ProcessMetrics {
  public:
   // Creates a ProcessMetrics for the specified process.
   // The caller owns the returned object.
   static ProcessMetrics* CreateProcessMetrics(ProcessHandle process);
 
   ~ProcessMetrics();
 
-  // Returns the current space allocated for the pagefile, in bytes (these pages
-  // may or may not be in memory).
-  size_t GetPagefileUsage() const;
-  // Returns the peak space allocated for the pagefile, in bytes.
-  size_t GetPeakPagefileUsage() const;
-  // Returns the current working set size, in bytes.
-  size_t GetWorkingSetSize() const;
-  // Returns private usage, in bytes. Private bytes is the amount
-  // of memory currently allocated to a process that cannot be shared.
-  // Note: returns 0 on unsupported OSes: prior to XP SP2.
-  size_t GetPrivateBytes() const;
-  // Fills a CommittedKBytes with both resident and paged
-  // memory usage as per definition of CommittedBytes.
-  void GetCommittedKBytes(CommittedKBytes* usage) const;
-  // Fills a WorkingSetKBytes containing resident private and shared memory
-  // usage in bytes, as per definition of WorkingSetBytes.
-  bool GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const;
-
   // Returns the CPU usage in percent since the last time this method was
   // called. The first time this method is called it returns 0 and will return
   // the actual CPU info on subsequent calls.
   // Note that on multi-processor machines, the CPU usage value is for all
   // CPUs. So if you have 2 CPUs and your process is using all the cycles
   // of 1 CPU and not the other CPU, this method returns 50.
   int GetCPUUsage();
 
--- a/ipc/chromium/src/base/process_util_posix.cc
+++ b/ipc/chromium/src/base/process_util_posix.cc
@@ -275,33 +275,16 @@ bool DidProcessCrash(bool* child_exited,
   }
 
   if (WIFEXITED(status))
     return WEXITSTATUS(status) != 0;
 
   return false;
 }
 
-bool WaitForExitCode(ProcessHandle handle, int* exit_code) {
-  int status;
-  if (HANDLE_EINTR(waitpid(handle, &status, 0)) == -1) {
-    NOTREACHED();
-    return false;
-  }
-
-  if (WIFEXITED(status)) {
-    *exit_code = WEXITSTATUS(status);
-    return true;
-  }
-
-  // If it didn't exit cleanly, it must have been signaled.
-  DCHECK(WIFSIGNALED(status));
-  return false;
-}
-
 namespace {
 
 int64_t TimeValToMicroseconds(const struct timeval& tv) {
   return tv.tv_sec * kMicrosecondsPerSecond + tv.tv_usec;
 }
 
 }
 
@@ -339,147 +322,9 @@ int ProcessMetrics::GetCPUUsage() {
                              time_delta);
 
   last_system_time_ = system_time;
   last_time_ = time;
 
   return cpu;
 }
 
-bool GetAppOutput(const CommandLine& cl, std::string* output) {
-  int pipe_fd[2];
-  pid_t pid;
-
-  // Illegal to allocate memory after fork and before execvp
-  InjectiveMultimap fd_shuffle1, fd_shuffle2;
-  fd_shuffle1.reserve(3);
-  fd_shuffle2.reserve(3);
-  const std::vector<std::string>& argv = cl.argv();
-  scoped_array<char*> argv_cstr(new char*[argv.size() + 1]);
-
-  if (pipe(pipe_fd) < 0)
-    return false;
-
-  switch (pid = fork()) {
-    case -1:  // error
-      close(pipe_fd[0]);
-      close(pipe_fd[1]);
-      return false;
-    case 0:  // child
-      {
-        // Obscure fork() rule: in the child, if you don't end up doing exec*(),
-        // you call _exit() instead of exit(). This is because _exit() does not
-        // call any previously-registered (in the parent) exit handlers, which
-        // might do things like block waiting for threads that don't even exist
-        // in the child.
-        int dev_null = open("/dev/null", O_WRONLY);
-        if (dev_null < 0)
-          _exit(127);
-
-        fd_shuffle1.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true));
-        fd_shuffle1.push_back(InjectionArc(dev_null, STDERR_FILENO, true));
-        fd_shuffle1.push_back(InjectionArc(dev_null, STDIN_FILENO, true));
-        // Adding another element here? Remeber to increase the argument to
-        // reserve(), above.
-
-        std::copy(fd_shuffle1.begin(), fd_shuffle1.end(),
-                  std::back_inserter(fd_shuffle2));
-
-        // fd_shuffle1 is mutated by this call because it cannot malloc.
-        if (!ShuffleFileDescriptors(&fd_shuffle1))
-          _exit(127);
-
-        CloseSuperfluousFds(fd_shuffle2);
-
-        for (size_t i = 0; i < argv.size(); i++)
-          argv_cstr[i] = const_cast<char*>(argv[i].c_str());
-        argv_cstr[argv.size()] = NULL;
-        execvp(argv_cstr[0], argv_cstr.get());
-        _exit(127);
-      }
-    default:  // parent
-      {
-        // Close our writing end of pipe now. Otherwise later read would not
-        // be able to detect end of child's output (in theory we could still
-        // write to the pipe).
-        close(pipe_fd[1]);
-
-        int exit_code = EXIT_FAILURE;
-        bool success = WaitForExitCode(pid, &exit_code);
-        if (!success || exit_code != EXIT_SUCCESS) {
-          close(pipe_fd[0]);
-          return false;
-        }
-
-        char buffer[256];
-        std::string buf_output;
-
-        while (true) {
-          ssize_t bytes_read =
-              HANDLE_EINTR(read(pipe_fd[0], buffer, sizeof(buffer)));
-          if (bytes_read <= 0)
-            break;
-          buf_output.append(buffer, bytes_read);
-        }
-        output->swap(buf_output);
-        close(pipe_fd[0]);
-        return true;
-      }
-  }
-}
-
-int GetProcessCount(const std::wstring& executable_name,
-                    const ProcessFilter* filter) {
-  int count = 0;
-
-  NamedProcessIterator iter(executable_name, filter);
-  while (iter.NextProcessEntry())
-    ++count;
-  return count;
-}
-
-bool KillProcesses(const std::wstring& executable_name, int exit_code,
-                   const ProcessFilter* filter) {
-  bool result = true;
-  const ProcessEntry* entry;
-
-  NamedProcessIterator iter(executable_name, filter);
-  while ((entry = iter.NextProcessEntry()) != NULL)
-    result = KillProcess((*entry).pid, exit_code, true) && result;
-
-  return result;
-}
-
-bool WaitForProcessesToExit(const std::wstring& executable_name,
-                            int wait_milliseconds,
-                            const ProcessFilter* filter) {
-  bool result = false;
-
-  // TODO(port): This is inefficient, but works if there are multiple procs.
-  // TODO(port): use waitpid to avoid leaving zombies around
-
-  base::Time end_time = base::Time::Now() +
-      base::TimeDelta::FromMilliseconds(wait_milliseconds);
-  do {
-    NamedProcessIterator iter(executable_name, filter);
-    if (!iter.NextProcessEntry()) {
-      result = true;
-      break;
-    }
-    PlatformThread::Sleep(100);
-  } while ((base::Time::Now() - end_time) > base::TimeDelta());
-
-  return result;
-}
-
-bool CleanupProcesses(const std::wstring& executable_name,
-                      int wait_milliseconds,
-                      int exit_code,
-                      const ProcessFilter* filter) {
-  bool exited_cleanly =
-      WaitForProcessesToExit(executable_name, wait_milliseconds,
-                           filter);
-  if (!exited_cleanly)
-    KillProcesses(executable_name, exit_code, filter);
-  return exited_cleanly;
-}
-
 }  // namespace base
--- a/ipc/chromium/src/base/process_util_win.cc
+++ b/ipc/chromium/src/base/process_util_win.cc
@@ -350,107 +350,16 @@ bool LaunchApp(const std::wstring& cmdli
 }
 
 bool LaunchApp(const CommandLine& cl,
                bool wait, bool start_hidden, ProcessHandle* process_handle) {
   return LaunchApp(cl.command_line_string(), wait,
                    start_hidden, process_handle);
 }
 
-// Attempts to kill the process identified by the given process
-// entry structure, giving it the specified exit code.
-// Returns true if this is successful, false otherwise.
-bool KillProcessById(ProcessId process_id, int exit_code, bool wait) {
-  HANDLE process = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE,
-                               FALSE,  // Don't inherit handle
-                               process_id);
-  if (!process)
-    return false;
-
-  bool ret = KillProcess(process, exit_code, wait);
-  CloseHandle(process);
-  return ret;
-}
-
-bool GetAppOutput(const std::wstring& cmd_line, std::string* output) {
-  if (!output) {
-    NOTREACHED();
-    return false;
-  }
-
-  HANDLE out_read = NULL;
-  HANDLE out_write = NULL;
-
-  SECURITY_ATTRIBUTES sa_attr;
-  // Set the bInheritHandle flag so pipe handles are inherited.
-  sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
-  sa_attr.bInheritHandle = TRUE;
-  sa_attr.lpSecurityDescriptor = NULL;
-
-  // Create the pipe for the child process's STDOUT.
-  if (!CreatePipe(&out_read, &out_write, &sa_attr, 0)) {
-    NOTREACHED() << "Failed to create pipe";
-    return false;
-  }
-
-  // Ensure we don't leak the handles.
-  ScopedHandle scoped_out_read(out_read);
-  ScopedHandle scoped_out_write(out_write);
-
-  // Ensure the read handle to the pipe for STDOUT is not inherited.
-  if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) {
-    NOTREACHED() << "Failed to disabled pipe inheritance";
-    return false;
-  }
-
-  // Now create the child process
-  PROCESS_INFORMATION proc_info = { 0 };
-  STARTUPINFO start_info = { 0 };
-
-  start_info.cb = sizeof(STARTUPINFO);
-  start_info.hStdOutput = out_write;
-  // Keep the normal stdin and stderr.
-  start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
-  start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
-  start_info.dwFlags |= STARTF_USESTDHANDLES;
-
-  // Create the child process.
-  if (!CreateProcess(NULL, const_cast<wchar_t*>(cmd_line.c_str()), NULL, NULL,
-                     TRUE,  // Handles are inherited.
-                     0, NULL, NULL, &start_info, &proc_info)) {
-    NOTREACHED() << "Failed to start process";
-    return false;
-  }
-
-  // We don't need the thread handle, close it now.
-  CloseHandle(proc_info.hThread);
-
-  // Close our writing end of pipe now. Otherwise later read would not be able
-  // to detect end of child's output.
-  scoped_out_write.Close();
-
-  // Read output from the child process's pipe for STDOUT
-  const int kBufferSize = 1024;
-  char buffer[kBufferSize];
-
-  for (;;) {
-    DWORD bytes_read = 0;
-    BOOL success = ReadFile(out_read, buffer, kBufferSize, &bytes_read, NULL);
-    if (!success || bytes_read == 0)
-      break;
-    output->append(buffer, bytes_read);
-  }
-
-  // Let's wait for the process to finish.
-  WaitForSingleObject(proc_info.hProcess, INFINITE);
-  CloseHandle(proc_info.hProcess);
-
-  return true;
-}
-
 bool KillProcess(ProcessHandle process, int exit_code, bool wait) {
   bool result = (TerminateProcess(process, exit_code) != FALSE);
   if (result && wait) {
     // The process may not end immediately due to pending I/O
     if (WAIT_OBJECT_0 != WaitForSingleObject(process, 60 * 1000))
       DLOG(ERROR) << "Error waiting for process exit: " << GetLastError();
   } else if (!result) {
     DLOG(ERROR) << "Unable to terminate process: " << GetLastError();
@@ -484,29 +393,16 @@ bool DidProcessCrash(bool* child_exited,
       exitcode == 0xC000013A ||     // Control-C/end session.
       exitcode == 0x40010004) {     // Debugger terminated process/end session.
     return false;
   }
 
   return true;
 }
 
-bool WaitForExitCode(ProcessHandle handle, int* exit_code) {
-  ScopedHandle closer(handle);  // Ensure that we always close the handle.
-  if (::WaitForSingleObject(handle, INFINITE) != WAIT_OBJECT_0) {
-    NOTREACHED();
-    return false;
-  }
-  DWORD temp_code;  // Don't clobber out-parameters in case of failure.
-  if (!::GetExitCodeProcess(handle, &temp_code))
-    return false;
-  *exit_code = temp_code;
-  return true;
-}
-
 void SetCurrentProcessPrivileges(ChildPrivileges privs) {
 
 }
 
 NamedProcessIterator::NamedProcessIterator(const std::wstring& executable_name,
                                            const ProcessFilter* filter)
     : started_iteration_(false),
       executable_name_(executable_name),
@@ -549,75 +445,16 @@ bool NamedProcessIterator::IncludeEntry(
                                                  entry_.th32ParentProcessID));
 }
 
 void NamedProcessIterator::InitProcessEntry(ProcessEntry* entry) {
   memset(entry, 0, sizeof(*entry));
   entry->dwSize = sizeof(*entry);
 }
 
-int GetProcessCount(const std::wstring& executable_name,
-                    const ProcessFilter* filter) {
-  int count = 0;
-
-  NamedProcessIterator iter(executable_name, filter);
-  while (iter.NextProcessEntry())
-    ++count;
-  return count;
-}
-
-bool KillProcesses(const std::wstring& executable_name, int exit_code,
-                   const ProcessFilter* filter) {
-  bool result = true;
-  const ProcessEntry* entry;
-
-  NamedProcessIterator iter(executable_name, filter);
-  while (entry = iter.NextProcessEntry()) {
-    if (!KillProcessById((*entry).th32ProcessID, exit_code, true))
-      result = false;
-  }
-
-  return result;
-}
-
-bool WaitForProcessesToExit(const std::wstring& executable_name,
-                            int wait_milliseconds,
-                            const ProcessFilter* filter) {
-  const ProcessEntry* entry;
-  bool result = true;
-  DWORD start_time = GetTickCount();
-
-  NamedProcessIterator iter(executable_name, filter);
-  while (entry = iter.NextProcessEntry()) {
-    DWORD remaining_wait =
-      std::max(0, wait_milliseconds -
-          static_cast<int>(GetTickCount() - start_time));
-    HANDLE process = OpenProcess(SYNCHRONIZE,
-                                 FALSE,
-                                 entry->th32ProcessID);
-    DWORD wait_result = WaitForSingleObject(process, remaining_wait);
-    CloseHandle(process);
-    result = result && (wait_result == WAIT_OBJECT_0);
-  }
-
-  return result;
-}
-
-bool CleanupProcesses(const std::wstring& executable_name,
-                      int wait_milliseconds,
-                      int exit_code,
-                      const ProcessFilter* filter) {
-  bool exited_cleanly = WaitForProcessesToExit(executable_name,
-                                               wait_milliseconds,
-                                               filter);
-  if (!exited_cleanly)
-    KillProcesses(executable_name, exit_code, filter);
-  return exited_cleanly;
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // ProcesMetrics
 
 ProcessMetrics::ProcessMetrics(ProcessHandle process) : process_(process),
                                                         last_time_(0),
                                                         last_system_time_(0) {
   SYSTEM_INFO system_info;
   GetSystemInfo(&system_info);
@@ -626,161 +463,16 @@ ProcessMetrics::ProcessMetrics(ProcessHa
 
 // static
 ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) {
   return new ProcessMetrics(process);
 }
 
 ProcessMetrics::~ProcessMetrics() { }
 
-size_t ProcessMetrics::GetPagefileUsage() const {
-  PROCESS_MEMORY_COUNTERS pmc;
-  if (GetProcessMemoryInfo(process_, &pmc, sizeof(pmc))) {
-    return pmc.PagefileUsage;
-  }
-  return 0;
-}
-
-// Returns the peak space allocated for the pagefile, in bytes.
-size_t ProcessMetrics::GetPeakPagefileUsage() const {
-  PROCESS_MEMORY_COUNTERS pmc;
-  if (GetProcessMemoryInfo(process_, &pmc, sizeof(pmc))) {
-    return pmc.PeakPagefileUsage;
-  }
-  return 0;
-}
-
-// Returns the current working set size, in bytes.
-size_t ProcessMetrics::GetWorkingSetSize() const {
-  PROCESS_MEMORY_COUNTERS pmc;
-  if (GetProcessMemoryInfo(process_, &pmc, sizeof(pmc))) {
-    return pmc.WorkingSetSize;
-  }
-  return 0;
-}
-
-size_t ProcessMetrics::GetPrivateBytes() const {
-  // PROCESS_MEMORY_COUNTERS_EX is not supported until XP SP2.
-  // GetProcessMemoryInfo() will simply fail on prior OS. So the requested
-  // information is simply not available. Hence, we will return 0 on unsupported
-  // OSes. Unlike most Win32 API, we don't need to initialize the "cb" member.
-  PROCESS_MEMORY_COUNTERS_EX pmcx;
-  if (GetProcessMemoryInfo(process_,
-                          reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&pmcx),
-                          sizeof(pmcx))) {
-      return pmcx.PrivateUsage;
-  }
-  return 0;
-}
-
-void ProcessMetrics::GetCommittedKBytes(CommittedKBytes* usage) const {
-  MEMORY_BASIC_INFORMATION mbi = {0};
-  size_t committed_private = 0;
-  size_t committed_mapped = 0;
-  size_t committed_image = 0;
-  void* base_address = NULL;
-  while (VirtualQueryEx(process_, base_address, &mbi, sizeof(mbi)) ==
-      sizeof(mbi)) {
-    if (mbi.State == MEM_COMMIT) {
-      if (mbi.Type == MEM_PRIVATE) {
-        committed_private += mbi.RegionSize;
-      } else if (mbi.Type == MEM_MAPPED) {
-        committed_mapped += mbi.RegionSize;
-      } else if (mbi.Type == MEM_IMAGE) {
-        committed_image += mbi.RegionSize;
-      } else {
-        NOTREACHED();
-      }
-    }
-    void* new_base = (static_cast<BYTE*>(mbi.BaseAddress)) + mbi.RegionSize;
-    // Avoid infinite loop by weird MEMORY_BASIC_INFORMATION.
-    // If we query 64bit processes in a 32bit process, VirtualQueryEx()
-    // returns such data.
-    if (new_base <= base_address) {
-      usage->image = 0;
-      usage->mapped = 0;
-      usage->priv = 0;
-      return;
-    }
-    base_address = new_base;
-  }
-  usage->image = committed_image / 1024;
-  usage->mapped = committed_mapped / 1024;
-  usage->priv = committed_private / 1024;
-}
-
-bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const {
-  size_t ws_private = 0;
-  size_t ws_shareable = 0;
-  size_t ws_shared = 0;
-
-  DCHECK(ws_usage);
-  memset(ws_usage, 0, sizeof(*ws_usage));
-
-  DWORD number_of_entries = 4096;  // Just a guess.
-  PSAPI_WORKING_SET_INFORMATION* buffer = NULL;
-  int retries = 5;
-  for (;;) {
-    DWORD buffer_size = sizeof(PSAPI_WORKING_SET_INFORMATION) +
-                        (number_of_entries * sizeof(PSAPI_WORKING_SET_BLOCK));
-
-    // if we can't expand the buffer, don't leak the previous
-    // contents or pass a NULL pointer to QueryWorkingSet
-    PSAPI_WORKING_SET_INFORMATION* new_buffer =
-        reinterpret_cast<PSAPI_WORKING_SET_INFORMATION*>(
-            realloc(buffer, buffer_size));
-    if (!new_buffer) {
-      free(buffer);
-      return false;
-    }
-    buffer = new_buffer;
-
-    // Call the function once to get number of items
-    if (QueryWorkingSet(process_, buffer, buffer_size))
-      break;  // Success
-
-    if (GetLastError() != ERROR_BAD_LENGTH) {
-      free(buffer);
-      return false;
-    }
-
-    number_of_entries = static_cast<DWORD>(buffer->NumberOfEntries);
-
-    // Maybe some entries are being added right now. Increase the buffer to
-    // take that into account.
-    number_of_entries = static_cast<DWORD>(number_of_entries * 1.25);
-
-    if (--retries == 0) {
-      free(buffer);  // If we're looping, eventually fail.
-      return false;
-    }
-  }
-
-  // On windows 2000 the function returns 1 even when the buffer is too small.
-  // The number of entries that we are going to parse is the minimum between the
-  // size we allocated and the real number of entries.
-  number_of_entries =
-      std::min(number_of_entries, static_cast<DWORD>(buffer->NumberOfEntries));
-  for (unsigned int i = 0; i < number_of_entries; i++) {
-    if (buffer->WorkingSetInfo[i].Shared) {
-      ws_shareable++;
-      if (buffer->WorkingSetInfo[i].ShareCount > 1)
-        ws_shared++;
-    } else {
-      ws_private++;
-    }
-  }
-
-  ws_usage->priv = ws_private * PAGESIZE_KB;
-  ws_usage->shareable = ws_shareable * PAGESIZE_KB;
-  ws_usage->shared = ws_shared * PAGESIZE_KB;
-  free(buffer);
-  return true;
-}
-
 static uint64_t FileTimeToUTC(const FILETIME& ftime) {
   LARGE_INTEGER li;
   li.LowPart = ftime.dwLowDateTime;
   li.HighPart = ftime.dwHighDateTime;
   return li.QuadPart;
 }
 
 int ProcessMetrics::GetCPUUsage() {
--- a/ipc/chromium/src/base/process_win.cc
+++ b/ipc/chromium/src/base/process_win.cc
@@ -31,79 +31,16 @@ bool Process::IsProcessBackgrounded() co
 }
 
 bool Process::SetProcessBackgrounded(bool value) {
   DCHECK(process_);
   DWORD priority = value ? BELOW_NORMAL_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS;
   return (SetPriorityClass(process_, priority) != 0);
 }
 
-// According to MSDN, these are the default values which XP
-// uses to govern working set soft limits.
-// http://msdn.microsoft.com/en-us/library/ms686234.aspx
-static const int kWinDefaultMinSet = 50 * 4096;
-static const int kWinDefaultMaxSet = 345 * 4096;
-static const int kDampingFactor = 2;
-
-bool Process::ReduceWorkingSet() {
-  if (!process_)
-    return false;
-  // The idea here is that when we the process' working set has gone
-  // down, we want to release those pages to the OS quickly.  However,
-  // when it is not going down, we want to be careful not to release
-  // too much back to the OS, as it could cause additional paging.
-
-  // We use a damping function to lessen the working set over time.
-  // As the process grows/shrinks, this algorithm will lag with
-  // working set reduction.
-  //
-  // The intended algorithm is:
-  //   TargetWorkingSetSize = (LastWorkingSet/2 + CurrentWorkingSet) /2
-
-  scoped_ptr<ProcessMetrics> metrics(
-      ProcessMetrics::CreateProcessMetrics(process_));
-  WorkingSetKBytes working_set;
-  if (!metrics->GetWorkingSetKBytes(&working_set))
-    return false;
-
-
-  // We want to compute the amount of working set that the process
-  // needs to keep in memory.  Since other processes contain the
-  // pages which are shared, we don't need to reserve them in our
-  // process, the system already has them tagged.  Keep in mind, we
-  // don't get to control *which* pages get released, but if we
-  // assume reasonable distribution of pages, this should generally
-  // be the right value.
-  size_t current_working_set_size  = working_set.priv +
-                                     working_set.shareable;
-
-  size_t max_size = current_working_set_size;
-  if (last_working_set_size_)
-    max_size = (max_size + last_working_set_size_) / 2;  // Average.
-  max_size *= 1024;  // Convert to KBytes.
-  last_working_set_size_ = current_working_set_size / kDampingFactor;
-
-  BOOL rv = SetProcessWorkingSetSize(process_, kWinDefaultMinSet, max_size);
-  return rv == TRUE;
-}
-
-bool Process::UnReduceWorkingSet() {
-  if (!process_)
-    return false;
-
-  if (!last_working_set_size_)
-    return true;  // There was nothing to undo.
-
-  // We've had a reduced working set.  Make sure we have lots of
-  // headroom now that we're active again.
-  size_t limit = last_working_set_size_ * kDampingFactor * 2 * 1024;
-  BOOL rv = SetProcessWorkingSetSize(process_, kWinDefaultMinSet, limit);
-  return rv == TRUE;
-}
-
 bool Process::EmptyWorkingSet() {
   if (!process_)
     return false;
 
   BOOL rv = SetProcessWorkingSetSize(process_, -1, -1);
   return rv == TRUE;
 }
 
deleted file mode 100644
--- a/ipc/chromium/src/base/string_escape.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/string_escape.h"
-
-#include <string>
-
-#include "base/string_util.h"
-
-namespace string_escape {
-
-// Try to escape |c| as a "SingleEscapeCharacter" (\n, etc).  If successful,
-// returns true and appends the escape sequence to |dst|.
-template<typename CHAR>
-static bool JavascriptSingleEscapeChar(const CHAR c, std::string* dst) {
-  // WARNING: if you add a new case here, you need to update the reader as well.
-  switch (c) {
-    case '\b':
-      dst->append("\\b");
-      break;
-    case '\f':
-      dst->append("\\f");
-      break;
-    case '\n':
-      dst->append("\\n");
-      break;
-    case '\r':
-      dst->append("\\r");
-      break;
-    case '\t':
-      dst->append("\\t");
-      break;
-    case '\v':
-      dst->append("\\v");
-      break;
-    case '\\':
-      dst->append("\\\\");
-      break;
-    case '"':
-      dst->append("\\\"");
-      break;
-    default:
-      return false;
-  }
-  return true;
-}
-
-void JavascriptDoubleQuote(const string16& str,
-                           bool put_in_quotes,
-                           std::string* dst) {
-  if (put_in_quotes)
-    dst->push_back('"');
-
-  for (string16::const_iterator it = str.begin(); it != str.end(); ++it) {
-    char16 c = *it;
-    if (!JavascriptSingleEscapeChar(c, dst)) {
-      if (c > 255) {
-        // Non-ascii values need to be unicode dst->
-        // TODO(tc): Some unicode values are handled specially. See
-        // spidermonkey code.
-        StringAppendF(dst, "\\u%04X", c);
-      } else if (c < 32 || c > 126) {
-        // Spidermonkey hex escapes these values.
-        StringAppendF(dst, "\\x%02X", c);
-      } else {
-        dst->push_back(static_cast<char>(c));
-      }
-    }
-  }
-
-  if (put_in_quotes)
-    dst->push_back('"');
-}
-
-void JavascriptDoubleQuote(const std::string& str,
-                           bool put_in_quotes,
-                           std::string* dst) {
-  if (put_in_quotes)
-    dst->push_back('"');
-
-  for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) {
-    unsigned char c = *it;
-    if (!JavascriptSingleEscapeChar(c, dst)) {
-      // Hex encode if the character is non-printable 7bit ascii
-      if (c < 32 || c == 127) {
-        StringAppendF(dst, "\\x%02X", c);
-      } else {
-        dst->push_back(static_cast<char>(c));
-      }
-    }
-  }
-
-  if (put_in_quotes)
-    dst->push_back('"');
-}
-
-}  // namespace string_escape
deleted file mode 100644
--- a/ipc/chromium/src/base/string_escape.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// This file defines utility functions for escaping strings.
-
-#ifndef BASE_STRING_ESCAPE_H__
-#define BASE_STRING_ESCAPE_H__
-
-#include "base/string16.h"
-
-namespace string_escape {
-
-// Escape |str| appropriately for a javascript string litereal, _appending_ the
-// result to |dst|. This will create standard escape sequences (\b, \n),
-// hex escape sequences (\x00), and unicode escape sequences (\uXXXX).
-// If |put_in_quotes| is true, the result will be surrounded in double quotes.
-// The outputted literal, when interpreted by the browser, should result in a
-// javascript string that is identical and the same length as the input |str|.
-void JavascriptDoubleQuote(const string16& str,
-                           bool put_in_quotes,
-                           std::string* dst);
-
-// Similar to the wide version, but for narrow strings.  It will not use
-// \uXXXX unicode escape sequences.  It will pass non-7bit characters directly
-// into the string unencoded, allowing the browser to interpret the encoding.
-// The outputted literal, when interpreted by the browser, could result in a
-// javascript string of a different length than the input |str|.
-void JavascriptDoubleQuote(const std::string& str,
-                           bool put_in_quotes,
-                           std::string* dst);
-
-}  // namespace string_escape
-
-#endif  // BASE_STRING_ESCAPE_H__
--- a/ipc/chromium/src/base/string_util.h
+++ b/ipc/chromium/src/base/string_util.h
@@ -213,54 +213,23 @@ std::wstring StringPrintf(const wchar_t*
 const std::string& SStringPrintf(std::string* dst, const char* format, ...);
 const std::wstring& SStringPrintf(std::wstring* dst,
                                   const wchar_t* format, ...);
 
 // Append result to a supplied string
 void StringAppendF(std::string* dst, const char* format, ...);
 void StringAppendF(std::wstring* dst, const wchar_t* format, ...);
 
-// This is mpcomplete's pattern for saving a string copy when dealing with
-// a function that writes results into a wchar_t[] and wanting the result to
-// end up in a std::wstring.  It ensures that the std::wstring's internal
-// buffer has enough room to store the characters to be written into it, and
-// sets its .length() attribute to the right value.
-//
-// The reserve() call allocates the memory required to hold the string
-// plus a terminating null.  This is done because resize() isn't
-// guaranteed to reserve space for the null.  The resize() call is
-// simply the only way to change the string's 'length' member.
-//
-// XXX-performance: the call to wide.resize() takes linear time, since it fills
-// the string's buffer with nulls.  I call it to change the length of the
-// string (needed because writing directly to the buffer doesn't do this).
-// Perhaps there's a constant-time way to change the string's length.
-template <class string_type>
-inline typename string_type::value_type* WriteInto(string_type* str,
-                                                   size_t length_with_null) {
-  str->reserve(length_with_null);
-  str->resize(length_with_null - 1);
-  return &((*str)[0]);
-}
-
 //-----------------------------------------------------------------------------
 
 // Splits |str| into a vector of strings delimited by |s|. Append the results
 // into |r| as they appear. If several instances of |s| are contiguous, or if
 // |str| begins with or ends with |s|, then an empty string is inserted.
 //
 // Every substring is trimmed of any leading or trailing white space.
 void SplitString(const std::wstring& str,
                  wchar_t s,
                  std::vector<std::wstring>* r);
 void SplitString(const std::string& str,
                  char s,
                  std::vector<std::string>* r);
 
-// Returns true if the string passed in matches the pattern. The pattern
-// string can contain wildcards like * and ?
-// TODO(iyengar) This function may not work correctly for CJK strings as
-// it does individual character matches.
-// The backslash character (\) is an escape character for * and ?
-bool MatchPattern(const std::wstring& string, const std::wstring& pattern);
-bool MatchPattern(const std::string& string, const std::string& pattern);
-
 #endif  // BASE_STRING_UTIL_H_
--- a/ipc/chromium/src/base/sys_string_conversions.h
+++ b/ipc/chromium/src/base/sys_string_conversions.h
@@ -8,25 +8,16 @@
 // Provides system-dependent string type conversions for cases where it's
 // necessary to not use ICU. Generally, you should not need this in Chrome,
 // but it is used in some shared code. Dependencies should be minimal.
 
 #include <string>
 #include "base/basictypes.h"
 #include "base/string16.h"
 
-#if defined(OS_MACOSX)
-#include <CoreFoundation/CoreFoundation.h>
-#ifdef __OBJC__
-@class NSString;
-#else
-class NSString;
-#endif
-#endif  // OS_MACOSX
-
 class StringPiece;
 
 namespace base {
 
 // Converts between wide and UTF-8 representations of a string. On error, the
 // result is system-dependent.
 std::string SysWideToUTF8(const std::wstring& wide);
 std::wstring SysUTF8ToWide(const StringPiece& utf8);
@@ -44,40 +35,11 @@ std::wstring SysNativeMBToWide(const Str
 // Converts between 8-bit and wide strings, using the given code page. The
 // code page identifier is one accepted by the Windows function
 // MultiByteToWideChar().
 std::wstring SysMultiByteToWide(const StringPiece& mb, uint32_t code_page);
 std::string SysWideToMultiByte(const std::wstring& wide, uint32_t code_page);
 
 #endif  // defined(OS_WIN)
 
-// Mac-specific ----------------------------------------------------------------
-
-#if defined(OS_MACOSX)
-
-// Converts between STL strings and CFStringRefs/NSStrings.
-
-// Creates a string, and returns it with a refcount of 1. You are responsible
-// for releasing it. Returns NULL on failure.
-CFStringRef SysUTF8ToCFStringRef(const std::string& utf8);
-CFStringRef SysUTF16ToCFStringRef(const string16& utf16);
-CFStringRef SysWideToCFStringRef(const std::wstring& wide);
-
-// Same, but returns an autoreleased NSString.
-NSString* SysUTF8ToNSString(const std::string& utf8);
-NSString* SysUTF16ToNSString(const string16& utf16);
-NSString* SysWideToNSString(const std::wstring& wide);
-
-// Converts a CFStringRef to an STL string. Returns an empty string on failure.
-std::string SysCFStringRefToUTF8(CFStringRef ref);
-string16 SysCFStringRefToUTF16(CFStringRef ref);
-std::wstring SysCFStringRefToWide(CFStringRef ref);
-
-// Same, but accepts NSString input.
-std::string SysNSStringToUTF8(NSString* ref);
-string16 SysNSStringToUTF16(NSString* ref);
-std::wstring SysNSStringToWide(NSString* ref);
-
-#endif  // defined(OS_MACOSX)
-
 }  // namespace base
 
 #endif  // BASE_SYS_STRING_CONVERSIONS_H_
--- a/ipc/chromium/src/base/sys_string_conversions_mac.mm
+++ b/ipc/chromium/src/base/sys_string_conversions_mac.mm
@@ -3,17 +3,16 @@
 // found in the LICENSE file.
 
 #include "base/sys_string_conversions.h"
 
 #import <Foundation/Foundation.h>
 
 #include <vector>
 
-#include "base/foundation_utils_mac.h"
 #include "base/scoped_cftyperef.h"
 #include "base/string_piece.h"
 
 namespace base {
 
 namespace {
 
 // Convert the supplied CFString into the specified encoding, and return it as
@@ -139,60 +138,9 @@ std::wstring SysUTF8ToWide(const StringP
 std::string SysWideToNativeMB(const std::wstring& wide) {
   return SysWideToUTF8(wide);
 }
 
 std::wstring SysNativeMBToWide(const StringPiece& native_mb) {
   return SysUTF8ToWide(native_mb);
 }
 
-CFStringRef SysUTF8ToCFStringRef(const std::string& utf8) {
-  return STLStringToCFStringWithEncodingsT(utf8, kNarrowStringEncoding);
-}
-
-CFStringRef SysUTF16ToCFStringRef(const string16& utf16) {
-  return STLStringToCFStringWithEncodingsT(utf16, kMediumStringEncoding);
-}
-
-CFStringRef SysWideToCFStringRef(const std::wstring& wide) {
-  return STLStringToCFStringWithEncodingsT(wide, kWideStringEncoding);
-}
-
-NSString* SysUTF8ToNSString(const std::string& utf8) {
-  return CFTypeRefToNSObjectAutorelease(SysUTF8ToCFStringRef(utf8));
-}
-
-NSString* SysUTF16ToNSString(const string16& utf16) {
-  return CFTypeRefToNSObjectAutorelease(SysUTF16ToCFStringRef(utf16));
-}
-
-NSString* SysWideToNSString(const std::wstring& wide) {
-  return CFTypeRefToNSObjectAutorelease(SysWideToCFStringRef(wide));
-}
-
-std::string SysCFStringRefToUTF8(CFStringRef ref) {
-  return CFStringToSTLStringWithEncodingT<std::string>(ref,
-                                                       kNarrowStringEncoding);
-}
-
-string16 SysCFStringRefToUTF16(CFStringRef ref) {
-  return CFStringToSTLStringWithEncodingT<string16>(ref,
-                                                    kMediumStringEncoding);
-}
-
-std::wstring SysCFStringRefToWide(CFStringRef ref) {
-  return CFStringToSTLStringWithEncodingT<std::wstring>(ref,
-                                                        kWideStringEncoding);
-}
-
-std::string SysNSStringToUTF8(NSString* nsstring) {
-  return SysCFStringRefToUTF8(reinterpret_cast<CFStringRef>(nsstring));
-}
-
-string16 SysNSStringToUTF16(NSString* nsstring) {
-  return SysCFStringRefToUTF16(reinterpret_cast<CFStringRef>(nsstring));
-}
-
-std::wstring SysNSStringToWide(NSString* nsstring) {
-  return SysCFStringRefToWide(reinterpret_cast<CFStringRef>(nsstring));
-}
-
 }  // namespace base
--- a/ipc/chromium/src/base/win_util.cc
+++ b/ipc/chromium/src/base/win_util.cc
@@ -12,35 +12,16 @@
 #include "base/scoped_handle.h"
 #include "base/scoped_ptr.h"
 #include "base/singleton.h"
 #include "base/string_util.h"
 #include "base/tracked.h"
 
 namespace win_util {
 
-#define SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(struct_name, member) \
-    offsetof(struct_name, member) + \
-    (sizeof static_cast<struct_name*>(NULL)->member)
-#define NONCLIENTMETRICS_SIZE_PRE_VISTA \
-    SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(NONCLIENTMETRICS, lfMessageFont)
-
-void GetNonClientMetrics(NONCLIENTMETRICS* metrics) {
-  DCHECK(metrics);
-
-  static const UINT SIZEOF_NONCLIENTMETRICS =
-      (GetWinVersion() >= WINVERSION_VISTA) ?
-      sizeof(NONCLIENTMETRICS) : NONCLIENTMETRICS_SIZE_PRE_VISTA;
-  metrics->cbSize = SIZEOF_NONCLIENTMETRICS;
-  const bool success = !!SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
-                                              SIZEOF_NONCLIENTMETRICS, metrics,
-                                              0);
-  DCHECK(success);
-}
-
 WinVersion GetWinVersion() {
   static bool checked_version = false;
   static WinVersion win_version = WINVERSION_PRE_2000;
   if (!checked_version) {
     OSVERSIONINFOEX version_info;
     version_info.dwOSVersionInfoSize = sizeof version_info;
     GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info));
     if (version_info.dwMajorVersion == 5) {
@@ -70,295 +51,28 @@ WinVersion GetWinVersion() {
     } else if (version_info.dwMajorVersion > 6) {
       win_version = WINVERSION_WIN7;
     }
     checked_version = true;
   }
   return win_version;
 }
 
-void GetServicePackLevel(int* major, int* minor) {
-  DCHECK(major && minor);
-  static bool checked_version = false;
-  static int service_pack_major = -1;
-  static int service_pack_minor = -1;
-  if (!checked_version) {
-    OSVERSIONINFOEX version_info = {0};
-    version_info.dwOSVersionInfoSize = sizeof(version_info);
-    GetVersionEx(reinterpret_cast<OSVERSIONINFOW*>(&version_info));
-    service_pack_major = version_info.wServicePackMajor;
-    service_pack_minor = version_info.wServicePackMinor;
-    checked_version = true;
-  }
-
-  *major = service_pack_major;
-  *minor = service_pack_minor;
-}
-
-bool AddAccessToKernelObject(HANDLE handle, WELL_KNOWN_SID_TYPE known_sid,
-                             ACCESS_MASK access) {
-  PSECURITY_DESCRIPTOR descriptor = NULL;
-  PACL old_dacl = NULL;
-  PACL new_dacl = NULL;
-
-  if (ERROR_SUCCESS != GetSecurityInfo(handle, SE_KERNEL_OBJECT,
-            DACL_SECURITY_INFORMATION, NULL, NULL, &old_dacl, NULL,
-            &descriptor))
-    return false;
-
-  BYTE sid[SECURITY_MAX_SID_SIZE] = {0};
-  DWORD size_sid = SECURITY_MAX_SID_SIZE;
-
-  if (known_sid == WinSelfSid) {
-    // We hijack WinSelfSid when we want to add the current user instead of
-    // a known sid.
-    HANDLE token = NULL;
-    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token)) {
-      LocalFree(descriptor);
-      return false;
-    }
-
-    DWORD size = sizeof(TOKEN_USER) + size_sid;
-    TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(new BYTE[size]);
-    scoped_ptr<TOKEN_USER> token_user_ptr(token_user);
-    BOOL ret = GetTokenInformation(token, TokenUser, token_user, size, &size);
-
-    CloseHandle(token);
-
-    if (!ret) {
-      LocalFree(descriptor);
-      return false;
-    }
-    memcpy(sid, token_user->User.Sid, size_sid);
-  } else {
-    if (!CreateWellKnownSid(known_sid , NULL, sid, &size_sid)) {
-      LocalFree(descriptor);
-      return false;
-    }
-  }
-
-  EXPLICIT_ACCESS new_access = {0};
-  new_access.grfAccessMode = GRANT_ACCESS;
-  new_access.grfAccessPermissions = access;
-  new_access.grfInheritance = NO_INHERITANCE;
-
-  new_access.Trustee.pMultipleTrustee = NULL;
-  new_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
-  new_access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
-  new_access.Trustee.ptstrName = reinterpret_cast<LPWSTR>(&sid);
-
-  if (ERROR_SUCCESS != SetEntriesInAcl(1, &new_access, old_dacl, &new_dacl)) {
-    LocalFree(descriptor);
-    return false;
-  }
-
-  DWORD result = SetSecurityInfo(handle, SE_KERNEL_OBJECT,
-                                 DACL_SECURITY_INFORMATION, NULL, NULL,
-                                 new_dacl, NULL);
-
-  LocalFree(new_dacl);
-  LocalFree(descriptor);
-
-  if (ERROR_SUCCESS != result)
-    return false;
-
-  return true;
-}
-
-bool GetUserSidString(std::wstring* user_sid) {
-  // Get the current token.
-  HANDLE token = NULL;
-  if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token))
-    return false;
-  ScopedHandle token_scoped(token);
-
-  DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE;
-  scoped_ptr<TOKEN_USER> user(reinterpret_cast<TOKEN_USER*>(new BYTE[size]));
-
-  if (!::GetTokenInformation(token, TokenUser, user.get(), size, &size))
-    return false;
-
-  if (!user->User.Sid)
-    return false;
-
-  // Convert the data to a string.
-  wchar_t* sid_string;
-  if (!::ConvertSidToStringSid(user->User.Sid, &sid_string))
-    return false;
-
-  *user_sid = sid_string;
-
-  ::LocalFree(sid_string);
-
-  return true;
-}
-
-bool GetLogonSessionOnlyDACL(SECURITY_DESCRIPTOR** security_descriptor) {
-  // Get the current token.
-  HANDLE token = NULL;
-  if (!OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token))
-    return false;
-  ScopedHandle token_scoped(token);
-
-  // Get the size of the TokenGroups structure.
-  DWORD size = 0;
-  BOOL result = GetTokenInformation(token, TokenGroups, NULL,  0, &size);
-  if (result != FALSE && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
-    return false;
-
-  // Get the data.
-  scoped_ptr<TOKEN_GROUPS> token_groups;
-  token_groups.reset(reinterpret_cast<TOKEN_GROUPS*>(new char[size]));
-
-  if (!GetTokenInformation(token, TokenGroups, token_groups.get(), size, &size))
-    return false;
-
-  // Look for the logon sid.
-  SID* logon_sid = NULL;
-  for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) {
-    if ((token_groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) != 0) {
-        logon_sid = static_cast<SID*>(token_groups->Groups[i].Sid);
-        break;
-    }
-  }
-
-  if (!logon_sid)
-    return false;
-
-  // Convert the data to a string.
-  wchar_t* sid_string;
-  if (!ConvertSidToStringSid(logon_sid, &sid_string))
-    return false;
-
-  static const wchar_t dacl_format[] = L"D:(A;OICI;GA;;;%ls)";
-  wchar_t dacl[SECURITY_MAX_SID_SIZE + arraysize(dacl_format) + 1] = {0};
-  wsprintf(dacl, dacl_format, sid_string);
-
-  LocalFree(sid_string);
-
-  // Convert the string to a security descriptor
-  if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
-      dacl,
-      SDDL_REVISION_1,
-      reinterpret_cast<PSECURITY_DESCRIPTOR*>(security_descriptor),
-      NULL)) {
-    return false;
-  }
-
-  return true;
-}
-
-#pragma warning(push)
-#pragma warning(disable:4312 4244)
-WNDPROC SetWindowProc(HWND hwnd, WNDPROC proc) {
-  // The reason we don't return the SetwindowLongPtr() value is that it returns
-  // the orignal window procedure and not the current one. I don't know if it is
-  // a bug or an intended feature.
-  WNDPROC oldwindow_proc =
-      reinterpret_cast<WNDPROC>(GetWindowLongPtr(hwnd, GWLP_WNDPROC));
-  SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(proc));
-  return oldwindow_proc;
-}
-
-void* SetWindowUserData(HWND hwnd, void* user_data) {
-  return
-      reinterpret_cast<void*>(SetWindowLongPtr(hwnd, GWLP_USERDATA,
-          reinterpret_cast<LONG_PTR>(user_data)));
-}
-
-void* GetWindowUserData(HWND hwnd) {
-  return reinterpret_cast<void*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
-}
-
-// Maps to the WNDPROC for a window that was active before the subclass was
-// installed.
-static const wchar_t* const kHandlerKey = L"__ORIGINAL_MESSAGE_HANDLER__";
-
-bool IsSubclassed(HWND window, WNDPROC subclass_proc) {
-  WNDPROC original_handler =
-      reinterpret_cast<WNDPROC>(GetWindowLongPtr(window, GWLP_WNDPROC));
-  return original_handler == subclass_proc;
-}
-
-bool Subclass(HWND window, WNDPROC subclass_proc) {
-  WNDPROC original_handler =
-      reinterpret_cast<WNDPROC>(GetWindowLongPtr(window, GWLP_WNDPROC));
-  if (original_handler != subclass_proc) {
-    win_util::SetWindowProc(window, subclass_proc);
-    SetProp(window, kHandlerKey, (void*)original_handler);
-    return true;
-  }
-  return false;
-}
-
-bool Unsubclass(HWND window, WNDPROC subclass_proc) {
-  WNDPROC current_handler =
-      reinterpret_cast<WNDPROC>(GetWindowLongPtr(window, GWLP_WNDPROC));
-  if (current_handler == subclass_proc) {
-    HANDLE original_handler = GetProp(window, kHandlerKey);
-    if (original_handler) {
-      RemoveProp(window, kHandlerKey);
-      win_util::SetWindowProc(window,
-                              reinterpret_cast<WNDPROC>(original_handler));
-      return true;
-    }
-  }
-  return false;
-}
-
-WNDPROC GetSuperclassWNDPROC(HWND window) {
-  return reinterpret_cast<WNDPROC>(GetProp(window, kHandlerKey));
-}
-
-#pragma warning(pop)
-
 bool IsShiftPressed() {
   return (::GetKeyState(VK_SHIFT) & 0x80) == 0x80;
 }
 
 bool IsCtrlPressed() {
   return (::GetKeyState(VK_CONTROL) & 0x80) == 0x80;
 }
 
 bool IsAltPressed() {
   return (::GetKeyState(VK_MENU) & 0x80) == 0x80;
 }
 
-std::wstring GetClassName(HWND window) {
-  // GetClassNameW will return a truncated result (properly null terminated) if
-  // the given buffer is not large enough.  So, it is not possible to determine
-  // that we got the entire class name if the result is exactly equal to the
-  // size of the buffer minus one.
-  DWORD buffer_size = MAX_PATH;
-  while (true) {
-    std::wstring output;
-    DWORD size_ret =
-        GetClassNameW(window, WriteInto(&output, buffer_size), buffer_size);
-    if (size_ret == 0)
-      break;
-    if (size_ret < (buffer_size - 1)) {
-      output.resize(size_ret);
-      return output;
-    }
-    buffer_size *= 2;
-  }
-  return std::wstring();  // error
-}
-
-bool UserAccountControlIsEnabled() {
-  RegKey key(HKEY_LOCAL_MACHINE,
-      L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System");
-  DWORD uac_enabled;
-  if (!key.ReadValueDW(L"EnableLUA", &uac_enabled))
-    return true;
-  // Users can set the EnableLUA value to something arbitrary, like 2, which
-  // Vista will treat as UAC enabled, so we make sure it is not set to 0.
-  return (uac_enabled != 0);
-}
-
 std::wstring FormatMessage(unsigned messageid) {
   wchar_t* string_buffer = NULL;
   unsigned string_length = ::FormatMessage(
       FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
       FORMAT_MESSAGE_IGNORE_INSERTS, NULL, messageid, 0,
       reinterpret_cast<wchar_t *>(&string_buffer), 0, NULL);
 
   std::wstring formatted_string;
@@ -371,76 +85,16 @@ std::wstring FormatMessage(unsigned mess
   }
   return formatted_string;
 }
 
 std::wstring FormatLastWin32Error() {
   return FormatMessage(GetLastError());
 }
 
-typedef std::map<HWND, tracked_objects::Location> HWNDInfoMap;
-struct HWNDBirthMapTrait : public DefaultSingletonTraits<HWNDInfoMap> {
-};
-struct HWNDDeathMapTrait : public DefaultSingletonTraits<HWNDInfoMap> {
-};
-
-void NotifyHWNDCreation(const tracked_objects::Location& from_here, HWND hwnd) {
-  HWNDInfoMap* birth_map = Singleton<HWNDInfoMap, HWNDBirthMapTrait>::get();
-  HWNDInfoMap::iterator birth_iter = birth_map->find(hwnd);
-  if (birth_iter != birth_map->end()) {
-    birth_map->erase(birth_iter);
-
-    // We have already seen this HWND, was it destroyed?
-    HWNDInfoMap* death_map = Singleton<HWNDInfoMap, HWNDDeathMapTrait>::get();
-    HWNDInfoMap::iterator death_iter = death_map->find(hwnd);
-    if (death_iter == death_map->end()) {
-      // We did not get a destruction notification.  The code is probably not
-      // calling NotifyHWNDDestruction for that HWND.
-      NOTREACHED() << "Creation of HWND reported for already tracked HWND. The "
-                      "HWND destruction is probably not tracked properly. "
-                      "Fix it!";
-    } else {
-      death_map->erase(death_iter);
-    }
-  }
-  birth_map->insert(std::pair<HWND, tracked_objects::Location>(hwnd,
-                                                              from_here));
-}
-
-void NotifyHWNDDestruction(const tracked_objects::Location& from_here,
-                           HWND hwnd) {
-  HWNDInfoMap* death_map = Singleton<HWNDInfoMap, HWNDDeathMapTrait>::get();
-  HWNDInfoMap::iterator death_iter = death_map->find(hwnd);
-
-  HWNDInfoMap* birth_map = Singleton<HWNDInfoMap, HWNDBirthMapTrait>::get();
-  HWNDInfoMap::iterator birth_iter = birth_map->find(hwnd);
-
-  if (death_iter != death_map->end()) {
-    std::string allocation, first_delete, second_delete;
-    if (birth_iter != birth_map->end())
-      birth_iter->second.Write(true, true, &allocation);
-    death_iter->second.Write(true, true, &first_delete);
-    from_here.Write(true, true, &second_delete);
-    LOG(FATAL) << "Double delete of an HWND. Please file a bug with info on "
-        "how you got that assertion and the following information:\n"
-        "Double delete of HWND 0x" << hwnd << "\n" <<
-        "Allocated at " << allocation << "\n" <<
-        "Deleted first at " << first_delete << "\n" <<
-        "Deleted again at " << second_delete;
-    death_map->erase(death_iter);
-  }
-
-  if (birth_iter == birth_map->end()) {
-    NOTREACHED() << "Destruction of HWND reported for unknown HWND. The HWND "
-                    "construction is probably not tracked properly. Fix it!";
-  }
-  death_map->insert(std::pair<HWND, tracked_objects::Location>(hwnd,
-                                                               from_here));
-}
-
 }  // namespace win_util
 
 #ifdef _MSC_VER
 //
 // If the ASSERT below fails, please install Visual Studio 2005 Service Pack 1.
 //
 extern char VisualStudio2005ServicePack1Detection[10];
 COMPILE_ASSERT(sizeof(&VisualStudio2005ServicePack1Detection) == sizeof(void*),
--- a/ipc/chromium/src/base/win_util.h
+++ b/ipc/chromium/src/base/win_util.h
@@ -22,101 +22,30 @@ enum WinVersion {
   WINVERSION_2000 = 1,
   WINVERSION_XP = 2,
   WINVERSION_SERVER_2003 = 3,
   WINVERSION_VISTA = 4,
   WINVERSION_2008 = 5,
   WINVERSION_WIN7 = 6
 };
 
-void GetNonClientMetrics(NONCLIENTMETRICS* metrics);
-
 // Returns the running version of Windows.
 WinVersion GetWinVersion();
 
-// Returns the major and minor version of the service pack installed.
-void GetServicePackLevel(int* major, int* minor);
-
-// Adds an ACE in the DACL of the object referenced by handle. The ACE is
-// granting |access| to the user |known_sid|.
-// If |known_sid| is WinSelfSid, the sid of the current user will be added to
-// the DACL.
-bool AddAccessToKernelObject(HANDLE handle, WELL_KNOWN_SID_TYPE known_sid,
-                             ACCESS_MASK access);
-
-// Returns the string representing the current user sid.
-bool GetUserSidString(std::wstring* user_sid);
-
-// Creates a security descriptor with a DACL that has one ace giving full
-// access to the current logon session.
-// The security descriptor returned must be freed using LocalFree.
-// The function returns true if it succeeds, false otherwise.
-bool GetLogonSessionOnlyDACL(SECURITY_DESCRIPTOR** security_descriptor);
-
-// Useful for subclassing a HWND.  Returns the previous window procedure.
-WNDPROC SetWindowProc(HWND hwnd, WNDPROC wndproc);
-
-// Returns true if the existing window procedure is the same as |subclass_proc|.
-bool IsSubclassed(HWND window, WNDPROC subclass_proc);
-
-// Subclasses a window, replacing its existing window procedure with the
-// specified one. Returns true if the current window procedure was replaced,
-// false if the window has already been subclassed with the specified
-// subclass procedure.
-bool Subclass(HWND window, WNDPROC subclass_proc);
-
-// Unsubclasses a window subclassed using Subclass. Returns true if
-// the window was subclassed with the specified |subclass_proc| and the window
-// was successfully unsubclassed, false if the window's window procedure is not
-// |subclass_proc|.
-bool Unsubclass(HWND window, WNDPROC subclass_proc);
-
-// Retrieves the original WNDPROC of a window subclassed using
-// SubclassWindow.
-WNDPROC GetSuperclassWNDPROC(HWND window);
-
-// Pointer-friendly wrappers around Get/SetWindowLong(..., GWLP_USERDATA, ...)
-// Returns the previously set value.
-void* SetWindowUserData(HWND hwnd, void* user_data);
-void* GetWindowUserData(HWND hwnd);
-
 // Returns true if the shift key is currently pressed.
 bool IsShiftPressed();
 
 // Returns true if the ctrl key is currently pressed.
 bool IsCtrlPressed();
 
 // Returns true if the alt key is currently pressed.
 bool IsAltPressed();
 
-// A version of the GetClassNameW API that returns the class name in an
-// std::wstring.  An empty result indicates a failure to get the class name.
-std::wstring GetClassName(HWND window);
-
-// Returns false if user account control (UAC) has been disabled with the
-// EnableLUA registry flag. Returns true if user account control is enabled.
-// NOTE: The EnableLUA registry flag, which is ignored on Windows XP
-// machines, might still exist and be set to 0 (UAC disabled), in which case
-// this function will return false. You should therefore check this flag only
-// if the OS is Vista.
-bool UserAccountControlIsEnabled();
-
 // Use the Win32 API FormatMessage() function to generate a string, using
 // Windows's default Message Compiled resources; ignoring the inserts.
 std::wstring FormatMessage(unsigned messageid);
 
 // Uses the last Win32 error to generate a human readable message string.
 std::wstring FormatLastWin32Error();
 
-// These 2 methods are used to track HWND creation/destruction to investigate
-// a mysterious crasher http://crbugs.com/4714 (crasher in on NCDestroy) that
-// might be caused by a multiple delete of an HWND.
-void NotifyHWNDCreation(const tracked_objects::Location& from_here, HWND hwnd);
-void NotifyHWNDDestruction(const tracked_objects::Location& from_here,
-                           HWND hwnd);
-
-#define TRACK_HWND_CREATION(hwnd) win_util::NotifyHWNDCreation(FROM_HERE, hwnd)
-#define TRACK_HWND_DESTRUCTION(hwnd) \
-    win_util::NotifyHWNDDestruction(FROM_HERE, hwnd)
-
 }  // namespace win_util
 
 #endif  // BASE_WIN_UTIL_H__
--- a/ipc/chromium/src/chrome/common/child_process_info.h
+++ b/ipc/chromium/src/chrome/common/child_process_info.h
@@ -33,17 +33,16 @@ class ChildProcessInfo {
   virtual int GetProcessId() const {
     if (pid_ != -1)
       return pid_;
 
     pid_ = process_.pid();
     return pid_;
   }
   void SetProcessBackgrounded() const { process_.SetProcessBackgrounded(true); }
-  void ReduceWorkingSet() const { process_.ReduceWorkingSet(); }
 
   // Returns an English name of the process type, should only be used for non
   // user-visible strings, or debugging pages like about:memory.
   static std::wstring GetTypeNameInEnglish(ProcessType type);
 
   // Returns a localized title for the child process.  For example, a plugin
   // process would be "Plug-in: Flash" when name is "Flash".
   std::wstring GetLocalizedTitle() const;
--- a/js/public/Value.h
+++ b/js/public/Value.h
@@ -1269,16 +1269,24 @@ static inline Value
 DoubleValue(double dbl)
 {
     Value v;
     v.setDouble(dbl);
     return v;
 }
 
 static inline Value
+Float32Value(float f)
+{
+    Value v;
+    v.setDouble(f);
+    return v;
+}
+
+static inline Value
 StringValue(JSString *str)
 {
     Value v;
     v.setString(str);
     return v;
 }
 
 static inline Value
--- a/js/src/assembler/assembler/X86Assembler.h
+++ b/js/src/assembler/assembler/X86Assembler.h
@@ -2175,32 +2175,55 @@ public:
     void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         spew("addsd      %s, %s",
              nameFPReg(src), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
     }
 
+    void addss_rr(XMMRegisterID src, XMMRegisterID dst)
+    {
+        spew("addss      %s, %s",
+             nameFPReg(src), nameFPReg(dst));
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
+    }
+
     void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
     {
         spew("addsd      %s0x%x(%s), %s",
              PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset);
     }
 
+    void addss_mr(int offset, RegisterID base, XMMRegisterID dst)
+    {
+        spew("addss      %s0x%x(%s), %s",
+             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset);
+    }
+
 #if !WTF_CPU_X86_64
     void addsd_mr(const void* address, XMMRegisterID dst)
     {
         spew("addsd      %p, %s",
              address, nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, address);
     }
+    void addss_mr(const void* address, XMMRegisterID dst)
+    {
+        spew("addss      %p, %s",
+             address, nameFPReg(dst));
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, address);
+    }
 #endif
 
     void cvtss2sd_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         spew("cvtss2sd   %s, %s",
              nameFPReg(src), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F3);
         m_formatter.twoByteOp(OP2_CVTSS2SD_VsdEd, (RegisterID)dst, (RegisterID)src);
@@ -2209,16 +2232,24 @@ public:
     void cvtsd2ss_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         spew("cvtsd2ss   %s, %s",
              nameFPReg(src), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_CVTSD2SS_VsdEd, (RegisterID)dst, (RegisterID)src);
     }
 
+    void cvtsi2ss_rr(RegisterID src, XMMRegisterID dst)
+    {
+        spew("cvtsi2ss   %s, %s",
+             nameIReg(src), nameFPReg(dst));
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
+    }
+
     void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst)
     {
         spew("cvtsi2sd   %s, %s",
              nameIReg(src), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
     }
 
@@ -2243,16 +2274,32 @@ public:
     void cvtsi2sd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
     {
         spew("cvtsi2sd   %d(%s,%s,%d), %s",
              offset, nameIReg(base), nameIReg(index), 1<<scale, nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, index, scale, offset);
     }
 
+    void cvtsi2ss_mr(int offset, RegisterID base, XMMRegisterID dst)
+    {
+        spew("cvtsi2ss   %s0x%x(%s), %s",
+             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
+    }
+
+    void cvtsi2ss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
+    {
+        spew("cvtsi2ss   %d(%s,%s,%d), %s",
+             offset, nameIReg(base), nameIReg(index), 1<<scale, nameFPReg(dst));
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, index, scale, offset);
+    }
+
 #if !WTF_CPU_X86_64
     void cvtsi2sd_mr(const void* address, XMMRegisterID dst)
     {
         spew("cvtsi2sd   %p, %s",
              address, nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, address);
     }
@@ -2261,16 +2308,24 @@ public:
     void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
     {
         spew("cvttsd2si  %s, %s",
              nameFPReg(src), nameIReg(4, dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
     }
 
+    void cvttss2si_rr(XMMRegisterID src, RegisterID dst)
+    {
+        spew("cvttss2si  %s, %s",
+             nameFPReg(src), nameIReg(4, dst));
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
+    }
+
 #if WTF_CPU_X86_64
     void cvttsd2sq_rr(XMMRegisterID src, RegisterID dst)
     {
         spew("cvttsd2sq  %s, %s",
              nameFPReg(src), nameIReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp64(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
     }
@@ -2386,52 +2441,32 @@ public:
     void movss_rm_disp32(XMMRegisterID src, int offset, RegisterID base)
     {
         spew("movss      %s, %s0x%x(%s)",
              nameFPReg(src), PRETTY_PRINT_OFFSET(offset), nameIReg(base));
         m_formatter.prefix(PRE_SSE_F3);
         m_formatter.twoByteOp_disp32(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset);
     }
 
-#if !WTF_CPU_X86_64
-    void movss_rm(XMMRegisterID src, const void* addr)
-    {
-        spew("movss      %s, %p",
-             nameFPReg(src), addr);
-        m_formatter.prefix(PRE_SSE_F3);
-        m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, addr);
-    }
-#endif
-
     void movss_mr(int offset, RegisterID base, XMMRegisterID dst)
     {
         spew("movss      %s0x%x(%s), %s",
              PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F3);
         m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
     }
 
     void movss_mr_disp32(int offset, RegisterID base, XMMRegisterID dst)
     {
         spew("movss      %s0x%x(%s), %s",
              PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F3);
         m_formatter.twoByteOp_disp32(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
     }
 
-#if !WTF_CPU_X86_64
-    void movss_mr(const void* addr, XMMRegisterID dst)
-    {
-        spew("movss      %p, %s",
-             addr, nameFPReg(dst));
-        m_formatter.prefix(PRE_SSE_F3);
-        m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, addr);
-    }
-#endif
-
     void movsd_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
     {
         spew("movsd      %s, %d(%s,%s,%d)",
              nameFPReg(src), offset, nameIReg(base), nameIReg(index), 1<<scale);
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset);
     }
 
@@ -2478,32 +2513,56 @@ public:
     void movsd_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         spew("movsd      %s, %s",
              nameFPReg(src), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
     }
 
+    void movss_rr(XMMRegisterID src, XMMRegisterID dst)
+    {
+        spew("movss      %s, %s",
+             nameFPReg(src), nameFPReg(dst));
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
+    }
+
 #if !WTF_CPU_X86_64
     void movsd_mr(const void* address, XMMRegisterID dst)
     {
         spew("movsd      %p, %s",
              address, nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, address);
     }
 
+    void movss_mr(const void* address, XMMRegisterID dst)
+    {
+        spew("movss      %p, %s",
+             address, nameFPReg(dst));
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, address);
+    }
+
     void movsd_rm(XMMRegisterID src, const void* address)
     {
         spew("movsd      %s, %p",
              nameFPReg(src), address);
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, address);
     }
+
+    void movss_rm(XMMRegisterID src, const void* address)
+    {
+        spew("movss      %s, %p",
+             nameFPReg(src), address);
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, address);
+    }
 #else
     JmpSrc movsd_ripr(XMMRegisterID dst)
     {
         spew("movsd      \?(%%rip), %s",
              nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteRipOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, 0);
         return JmpSrc(m_formatter.size());
@@ -2553,48 +2612,87 @@ public:
     void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         spew("mulsd      %s, %s",
              nameFPReg(src), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
     }
 
+    void mulss_rr(XMMRegisterID src, XMMRegisterID dst)
+    {
+        spew("mulss      %s, %s",
+             nameFPReg(src), nameFPReg(dst));
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
+    }
+
     void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
     {
         spew("mulsd      %s0x%x(%s), %s",
              PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, base, offset);
     }
 
+    void mulss_mr(int offset, RegisterID base, XMMRegisterID dst)
+    {
+        spew("mulss      %s0x%x(%s), %s",
+             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, base, offset);
+    }
+
     void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
     {
         FIXME_INSN_PRINTING;
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.twoByteOp(OP2_PEXTRW_GdUdIb, (RegisterID)dst, (RegisterID)src);
         m_formatter.immediate8(whichWord);
     }
 
     void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         spew("subsd      %s, %s",
              nameFPReg(src), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
     }
 
+    void subss_rr(XMMRegisterID src, XMMRegisterID dst)
+    {
+        spew("subss      %s, %s",
+             nameFPReg(src), nameFPReg(dst));
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
+    }
+
     void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
     {
         spew("subsd      %s0x%x(%s), %s",
              PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset);
     }
 
+    void subss_mr(int offset, RegisterID base, XMMRegisterID dst)
+    {
+        spew("subss      %s0x%x(%s), %s",
+             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset);
+    }
+
+    void ucomiss_rr(XMMRegisterID src, XMMRegisterID dst)
+    {
+        spew("ucomiss    %s, %s",
+             nameFPReg(src), nameFPReg(dst));
+        m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src);
+    }
+
     void ucomisd_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         spew("ucomisd    %s, %s",
              nameFPReg(src), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src);
     }
 
@@ -2609,32 +2707,55 @@ public:
     void divsd_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         spew("divsd      %s, %s",
              nameFPReg(src), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
     }
 
+    void divss_rr(XMMRegisterID src, XMMRegisterID dst)
+    {
+        spew("divss      %s, %s",
+             nameFPReg(src), nameFPReg(dst));
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
+    }
+
     void divsd_mr(int offset, RegisterID base, XMMRegisterID dst)
     {
         spew("divsd      %s0x%x(%s), %s",
              PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, base, offset);
     }
 
+    void divss_mr(int offset, RegisterID base, XMMRegisterID dst)
+    {
+        spew("divss      %s0x%x(%s), %s",
+             PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, base, offset);
+    }
+
     void xorpd_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         spew("xorpd      %s, %s",
              nameFPReg(src), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
     }
 
+    void xorps_rr(XMMRegisterID src, XMMRegisterID dst)
+    {
+        spew("xorps      %s, %s",
+             nameFPReg(src), nameFPReg(dst));
+        m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
+    }
+
     void orpd_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         spew("orpd       %s, %s",
              nameFPReg(src), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.twoByteOp(OP2_ORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
     }
 
@@ -2789,16 +2910,21 @@ public:
         m_formatter.jumpTablePointer(ptr);
     }
 
     void doubleConstant(double d)
     {
         spew(".double %.20f", d);
         m_formatter.doubleConstant(d);
     }
+    void floatConstant(float f)
+    {
+        spew(".float %.20f", f);
+        m_formatter.floatConstant(f);
+    }
 
     void int64Constant(int64_t i)
     {
         spew(".quad %lld", (long long)i);
         m_formatter.int64Constant(i);
     }
 
     // Linking & patching:
@@ -3429,16 +3555,27 @@ private:
             union {
                 uint64_t u64;
                 double d;
             } u;
             u.d = d;
             m_buffer.putInt64Unchecked(u.u64);
         }
 
+        void floatConstant(float f)
+        {
+            m_buffer.ensureSpace(sizeof(float));
+            union {
+                uint32_t u32;
+                float f;
+            } u;
+            u.f = f;
+            m_buffer.putIntUnchecked(u.u32);
+        }
+
         void int64Constant(int64_t i)
         {
             m_buffer.ensureSpace(sizeof(int64_t));
             m_buffer.putInt64Unchecked(i);
         }
 
         // Administrative methods:
 
deleted file mode 100644
--- a/js/src/builtin/Iterator-inl.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * 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/. */
-
-#ifndef builtin_Iterator_inl_h
-#define builtin_Iterator_inl_h
-
-#include "jsiter.h"
-
-#include "vm/ObjectImpl-inl.h"
-
-inline void
-js::PropertyIteratorObject::setNativeIterator(js::NativeIterator *ni)
-{
-    setPrivate(ni);
-}
-
-#endif /* builtin_Iterator_inl_h */
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -8,17 +8,16 @@
 
 #include "jscntxt.h"
 
 #include "vm/RegExpStatics.h"
 #include "vm/StringBuffer.h"
 
 #include "jsobjinlines.h"
 
-#include "vm/RegExpObject-inl.h"
 #include "vm/RegExpStatics-inl.h"
 
 using namespace js;
 using namespace js::types;
 
 using mozilla::ArrayLength;
 
 static inline bool
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -6512,16 +6512,24 @@ Parser<ParseHandler>::arrayInitializer()
         }
 
         MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_AFTER_LIST);
     }
     handler.setEndPosition(literal, pos().end);
     return literal;
 }
 
+static JSAtom*
+DoubleToAtom(ExclusiveContext *cx, double value)
+{
+    // This is safe because doubles can not be moved.
+    Value tmp = DoubleValue(value);
+    return ToAtom<CanGC>(cx, HandleValue::fromMarkedLocation(&tmp));
+}
+
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::objectLiteral()
 {
     JS_ASSERT(tokenStream.isCurrentTokenType(TOK_LC));
 
     /*
      * A map from property names we've seen thus far to a mask of property
@@ -6535,28 +6543,26 @@ Parser<ParseHandler>::objectLiteral()
         VALUE   = 0x4 | GET | SET
     };
 
     Node literal = handler.newObjectLiteral(pos().begin);
     if (!literal)
         return null();
 
     RootedAtom atom(context);
-    Value tmp;
     for (;;) {
         TokenKind ltok = tokenStream.getToken(TokenStream::KeywordIsName);
         if (ltok == TOK_RC)
             break;
 
         JSOp op = JSOP_INITPROP;
         Node propname;
         switch (ltok) {
           case TOK_NUMBER:
-            tmp = DoubleValue(tokenStream.currentToken().number());
-            atom = ToAtom<CanGC>(context, HandleValue::fromMarkedLocation(&tmp));
+            atom = DoubleToAtom(context, tokenStream.currentToken().number());
             if (!atom)
                 return null();
             propname = newNumber(tokenStream.currentToken());
             break;
 
           case TOK_NAME: {
             atom = tokenStream.currentName();
             if (atom == context->names().get) {
@@ -6581,29 +6587,26 @@ Parser<ParseHandler>::objectLiteral()
             } else if (tt == TOK_STRING) {
                 atom = tokenStream.currentToken().atom();
 
                 uint32_t index;
                 if (atom->isIndex(&index)) {
                     propname = handler.newNumber(index, NoDecimal, pos());
                     if (!propname)
                         return null();
-                    tmp = DoubleValue(index);
-                    atom = ToAtom<CanGC>(context, HandleValue::fromMarkedLocation(&tmp));
+                    atom = DoubleToAtom(context, index);
                     if (!atom)
                         return null();
                 } else {
                     propname = stringLiteral();
                     if (!propname)
                         return null();
                 }
             } else if (tt == TOK_NUMBER) {
-                double number = tokenStream.currentToken().number();
-                tmp = DoubleValue(number);
-                atom = ToAtom<CanGC>(context, HandleValue::fromMarkedLocation(&tmp));
+                atom = DoubleToAtom(context, tokenStream.currentToken().number());
                 if (!atom)
                     return null();
                 propname = newNumber(tokenStream.currentToken());
                 if (!propname)
                     return null();
             } else {
                 // Not an accessor property after all.
                 tokenStream.ungetToken();
--- a/js/src/gc/Barrier-inl.h
+++ b/js/src/gc/Barrier-inl.h
@@ -13,42 +13,16 @@
 
 #include "gc/Marking.h"
 #include "gc/StoreBuffer.h"
 
 #include "vm/String-inl.h"
 
 namespace js {
 
-template <typename T, typename Unioned>
-void
-EncapsulatedPtr<T, Unioned>::pre()
-{
-    T::writeBarrierPre(value);
-}
-
-template <typename T>
-inline void
-RelocatablePtr<T>::post()
-{
-#ifdef JSGC_GENERATIONAL
-    JS_ASSERT(this->value);
-    T::writeBarrierPostRelocate(this->value, &this->value);
-#endif
-}
-
-template <typename T>
-inline void
-RelocatablePtr<T>::relocate(JSRuntime *rt)
-{
-#ifdef JSGC_GENERATIONAL
-    T::writeBarrierPostRemove(this->value, &this->value);
-#endif
-}
-
 #ifdef JSGC_GENERATIONAL
 class DenseRangeRef : public gc::BufferableRef
 {
     JSObject *owner;
     uint32_t start;
     uint32_t end;
 
   public:
--- a/js/src/gc/Barrier.cpp
+++ b/js/src/gc/Barrier.cpp
@@ -44,11 +44,16 @@ HeapSlot::preconditionForSet(Zone *zone,
 void
 HeapSlot::preconditionForWriteBarrierPost(JSObject *obj, Kind kind, uint32_t slot, Value target)
 {
     JS_ASSERT_IF(kind == Slot, obj->getSlotAddressUnchecked(slot)->get() == target);
     JS_ASSERT_IF(kind == Element,
                  static_cast<HeapSlot *>(obj->getDenseElements() + slot)->get() == target);
 }
 
+bool
+RuntimeFromMainThreadIsHeapMajorCollecting(JS::shadow::Zone *shadowZone)
+{
+    return shadowZone->runtimeFromMainThread()->isHeapMajorCollecting();
+}
 #endif // DEBUG
 
 } // namespace js
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -192,17 +192,17 @@ class EncapsulatedPtr
     Unioned *unsafeGetUnioned() { return &other; }
 
     T &operator*() const { return *value; }
     T *operator->() const { return value; }
 
     operator T*() const { return value; }
 
   protected:
-    void pre();
+    void pre() { T::writeBarrierPre(value); }
 };
 
 template <class T, class Unioned = uintptr_t>
 class HeapPtr : public EncapsulatedPtr<T, Unioned>
 {
   public:
     HeapPtr() : EncapsulatedPtr<T>(NULL) {}
     explicit HeapPtr(T *v) : EncapsulatedPtr<T>(v) { post(); }
@@ -315,18 +315,28 @@ class RelocatablePtr : public Encapsulat
             JSRuntime *rt = this->value->runtimeFromMainThread();
             this->value = v;
             relocate(rt);
         }
         return *this;
     }
 
   protected:
-    inline void post();
-    inline void relocate(JSRuntime *rt);
+    void post() {
+#ifdef JSGC_GENERATIONAL
+        JS_ASSERT(this->value);
+        T::writeBarrierPostRelocate(this->value, &this->value);
+#endif
+    }
+
+    void relocate(JSRuntime *rt) {
+#ifdef JSGC_GENERATIONAL
+        T::writeBarrierPostRemove(this->value, &this->value);
+#endif
+    }
 };
 
 /*
  * This is a hack for RegExpStatics::updateFromMatch. It allows us to do two
  * barriers with only one branch to check if we're in an incremental GC.
  */
 template<class T1, class T2>
 static inline void
@@ -917,11 +927,16 @@ class ReadBarrieredValue
 
     inline const Value &get() const;
     Value *unsafeGet() { return &value; }
     inline operator const Value &() const;
 
     inline JSObject &toObject() const;
 };
 
+#ifdef DEBUG
+bool
+RuntimeFromMainThreadIsHeapMajorCollecting(JS::shadow::Zone *shadowZone);
+#endif
+
 } /* namespace js */
 
 #endif /* gc_Barrier_h */
--- a/js/src/gc/Heap.h
+++ b/js/src/gc/Heap.h
@@ -94,16 +94,17 @@ struct Cell
   public:
     inline ArenaHeader *arenaHeader() const;
     inline AllocKind tenuredGetAllocKind() const;
     MOZ_ALWAYS_INLINE bool isMarked(uint32_t color = BLACK) const;
     MOZ_ALWAYS_INLINE bool markIfUnmarked(uint32_t color = BLACK) const;
     MOZ_ALWAYS_INLINE void unmark(uint32_t color) const;
 
     inline JSRuntime *runtimeFromMainThread() const;
+    inline JS::shadow::Runtime *shadowRuntimeFromMainThread() const;
     inline JS::Zone *tenuredZone() const;
     inline bool tenuredIsInsideZone(JS::Zone *zone) const;
 
     // Note: Unrestricted access to the runtime of a GC thing from an arbitrary
     // thread can easily lead to races. Use this method very carefully.
     inline JSRuntime *runtimeFromAnyThread() const;
     inline JS::shadow::Runtime *shadowRuntimeFromAnyThread() const;
 
@@ -958,16 +959,22 @@ Cell::arenaHeader() const
 inline JSRuntime *
 Cell::runtimeFromMainThread() const
 {
     JSRuntime *rt = chunk()->info.runtime;
     JS_ASSERT(CurrentThreadCanAccessRuntime(rt));
     return rt;
 }
 
+inline JS::shadow::Runtime *
+Cell::shadowRuntimeFromMainThread() const
+{
+    return reinterpret_cast<JS::shadow::Runtime*>(runtimeFromMainThread());
+}
+
 inline JSRuntime *
 Cell::runtimeFromAnyThread() const
 {
     return chunk()->info.runtime;
 }
 
 inline JS::shadow::Runtime *
 Cell::shadowRuntimeFromAnyThread() const
--- a/js/src/gc/Marking.h
+++ b/js/src/gc/Marking.h
@@ -3,17 +3,16 @@
  * 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/. */
 
 #ifndef gc_Marking_h
 #define gc_Marking_h
 
 #include "gc/Barrier.h"
-#include "jit/IonCode.h"
 #include "js/TypeDecls.h"
 
 class JSAtom;
 class JSLinearString;
 
 namespace js {
 
 class ArgumentsObject;
@@ -25,16 +24,26 @@ struct GCMarker;
 class GlobalObject;
 class LazyScript;
 class ScopeObject;
 class Shape;
 class UnownedBaseShape;
 
 template<class, typename> class HeapPtr;
 
+namespace jit {
+class IonCode;
+class IonScript;
+class VMFunction;
+}
+
+namespace types {
+class Type;
+}
+
 namespace gc {
 
 /*** Object Marking ***/
 
 /*
  * These functions expose marking functionality for all of the different GC
  * thing kinds. For each GC thing, there are several variants. As an example,
  * these are the variants generated for JSObject. They are listed from most to
--- a/js/src/gc/Rooting.h
+++ b/js/src/gc/Rooting.h
@@ -28,13 +28,13 @@ typedef JS::Handle<js::ScriptSourceObjec
 
 typedef JS::MutableHandle<Shape*>      MutableHandleShape;
 typedef JS::MutableHandle<JSAtom*>     MutableHandleAtom;
 
 typedef JS::Rooted<Shape*>             RootedShape;
 typedef JS::Rooted<types::TypeObject*> RootedTypeObject;
 typedef JS::Rooted<JSAtom*>            RootedAtom;
 typedef JS::Rooted<PropertyName*>      RootedPropertyName;
-typedef Rooted<js::ScriptSourceObject*> RootedScriptSource;
+typedef JS::Rooted<js::ScriptSourceObject*> RootedScriptSource;
 
 } /* namespace js */
 
 #endif /* gc_Rooting_h */
--- a/js/src/jit-test/tests/asm.js/testBasic.js
+++ b/js/src/jit-test/tests/asm.js/testBasic.js
@@ -41,41 +41,36 @@ assertEq(asmLink(asmCompile('x', USE_ASM
 assertEq(asmLink(asmCompile('x','y', USE_ASM + 'function f(){} return f'), 1, 2)(), undefined);
 
 assertEq(asmLink(asmCompile(USE_ASM + 'function f(i) {i=i|0} return f'))(42), undefined);
 assertEq(asmLink(asmCompile(USE_ASM + 'function f() {var i=0;; var j=1;} return f'))(), undefined); // bug 877965 second part
 assertAsmTypeFail(USE_ASM + 'function f(i) {i=i|0;var i} return f');
 assertAsmTypeFail(USE_ASM + 'function f(i) {i=i|0;var i=0} return f');
 
 assertAsmTypeFail('glob', USE_ASM + 'var im=glob.imul; function f() {} return f');
-var code = asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i,j) {i=i|0;j=j|0; return im(i,j)|0} return f');
-assertAsmLinkAlwaysFail(code, null);
-assertAsmLinkAlwaysFail(code, {});
-assertAsmLinkAlwaysFail(code, {imul:Math.imul});
-assertEq(asmLink(code, {Math:{imul:Math.imul}})(2,3), 6);
-var code = asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i,j) {i=i|0;j=j|0; return im(i,j)|0} return f');
-assertEq(asmLink(code, this)(8,4), 32);
+assertAsmLinkAlwaysFail(asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i,j) {i=i|0;j=j|0; return im(i,j)|0} return f'), null);
+assertAsmLinkAlwaysFail(asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i,j) {i=i|0;j=j|0; return im(i,j)|0} return f'), {});
+assertAsmLinkAlwaysFail(asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i,j) {i=i|0;j=j|0; return im(i,j)|0} return f'), {imul:Math.imul});
+assertEq(asmLink(asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i,j) {i=i|0;j=j|0; return im(i,j)|0} return f'), {Math:{imul:Math.imul}})(2,3), 6);
+assertEq(asmLink(asmCompile('glob', USE_ASM + 'var im=glob.Math.imul; function f(i,j) {i=i|0;j=j|0; return im(i,j)|0} return f'), this)(8,4), 32);
 
-var code = asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f');
-assertAsmLinkAlwaysFail(code, null, null);
-assertAsmLinkAlwaysFail(code, this, null, null);
-assertAsmLinkAlwaysFail(code, this, null, null);
-assertAsmLinkAlwaysFail(code, this, null, new ArrayBuffer(1));
-assertAsmLinkFail(code, this, null, new ArrayBuffer(100));
-assertAsmLinkFail(code, this, null, new ArrayBuffer(4000));
-assertEq(asmLink(code, this, null, new ArrayBuffer(4096))(), undefined);
-var code = asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f');
-assertEq(asmLink(code, this, null, new ArrayBuffer(2*4096))(), undefined);
+assertAsmLinkAlwaysFail(asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f'), null, null);
+assertAsmLinkAlwaysFail(asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f'), this, null, null);
+assertAsmLinkAlwaysFail(asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f'), this, null, null);
+assertAsmLinkAlwaysFail(asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f'), this, null, new ArrayBuffer(1));
+assertAsmLinkFail(asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f'), this, null, new ArrayBuffer(100));
+assertAsmLinkFail(asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f'), this, null, new ArrayBuffer(4000));
+assertEq(asmLink(asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f'), this, null, new ArrayBuffer(4096))(), undefined);
+assertEq(asmLink(asmCompile('glob','i','b', USE_ASM + 'var i32=new glob.Int32Array(b); function f(){} return f'), this, null, new ArrayBuffer(2*4096))(), undefined);
 
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i]|0; return i|0}; return f');
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i>>1]|0; return i|0}; return f');
 assertAsmTypeFail('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i>>1]|0; return i|0}; return f');
-var code = asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i>>2]|0; return i|0}; return f');
-assertAsmLinkAlwaysFail(code, this, null, new ArrayBuffer(4095));
-assertEq(code(this, null, new ArrayBuffer(4096))(), 0);
+assertAsmLinkAlwaysFail(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i>>2]|0; return i|0}; return f'), this, null, new ArrayBuffer(4095));
+assertEq(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f(i) {i=i|0; i = i32[i>>2]|0; return i|0}; return f')(this, null, new ArrayBuffer(4096))(), 0);
 
 var exp = asmLink(asmCompile(USE_ASM + "return {}"));
 assertEq(Object.keys(exp).length, 0);
 
 var exp = asmLink(asmCompile(USE_ASM + "function f() { return 3 } return {f:f,f:f}"));
 assertEq(exp.f(), 3);
 assertEq(Object.keys(exp).join(), 'f');
 
--- a/js/src/jit-test/tests/asm.js/testGlobals.js
+++ b/js/src/jit-test/tests/asm.js/testGlobals.js
@@ -17,36 +17,32 @@ assertEq(f(42), 0);
 assertEq(f(-1), 42);
 
 assertAsmTypeFail('global', USE_ASM + "var i=global; function f() { return i|0 } return f");
 assertAsmTypeFail('global', USE_ASM + "var i=global|0; function f() { return i|0 } return f");
 assertAsmTypeFail('global', USE_ASM + "var j=0;var i=j.i|0; function f() { return i|0 } return f");
 assertAsmTypeFail('global', USE_ASM + "var i=global.i|0; function f() { return i|0 } return f");
 assertAsmTypeFail('global', USE_ASM + "var i=global.i|0; function f() { return i|0 } return f");
 assertAsmTypeFail('global', USE_ASM + 'var i=global.Infinity; function f() { i = 0.0 } return f');
-var code = asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f');
-assertAsmLinkAlwaysFail(code, undefined);
-assertAsmLinkAlwaysFail(code, null);
-assertAsmLinkFail(code, 3);
-assertAsmLinkFail(code, {});
-assertAsmLinkFail(code, {Infinity:NaN});
-assertAsmLinkFail(code, {Infinity:-Infinity});
-assertEq(asmLink(code, {Infinity:Infinity})(), Infinity);
-var code = asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f');
-assertEq(asmLink(code, this)(), Infinity);
-var code = asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f');
-assertAsmLinkAlwaysFail(code, undefined);
-assertAsmLinkAlwaysFail(code, null);
-assertAsmLinkFail(code, 3);
-assertAsmLinkFail(code, {});
-assertAsmLinkFail(code, {Infinity:Infinity});
-assertAsmLinkFail(code, {Infinity:-Infinity});
-assertEq(asmLink(code, {NaN:NaN})(), NaN);
-var code = asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f');
-assertEq(asmLink(code, this)(), NaN);
+assertAsmLinkAlwaysFail(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f'), undefined);
+assertAsmLinkAlwaysFail(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f'), null);
+assertAsmLinkFail(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f'), 3);
+assertAsmLinkFail(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f'), {});
+assertAsmLinkFail(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f'), {Infinity:NaN});
+assertAsmLinkFail(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f'), {Infinity:-Infinity});
+assertEq(asmLink(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f'), {Infinity:Infinity})(), Infinity);
+assertEq(asmLink(asmCompile('global', USE_ASM + 'var i=global.Infinity; function f() { return +i } return f'), this)(), Infinity);
+assertAsmLinkAlwaysFail(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f'), undefined);
+assertAsmLinkAlwaysFail(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f'), null);
+assertAsmLinkFail(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f'), 3);
+assertAsmLinkFail(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f'), {});
+assertAsmLinkFail(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f'), {Infinity:Infinity});
+assertAsmLinkFail(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f'), {Infinity:-Infinity});
+assertEq(asmLink(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f'), {NaN:NaN})(), NaN);
+assertEq(asmLink(asmCompile('global', USE_ASM + 'var i=global.NaN; function f() { return +i } return f'), this)(), NaN);
 
 assertAsmLinkFail(asmCompile('glob','foreign','buf', USE_ASM + 'var t = new glob.Int32Array(buf); function f() {} return f'), {get Int32Array(){return Int32Array}}, null, new ArrayBuffer(4096))
 assertAsmLinkFail(asmCompile('glob','foreign','buf', USE_ASM + 'var t = new glob.Int32Array(buf); function f() {} return f'), new Proxy({}, {get:function() {return Int32Array}}), null, new ArrayBuffer(4096))
 assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var t = glob.Math.sin; function f() {} return f'), {get Math(){return Math}});
 assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var t = glob.Math.sin; function f() {} return f'), new Proxy({}, {get:function(){return Math}}));
 assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var t = glob.Math.sin; function f() {} return f'), {Math:{get sin(){return Math.sin}}});
 assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var t = glob.Math.sin; function f() {} return f'), {Math:new Proxy({}, {get:function(){return Math.sin}})});
 assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var t = glob.Infinity; function f() {} return f'), {get Infinity(){return Infinity}});
@@ -64,8 +60,17 @@ assertAsmLinkAlwaysFail(asmCompile('glob
 assertAsmLinkAlwaysFail(asmCompile('global', 'imp', USE_ASM + "var i=imp.i|0; function f() { return i|0 } return f"), null, null);
 assertAsmLinkAlwaysFail(asmCompile('global', 'imp', USE_ASM + "var i=imp.i|0; function f() { return i|0 } return f"), this, null);
 assertAsmLinkFail(asmCompile('global', 'imp', USE_ASM + "var i=imp.i|0; function f() { return i|0 } return f"), this, 42);
 assertEq(asmLink(asmCompile('global', 'imp', USE_ASM + "var i=imp.i|0; function f() { return i|0 } return f")(null, {i:42})), 42);
 assertEq(asmLink(asmCompile('global', 'imp', USE_ASM + "var i=imp.i|0; function f() { return i|0 } return f")(null, {i:1.4})), 1);
 assertEq(asmLink(asmCompile('global', 'imp', USE_ASM + "var i=+imp.i; function f() { return +i } return f")(null, {i:42})), 42);
 assertEq(asmLink(asmCompile('global', 'imp', USE_ASM + "var i=+imp.i; function f() { return +i } return f")(this, {i:1.4})), 1.4);
 assertEq(asmLink(asmCompile(USE_ASM + "var g=0; function f() { var i=42; while (1) { break; } g = i; return g|0 } return f"))(), 42);
+
+var f1 = asmCompile('global', 'foreign', 'heap', USE_ASM + 'var i32 = new global.Int32Array(heap); function g() { return i32[4]|0 } return g');
+var global = this;
+var ab = new ArrayBuffer(4096);
+var p = new Proxy(global,
+                  {has:function(name) { f1(global, null, ab); return true},
+                   getOwnPropertyDescriptor:function(name) { return {value:Int32Array}}});
+new Int32Array(ab)[4] = 42;
+assertEq(f1(p, null, ab)(), 42);
--- a/js/src/jit-test/tests/asm.js/testHeapAccess.js
+++ b/js/src/jit-test/tests/asm.js/testHeapAccess.js
@@ -437,11 +437,19 @@ assertEq(asmLink(asmCompile('glob', 'imp
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f32[(8192&8191)>>2] = -1.0; f32[0] = 0.0; return +f32[(8192&8191)>>2]; } return f'), this, null, buf)(),0.0);
 
 var buf = new ArrayBuffer(8192);
 new Float64Array(buf)[1023] = -1.0;
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[(8184&8191)>>3]; } return f'), this, null, buf)(),-1.0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return +f64[(8191&8191)>>3]; } return f'), this, null, buf)(),-1.0);
 assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { f64[(8192&8191)>>3] = -1.0; f64[0] = 0.0; return +f64[(8192&8191)>>3]; } return f'), this, null, buf)(),0.0);
 
+// Bug 913867
+var buf = new ArrayBuffer(8192);
+new Int32Array(buf)[0] = 0x55aa5a5a;
+assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[(0&0)>>2]|0; } return f'), this, null, buf)(),0x55aa5a5a);
+assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f() { return i32[(4&0)>>2]|0; } return f'), this, null, buf)(),0x55aa5a5a);
+assertEq(asmLink(asmCompile('glob', 'imp', 'b', USE_ASM + HEAP_IMPORTS + 'function f1() { i32[0] = 1; return 8; }; function f() { return i32[((f1()|0)&0)>>2]|0; } return f'), this, null, buf)(),1);
+assertEq(new Int32Array(buf)[0], 1);
+
 
 // Bug 882012
 assertEq(asmLink(asmCompile('stdlib', 'foreign', 'heap', USE_ASM + "var id=foreign.id;var doubles=new stdlib.Float64Array(heap);function g(){doubles[0]=+id(2.0);return +doubles[0];}return g"), this, {id: function(x){return x;}}, BUF_64KB)(), 2.0);
--- a/js/src/jit-test/tests/asm.js/testMathLib.js
+++ b/js/src/jit-test/tests/asm.js/testMathLib.js
@@ -1,96 +1,82 @@
 load(libdir + "asm.js");
 
 function testUnary(f, g) {
     var numbers = [NaN, Infinity, -Infinity, -10000, -3.4, -0, 0, 3.4, 10000];
     for (n of numbers)
         assertEq(f(n), g(n));
 }
 
-var code = asmCompile('glob', USE_ASM + 'var sq=glob.Math.sin; function f(d) { d=+d; return +sq(d) } return f');
-assertAsmLinkFail(code, {Math:{sin:Math.sqrt}});
-assertAsmLinkFail(code, {Math:{sin:null}});
-testUnary(asmLink(code, {Math:{sin:Math.sin}}), Math.sin);
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var sq=glob.Math.sin; function f(d) { d=+d; return +sq(d) } return f'), {Math:{sin:Math.sqrt}});
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var sq=glob.Math.sin; function f(d) { d=+d; return +sq(d) } return f'), {Math:{sin:null}});
+testUnary(asmLink(asmCompile('glob', USE_ASM + 'var sq=glob.Math.sin; function f(d) { d=+d; return +sq(d) } return f'), {Math:{sin:Math.sin}}), Math.sin);
 
-var code = asmCompile('glob', USE_ASM + 'var co=glob.Math.cos; function f(d) { d=+d; return +co(d) } return f');
-assertAsmLinkFail(code, {Math:{cos:Math.sqrt}});
-assertAsmLinkFail(code, {Math:{cos:null}});
-testUnary(asmLink(code, {Math:{cos:Math.cos}}), Math.cos);
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var co=glob.Math.cos; function f(d) { d=+d; return +co(d) } return f'), {Math:{cos:Math.sqrt}});
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var co=glob.Math.cos; function f(d) { d=+d; return +co(d) } return f'), {Math:{cos:null}});
+testUnary(asmLink(asmCompile('glob', USE_ASM + 'var co=glob.Math.cos; function f(d) { d=+d; return +co(d) } return f'), {Math:{cos:Math.cos}}), Math.cos);
 
-var code = asmCompile('glob', USE_ASM + 'var ta=glob.Math.tan; function f(d) { d=+d; return +ta(d) } return f');
-assertAsmLinkFail(code, {Math:{tan:Math.sqrt}});
-assertAsmLinkFail(code, {Math:{tan:null}});
-testUnary(asmLink(code, {Math:{tan:Math.tan}}), Math.tan);
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var ta=glob.Math.tan; function f(d) { d=+d; return +ta(d) } return f'), {Math:{tan:Math.sqrt}});
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var ta=glob.Math.tan; function f(d) { d=+d; return +ta(d) } return f'), {Math:{tan:null}});
+testUnary(asmLink(asmCompile('glob', USE_ASM + 'var ta=glob.Math.tan; function f(d) { d=+d; return +ta(d) } return f'), {Math:{tan:Math.tan}}), Math.tan);
 
-var code = asmCompile('glob', USE_ASM + 'var as=glob.Math.asin; function f(d) { d=+d; return +as(d) } return f');
-assertAsmLinkFail(code, {Math:{asin:Math.sqrt}});
-assertAsmLinkFail(code, {Math:{asin:null}});
-testUnary(asmLink(code, {Math:{asin:Math.asin}}), Math.asin);
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var as=glob.Math.asin; function f(d) { d=+d; return +as(d) } return f'), {Math:{asin:Math.sqrt}});
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var as=glob.Math.asin; function f(d) { d=+d; return +as(d) } return f'), {Math:{asin:null}});
+testUnary(asmLink(asmCompile('glob', USE_ASM + 'var as=glob.Math.asin; function f(d) { d=+d; return +as(d) } return f'), {Math:{asin:Math.asin}}), Math.asin);
 
-var code = asmCompile('glob', USE_ASM + 'var ac=glob.Math.acos; function f(d) { d=+d; return +ac(d) } return f');
-assertAsmLinkFail(code, {Math:{acos:Math.sqrt}});
-assertAsmLinkFail(code, {Math:{acos:null}});
-testUnary(asmLink(code, {Math:{acos:Math.acos}}), Math.acos);
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var ac=glob.Math.acos; function f(d) { d=+d; return +ac(d) } return f'), {Math:{acos:Math.sqrt}});
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var ac=glob.Math.acos; function f(d) { d=+d; return +ac(d) } return f'), {Math:{acos:null}});
+testUnary(asmLink(asmCompile('glob', USE_ASM + 'var ac=glob.Math.acos; function f(d) { d=+d; return +ac(d) } return f'), {Math:{acos:Math.acos}}), Math.acos);
 
-var code = asmCompile('glob', USE_ASM + 'var at=glob.Math.atan; function f(d) { d=+d; return +at(d) } return f');
-assertAsmLinkFail(code, {Math:{atan:Math.sqrt}});
-assertAsmLinkFail(code, {Math:{atan:null}});
-testUnary(asmLink(code, {Math:{atan:Math.atan}}), Math.atan);
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var at=glob.Math.atan; function f(d) { d=+d; return +at(d) } return f'), {Math:{atan:Math.sqrt}});
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var at=glob.Math.atan; function f(d) { d=+d; return +at(d) } return f'), {Math:{atan:null}});
+testUnary(asmLink(asmCompile('glob', USE_ASM + 'var at=glob.Math.atan; function f(d) { d=+d; return +at(d) } return f'), {Math:{atan:Math.atan}}), Math.atan);
 
-var code = asmCompile('glob', USE_ASM + 'var ce=glob.Math.ceil; function f(d) { d=+d; return +ce(d) } return f');
-assertAsmLinkFail(code, {Math:{ceil:Math.sqrt}});
-assertAsmLinkFail(code, {Math:{ceil:null}});
-testUnary(asmLink(code, {Math:{ceil:Math.ceil}}), Math.ceil);
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var ce=glob.Math.ceil; function f(d) { d=+d; return +ce(d) } return f'), {Math:{ceil:Math.sqrt}});
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var ce=glob.Math.ceil; function f(d) { d=+d; return +ce(d) } return f'), {Math:{ceil:null}});
+testUnary(asmLink(asmCompile('glob', USE_ASM + 'var ce=glob.Math.ceil; function f(d) { d=+d; return +ce(d) } return f'), {Math:{ceil:Math.ceil}}), Math.ceil);
 
-var code = asmCompile('glob', USE_ASM + 'var fl=glob.Math.floor; function f(d) { d=+d; return +fl(d) } return f');
-assertAsmLinkFail(code, {Math:{floor:Math.sqrt}});
-assertAsmLinkFail(code, {Math:{floor:null}});
-testUnary(asmLink(code, {Math:{floor:Math.floor}}), Math.floor);
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var fl=glob.Math.floor; function f(d) { d=+d; return +fl(d) } return f'), {Math:{floor:Math.sqrt}});
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var fl=glob.Math.floor; function f(d) { d=+d; return +fl(d) } return f'), {Math:{floor:null}});
+testUnary(asmLink(asmCompile('glob', USE_ASM + 'var fl=glob.Math.floor; function f(d) { d=+d; return +fl(d) } return f'), {Math:{floor:Math.floor}}), Math.floor);
 
-var code = asmCompile('glob', USE_ASM + 'var exq=glob.Math.exp; function f(d) { d=+d; return +exq(d) } return f');
-assertAsmLinkFail(code, {Math:{exp:Math.sqrt}});
-assertAsmLinkFail(code, {Math:{exp:null}});
-testUnary(asmLink(code, {Math:{exp:Math.exp}}), Math.exp);
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var exq=glob.Math.exp; function f(d) { d=+d; return +exq(d) } return f'), {Math:{exp:Math.sqrt}});
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var exq=glob.Math.exp; function f(d) { d=+d; return +exq(d) } return f'), {Math:{exp:null}});
+testUnary(asmLink(asmCompile('glob', USE_ASM + 'var exq=glob.Math.exp; function f(d) { d=+d; return +exq(d) } return f'), {Math:{exp:Math.exp}}), Math.exp);
 
-var code = asmCompile('glob', USE_ASM + 'var lo=glob.Math.log; function f(d) { d=+d; return +lo(d) } return f');
-assertAsmLinkFail(code, {Math:{log:Math.sqrt}});
-assertAsmLinkFail(code, {Math:{log:null}});
-testUnary(asmLink(code, {Math:{log:Math.log}}), Math.log);
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var lo=glob.Math.log; function f(d) { d=+d; return +lo(d) } return f'), {Math:{log:Math.sqrt}});
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var lo=glob.Math.log; function f(d) { d=+d; return +lo(d) } return f'), {Math:{log:null}});
+testUnary(asmLink(asmCompile('glob', USE_ASM + 'var lo=glob.Math.log; function f(d) { d=+d; return +lo(d) } return f'), {Math:{log:Math.log}}), Math.log);
 
-var code = asmCompile('glob', USE_ASM + 'var sq=glob.Math.sqrt; function f(d) { d=+d; return +sq(d) } return f');
-assertAsmLinkFail(code, {Math:{sqrt:Math.sin}});
-assertAsmLinkFail(code, {Math:{sqrt:null}});
-testUnary(asmLink(code, {Math:{sqrt:Math.sqrt}}), Math.sqrt);
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var sq=glob.Math.sqrt; function f(d) { d=+d; return +sq(d) } return f'), {Math:{sqrt:Math.sin}});
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var sq=glob.Math.sqrt; function f(d) { d=+d; return +sq(d) } return f'), {Math:{sqrt:null}});
+testUnary(asmLink(asmCompile('glob', USE_ASM + 'var sq=glob.Math.sqrt; function f(d) { d=+d; return +sq(d) } return f'), {Math:{sqrt:Math.sqrt}}), Math.sqrt);
 
-var code = asmCompile('glob', USE_ASM + 'var abs=glob.Math.abs; function f(d) { d=+d; return +abs(d) } return f');
-assertAsmLinkFail(code, {Math:{abs:Math.sin}});
-assertAsmLinkFail(code, {Math:{abs:null}});
-testUnary(asmLink(code, {Math:{abs:Math.abs}}), Math.abs);
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var abs=glob.Math.abs; function f(d) { d=+d; return +abs(d) } return f'), {Math:{abs:Math.sin}});
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var abs=glob.Math.abs; function f(d) { d=+d; return +abs(d) } return f'), {Math:{abs:null}});
+testUnary(asmLink(asmCompile('glob', USE_ASM + 'var abs=glob.Math.abs; function f(d) { d=+d; return +abs(d) } return f'), {Math:{abs:Math.abs}}), Math.abs);
 
 var f = asmLink(asmCompile('glob', USE_ASM + 'var abs=glob.Math.abs; function f(i) { i=i|0; return abs(i|0)|0 } return f'), this);
 for (n of [-Math.pow(2,31)-1, -Math.pow(2,31), -Math.pow(2,31)+1, -1, 0, 1, Math.pow(2,31)-2, Math.pow(2,31)-1, Math.pow(2,31)])
     assertEq(f(n), Math.abs(n|0)|0);
 
 function testBinary(f, g) {
     var numbers = [NaN, Infinity, -Infinity, -10000, -3.4, -0, 0, 3.4, 10000];
     for (n of numbers)
         for (o of numbers)
             assertEq(f(n,o), g(n,o));
 }
 
-var code = asmCompile('glob', USE_ASM + 'var po=glob.Math.pow; function f(d,e) { d=+d;e=+e; return +po(d,e) } return f');
-assertAsmLinkFail(code, {Math:{pow:Math.sin}});
-assertAsmLinkFail(code, {Math:{pow:null}});
-testBinary(asmLink(code, {Math:{pow:Math.pow}}), Math.pow);
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var po=glob.Math.pow; function f(d,e) { d=+d;e=+e; return +po(d,e) } return f'), {Math:{pow:Math.sin}});
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var po=glob.Math.pow; function f(d,e) { d=+d;e=+e; return +po(d,e) } return f'), {Math:{pow:null}});
+testBinary(asmLink(asmCompile('glob', USE_ASM + 'var po=glob.Math.pow; function f(d,e) { d=+d;e=+e; return +po(d,e) } return f'), {Math:{pow:Math.pow}}), Math.pow);
 
-var code = asmCompile('glob', USE_ASM + 'var at=glob.Math.atan2; function f(d,e) { d=+d;e=+e; return +at(d,e) } return f');
-assertAsmLinkFail(code, {Math:{atan2:Math.sin}});
-assertAsmLinkFail(code, {Math:{atan2:null}});
-testBinary(asmLink(code, {Math:{atan2:Math.atan2}}), Math.atan2);
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var at=glob.Math.atan2; function f(d,e) { d=+d;e=+e; return +at(d,e) } return f'), {Math:{atan2:Math.sin}});
+assertAsmLinkFail(asmCompile('glob', USE_ASM + 'var at=glob.Math.atan2; function f(d,e) { d=+d;e=+e; return +at(d,e) } return f'), {Math:{atan2:null}});
+testBinary(asmLink(asmCompile('glob', USE_ASM + 'var at=glob.Math.atan2; function f(d,e) { d=+d;e=+e; return +at(d,e) } return f'), {Math:{atan2:Math.atan2}}), Math.atan2);
 
 assertAsmTypeFail('glob', USE_ASM + 'var sin=glob.Math.sin; function f(d) { d=+d; d = sin(d); } return f');
 assertAsmTypeFail('glob', USE_ASM + 'var sin=glob.Math.sin; function f(d) { d=+d; var i=0; i = sin(d)|0; } return f');
 assertAsmTypeFail('glob', USE_ASM + 'var pow=glob.Math.pow; function f(d) { d=+d; d = pow(d,d); } return f');
 assertAsmTypeFail('glob', USE_ASM + 'var pow=glob.Math.pow; function f(d) { d=+d; var i=0; i = pow(d,d)|0; } return f');
 assertAsmTypeFail('glob', USE_ASM + 'var atan2=glob.Math.atan2; function f(d) { d=+d; d = atan2(d,d); } return f');
 assertAsmTypeFail('glob', USE_ASM + 'var atan2=glob.Math.atan2; function f(d) { d=+d; var i=0; i = atan2(d,d)|0; } return f');
 assertAsmTypeFail('glob', USE_ASM + 'var sqrt=glob.Math.sqrt; function f(d) { d=+d; d = sqrt(d); } return f');
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Object-evalInGlobal-09.js
@@ -0,0 +1,9 @@
+// The frame created for evalInGlobal is never marked as a 'FUNCTION' frame.
+
+(function () {
+  var g = newGlobal();
+  var dbg = new Debugger;
+  var gw = dbg.addDebuggee(g);
+  gw.evalInGlobalWithBindings("eval('Math')",{}).return
+})();
+
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug911707.js
@@ -0,0 +1,5 @@
+// |jit-test| ion-eager
+x = [ "CNY", "TWD", "invalid" ];
+Object.freeze(x).map(function() {
+    x.length = 6
+})
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug911708.js
@@ -0,0 +1,8 @@
+function x() {
+    yield x
+}
+new(x)
+ParallelArray([7247], function() {
+    --x
+    eval("")
+})
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -34,16 +34,17 @@
 #include "gc/Barrier-inl.h"
 
 using namespace js;
 using namespace js::frontend;
 using namespace js::jit;
 
 using mozilla::AddToHash;
 using mozilla::ArrayLength;
+using mozilla::CountLeadingZeroes32;
 using mozilla::DebugOnly;
 using mozilla::HashGeneric;
 using mozilla::IsNaN;
 using mozilla::IsNegativeZero;
 using mozilla::Maybe;
 using mozilla::OldMove;
 using mozilla::MoveRef;
 
@@ -3112,18 +3113,20 @@ FoldMaskedArrayIndex(FunctionCompiler &f
 {
     ParseNode *indexNode = BinaryLeft(*indexExpr);
     ParseNode *maskNode = BinaryRight(*indexExpr);
 
     uint32_t mask2;
     if (IsLiteralUint32(maskNode, &mask2)) {
         // Flag the access to skip the bounds check if the mask ensures that an 'out of
         // bounds' access can not occur based on the current heap length constraint.
-        if (mozilla::CountLeadingZeroes32(f.m().minHeapLength() - 1) <= mozilla::CountLeadingZeroes32(mask2))
+        if (mask2 == 0 ||
+            CountLeadingZeroes32(f.m().minHeapLength() - 1) <= CountLeadingZeroes32(mask2)) {
             *needsBoundsCheck = NO_BOUNDS_CHECK;
+        }
         *mask &= mask2;
         *indexExpr = indexNode;
         return true;
     }
 
     return false;
 }
 
@@ -5973,17 +5976,18 @@ GenerateFFIIonExit(ModuleCompiler &m, co
 #else
     masm.branchTestMagic(Assembler::Equal, JSReturnOperand, throwLabel);
 #endif
 
     switch (exit.sig().retType().which()) {
       case RetType::Void:
         break;
       case RetType::Signed:
-        masm.convertValueToInt32(JSReturnOperand, ReturnFloatReg, ReturnReg, &oolConvert);
+        masm.convertValueToInt32(JSReturnOperand, ReturnFloatReg, ReturnReg, &oolConvert,
+                                 /* -0 check */ false);
         break;
       case RetType::Double:
         masm.convertValueToDouble(JSReturnOperand, ReturnFloatReg, &oolConvert);
 #if defined(JS_CPU_ARM) && !defined(JS_CPU_ARM_HARDFP)
         masm.boxDouble(ReturnFloatReg, softfpReturnOperand);
 #endif
         break;
     }
--- a/js/src/jit/AsmJSLink.cpp
+++ b/js/src/jit/AsmJSLink.cpp
@@ -190,16 +190,17 @@ ValidateGlobalConstant(JSContext *cx, As
 static bool
 DynamicallyLinkModule(JSContext *cx, CallArgs args, AsmJSModule &module)
 {
     if (module.isLinked())
         return LinkFail(cx, "As a temporary limitation, modules cannot be linked more than "
                             "once. This limitation should be removed in a future release. To "
                             "work around this, compile a second module (e.g., using the "
                             "Function constructor).");
+    module.setIsLinked();
 
     RootedValue globalVal(cx, UndefinedValue());
     if (args.length() > 0)
         globalVal = args[0];
 
     RootedValue importVal(cx, UndefinedValue());
     if (args.length() > 1)
         importVal = args[1];
@@ -222,17 +223,17 @@ DynamicallyLinkModule(JSContext *cx, Cal
         // loads and stores start on an aligned boundary and the heap byteLength has larger alignment.
         JS_ASSERT((module.minHeapLength() - 1) <= INT32_MAX);
         if (heap->byteLength() < module.minHeapLength())
             return LinkFail(cx, "ArrayBuffer byteLength less than the largest source code heap length constraint.");
 
         if (!ArrayBufferObject::prepareForAsmJS(cx, heap))
             return LinkFail(cx, "Unable to prepare ArrayBuffer for asm.js use");
 
-        module.patchHeapAccesses(heap, cx);
+        module.initHeap(heap, cx);
     }
 
     AutoObjectVector ffis(cx);
     if (!ffis.resize(module.numFFIs()))
         return false;
 
     for (unsigned i = 0; i < module.numGlobals(); i++) {
         AsmJSModule::Global &global = module.global(i);
@@ -258,17 +259,16 @@ DynamicallyLinkModule(JSContext *cx, Cal
                 return false;
             break;
         }
     }
 
     for (unsigned i = 0; i < module.numExits(); i++)
         module.exitIndexToGlobalDatum(i).fun = &ffis[module.exit(i).ffiIndex()]->as<JSFunction>();
 
-    module.setIsLinked(heap);
     return true;
 }
 
 AsmJSActivation::AsmJSActivation(JSContext *cx, AsmJSModule &module)
   : cx_(cx),
     module_(module),
     errorRejoinSP_(NULL),
     profiler_(NULL),
--- a/js/src/jit/AsmJSModule.cpp
+++ b/js/src/jit/AsmJSModule.cpp
@@ -17,18 +17,23 @@
 
 #include "js/MemoryMetrics.h"
 
 #include "jsobjinlines.h"
 
 using namespace js;
 
 void
-AsmJSModule::patchHeapAccesses(ArrayBufferObject *heap, JSContext *cx)
+AsmJSModule::initHeap(Handle<ArrayBufferObject*> heap, JSContext *cx)
 {
+    JS_ASSERT(linked_);
+    JS_ASSERT(!maybeHeap_);
+    maybeHeap_ = heap;
+    heapDatum() = heap->dataPointer();
+
     JS_ASSERT(IsPowerOfTwo(heap->byteLength()));
 #if defined(JS_CPU_X86)
     uint8_t *heapOffset = heap->dataPointer();
     void *heapLength = (void*)heap->byteLength();
     for (unsigned i = 0; i < heapAccesses_.length(); i++) {
         const jit::AsmJSHeapAccess &access = heapAccesses_[i];
         if (access.hasLengthCheck())
             JSC::X86Assembler::setPointer(access.patchLengthAt(code_), heapLength);
--- a/js/src/jit/AsmJSModule.h
+++ b/js/src/jit/AsmJSModule.h
@@ -625,17 +625,17 @@ class AsmJSModule
         return heapAccesses_.length();
     }
     jit::AsmJSHeapAccess &heapAccess(unsigned i) {
         return heapAccesses_[i];
     }
     const jit::AsmJSHeapAccess &heapAccess(unsigned i) const {
         return heapAccesses_[i];
     }
-    void patchHeapAccesses(ArrayBufferObject *heap, JSContext *cx);
+    void initHeap(Handle<ArrayBufferObject*> heap, JSContext *cx);
 
     void requireHeapLengthToBeAtLeast(uint32_t len) {
         if (len > minHeapLength_)
             minHeapLength_ = len;
     }
     uint32_t minHeapLength() const {
         return minHeapLength_;
     }
@@ -650,21 +650,19 @@ class AsmJSModule
 
     void setOperationCallbackExit(uint8_t *ptr) {
         operationCallbackExit_ = ptr;
     }
     uint8_t *operationCallbackExit() const {
         return operationCallbackExit_;
     }
 
-    void setIsLinked(Handle<ArrayBufferObject*> maybeHeap) {
+    void setIsLinked() {
         JS_ASSERT(!linked_);
         linked_ = true;
-        maybeHeap_ = maybeHeap;
-        heapDatum() = maybeHeap_ ? maybeHeap_->dataPointer() : NULL;
     }
     bool isLinked() const {
         return linked_;
     }
     uint8_t *maybeHeap() const {
         JS_ASSERT(linked_);
         return heapDatum();
     }
--- a/js/src/jit/BacktrackingAllocator.cpp
+++ b/js/src/jit/BacktrackingAllocator.cpp
@@ -1163,136 +1163,138 @@ BacktrackingAllocator::populateSafepoint
     }
 
     return true;
 }
 
 void
 BacktrackingAllocator::dumpRegisterGroups()
 {
-    printf("Register groups:\n");
+    fprintf(stderr, "Register groups:\n");
     for (size_t i = 0; i < graph.numVirtualRegisters(); i++) {
         VirtualRegisterGroup *group = vregs[i].group();
         if (group && i == group->canonicalReg()) {
             for (size_t j = 0; j < group->registers.length(); j++)
-                printf(" v%u", group->registers[j]);
-            printf("\n");
+                fprintf(stderr, " v%u", group->registers[j]);
+            fprintf(stderr, "\n");
         }
     }
 }
 
 void
 BacktrackingAllocator::dumpLiveness()
 {
 #ifdef DEBUG
-    printf("Virtual Registers:\n");
+    fprintf(stderr, "Virtual Registers:\n");
 
     for (size_t blockIndex = 0; blockIndex < graph.numBlocks(); blockIndex++) {
         LBlock *block = graph.getBlock(blockIndex);
         MBasicBlock *mir = block->mir();
 
-        printf("\nBlock %lu", static_cast<unsigned long>(blockIndex));
+        fprintf(stderr, "\nBlock %lu", static_cast<unsigned long>(blockIndex));
         for (size_t i = 0; i < mir->numSuccessors(); i++)
-            printf(" [successor %u]", mir->getSuccessor(i)->id());
-        printf("\n");
+            fprintf(stderr, " [successor %u]", mir->getSuccessor(i)->id());
+        fprintf(stderr, "\n");
 
         for (size_t i = 0; i < block->numPhis(); i++) {
             LPhi *phi = block->getPhi(i);
 
-            printf("Phi v%u <-", phi->getDef(0)->virtualRegister());
+            fprintf(stderr, "[%u,%u Phi v%u <-",
+                    inputOf(phi).pos(), outputOf(phi).pos(),
+                    phi->getDef(0)->virtualRegister());
             for (size_t j = 0; j < phi->numOperands(); j++)
-                printf(" v%u", phi->getOperand(j)->toUse()->virtualRegister());
-            printf("\n");
+                fprintf(stderr, " v%u", phi->getOperand(j)->toUse()->virtualRegister());
+            fprintf(stderr, "]\n");
         }
 
         for (LInstructionIterator iter = block->begin(); iter != block->end(); iter++) {
             LInstruction *ins = *iter;
 
-            printf("[%u,%u %s]", inputOf(ins).pos(), outputOf(ins).pos(), ins->opName());
+            fprintf(stderr, "[%u,%u %s]", inputOf(ins).pos(), outputOf(ins).pos(), ins->opName());
 
             for (size_t i = 0; i < ins->numTemps(); i++) {
                 LDefinition *temp = ins->getTemp(i);
                 if (!temp->isBogusTemp())
-                    printf(" [temp v%u]", temp->virtualRegister());
+                    fprintf(stderr, " [temp v%u]", temp->virtualRegister());
             }
 
             for (size_t i = 0; i < ins->numDefs(); i++) {
                 LDefinition *def = ins->getDef(i);
-                printf(" [def v%u]", def->virtualRegister());
+                fprintf(stderr, " [def v%u]", def->virtualRegister());
             }
 
             for (LInstruction::InputIterator alloc(*ins); alloc.more(); alloc.next()) {
                 if (alloc->isUse())
-                    printf(" [use v%u]", alloc->toUse()->virtualRegister());
+                    fprintf(stderr, " [use v%u]", alloc->toUse()->virtualRegister());
             }
 
-            printf("\n");
+            fprintf(stderr, "\n");
         }
     }
 
-    printf("\nLive Ranges:\n\n");
+    fprintf(stderr, "\nLive Ranges:\n\n");
 
     for (size_t i = 0; i < AnyRegister::Total; i++)
-        printf("reg %s: %s\n", AnyRegister::FromCode(i).name(), IntervalString(fixedIntervals[i]));
+        fprintf(stderr, "reg %s: %s\n", AnyRegister::FromCode(i).name(), IntervalString(fixedIntervals[i]));
 
     for (size_t i = 0; i < graph.numVirtualRegisters(); i++) {
-        printf("v%lu:", static_cast<unsigned long>(i));
+        fprintf(stderr, "v%lu:", static_cast<unsigned long>(i));
         VirtualRegister &vreg = vregs[i];
         for (size_t j = 0; j < vreg.numIntervals(); j++) {
             if (j)
-                printf(" *");
-            printf("%s", IntervalString(vreg.getInterval(j)));
+                fprintf(stderr, " *");
+            fprintf(stderr, "%s", IntervalString(vreg.getInterval(j)));
         }
-        printf("\n");
+        fprintf(stderr, "\n");
     }
 
-    printf("\n");
+    fprintf(stderr, "\n");
 #endif // DEBUG
 }
 
 #ifdef DEBUG
 struct BacktrackingAllocator::PrintLiveIntervalRange
 {
     void operator()(const AllocatedRange &item)
     {
         if (item.range == item.interval->getRange(0)) {
-            printf("  v%u: %s\n",
+            fprintf(stderr, "  v%u: %s\n",
                    item.interval->hasVreg() ? item.interval->vreg() : 0,
                    IntervalString(item.interval));
         }
     }
 };
 #endif
 
 void
 BacktrackingAllocator::dumpAllocations()
 {
 #ifdef DEBUG
-    printf("Allocations:\n");
+    fprintf(stderr, "Allocations:\n");
 
     for (size_t i = 0; i < graph.numVirtualRegisters(); i++) {
-        printf("v%lu:", static_cast<unsigned long>(i));
+        fprintf(stderr, "v%lu:", static_cast<unsigned long>(i));
         VirtualRegister &vreg = vregs[i];
         for (size_t j = 0; j < vreg.numIntervals(); j++) {
             if (j)
-                printf(" *");
+                fprintf(stderr, " *");
             LiveInterval *interval = vreg.getInterval(j);
-            printf("%s :: %s", IntervalString(interval), interval->getAllocation()->toString());
+            fprintf(stderr, "%s :: %s", IntervalString(interval), interval->getAllocation()->toString());
         }
-        printf("\n");
+        fprintf(stderr, "\n");
     }
 
-    printf("\n");
+    fprintf(stderr, "\n");
 
     for (size_t i = 0; i < AnyRegister::Total; i++) {
-        printf("reg %s:\n", AnyRegister::FromCode(i).name());
+        fprintf(stderr, "reg %s:\n", AnyRegister::FromCode(i).name());
         registers[i].allocations.forEach(PrintLiveIntervalRange());