Merge inbound to m-c a=merge CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Thu, 19 Mar 2015 19:15:11 -0700
changeset 234584 3257d9c4b257ee422629ca7d94fb83ee7883d523
parent 234581 988afda9eac4989e7a3aa5192c678a8f41ba69e8 (current diff)
parent 234479 b3fcbf6497653ca51fc762c2444470fba7270021 (diff)
child 234585 02ca416c13a5d084f20b10147635bdc6c4f3932a
push id57166
push userkwierso@gmail.com
push dateFri, 20 Mar 2015 02:30:44 +0000
treeherdermozilla-inbound@4d2d97b3ba34 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to m-c a=merge CLOSED TREE
browser/components/sessionstore/test/browser.ini
modules/brotli/dec/README
--- a/accessible/base/MarkupMap.h
+++ b/accessible/base/MarkupMap.h
@@ -200,32 +200,32 @@ MARKUPMAP(munderover_,
           AttrFromDOM(accentunder_, accentunder_),
           AttrFromDOM(align, align))
 
 MARKUPMAP(mmultiscripts_,
           New_HyperText,
           roles::MATHML_MULTISCRIPTS)
 
 MARKUPMAP(mtable_,
-          New_HyperText,
+          New_HTMLTableAccessible,
           roles::MATHML_TABLE,
           AttrFromDOM(align, align),
           AttrFromDOM(columnlines_, columnlines_),
           AttrFromDOM(rowlines_, rowlines_))
 
 MARKUPMAP(mlabeledtr_,
-          New_HyperText,
+          New_HTMLTableRowAccessible,
           roles::MATHML_LABELED_ROW)
 
 MARKUPMAP(mtr_,
-          New_HyperText,
+          New_HTMLTableRowAccessible,
           roles::MATHML_TABLE_ROW)
 
 MARKUPMAP(mtd_,
-          New_HyperText,
+          New_HTMLTableCellAccessible,
           roles::MATHML_CELL)
 
 MARKUPMAP(maction_,
           New_HyperText,
           roles::MATHML_ACTION,
           AttrFromDOM(actiontype_, actiontype_),
           AttrFromDOM(selection_, selection_))
 
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -196,16 +196,28 @@ static Accessible* New_HTMLLabel(nsICont
 
 static Accessible* New_HTMLOutput(nsIContent* aContent, Accessible* aContext)
   { return new HTMLOutputAccessible(aContent, aContext->Document()); }
 
 static Accessible* New_HTMLProgress(nsIContent* aContent, Accessible* aContext)
   { return new HTMLProgressMeterAccessible(aContent, aContext->Document()); }
 
 static Accessible*
+New_HTMLTableAccessible(nsIContent* aContent, Accessible* aContext)
+  { return new HTMLTableAccessible(aContent, aContext->Document()); }
+
+static Accessible*
+New_HTMLTableRowAccessible(nsIContent* aContent, Accessible* aContext)
+  { return new HTMLTableRowAccessible(aContent, aContext->Document()); }
+
+static Accessible*
+New_HTMLTableCellAccessible(nsIContent* aContent, Accessible* aContext)
+  { return new HTMLTableCellAccessible(aContent, aContext->Document()); }
+
+static Accessible*
 New_HTMLTableHeaderCell(nsIContent* aContent, Accessible* aContext)
 {
   if (aContext->IsTableRow() && aContext->GetContent() == aContent->GetParent())
     return new HTMLTableHeaderCellAccessibleWrap(aContent, aContext->Document());
   return nullptr;
 }
 
 static Accessible*
--- a/accessible/html/HTMLTableAccessible.cpp
+++ b/accessible/html/HTMLTableAccessible.cpp
@@ -55,16 +55,19 @@ HTMLTableCellAccessible::
 NS_IMPL_ISUPPORTS_INHERITED0(HTMLTableCellAccessible, HyperTextAccessible)
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableCellAccessible: Accessible implementation
 
 role
 HTMLTableCellAccessible::NativeRole()
 {
+  if (mContent->IsMathMLElement(nsGkAtoms::mtd_)) {
+    return roles::MATHML_CELL;
+  }
   return roles::CELL;
 }
 
 uint64_t
 HTMLTableCellAccessible::NativeState()
 {
   uint64_t state = HyperTextAccessibleWrap::NativeState();
 
@@ -143,18 +146,17 @@ HTMLTableCellAccessible::NativeAttribute
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableCellAccessible: TableCellAccessible implementation
 
 TableAccessible*
 HTMLTableCellAccessible::Table() const
 {
   Accessible* parent = const_cast<HTMLTableCellAccessible*>(this);
   while ((parent = parent->Parent())) {
-    roles::Role role = parent->Role();
-    if (role == roles::TABLE || role == roles::TREE_TABLE)
+    if (parent->IsTable())
       return parent->AsTable();
   }
 
   return nullptr;
 }
 
 uint32_t
 HTMLTableCellAccessible::ColIdx() const
@@ -344,16 +346,21 @@ HTMLTableHeaderCellAccessible::NativeRol
 // HTMLTableRowAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS_INHERITED0(HTMLTableRowAccessible, Accessible)
 
 role
 HTMLTableRowAccessible::NativeRole()
 {
+  if (mContent->IsMathMLElement(nsGkAtoms::mtr_)) {
+    return roles::MATHML_TABLE_ROW;
+  } else if (mContent->IsMathMLElement(nsGkAtoms::mlabeledtr_)) {
+    return roles::MATHML_LABELED_ROW;
+  }
   return roles::ROW;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS_INHERITED0(HTMLTableAccessible, Accessible)
@@ -379,16 +386,19 @@ HTMLTableAccessible::CacheChildren()
     }
     AppendChild(child);
   }
 }
 
 role
 HTMLTableAccessible::NativeRole()
 {
+  if (mContent->IsMathMLElement(nsGkAtoms::mtable_)) {
+    return roles::MATHML_TABLE;
+  }
   return roles::TABLE;
 }
 
 uint64_t
 HTMLTableAccessible::NativeState()
 {
   return Accessible::NativeState() | states::READONLY;
 }
@@ -416,16 +426,21 @@ HTMLTableAccessible::NativeName(nsString
   return eNameOK;
 }
 
 already_AddRefed<nsIPersistentProperties>
 HTMLTableAccessible::NativeAttributes()
 {
   nsCOMPtr<nsIPersistentProperties> attributes =
     AccessibleWrap::NativeAttributes();
+
+  if (mContent->IsMathMLElement(nsGkAtoms::mtable_)) {
+    GetAccService()->MarkupAttributes(mContent, attributes);
+  }
+
   if (IsProbablyLayoutTable()) {
     nsAutoString unused;
     attributes->SetStringProperty(NS_LITERAL_CSTRING("layout-guess"),
                                   NS_LITERAL_STRING("true"), unused);
   }
 
   return attributes.forget();
 }
--- a/accessible/tests/mochitest/table.js
+++ b/accessible/tests/mochitest/table.js
@@ -23,43 +23,61 @@ const kSpanned = kRowSpanned | kColSpann
 /**
  * Constants to define column header type.
  */
 const kNoColumnHeader = 0;
 const kListboxColumnHeader = 1;
 const kTreeColumnHeader = 2;
 
 /**
+ * Constants to define table type.
+ */
+const kTable = 0;
+const kTreeTable = 1;
+const kMathTable = 2;
+
+/**
  * Test table structure and related methods.
  *
  * @param  aIdentifier     [in] table accessible identifier
  * @param  aCellsArray     [in] two dimensional array (row X columns) of
  *                          cell types (see constants defined above).
  * @param  aColHeaderType  [in] specifies wether column header cells are
  *                          arranged into the list.
  * @param  aCaption        [in] caption text if any
  * @param  aSummary        [in] summary text if any
- * @param  aIsTreeTable    [in] specifies whether given table is tree table
+ * @param  aTableType      [in] specifies the table type.
+ * @param  aRowRoles       [in] array of row roles.
  */
 function testTableStruct(aIdentifier, aCellsArray, aColHeaderType,
-                         aCaption, aSummary, aIsTreeTable)
+                         aCaption, aSummary, aTableType, aRowRoles)
 {
   var tableNode = getNode(aIdentifier);
   var isGrid = tableNode.getAttribute("role") == "grid" ||
     tableNode.getAttribute("role") == "treegrid" ||
     tableNode.localName == "tree";
 
   var rowCount = aCellsArray.length;
   var colsCount = aCellsArray[0] ? aCellsArray[0].length : 0;
 
   // Test table accessible tree.
   var tableObj = {
-    role: aIsTreeTable ? ROLE_TREE_TABLE : ROLE_TABLE,
     children: []
   };
+  switch (aTableType) {
+    case kTable:
+      tableObj.role = ROLE_TABLE;
+      break;
+    case kTreeTable:
+      tableObj.role = ROLE_TREE_TABLE;
+      break;
+    case kMathTable:
+      tableObj.role = ROLE_MATHML_TABLE;
+      break;
+  }
 
   // caption accessible handling
   if (aCaption) {
     var captionObj = {
       role: ROLE_CAPTION,
       children: [
         {
           role: ROLE_TEXT_LEAF,
@@ -94,27 +112,28 @@ function testTableStruct(aIdentifier, aC
     }
 
     tableObj.children.push(headersObj);
   }
 
   // rows and cells accessibles
   for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
     var rowObj = {
-      role: ROLE_ROW,
+      role: aRowRoles ? aRowRoles[rowIdx] : ROLE_ROW,
       children: []
     };
 
     for (var colIdx = 0; colIdx < colsCount; colIdx++) {
       var celltype = aCellsArray[rowIdx][colIdx];
 
       var role = ROLE_NOTHING;
       switch (celltype) {
         case kDataCell:
-          role = (isGrid ? ROLE_GRID_CELL : ROLE_CELL);
+          role = (aTableType == kMathTable ? ROLE_MATHML_CELL :
+                  (isGrid ? ROLE_GRID_CELL : ROLE_CELL));
           break;
         case kRowHeaderCell:
           role = ROLE_ROWHEADER;
           break;
         case kColHeaderCell:
           role = ROLE_COLUMNHEADER;
           break;
       }
--- a/accessible/tests/mochitest/table/a11y.ini
+++ b/accessible/tests/mochitest/table/a11y.ini
@@ -4,16 +4,17 @@
 [test_headers_listbox.xul]
 [test_headers_table.html]
 [test_headers_tree.xul]
 [test_indexes_ariagrid.html]
 [test_indexes_listbox.xul]
 [test_indexes_table.html]
 [test_indexes_tree.xul]
 [test_layoutguess.html]
+[test_mtable.html]
 [test_sels_ariagrid.html]
 [test_sels_listbox.xul]
 [test_sels_table.html]
 [test_sels_tree.xul]
 [test_struct_ariagrid.html]
 [test_struct_ariatreegrid.html]
 [test_struct_listbox.xul]
 [test_struct_table.html]
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/table/test_mtable.html
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>MathML table tests</title>
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../role.js"></script>
+  <script type="application/javascript"
+          src="../table.js"></script>
+
+  <script type="application/javascript">
+    function doTest()
+    {
+      // 'Simple' table
+      var idxes = [
+        [0, 1],
+        [2, 3]
+      ];
+      testTableIndexes("simple", idxes);
+      var cellsArray = [
+        [kDataCell, kDataCell],
+        [kDataCell, kDataCell]
+      ];
+      var rowsArray = [ROLE_MATHML_TABLE_ROW, ROLE_MATHML_TABLE_ROW];
+      testTableStruct("simple", cellsArray, kNoColumnHeader,
+                      "", "", kMathTable, rowsArray);
+
+      // 'Complex' table
+      idxes = [
+        [0, 0, 0],
+        [1, 1, 2],
+        [1, 1, 3]
+      ];
+      testTableIndexes("complex", idxes);
+      cellsArray = [
+        [kDataCell,   kColSpanned, kColSpanned],
+        [kDataCell,   kColSpanned, kDataCell],
+        [kRowSpanned, kSpanned,    kDataCell],
+      ];
+      rowsArray = [
+        ROLE_MATHML_TABLE_ROW,
+        ROLE_MATHML_TABLE_ROW,
+        ROLE_MATHML_TABLE_ROW
+      ];
+      testTableStruct("complex", cellsArray, kNoColumnHeader,
+                      "", "", kMathTable, rowsArray);
+
+      // 'Simple' table with mlabeledtr
+      // At the moment we do not implement mlabeledtr but just hide the label
+      // with display: none. Thus we just test the role for now. See bug 689641.
+      var idxes = [[0]];
+      testTableIndexes("simple_label", idxes);
+      var cellsArray = [[kDataCell]];
+      rowsArray = [ROLE_MATHML_LABELED_ROW];
+      testTableStruct("simple_label", cellsArray, kNoColumnHeader,
+                      "", "", kMathTable, rowsArray);
+
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+</head>
+<body>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <math>
+    <mtable id="simple">
+      <mtr>
+        <mtd>
+          <mn>1</mn>
+        </mtd>
+        <mtd>
+          <mn>0</mn>
+        </mtd>
+      </mtr>
+      <mtr>
+        <mtd>
+          <mn>0</mn>
+        </mtd>
+        <mtd>
+          <mn>1</mn>
+        </mtd>
+      </mtr>
+    </mtable>
+
+    <mtable id="complex">
+      <mtr>
+        <mtd columnspan="3">
+          <mtext>1 x 3</mtext>
+        </mtd>
+      </mtr>
+      <mtr>
+        <mtd rowspan="2" columnspan="2">
+          <mtext>2 x 2</mtext>
+        </mtd>
+        <mtd>
+          <mtext>1 x 1</mtext>
+        </mtd>
+      </mtr>
+      <mtr>
+        <mtd>
+          <mtext>1 x 1</mtext>
+        </mtd>
+      </mtr>
+    </mtable>
+
+    <mtable id="simple_label">
+      <mlabeledtr>
+        <mtd><mtext>1</mtext></mtd>
+        <mtd><mtext>label</mtext></mtd>
+      </mlabeledtr>
+    </mtable>
+  </math>
+
+</body>
+</html>
--- a/accessible/tests/mochitest/table/test_struct_ariatreegrid.html
+++ b/accessible/tests/mochitest/table/test_struct_ariatreegrid.html
@@ -23,17 +23,18 @@
       // HTML based ARIA tree grid
 
       var cellsArray = [
         [kColHeaderCell, kColHeaderCell, kColHeaderCell],
         [kDataCell,      kDataCell,      kDataCell],
         [kDataCell,      kDataCell,      kDataCell]
       ];
 
-      testTableStruct("treegrid", cellsArray, kNoColumnHeader, "", "", true);
+      testTableStruct("treegrid", cellsArray, kNoColumnHeader, "", "",
+                      kTreeTable);
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
--- a/b2g/components/Frames.jsm
+++ b/b2g/components/Frames.jsm
@@ -20,32 +20,32 @@ const Observer = {
   _frames: new Map(),
 
   // Also save current number of iframes opened by app
   _apps: new Map(),
 
   start: function () {
     Services.obs.addObserver(this, 'remote-browser-shown', false);
     Services.obs.addObserver(this, 'inprocess-browser-shown', false);
-    Services.obs.addObserver(this, 'message-manager-disconnect', false);
+    Services.obs.addObserver(this, 'message-manager-close', false);
 
     SystemAppProxy.getFrames().forEach(frame => {
       let mm = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
       this._frames.set(mm, frame);
       let mozapp = frame.getAttribute('mozapp');
       if (mozapp) {
         this._apps.set(mozapp, (this._apps.get(mozapp) || 0) + 1);
       }
     });
   },
 
   stop: function () {
     Services.obs.removeObserver(this, 'remote-browser-shown');
     Services.obs.removeObserver(this, 'inprocess-browser-shown');
-    Services.obs.removeObserver(this, 'message-manager-disconnect');
+    Services.obs.removeObserver(this, 'message-manager-close');
     this._frames.clear();
     this._apps.clear();
   },
 
   observe: function (subject, topic, data) {
     switch(topic) {
 
       // Listen for frame creation in OOP (device) as well as in parent process (b2g desktop)
@@ -56,17 +56,17 @@ const Observer = {
         // get a ref to the app <iframe>
         frameLoader.QueryInterface(Ci.nsIFrameLoader);
         let frame = frameLoader.ownerElement;
         let mm = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
         this.onMessageManagerCreated(mm, frame);
         break;
 
       // Every time an iframe is destroyed, its message manager also is
-      case 'message-manager-disconnect':
+      case 'message-manager-close':
         this.onMessageManagerDestroyed(subject);
         break;
     }
   },
 
   onMessageManagerCreated: function (mm, frame) {
     this._frames.set(mm, frame);
 
--- a/browser/components/sessionstore/content/content-sessionStore.js
+++ b/browser/components/sessionstore/content/content-sessionStore.js
@@ -749,17 +749,17 @@ function handleRevivedTab() {
 
     removeEventListener("pagehide", handleRevivedTab);
 
     // We can't send a message using the frame message manager because by
     // the time we reach the unload event handler, it's "too late", and messages
     // won't be sent or received. The child-process message manager works though,
     // despite the fact that we're really running in the parent process.
     let browser = docShell.chromeEventHandler;
-    cpmm.sendSyncMessage("SessionStore:RemoteTabRevived", null, {browser: browser});
+    cpmm.sendAsyncMessage("SessionStore:RemoteTabRevived", null, {browser: browser});
   }
 }
 
 // If we're browsing from the tab crashed UI to a blacklisted URI that keeps
 // this browser non-remote, we'll handle that in a pagehide event.
 addEventListener("pagehide", handleRevivedTab);
 
 addEventListener("unload", () => {
--- a/browser/components/sessionstore/test/browser.ini
+++ b/browser/components/sessionstore/test/browser.ini
@@ -67,17 +67,17 @@ support-files =
 [browser_aboutSessionRestore.js]
 [browser_attributes.js]
 [browser_backup_recovery.js]
 [browser_broadcast.js]
 [browser_capabilities.js]
 [browser_cleaner.js]
 [browser_cookies.js]
 [browser_crashedTabs.js]
-skip-if = !e10s || os == "linux" # Waiting on OMTC enabled by default on Linux (Bug 994541)
+skip-if = !e10s || !crashreporter
 [browser_dying_cache.js]
 [browser_dynamic_frames.js]
 [browser_form_restore_events.js]
 [browser_formdata.js]
 skip-if = buildapp == 'mulet'
 [browser_formdata_format.js]
 [browser_formdata_xpath.js]
 [browser_frametree.js]
--- a/browser/components/sessionstore/test/browser_crashedTabs.js
+++ b/browser/components/sessionstore/test/browser_crashedTabs.js
@@ -10,16 +10,19 @@ const PAGE_2 = "data:text/html,<html><bo
 Services.prefs.setBoolPref("browser.tabs.animate", false);
 registerCleanupFunction(() => {
   Services.prefs.clearUserPref("browser.tabs.animate");
 });
 
 // Allow tabs to restore on demand so we can test pending states
 Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
 
+// Running this test in ASAN is slow.
+requestLongerTimeout(2);
+
 /**
  * Returns a Promise that resolves once a remote <xul:browser> has experienced
  * a crash. Also does the job of cleaning up the minidump of the crash.
  *
  * @param browser
  *        The <xul:browser> that will crash
  * @return Promise
  */
--- a/browser/components/uitour/UITour.jsm
+++ b/browser/components/uitour/UITour.jsm
@@ -679,17 +679,17 @@ this.UITour = {
       }
     }
 
     if (!this.tourBrowsersByWindow.has(window)) {
       this.tourBrowsersByWindow.set(window, new Set());
     }
     this.tourBrowsersByWindow.get(window).add(browser);
 
-    Services.obs.addObserver(this, "message-manager-disconnect", false);
+    Services.obs.addObserver(this, "message-manager-close", false);
 
     window.addEventListener("SSWindowClosing", this);
 
     return true;
   },
 
   handleEvent: function(aEvent) {
     log.debug("handleEvent: type =", aEvent.type, "event =", aEvent);
@@ -731,17 +731,17 @@ this.UITour = {
     }
   },
 
   observe: function(aSubject, aTopic, aData) {
     log.debug("observe: aTopic =", aTopic);
     switch (aTopic) {
       // The browser message manager is disconnected when the <browser> is
       // destroyed and we want to teardown at that point.
-      case "message-manager-disconnect": {
+      case "message-manager-close": {
         let winEnum = Services.wm.getEnumerator("navigator:browser");
         while (winEnum.hasMoreElements()) {
           let window = winEnum.getNext();
           if (window.closed)
             continue;
 
           let tourBrowsers = this.tourBrowsersByWindow.get(window);
           if (!tourBrowsers)
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js
@@ -45,44 +45,45 @@ let consoleOpened = Task.async(function*
 
   popup._panel.addEventListener("popupshown", function onShown() {
     popup._panel.removeEventListener("popupshown", onShown, false);
 
     ok(popup.isOpen, "popup is open");
 
     // 4 values, and the following properties:
     // __defineGetter__  __defineSetter__ __lookupGetter__ __lookupSetter__
-    // hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString
-    // toSource unwatch valueOf watch constructor.
-    is(popup.itemCount, 18, "popup.itemCount is correct");
+    // __proto__ hasOwnProperty isPrototypeOf propertyIsEnumerable
+    // toLocaleString toString toSource unwatch valueOf watch constructor.
+    is(popup.itemCount, 19, "popup.itemCount is correct");
 
     let sameItems = popup.getItems().reverse().map(function(e) {return e.label;});
     ok(sameItems.every(function(prop, index) {
       return [
         "__defineGetter__",
         "__defineSetter__",
         "__lookupGetter__",
         "__lookupSetter__",
+        "__proto__",
         "constructor",
         "hasOwnProperty",
         "isPrototypeOf",
         "item0",
         "item1",
         "item2",
         "item3",
         "propertyIsEnumerable",
         "toLocaleString",
         "toSource",
         "toString",
         "unwatch",
         "valueOf",
         "watch",
       ][index] === prop}), "getItems returns the items we expect");
 
-    is(popup.selectedIndex, 17,
+    is(popup.selectedIndex, 18,
        "Index of the first item from bottom is selected.");
     EventUtils.synthesizeKey("VK_DOWN", {});
 
     let prefix = jsterm.inputNode.value.replace(/[\S]/g, " ");
 
     is(popup.selectedIndex, 0, "index 0 is selected");
     is(popup.selectedItem.label, "watch", "watch is selected");
     is(completeNode.value, prefix + "watch",
@@ -110,17 +111,17 @@ let consoleOpened = Task.async(function*
       "Index is greater after PGDN");
 
     currentSelectionIndex = popup.selectedIndex;
     EventUtils.synthesizeKey("VK_PAGE_UP", {});
 
     ok(popup.selectedIndex < currentSelectionIndex, "Index is less after Page UP");
 
     EventUtils.synthesizeKey("VK_END", {});
-    is(popup.selectedIndex, 17, "index is last after End");
+    is(popup.selectedIndex, 18, "index is last after End");
 
     EventUtils.synthesizeKey("VK_HOME", {});
     is(popup.selectedIndex, 0, "index is first after Home");
 
     info("press Tab and wait for popup to hide");
     popup._panel.addEventListener("popuphidden", function popupHidden() {
       popup._panel.removeEventListener("popuphidden", popupHidden, false);
       deferred.resolve();
@@ -147,19 +148,19 @@ function popupHideAfterTab()
 
   ok(!completeNode.value, "completeNode is empty");
 
   popup._panel.addEventListener("popupshown", function onShown() {
     popup._panel.removeEventListener("popupshown", onShown, false);
 
     ok(popup.isOpen, "popup is open");
 
-    is(popup.itemCount, 18, "popup.itemCount is correct");
+    is(popup.itemCount, 19, "popup.itemCount is correct");
 
-    is(popup.selectedIndex, 17, "First index from bottom is selected");
+    is(popup.selectedIndex, 18, "First index from bottom is selected");
     EventUtils.synthesizeKey("VK_DOWN", {});
 
     let prefix = jsterm.inputNode.value.replace(/[\S]/g, " ");
 
     is(popup.selectedIndex, 0, "index 0 is selected");
     is(popup.selectedItem.label, "watch", "watch is selected");
     is(completeNode.value, prefix + "watch",
         "completeNode.value holds watch");
@@ -196,19 +197,19 @@ function testReturnKey()
 {
   let deferred = promise.defer();
 
   popup._panel.addEventListener("popupshown", function onShown() {
     popup._panel.removeEventListener("popupshown", onShown, false);
 
     ok(popup.isOpen, "popup is open");
 
-    is(popup.itemCount, 18, "popup.itemCount is correct");
+    is(popup.itemCount, 19, "popup.itemCount is correct");
 
-    is(popup.selectedIndex, 17, "First index from bottom is selected");
+    is(popup.selectedIndex, 18, "First index from bottom is selected");
     EventUtils.synthesizeKey("VK_DOWN", {});
 
     let prefix = jsterm.inputNode.value.replace(/[\S]/g, " ");
 
     is(popup.selectedIndex, 0, "index 0 is selected");
     is(popup.selectedItem.label, "watch", "watch is selected");
     is(completeNode.value, prefix + "watch",
         "completeNode.value holds watch");
--- a/build/autoconf/toolchain.m4
+++ b/build/autoconf/toolchain.m4
@@ -96,19 +96,19 @@ if test "$GNU_CC"; then
         GCC_USE_GNU_LD=1
     fi
 fi
 
 AC_SUBST(CLANG_CXX)
 AC_SUBST(CLANG_CL)
 
 if test -n "$GNU_CC" -a -z "$CLANG_CC" ; then
-    if test "$GCC_MAJOR_VERSION" -eq 4 -a "$GCC_MINOR_VERSION" -lt 6 ||
+    if test "$GCC_MAJOR_VERSION" -eq 4 -a "$GCC_MINOR_VERSION" -lt 7 ||
        test "$GCC_MAJOR_VERSION" -lt 4; then
-        AC_MSG_ERROR([Only GCC 4.6 or newer supported])
+        AC_MSG_ERROR([Only GCC 4.7 or newer supported])
     fi
 fi
 ])
 
 AC_DEFUN([MOZ_CROSS_COMPILER],
 [
 echo "cross compiling from $host to $target"
 
--- a/dom/activities/Activity.cpp
+++ b/dom/activities/Activity.cpp
@@ -20,19 +20,19 @@ NS_IMPL_RELEASE_INHERITED(Activity, DOMR
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(Activity, DOMRequest,
                                    mProxy)
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(Activity, DOMRequest)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 /* virtual */ JSObject*
-Activity::WrapObject(JSContext* aCx)
+Activity::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MozActivityBinding::Wrap(aCx, this);
+  return MozActivityBinding::Wrap(aCx, this, aGivenProto);
 }
 
 nsresult
 Activity::Initialize(nsPIDOMWindow* aWindow,
                      JSContext* aCx,
                      const ActivityOptions& aOptions)
 {
   MOZ_ASSERT(aWindow);
--- a/dom/activities/Activity.h
+++ b/dom/activities/Activity.h
@@ -16,17 +16,17 @@ namespace mozilla {
 namespace dom {
 
 class Activity : public DOMRequest
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(Activity, DOMRequest)
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static already_AddRefed<Activity>
   Constructor(const GlobalObject& aOwner,
               const ActivityOptions& aOptions,
               ErrorResult& aRv)
   {
     nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aOwner.GetAsSupports());
     if (!window) {
--- a/dom/animation/Animation.cpp
+++ b/dom/animation/Animation.cpp
@@ -61,19 +61,19 @@ const double ComputedTiming::kNullTimeFr
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Animation, mDocument, mTarget)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(Animation, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(Animation, Release)
 
 JSObject*
-Animation::WrapObject(JSContext* aCx)
+Animation::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return AnimationBinding::Wrap(aCx, this);
+  return AnimationBinding::Wrap(aCx, this, aGivenProto);
 }
 
 already_AddRefed<AnimationEffect>
 Animation::GetEffect()
 {
   nsRefPtr<AnimationEffect> effect = new AnimationEffect(this);
   return effect.forget();
 }
--- a/dom/animation/Animation.h
+++ b/dom/animation/Animation.h
@@ -184,17 +184,17 @@ public:
   {
     MOZ_ASSERT(aTarget, "null animation target is not yet supported");
   }
 
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(Animation)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(Animation)
 
   nsIDocument* GetParentObject() const { return mDocument; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // FIXME: If we succeed in moving transition-specific code to a type of
   // AnimationEffect (as per the Web Animations API) we should remove these
   // virtual methods.
   virtual ElementPropertyTransition* AsTransition() { return nullptr; }
   virtual const ElementPropertyTransition* AsTransition() const {
     return nullptr;
   }
--- a/dom/animation/AnimationEffect.cpp
+++ b/dom/animation/AnimationEffect.cpp
@@ -10,15 +10,15 @@ namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AnimationEffect, mAnimation)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AnimationEffect, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AnimationEffect, Release)
 
 JSObject*
-AnimationEffect::WrapObject(JSContext* aCx)
+AnimationEffect::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return AnimationEffectBinding::Wrap(aCx, this);
+  return AnimationEffectBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/animation/AnimationEffect.h
+++ b/dom/animation/AnimationEffect.h
@@ -22,17 +22,17 @@ public:
     : mAnimation(aAnimation)
   {
   }
 
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AnimationEffect)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AnimationEffect)
 
   Animation* GetParentObject() const { return mAnimation; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // AnimationEffect interface
   void GetName(nsString& aRetVal) const {
     aRetVal = mAnimation->Name();
   }
 
 private:
   ~AnimationEffect() { }
--- a/dom/animation/AnimationPlayer.cpp
+++ b/dom/animation/AnimationPlayer.cpp
@@ -21,19 +21,19 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(An
 NS_IMPL_CYCLE_COLLECTING_ADDREF(AnimationPlayer)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(AnimationPlayer)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AnimationPlayer)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 JSObject*
-AnimationPlayer::WrapObject(JSContext* aCx)
+AnimationPlayer::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return dom::AnimationPlayerBinding::Wrap(aCx, this);
+  return dom::AnimationPlayerBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 AnimationPlayer::SetStartTime(const Nullable<TimeDuration>& aNewStartTime)
 {
 #if 1
   // Bug 1096776: once we support inactive/missing timelines we'll want to take
   // the disabled branch.
--- a/dom/animation/AnimationPlayer.h
+++ b/dom/animation/AnimationPlayer.h
@@ -59,17 +59,17 @@ public:
     , mIsRelevant(false)
   {
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(AnimationPlayer)
 
   AnimationTimeline* GetParentObject() const { return mTimeline; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual CSSAnimationPlayer* AsCSSAnimationPlayer() { return nullptr; }
   virtual CSSTransitionPlayer* AsCSSTransitionPlayer() { return nullptr; }
 
   // AnimationPlayer methods
   Animation* GetSource() const { return mSource; }
   AnimationTimeline* Timeline() const { return mTimeline; }
   Nullable<TimeDuration> GetStartTime() const { return mStartTime; }
--- a/dom/animation/AnimationTimeline.cpp
+++ b/dom/animation/AnimationTimeline.cpp
@@ -16,19 +16,19 @@ namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(AnimationTimeline, mDocument, mWindow)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AnimationTimeline, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AnimationTimeline, Release)
 
 JSObject*
-AnimationTimeline::WrapObject(JSContext* aCx)
+AnimationTimeline::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return AnimationTimelineBinding::Wrap(aCx, this);
+  return AnimationTimelineBinding::Wrap(aCx, this, aGivenProto);
 }
 
 Nullable<TimeDuration>
 AnimationTimeline::GetCurrentTime() const
 {
   return ToTimelineTime(GetCurrentTimeStamp());
 }
 
--- a/dom/animation/AnimationTimeline.h
+++ b/dom/animation/AnimationTimeline.h
@@ -36,17 +36,17 @@ protected:
 public:
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AnimationTimeline)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AnimationTimeline)
 
   nsIGlobalObject* GetParentObject() const
   {
     return mWindow;
   }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // AnimationTimeline methods
   Nullable<TimeDuration> GetCurrentTime() const;
 
   // Wrapper functions for AnimationTimeline DOM methods when called from
   // script.
   Nullable<double> GetCurrentTimeAsDouble() const;
 
--- a/dom/archivereader/ArchiveReader.cpp
+++ b/dom/archivereader/ArchiveReader.cpp
@@ -56,19 +56,19 @@ ArchiveReader::ArchiveReader(File& aBlob
   MOZ_ASSERT(aWindow);
 }
 
 ArchiveReader::~ArchiveReader()
 {
 }
 
 /* virtual */ JSObject*
-ArchiveReader::WrapObject(JSContext* aCx)
+ArchiveReader::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return ArchiveReaderBinding::Wrap(aCx, this);
+  return ArchiveReaderBinding::Wrap(aCx, this, aGivenProto);
 }
 
 nsresult
 ArchiveReader::RegisterRequest(ArchiveRequest* aRequest)
 {
   switch (mStatus) {
     // Append to the list and let's start to work:
     case NOT_STARTED:
--- a/dom/archivereader/ArchiveReader.h
+++ b/dom/archivereader/ArchiveReader.h
@@ -46,17 +46,17 @@ public:
   ArchiveReader(File& aBlob, nsPIDOMWindow* aWindow,
                 const nsACString& aEncoding);
 
   nsIDOMWindow* GetParentObject() const
   {
     return mWindow;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   already_AddRefed<ArchiveRequest> GetFilenames();
   already_AddRefed<ArchiveRequest> GetFile(const nsAString& filename);
   already_AddRefed<ArchiveRequest> GetFiles();
 
   nsresult GetInputStream(nsIInputStream** aInputStream);
   nsresult GetSize(uint64_t* aSize);
 
--- a/dom/archivereader/ArchiveRequest.cpp
+++ b/dom/archivereader/ArchiveRequest.cpp
@@ -72,19 +72,19 @@ nsresult
 ArchiveRequest::PreHandleEvent(EventChainPreVisitor& aVisitor)
 {
   aVisitor.mCanHandle = true;
   aVisitor.mParentTarget = nullptr;
   return NS_OK;
 }
 
 /* virtual */ JSObject*
-ArchiveRequest::WrapObject(JSContext* aCx)
+ArchiveRequest::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return ArchiveRequestBinding::Wrap(aCx, this);
+  return ArchiveRequestBinding::Wrap(aCx, this, aGivenProto);
 }
 
 ArchiveReader*
 ArchiveRequest::Reader() const
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   return mArchiveReader;
--- a/dom/archivereader/ArchiveRequest.h
+++ b/dom/archivereader/ArchiveRequest.h
@@ -21,17 +21,17 @@ BEGIN_ARCHIVEREADER_NAMESPACE
 
 /**
  * This is the ArchiveRequest that handles any operation
  * related to ArchiveReader
  */
 class ArchiveRequest : public mozilla::dom::DOMRequest
 {
 public:
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   ArchiveReader* Reader() const;
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ArchiveRequest, DOMRequest)
 
   ArchiveRequest(nsPIDOMWindow* aWindow,
--- a/dom/base/AnonymousContent.cpp
+++ b/dom/base/AnonymousContent.cpp
@@ -126,15 +126,16 @@ AnonymousContent::GetElementById(const n
       return kid->AsElement();
     }
   }
   return nullptr;
 }
 
 bool
 AnonymousContent::WrapObject(JSContext* aCx,
+                             JS::Handle<JSObject*> aGivenProto,
                              JS::MutableHandle<JSObject*> aReflector)
 {
-  return AnonymousContentBinding::Wrap(aCx, this, aReflector);
+  return AnonymousContentBinding::Wrap(aCx, this, aGivenProto, aReflector);
 }
 
 } // dom namespace
 } // mozilla namespace
--- a/dom/base/AnonymousContent.h
+++ b/dom/base/AnonymousContent.h
@@ -22,17 +22,17 @@ class AnonymousContent MOZ_FINAL
 public:
   // Ref counting and cycle collection
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AnonymousContent)
   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AnonymousContent)
 
   explicit AnonymousContent(Element* aContentNode);
   nsCOMPtr<Element> GetContentNode();
   void SetContentNode(Element* aContentNode);
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 
   // WebIDL methods
   void SetTextContentForElement(const nsAString& aElementId,
                                 const nsAString& aText,
                                 ErrorResult& aRv);
 
   void GetTextContentForElement(const nsAString& aElementId,
                                 DOMString& aText,
--- a/dom/base/Attr.cpp
+++ b/dom/base/Attr.cpp
@@ -379,15 +379,15 @@ Attr::Initialize()
 
 void
 Attr::Shutdown()
 {
   sInitialized = false;
 }
 
 JSObject*
-Attr::WrapNode(JSContext* aCx)
+Attr::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return AttrBinding::Wrap(aCx, this);
+  return AttrBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/Attr.h
+++ b/dom/base/Attr.h
@@ -77,17 +77,17 @@ public:
   static void Shutdown();
 
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(Attr,
                                                                    nsIAttribute)
 
   virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
   // WebIDL
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // XPCOM GetName() is OK
   // XPCOM GetValue() is OK
 
   void SetValue(const nsAString& aValue, ErrorResult& aRv);
 
   bool Specified() const;
 
--- a/dom/base/BarProps.cpp
+++ b/dom/base/BarProps.cpp
@@ -29,19 +29,19 @@ BarProp::~BarProp()
 
 nsPIDOMWindow*
 BarProp::GetParentObject() const
 {
   return mDOMWindow;
 }
 
 JSObject*
-BarProp::WrapObject(JSContext* aCx)
+BarProp::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BarPropBinding::Wrap(aCx, this);
+  return BarPropBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(BarProp, mDOMWindow)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(BarProp)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(BarProp)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BarProp)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
--- a/dom/base/BarProps.h
+++ b/dom/base/BarProps.h
@@ -35,17 +35,17 @@ public:
   explicit BarProp(nsGlobalWindow *aWindow);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BarProp)
 
   nsPIDOMWindow* GetParentObject() const;
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual bool GetVisible(ErrorResult& aRv) = 0;
   virtual void SetVisible(bool aVisible, ErrorResult& aRv) = 0;
 
 protected:
   virtual ~BarProp();
 
   bool GetVisibleByFlag(uint32_t aChromeFlag, ErrorResult& aRv);
--- a/dom/base/Comment.cpp
+++ b/dom/base/Comment.cpp
@@ -69,15 +69,15 @@ Comment::Constructor(const GlobalObject&
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   return window->GetDoc()->CreateComment(aData);
 }
 
 JSObject*
-Comment::WrapNode(JSContext *aCx)
+Comment::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CommentBinding::Wrap(aCx, this);
+  return CommentBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/Comment.h
+++ b/dom/base/Comment.h
@@ -67,15 +67,15 @@ public:
   }
 #endif
 
   static already_AddRefed<Comment>
   Constructor(const GlobalObject& aGlobal, const nsAString& aData,
               ErrorResult& aRv);
 
 protected:
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_Comment_h
--- a/dom/base/Console.cpp
+++ b/dom/base/Console.cpp
@@ -717,19 +717,19 @@ Console::Observe(nsISupports* aSubject, 
 
     mTimerRegistry.Clear();
   }
 
   return NS_OK;
 }
 
 JSObject*
-Console::WrapObject(JSContext* aCx)
+Console::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return ConsoleBinding::Wrap(aCx, this);
+  return ConsoleBinding::Wrap(aCx, this, aGivenProto);
 }
 
 #define METHOD(name, string)                                          \
   void                                                                \
   Console::name(JSContext* aCx, const Sequence<JS::Value>& aData)     \
   {                                                                   \
     Method(aCx, Method##name, NS_LITERAL_STRING(string), aData);      \
   }
--- a/dom/base/Console.h
+++ b/dom/base/Console.h
@@ -39,17 +39,17 @@ public:
 
   // WebIDL methods
   nsISupports* GetParentObject() const
   {
     return mWindow;
   }
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void
   Log(JSContext* aCx, const Sequence<JS::Value>& aData);
 
   void
   Info(JSContext* aCx, const Sequence<JS::Value>& aData);
 
   void
--- a/dom/base/Crypto.cpp
+++ b/dom/base/Crypto.cpp
@@ -41,19 +41,19 @@ Crypto::~Crypto()
 void
 Crypto::Init(nsIGlobalObject* aParent)
 {
   mParent = do_QueryInterface(aParent);
   MOZ_ASSERT(mParent);
 }
 
 /* virtual */ JSObject*
-Crypto::WrapObject(JSContext* aCx)
+Crypto::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CryptoBinding::Wrap(aCx, this);
+  return CryptoBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
                         JS::MutableHandle<JSObject*> aRetval,
                         ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread(), "Called on the wrong thread");
--- a/dom/base/Crypto.h
+++ b/dom/base/Crypto.h
@@ -45,17 +45,17 @@ public:
 
   nsIGlobalObject*
   GetParentObject() const
   {
     return mParent;
   }
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static uint8_t*
   GetRandomValues(uint32_t aLength);
 
 private:
   nsCOMPtr<nsIGlobalObject> mParent;
   nsRefPtr<SubtleCrypto> mSubtle;
 };
--- a/dom/base/DOMCursor.cpp
+++ b/dom/base/DOMCursor.cpp
@@ -71,15 +71,15 @@ DOMCursor::Continue(ErrorResult& aRv)
     return;
   }
 
   Reset();
   mCallback->HandleContinue();
 }
 
 /* virtual */ JSObject*
-DOMCursor::WrapObject(JSContext* aCx)
+DOMCursor::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMCursorBinding::Wrap(aCx, this);
+  return DOMCursorBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/DOMCursor.h
+++ b/dom/base/DOMCursor.h
@@ -22,17 +22,17 @@ class DOMCursor : public DOMRequest
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMDOMCURSOR
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMCursor,
                                            DOMRequest)
 
   DOMCursor(nsPIDOMWindow* aWindow, nsICursorContinueCallback *aCallback);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   bool Done() const
   {
     return mFinished;
   }
   virtual void Continue(ErrorResult& aRv);
 
   void Reset();
--- a/dom/base/DOMError.cpp
+++ b/dom/base/DOMError.cpp
@@ -50,19 +50,19 @@ DOMError::DOMError(nsPIDOMWindow* aWindo
 {
 }
 
 DOMError::~DOMError()
 {
 }
 
 JSObject*
-DOMError::WrapObject(JSContext* aCx)
+DOMError::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMErrorBinding::Wrap(aCx, this);
+  return DOMErrorBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */ already_AddRefed<DOMError>
 DOMError::Constructor(const GlobalObject& aGlobal,
                       const nsAString& aName, const nsAString& aMessage,
                       ErrorResult& aRv)
 {
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
--- a/dom/base/DOMError.h
+++ b/dom/base/DOMError.h
@@ -54,17 +54,17 @@ public:
            const nsAString& aMessage);
 
   nsPIDOMWindow* GetParentObject() const
   {
     return mWindow;
   }
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static already_AddRefed<DOMError>
   Constructor(const GlobalObject& global, const nsAString& name,
               const nsAString& message, ErrorResult& aRv);
 
   void GetName(nsString& aRetval) const
   {
     aRetval = mName;
--- a/dom/base/DOMException.cpp
+++ b/dom/base/DOMException.cpp
@@ -485,19 +485,19 @@ Exception::Initialize(const nsACString& 
   mData = aData;
   mInner = aInner;
 
   mInitialized = true;
   return NS_OK;
 }
 
 JSObject*
-Exception::WrapObject(JSContext* cx)
+Exception::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return ExceptionBinding::Wrap(cx, this);
+  return ExceptionBinding::Wrap(cx, this, aGivenProto);
 }
 
 void
 Exception::GetMessageMoz(nsString& retval)
 {
   nsCString str;
 #ifdef DEBUG
   DebugOnly<nsresult> rv =
@@ -701,19 +701,19 @@ DOMException::Constructor(GlobalObject& 
     new DOMException(exceptionResult,
                      NS_ConvertUTF16toUTF8(aMessage),
                      name,
                      exceptionCode);
   return retval.forget();
 }
 
 JSObject*
-DOMException::WrapObject(JSContext* aCx)
+DOMException::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMExceptionBinding::Wrap(aCx, this);
+  return DOMExceptionBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */already_AddRefed<DOMException>
 DOMException::Create(nsresult aRv)
 {
   nsCString name;
   nsCString message;
   uint16_t code;
--- a/dom/base/DOMException.h
+++ b/dom/base/DOMException.h
@@ -58,17 +58,17 @@ public:
   NS_DECL_NSIXPCEXCEPTION
 
   // Cruft used by XPConnect for exceptions originating in JS implemented
   // components.
   bool StealJSVal(JS::Value* aVp);
   void StowJSVal(JS::Value& aVp);
 
   // WebIDL API
-  virtual JSObject* WrapObject(JSContext* cx)
+  virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
     MOZ_OVERRIDE;
 
   nsISupports* GetParentObject() const { return nullptr; }
 
   void GetMessageMoz(nsString& retval);
 
   uint32_t Result() const;
 
@@ -131,17 +131,17 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMDOMEXCEPTION
 
   // nsIException overrides
   NS_IMETHOD ToString(nsACString& aReturn) MOZ_OVERRIDE;
 
   // nsWrapperCache overrides
-  virtual JSObject* WrapObject(JSContext* aCx)
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
     MOZ_OVERRIDE;
 
   static already_AddRefed<DOMException>
   Constructor(GlobalObject& /* unused */,
               const nsAString& aMessage,
               const Optional<nsAString>& aName,
               ErrorResult& aError);
 
--- a/dom/base/DOMImplementation.cpp
+++ b/dom/base/DOMImplementation.cpp
@@ -24,19 +24,19 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMImplementation, mOwner)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMImplementation)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMImplementation)
 
 JSObject*
-DOMImplementation::WrapObject(JSContext* aCx)
+DOMImplementation::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMImplementationBinding::Wrap(aCx, this);
+  return DOMImplementationBinding::Wrap(aCx, this, aGivenProto);
 }
 
 bool
 DOMImplementation::HasFeature(const nsAString& aFeature,
                               const nsAString& aVersion)
 {
   return nsContentUtils::InternalIsSupported(
            static_cast<nsIDOMDOMImplementation*>(this),
--- a/dom/base/DOMImplementation.h
+++ b/dom/base/DOMImplementation.h
@@ -47,17 +47,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMImplementation)
 
   nsIDocument* GetParentObject() const
   {
     return mOwner;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // nsIDOMDOMImplementation
   NS_DECL_NSIDOMDOMIMPLEMENTATION
 
   bool HasFeature(const nsAString& aFeature, const nsAString& aVersion);
 
   already_AddRefed<DocumentType>
   CreateDocumentType(const nsAString& aQualifiedName,
--- a/dom/base/DOMMatrix.cpp
+++ b/dom/base/DOMMatrix.cpp
@@ -653,15 +653,15 @@ DOMMatrix::SetMatrixValue(const nsAStrin
     SetE(result._31);
     SetF(result._32);
   }
 
   return this;
 }
 
 JSObject*
-DOMMatrix::WrapObject(JSContext* aCx)
+DOMMatrix::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMMatrixBinding::Wrap(aCx, this);
+  return DOMMatrixBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/DOMMatrix.h
+++ b/dom/base/DOMMatrix.h
@@ -161,17 +161,17 @@ public:
   static already_AddRefed<DOMMatrix>
   Constructor(const GlobalObject& aGlobal, const Float32Array& aArray32, ErrorResult& aRv);
   static already_AddRefed<DOMMatrix>
   Constructor(const GlobalObject& aGlobal, const Float64Array& aArray64, ErrorResult& aRv);
   static already_AddRefed<DOMMatrix>
   Constructor(const GlobalObject& aGlobal, const Sequence<double>& aNumberSequence, ErrorResult& aRv);
 
   nsISupports* GetParentObject() const { return mParent; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 #define Set2DMatrixMember(entry2D, entry3D) \
 { \
   if (mMatrix3D) { \
     mMatrix3D->entry3D = v; \
   } else { \
     mMatrix2D->entry2D = v; \
   } \
--- a/dom/base/DOMParser.h
+++ b/dom/base/DOMParser.h
@@ -70,19 +70,19 @@ public:
   void Init(nsIPrincipal* aPrincipal, nsIURI* aDocumentURI,
             nsIURI* aBaseURI, mozilla::ErrorResult& rv);
 
   nsISupports* GetParentObject() const
   {
     return mOwner;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return mozilla::dom::DOMParserBinding::Wrap(aCx, this);
+    return mozilla::dom::DOMParserBinding::Wrap(aCx, this, aGivenProto);
   }
 
 private:
   explicit DOMParser(nsISupports* aOwner) : mOwner(aOwner), mAttemptedInit(false)
   {
     MOZ_ASSERT(aOwner);
   }
 
--- a/dom/base/DOMPoint.cpp
+++ b/dom/base/DOMPoint.cpp
@@ -32,12 +32,12 @@ DOMPoint::Constructor(const GlobalObject
                       double aZ, double aW, ErrorResult& aRV)
 {
   nsRefPtr<DOMPoint> obj =
     new DOMPoint(aGlobal.GetAsSupports(), aX, aY, aZ, aW);
   return obj.forget();
 }
 
 JSObject*
-DOMPoint::WrapObject(JSContext* aCx)
+DOMPoint::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMPointBinding::Wrap(aCx, this);
+  return DOMPointBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/base/DOMPoint.h
+++ b/dom/base/DOMPoint.h
@@ -59,17 +59,17 @@ public:
   static already_AddRefed<DOMPoint>
   Constructor(const GlobalObject& aGlobal, const DOMPointInit& aParams,
               ErrorResult& aRV);
   static already_AddRefed<DOMPoint>
   Constructor(const GlobalObject& aGlobal, double aX, double aY,
               double aZ, double aW, ErrorResult& aRV);
 
   nsISupports* GetParentObject() const { return mParent; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void SetX(double aX) { mX = aX; }
   void SetY(double aY) { mY = aY; }
   void SetZ(double aZ) { mZ = aZ; }
   void SetW(double aW) { mW = aW; }
 };
 
 }
--- a/dom/base/DOMQuad.cpp
+++ b/dom/base/DOMQuad.cpp
@@ -33,19 +33,19 @@ DOMQuad::DOMQuad(nsISupports* aParent)
 {
 }
 
 DOMQuad::~DOMQuad()
 {
 }
 
 JSObject*
-DOMQuad::WrapObject(JSContext* aCx)
+DOMQuad::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMQuadBinding::Wrap(aCx, this);
+  return DOMQuadBinding::Wrap(aCx, this, aGivenProto);
 }
 
 already_AddRefed<DOMQuad>
 DOMQuad::Constructor(const GlobalObject& aGlobal,
                      const DOMPointInit& aP1,
                      const DOMPointInit& aP2,
                      const DOMPointInit& aP3,
                      const DOMPointInit& aP4,
--- a/dom/base/DOMQuad.h
+++ b/dom/base/DOMQuad.h
@@ -30,17 +30,17 @@ class DOMQuad MOZ_FINAL : public nsWrapp
 public:
   DOMQuad(nsISupports* aParent, CSSPoint aPoints[4]);
   explicit DOMQuad(nsISupports* aParent);
 
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMQuad)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMQuad)
 
   nsISupports* GetParentObject() const { return mParent; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static already_AddRefed<DOMQuad>
   Constructor(const GlobalObject& aGlobal,
               const DOMPointInit& aP1,
               const DOMPointInit& aP2,
               const DOMPointInit& aP3,
               const DOMPointInit& aP4,
               ErrorResult& aRV);
--- a/dom/base/DOMRect.cpp
+++ b/dom/base/DOMRect.cpp
@@ -16,20 +16,20 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DO
 NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMRectReadOnly)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMRectReadOnly)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMRectReadOnly)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 JSObject*
-DOMRectReadOnly::WrapObject(JSContext* aCx)
+DOMRectReadOnly::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   MOZ_ASSERT(mParent);
-  return DOMRectReadOnlyBinding::Wrap(aCx, this);
+  return DOMRectReadOnlyBinding::Wrap(aCx, this, aGivenProto);
 }
 
 // -----------------------------------------------------------------------------
 
 NS_IMPL_ISUPPORTS_INHERITED(DOMRect, DOMRectReadOnly, nsIDOMClientRect)
 
 #define FORWARD_GETTER(_name)                                                   \
   NS_IMETHODIMP                                                                 \
@@ -42,20 +42,20 @@ NS_IMPL_ISUPPORTS_INHERITED(DOMRect, DOM
 FORWARD_GETTER(Left)
 FORWARD_GETTER(Top)
 FORWARD_GETTER(Right)
 FORWARD_GETTER(Bottom)
 FORWARD_GETTER(Width)
 FORWARD_GETTER(Height)
 
 JSObject*
-DOMRect::WrapObject(JSContext* aCx)
+DOMRect::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   MOZ_ASSERT(mParent);
-  return DOMRectBinding::Wrap(aCx, this);
+  return DOMRectBinding::Wrap(aCx, this, aGivenProto);
 }
 
 already_AddRefed<DOMRect>
 DOMRect::Constructor(const GlobalObject& aGlobal, ErrorResult& aRV)
 {
   nsRefPtr<DOMRect> obj =
     new DOMRect(aGlobal.GetAsSupports(), 0.0, 0.0, 0.0, 0.0);
   return obj.forget();
@@ -94,19 +94,19 @@ DOMRectList::GetLength(uint32_t* aLength
 NS_IMETHODIMP    
 DOMRectList::Item(uint32_t aIndex, nsIDOMClientRect** aReturn)
 {
   NS_IF_ADDREF(*aReturn = Item(aIndex));
   return NS_OK;
 }
 
 JSObject*
-DOMRectList::WrapObject(JSContext *cx)
+DOMRectList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::DOMRectListBinding::Wrap(cx, this);
+  return mozilla::dom::DOMRectListBinding::Wrap(cx, this, aGivenProto);
 }
 
 static double
 RoundFloat(double aValue)
 {
   return floor(aValue + 0.5);
 }
 
--- a/dom/base/DOMRect.h
+++ b/dom/base/DOMRect.h
@@ -38,17 +38,17 @@ public:
   {
   }
 
   nsISupports* GetParentObject() const
   {
     MOZ_ASSERT(mParent);
     return mParent;
   }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual double X() const = 0;
   virtual double Y() const = 0;
   virtual double Width() const = 0;
   virtual double Height() const = 0;
 
   double Left() const
   {
@@ -93,17 +93,17 @@ public:
   NS_DECL_NSIDOMCLIENTRECT
 
   static already_AddRefed<DOMRect>
   Constructor(const GlobalObject& aGlobal, ErrorResult& aRV);
   static already_AddRefed<DOMRect>
   Constructor(const GlobalObject& aGlobal, double aX, double aY,
               double aWidth, double aHeight, ErrorResult& aRV);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void SetRect(float aX, float aY, float aWidth, float aHeight) {
     mX = aX; mY = aY; mWidth = aWidth; mHeight = aHeight;
   }
   void SetLayoutRect(const nsRect& aLayoutRect);
 
   virtual double X() const MOZ_OVERRIDE
   {
@@ -156,17 +156,17 @@ public:
   {
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMRectList)
 
   NS_DECL_NSIDOMCLIENTRECTLIST
   
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsISupports* GetParentObject()
   {
     return mParent;
   }
 
   void Append(DOMRect* aElement) { mArray.AppendElement(aElement); }
 
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -61,19 +61,19 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DOMRequest)
   NS_INTERFACE_MAP_ENTRY(nsIDOMDOMRequest)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(DOMRequest, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(DOMRequest, DOMEventTargetHelper)
 
 /* virtual */ JSObject*
-DOMRequest::WrapObject(JSContext* aCx)
+DOMRequest::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMRequestBinding::Wrap(aCx, this);
+  return DOMRequestBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_EVENT_HANDLER(DOMRequest, success)
 NS_IMPL_EVENT_HANDLER(DOMRequest, error)
 
 NS_IMETHODIMP
 DOMRequest::GetReadyState(nsAString& aReadyState)
 {
--- a/dom/base/DOMRequest.h
+++ b/dom/base/DOMRequest.h
@@ -42,17 +42,17 @@ public:
                                                          DOMEventTargetHelper)
 
   // WrapperCache
   nsPIDOMWindow* GetParentObject() const
   {
     return GetOwner();
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL Interface
   DOMRequestReadyState ReadyState() const
   {
     return mDone ? DOMRequestReadyState::Done
                  : DOMRequestReadyState::Pending;
   }
 
--- a/dom/base/DOMStringList.cpp
+++ b/dom/base/DOMStringList.cpp
@@ -19,15 +19,15 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 DOMStringList::~DOMStringList()
 {
 }
 
 JSObject*
-DOMStringList::WrapObject(JSContext* aCx)
+DOMStringList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMStringListBinding::Wrap(aCx, this);
+  return DOMStringListBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/DOMStringList.h
+++ b/dom/base/DOMStringList.h
@@ -19,17 +19,17 @@ class DOMStringList : public nsISupports
 {
 protected:
   virtual ~DOMStringList();
 
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMStringList)
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   nsISupports* GetParentObject()
   {
     return nullptr;
   }
 
   void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aResult)
   {
     EnsureFresh();
--- a/dom/base/DocumentFragment.cpp
+++ b/dom/base/DocumentFragment.cpp
@@ -19,19 +19,19 @@
 #include "nsPIDOMWindow.h"
 #include "nsIDocument.h"
 #include "mozilla/IntegerPrintfMacros.h"
 
 namespace mozilla {
 namespace dom {
 
 JSObject*
-DocumentFragment::WrapNode(JSContext *aCx)
+DocumentFragment::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DocumentFragmentBinding::Wrap(aCx, this);
+  return DocumentFragmentBinding::Wrap(aCx, this, aGivenProto);
 }
 
 bool
 DocumentFragment::IsNodeOfType(uint32_t aFlags) const
 {
   return !(aFlags & ~(eCONTENT | eDOCUMENT_FRAGMENT));
 }
 
--- a/dom/base/DocumentFragment.h
+++ b/dom/base/DocumentFragment.h
@@ -60,17 +60,17 @@ public:
                                             nsGkAtoms::documentFragmentNodeName,
                                             nullptr, kNameSpaceID_None,
                                             nsIDOMNode::DOCUMENT_FRAGMENT_NODE)),
       mHost(nullptr)
   {
     Init();
   }
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // nsIContent
   nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                    const nsAString& aValue, bool aNotify)
   {
     return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
   }
   virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
--- a/dom/base/DocumentType.cpp
+++ b/dom/base/DocumentType.cpp
@@ -55,19 +55,19 @@ NS_NewDOMDocumentType(nsNodeInfoManager*
     new mozilla::dom::DocumentType(ni, aPublicId, aSystemId, aInternalSubset);
   return docType.forget();
 }
 
 namespace mozilla {
 namespace dom {
 
 JSObject*
-DocumentType::WrapNode(JSContext *cx)
+DocumentType::WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DocumentTypeBinding::Wrap(cx, this);
+  return DocumentTypeBinding::Wrap(cx, this, aGivenProto);
 }
 
 DocumentType::DocumentType(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
                            const nsAString& aPublicId,
                            const nsAString& aSystemId,
                            const nsAString& aInternalSubset) :
   DocumentTypeForward(aNodeInfo),
   mPublicId(aPublicId),
--- a/dom/base/DocumentType.h
+++ b/dom/base/DocumentType.h
@@ -72,17 +72,17 @@ public:
   virtual nsGenericDOMDataNode* CloneDataNode(mozilla::dom::NodeInfo *aNodeInfo,
                                               bool aCloneText) const MOZ_OVERRIDE;
 
   virtual nsIDOMNode* AsDOMNode() MOZ_OVERRIDE { return this; }
 
 protected:
   virtual ~DocumentType();
 
-  virtual JSObject* WrapNode(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsString mPublicId;
   nsString mSystemId;
   nsString mInternalSubset;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -401,19 +401,19 @@ Element::GetBindingURL(nsIDocument *aDoc
   NS_ENSURE_TRUE(sc, false);
 
   *aResult = sc->StyleDisplay()->mBinding;
 
   return true;
 }
 
 JSObject*
-Element::WrapObject(JSContext *aCx)
+Element::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  JS::Rooted<JSObject*> obj(aCx, nsINode::WrapObject(aCx));
+  JS::Rooted<JSObject*> obj(aCx, nsINode::WrapObject(aCx, aGivenProto));
   if (!obj) {
     return nullptr;
   }
 
   // Custom element prototype swizzling.
   CustomElementData* data = GetCustomElementData();
   if (obj && data) {
     // If this is a registered custom element then fix the prototype.
@@ -1103,19 +1103,19 @@ DestinationInsertionPointList::GetLength
 
 int32_t
 DestinationInsertionPointList::IndexOf(nsIContent* aContent)
 {
   return mDestinationPoints.IndexOf(aContent);
 }
 
 JSObject*
-DestinationInsertionPointList::WrapObject(JSContext* aCx)
+DestinationInsertionPointList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return NodeListBinding::Wrap(aCx, this);
+  return NodeListBinding::Wrap(aCx, this, aGivenProto);
 }
 
 already_AddRefed<DestinationInsertionPointList>
 Element::GetDestinationInsertionPoints()
 {
   nsRefPtr<DestinationInsertionPointList> list =
     new DestinationInsertionPointList(this);
   return list.forget();
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -955,17 +955,17 @@ public:
     GetElementsByTagNameNS(const nsAString& aNamespaceURI,
                            const nsAString& aLocalName,
                            nsIDOMHTMLCollection** aResult);
   nsresult
     GetElementsByClassName(const nsAString& aClassNames,
                            nsIDOMHTMLCollection** aResult);
   void GetClassList(nsISupports** aClassList);
 
-  virtual JSObject* WrapObject(JSContext *aCx) MOZ_FINAL MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_FINAL MOZ_OVERRIDE;
 
   nsINode* GetScopeChainParent() const MOZ_OVERRIDE;
 
   /**
    * Locate an nsIEditor rooted at this content node, if there is one.
    */
   nsIEditor* GetEditorInternal();
 
@@ -1310,17 +1310,17 @@ public:
   // nsIDOMNodeList
   NS_DECL_NSIDOMNODELIST
 
   // nsINodeList
   virtual nsIContent* Item(uint32_t aIndex) MOZ_OVERRIDE;
   virtual int32_t IndexOf(nsIContent* aContent) MOZ_OVERRIDE;
   virtual nsINode* GetParentObject() MOZ_OVERRIDE { return mParent; }
   virtual uint32_t Length() const;
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 protected:
   virtual ~DestinationInsertionPointList();
 
   nsRefPtr<Element> mParent;
   nsCOMArray<nsIContent> mDestinationPoints;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(Element, NS_ELEMENT_IID)
--- a/dom/base/EventSource.cpp
+++ b/dom/base/EventSource.cpp
@@ -260,19 +260,19 @@ EventSource::Init(nsISupports* aOwner,
   // url parameter, so we don't care about the InitChannelAndRequestEventSource
   // result.
   InitChannelAndRequestEventSource();
 
   return NS_OK;
 }
 
 /* virtual */ JSObject*
-EventSource::WrapObject(JSContext* aCx)
+EventSource::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return EventSourceBinding::Wrap(aCx, this);
+  return EventSourceBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */ already_AddRefed<EventSource>
 EventSource::Constructor(const GlobalObject& aGlobal,
                          const nsAString& aURL,
                          const EventSourceInit& aEventSourceInitDict,
                          ErrorResult& aRv)
 {
--- a/dom/base/EventSource.h
+++ b/dom/base/EventSource.h
@@ -53,17 +53,17 @@ public:
 
   NS_DECL_NSIOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSICHANNELEVENTSINK
   NS_DECL_NSIINTERFACEREQUESTOR
 
   // nsWrapperCache
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL
   nsPIDOMWindow*
   GetParentObject() const
   {
     return GetOwner();
   }
   static already_AddRefed<EventSource>
--- a/dom/base/File.cpp
+++ b/dom/base/File.cpp
@@ -554,20 +554,20 @@ File::SetMutable(bool aMutable)
 
 NS_IMETHODIMP_(bool)
 File::IsMemoryFile()
 {
   return mImpl->IsMemoryFile();
 }
 
 JSObject*
-File::WrapObject(JSContext* aCx)
+File::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return IsFile() ? FileBinding::Wrap(aCx, this)
-                  : BlobBinding::Wrap(aCx, this);
+  return IsFile() ? FileBinding::Wrap(aCx, this, aGivenProto)
+                  : BlobBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */ already_AddRefed<File>
 File::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsRefPtr<MultipartFileImpl> impl = new MultipartFileImpl();
 
   impl->InitializeBlob();
@@ -1230,19 +1230,19 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFileList)
   NS_INTERFACE_MAP_ENTRY(nsIDOMFileList)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(FileList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(FileList)
 
 JSObject*
-FileList::WrapObject(JSContext *cx)
+FileList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::FileListBinding::Wrap(cx, this);
+  return mozilla::dom::FileListBinding::Wrap(cx, this, aGivenProto);
 }
 
 NS_IMETHODIMP
 FileList::GetLength(uint32_t* aLength)
 {
   *aLength = Length();
 
   return NS_OK;
--- a/dom/base/File.h
+++ b/dom/base/File.h
@@ -184,17 +184,17 @@ public:
 
   // File constructor - ChromeOnly
   static already_AddRefed<File>
   Constructor(const GlobalObject& aGlobal,
               nsIFile* aData,
               const ChromeFilePropertyBag& aBag,
               ErrorResult& aRv);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   uint64_t GetSize(ErrorResult& aRv);
 
   // XPCOM GetType is OK
 
   // XPCOM GetName is OK
 
   int64_t GetLastModified(ErrorResult& aRv);
@@ -823,17 +823,17 @@ public:
   {
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(FileList)
 
   NS_DECL_NSIDOMFILELIST
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsISupports* GetParentObject()
   {
     return mParent;
   }
 
   void Disconnect()
   {
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -396,19 +396,19 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_E
 
 NS_INTERFACE_TABLE_HEAD(nsChildContentList)
   NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY
   NS_INTERFACE_TABLE(nsChildContentList, nsINodeList, nsIDOMNodeList)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsChildContentList)
 NS_INTERFACE_MAP_END
 
 JSObject*
-nsChildContentList::WrapObject(JSContext *cx)
+nsChildContentList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return NodeListBinding::Wrap(cx, this);
+  return NodeListBinding::Wrap(cx, this, aGivenProto);
 }
 
 NS_IMETHODIMP
 nsChildContentList::GetLength(uint32_t* aLength)
 {
   *aLength = mNode ? mNode->GetChildCount() : 0;
 
   return NS_OK;
--- a/dom/base/FragmentOrElement.h
+++ b/dom/base/FragmentOrElement.h
@@ -51,17 +51,17 @@ public:
     : mNode(aNode)
   {
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsChildContentList)
 
   // nsWrapperCache
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // nsIDOMNodeList interface
   NS_DECL_NSIDOMNODELIST
 
   // nsINodeList interface
   virtual int32_t IndexOf(nsIContent* aContent) MOZ_OVERRIDE;
   virtual nsIContent* Item(uint32_t aIndex) MOZ_OVERRIDE;
 
--- a/dom/base/MessageChannel.cpp
+++ b/dom/base/MessageChannel.cpp
@@ -76,19 +76,19 @@ MessageChannel::MessageChannel(nsPIDOMWi
 }
 
 MessageChannel::~MessageChannel()
 {
   MOZ_COUNT_DTOR(MessageChannel);
 }
 
 JSObject*
-MessageChannel::WrapObject(JSContext* aCx)
+MessageChannel::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MessageChannelBinding::Wrap(aCx, this);
+  return MessageChannelBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */ already_AddRefed<MessageChannel>
 MessageChannel::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
   if (!window) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
--- a/dom/base/MessageChannel.h
+++ b/dom/base/MessageChannel.h
@@ -35,17 +35,17 @@ public:
 
   nsPIDOMWindow*
   GetParentObject() const
   {
     return mWindow;
   }
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static already_AddRefed<MessageChannel>
   Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
 
   MessagePort*
   Port1() const
   {
     return mPort1;
--- a/dom/base/MessagePort.cpp
+++ b/dom/base/MessagePort.cpp
@@ -218,17 +218,17 @@ PostMessageReadTransferStructuredClone(J
   StructuredCloneInfo* scInfo = static_cast<StructuredCloneInfo*>(aClosure);
   NS_ASSERTION(scInfo, "Must have scInfo!");
 
   if (tag == SCTAG_DOM_MAP_MESSAGEPORT) {
     MessagePort* port = static_cast<MessagePort*>(data);
     port->BindToOwner(scInfo->mPort->GetOwner());
     scInfo->mPorts.Put(port, nullptr);
 
-    JS::Rooted<JSObject*> obj(aCx, port->WrapObject(aCx));
+    JS::Rooted<JSObject*> obj(aCx, port->WrapObject(aCx, JS::NullPtr()));
     if (!obj || !JS_WrapObject(aCx, &obj)) {
       return false;
     }
 
     MOZ_ASSERT(port->GetOwner() == scInfo->mPort->GetOwner());
     returnObject.set(obj);
     return true;
   }
@@ -409,19 +409,19 @@ MessagePort::MessagePort(nsPIDOMWindow* 
 }
 
 MessagePort::~MessagePort()
 {
   Close();
 }
 
 JSObject*
-MessagePort::WrapObject(JSContext* aCx)
+MessagePort::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MessagePortBinding::Wrap(aCx, this);
+  return MessagePortBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 MessagePort::PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
                             const Optional<Sequence<JS::Value>>& aTransferable,
                             ErrorResult& aRv)
 {
   nsRefPtr<PostMessageRunnable> event = new PostMessageRunnable();
--- a/dom/base/MessagePort.h
+++ b/dom/base/MessagePort.h
@@ -59,17 +59,17 @@ class MessagePort MOZ_FINAL : public Mes
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MessagePort,
                                            DOMEventTargetHelper)
 
   explicit MessagePort(nsPIDOMWindow* aWindow);
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual void
   PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
                  const Optional<Sequence<JS::Value>>& aTransferable,
                  ErrorResult& aRv) MOZ_OVERRIDE;
 
   virtual void
   Start() MOZ_OVERRIDE;
--- a/dom/base/MessagePortList.cpp
+++ b/dom/base/MessagePortList.cpp
@@ -15,15 +15,15 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Me
 NS_IMPL_CYCLE_COLLECTING_ADDREF(MessagePortList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(MessagePortList)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MessagePortList)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 JSObject*
-MessagePortList::WrapObject(JSContext* aCx)
+MessagePortList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MessagePortListBinding::Wrap(aCx, this);
+  return MessagePortListBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/MessagePortList.h
+++ b/dom/base/MessagePortList.h
@@ -36,17 +36,17 @@ public:
 
   nsISupports*
   GetParentObject() const
   {
     return mOwner;
   }
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   uint32_t
   Length() const
   {
     return mPorts.Length();
   }
 
   MessagePortBase*
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -2229,19 +2229,19 @@ Navigator::GetOwnPropertyNames(JSContext
     return;
   }
 
   NavigatorNameEnumeratorClosure closure(aCx, GetWrapper(), aNames);
   nameSpaceManager->EnumerateNavigatorNames(SaveNavigatorName, &closure);
 }
 
 JSObject*
-Navigator::WrapObject(JSContext* cx)
+Navigator::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return NavigatorBinding::Wrap(cx, this);
+  return NavigatorBinding::Wrap(cx, this, aGivenProto);
 }
 
 /* static */
 bool
 Navigator::HasWakeLockSupport(JSContext* /* unused*/, JSObject* /*unused */)
 {
   nsCOMPtr<nsIPowerManagerService> pmService =
     do_GetService(POWERMANAGERSERVICE_CONTRACTID);
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -319,17 +319,17 @@ public:
 
   static bool IsE10sEnabled(JSContext* aCx, JSObject* aGlobal);
 
   nsPIDOMWindow* GetParentObject() const
   {
     return GetWindow();
   }
 
-  virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // GetWindowFromGlobal returns the inner window for this global, if
   // any, else null.
   static already_AddRefed<nsPIDOMWindow> GetWindowFromGlobal(JSObject* aGlobal);
 
 #ifdef MOZ_EME
   already_AddRefed<Promise>
   RequestMediaKeySystemAccess(const nsAString& aKeySystem,
--- a/dom/base/NodeIterator.cpp
+++ b/dom/base/NodeIterator.cpp
@@ -284,15 +284,15 @@ void NodeIterator::ContentRemoved(nsIDoc
 {
     nsINode *container = NODE_FROM(aContainer, aDocument);
 
     mPointer.AdjustAfterRemoval(mRoot, container, aChild, aPreviousSibling);
     mWorkingPointer.AdjustAfterRemoval(mRoot, container, aChild, aPreviousSibling);
 }
 
 bool
-NodeIterator::WrapObject(JSContext *cx, JS::MutableHandle<JSObject*> aReflector)
+NodeIterator::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
 {
-    return NodeIteratorBinding::Wrap(cx, this, aReflector);
+    return NodeIteratorBinding::Wrap(cx, this, aGivenProto, aReflector);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/NodeIterator.h
+++ b/dom/base/NodeIterator.h
@@ -64,17 +64,17 @@ public:
         return NextOrPrevNode(&NodePointer::MoveToNext, aResult);
     }
     already_AddRefed<nsINode> PreviousNode(ErrorResult& aResult)
     {
         return NextOrPrevNode(&NodePointer::MoveToPrevious, aResult);
     }
     // The XPCOM Detach() is fine for our purposes
 
-    bool WrapObject(JSContext *cx, JS::MutableHandle<JSObject*> aReflector);
+    bool WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 
 private:
     virtual ~NodeIterator();
 
     struct NodePointer {
         NodePointer() : mNode(nullptr) {}
         NodePointer(nsINode *aNode, bool aBeforeNode);
 
--- a/dom/base/PerformanceEntry.cpp
+++ b/dom/base/PerformanceEntry.cpp
@@ -29,12 +29,12 @@ PerformanceEntry::PerformanceEntry(nsPer
   MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
 }
 
 PerformanceEntry::~PerformanceEntry()
 {
 }
 
 JSObject*
-PerformanceEntry::WrapObject(JSContext* aCx)
+PerformanceEntry::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::PerformanceEntryBinding::Wrap(aCx, this);
+  return mozilla::dom::PerformanceEntryBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/base/PerformanceEntry.h
+++ b/dom/base/PerformanceEntry.h
@@ -22,17 +22,17 @@ protected:
 public:
   PerformanceEntry(nsPerformance* aPerformance,
                    const nsAString& aName,
                    const nsAString& aEntryType);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(PerformanceEntry)
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsPerformance* GetParentObject() const
   {
     return mPerformance;
   }
 
   void GetName(nsAString& aName) const
   {
--- a/dom/base/PerformanceMark.cpp
+++ b/dom/base/PerformanceMark.cpp
@@ -16,12 +16,12 @@ PerformanceMark::PerformanceMark(nsPerfo
   mStartTime = aPerformance->GetDOMTiming()->TimeStampToDOMHighRes(mozilla::TimeStamp::Now());
 }
 
 PerformanceMark::~PerformanceMark()
 {
 }
 
 JSObject*
-PerformanceMark::WrapObject(JSContext* aCx)
+PerformanceMark::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PerformanceMarkBinding::Wrap(aCx, this);
+  return PerformanceMarkBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/base/PerformanceMark.h
+++ b/dom/base/PerformanceMark.h
@@ -13,17 +13,17 @@ namespace dom {
 
 // http://www.w3.org/TR/user-timing/#performancemark
 class PerformanceMark MOZ_FINAL : public PerformanceEntry
 {
 public:
   PerformanceMark(nsPerformance* aPerformance,
                   const nsAString& aName);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual DOMHighResTimeStamp StartTime() const MOZ_OVERRIDE
   {
     return mStartTime;
   }
 
 protected:
   virtual ~PerformanceMark();
--- a/dom/base/PerformanceMeasure.cpp
+++ b/dom/base/PerformanceMeasure.cpp
@@ -19,12 +19,12 @@ PerformanceMeasure::PerformanceMeasure(n
   MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
 }
 
 PerformanceMeasure::~PerformanceMeasure()
 {
 }
 
 JSObject*
-PerformanceMeasure::WrapObject(JSContext* aCx)
+PerformanceMeasure::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PerformanceMeasureBinding::Wrap(aCx, this);
+  return PerformanceMeasureBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/base/PerformanceMeasure.h
+++ b/dom/base/PerformanceMeasure.h
@@ -15,17 +15,17 @@ namespace dom {
 class PerformanceMeasure MOZ_FINAL : public PerformanceEntry
 {
 public:
   PerformanceMeasure(nsPerformance* aPerformance,
                      const nsAString& aName,
                      DOMHighResTimeStamp aStartTime,
                      DOMHighResTimeStamp aEndTime);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual DOMHighResTimeStamp StartTime() const MOZ_OVERRIDE
   {
     return mStartTime;
   }
 
   virtual DOMHighResTimeStamp Duration() const MOZ_OVERRIDE
   {
--- a/dom/base/PerformanceResourceTiming.cpp
+++ b/dom/base/PerformanceResourceTiming.cpp
@@ -38,12 +38,12 @@ PerformanceResourceTiming::~PerformanceR
 DOMHighResTimeStamp
 PerformanceResourceTiming::StartTime() const
 {
   DOMHighResTimeStamp startTime = mTiming->RedirectStartHighRes();
   return startTime ? startTime : mTiming->FetchStartHighRes();
 }
 
 JSObject*
-PerformanceResourceTiming::WrapObject(JSContext* aCx)
+PerformanceResourceTiming::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PerformanceResourceTimingBinding::Wrap(aCx, this);
+  return PerformanceResourceTimingBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/base/PerformanceResourceTiming.h
+++ b/dom/base/PerformanceResourceTiming.h
@@ -26,17 +26,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
       PerformanceResourceTiming,
       PerformanceEntry)
 
   PerformanceResourceTiming(nsPerformanceTiming* aPerformanceTiming,
                             nsPerformance* aPerformance,
                             const nsAString& aName);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 
   virtual DOMHighResTimeStamp StartTime() const MOZ_OVERRIDE;
 
   virtual DOMHighResTimeStamp Duration() const MOZ_OVERRIDE
   {
     return ResponseEnd() - StartTime();
   }
--- a/dom/base/ProcessGlobal.h
+++ b/dom/base/ProcessGlobal.h
@@ -53,17 +53,17 @@ public:
     if (!mGlobal) {
       return nullptr;
     }
 
     return mGlobal->GetJSObject();
   }
   virtual nsIPrincipal* GetPrincipal() MOZ_OVERRIDE { return mPrincipal; }
 
-  virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
     MOZ_CRASH("ProcessGlobal doesn't use DOM bindings!");
   }
 
 protected:
   virtual ~ProcessGlobal();
 
 private:
--- a/dom/base/ShadowRoot.cpp
+++ b/dom/base/ShadowRoot.cpp
@@ -99,19 +99,19 @@ ShadowRoot::~ShadowRoot()
 
   // nsINode destructor expects mSubtreeRoot == this.
   SetSubtreeRootPointer(this);
 
   SetHost(nullptr);
 }
 
 JSObject*
-ShadowRoot::WrapObject(JSContext* aCx)
+ShadowRoot::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::ShadowRootBinding::Wrap(aCx, this);
+  return mozilla::dom::ShadowRootBinding::Wrap(aCx, this, aGivenProto);
 }
 
 ShadowRoot*
 ShadowRoot::FromNode(nsINode* aNode)
 {
   if (aNode->IsInShadowTree() && !aNode->GetParentNode()) {
     MOZ_ASSERT(aNode->NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE,
                "ShadowRoot is a document fragment.");
--- a/dom/base/ShadowRoot.h
+++ b/dom/base/ShadowRoot.h
@@ -98,17 +98,17 @@ public:
 
   void SetAssociatedBinding(nsXBLBinding* aBinding) { mAssociatedBinding = aBinding; }
 
   nsISupports* GetParentObject() const { return mPoolHost; }
 
   nsIContent* GetPoolHost() { return mPoolHost; }
   nsTArray<HTMLShadowElement*>& ShadowDescendants() { return mShadowDescendants; }
 
-  JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static bool IsPooledNode(nsIContent* aChild, nsIContent* aContainer,
                            nsIContent* aHost);
   static ShadowRoot* FromNode(nsINode* aNode);
   static bool IsShadowInsertionPoint(nsIContent* aContent);
 
   static void RemoveDestInsertionPoint(nsIContent* aInsertionPoint,
                                        nsTArray<nsIContent*>& aDestInsertionPoints);
--- a/dom/base/StyleSheetList.cpp
+++ b/dom/base/StyleSheetList.cpp
@@ -18,19 +18,19 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsIDOMStyleSheetList)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(StyleSheetList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(StyleSheetList)
 
 /* virtual */ JSObject*
-StyleSheetList::WrapObject(JSContext* aCx)
+StyleSheetList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return StyleSheetListBinding::Wrap(aCx, this);
+  return StyleSheetListBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMETHODIMP
 StyleSheetList::GetLength(uint32_t* aLength)
 {
   *aLength = Length();
   return NS_OK;
 }
--- a/dom/base/StyleSheetList.h
+++ b/dom/base/StyleSheetList.h
@@ -19,17 +19,17 @@ namespace dom {
 class StyleSheetList : public nsIDOMStyleSheetList
                      , public nsWrapperCache
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(StyleSheetList)
   NS_DECL_NSIDOMSTYLESHEETLIST
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE MOZ_FINAL;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE MOZ_FINAL;
 
   virtual nsINode* GetParentObject() const = 0;
 
   virtual uint32_t Length() = 0;
   virtual CSSStyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) = 0;
   CSSStyleSheet* Item(uint32_t aIndex)
   {
     bool dummy = false;
--- a/dom/base/SubtleCrypto.cpp
+++ b/dom/base/SubtleCrypto.cpp
@@ -24,19 +24,19 @@ NS_INTERFACE_MAP_END
 
 
 SubtleCrypto::SubtleCrypto(nsIGlobalObject* aParent)
   : mParent(aParent)
 {
 }
 
 JSObject*
-SubtleCrypto::WrapObject(JSContext* aCx)
+SubtleCrypto::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return SubtleCryptoBinding::Wrap(aCx, this);
+  return SubtleCryptoBinding::Wrap(aCx, this, aGivenProto);
 }
 
 #define SUBTLECRYPTO_METHOD_BODY(Operation, aRv, ...)                   \
   MOZ_ASSERT(mParent);                                                  \
   nsRefPtr<Promise> p = Promise::Create(mParent, aRv);                  \
   if (aRv.Failed()) {                                                   \
     return nullptr;                                                     \
   }                                                                     \
--- a/dom/base/SubtleCrypto.h
+++ b/dom/base/SubtleCrypto.h
@@ -33,17 +33,17 @@ public:
 public:
   explicit SubtleCrypto(nsIGlobalObject* aParent);
 
   nsIGlobalObject* GetParentObject() const
   {
     return mParent;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   already_AddRefed<Promise> Encrypt(JSContext* cx,
                                     const ObjectOrString& algorithm,
                                     CryptoKey& key,
                                     const CryptoOperationData& data,
                                     ErrorResult& aRv);
 
   already_AddRefed<Promise> Decrypt(JSContext* cx,
--- a/dom/base/TreeWalker.cpp
+++ b/dom/base/TreeWalker.cpp
@@ -446,15 +446,15 @@ TreeWalker::NextSiblingInternal(bool aRe
         }
         if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT) {
             return nullptr;
         }
     }
 }
 
 bool
-TreeWalker::WrapObject(JSContext *aCx, JS::MutableHandle<JSObject*> aReflector)
+TreeWalker::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
 {
-    return TreeWalkerBinding::Wrap(aCx, this, aReflector);
+    return TreeWalkerBinding::Wrap(aCx, this, aGivenProto, aReflector);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/TreeWalker.h
+++ b/dom/base/TreeWalker.h
@@ -60,17 +60,17 @@ public:
     already_AddRefed<nsINode> ParentNode(ErrorResult& aResult);
     already_AddRefed<nsINode> FirstChild(ErrorResult& aResult);
     already_AddRefed<nsINode> LastChild(ErrorResult& aResult);
     already_AddRefed<nsINode> PreviousSibling(ErrorResult& aResult);
     already_AddRefed<nsINode> NextSibling(ErrorResult& aResult);
     already_AddRefed<nsINode> PreviousNode(ErrorResult& aResult);
     already_AddRefed<nsINode> NextNode(ErrorResult& aResult);
 
-    bool WrapObject(JSContext *aCx, JS::MutableHandle<JSObject*> aReflector);
+    bool WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 
 private:
     nsCOMPtr<nsINode> mCurrentNode;
 
     /*
      * Implements FirstChild and LastChild which only vary in which direction
      * they search.
      * @param aReversed Controls whether we search forwards or backwards
--- a/dom/base/URL.cpp
+++ b/dom/base/URL.cpp
@@ -42,19 +42,19 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
 NS_INTERFACE_MAP_END
 
 URL::URL(nsIURI* aURI)
   : mURI(aURI)
 {
 }
 
 bool
-URL::WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+URL::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
 {
-  return URLBinding::Wrap(aCx, this, aReflector);
+  return URLBinding::Wrap(aCx, this, aGivenProto, aReflector);
 }
 
 /* static */ already_AddRefed<URL>
 URL::Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
                  URL& aBase, ErrorResult& aRv)
 {
   nsresult rv;
   nsCOMPtr<nsIIOService> ioService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
--- a/dom/base/URL.h
+++ b/dom/base/URL.h
@@ -39,17 +39,17 @@ class URL MOZ_FINAL : public URLSearchPa
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(URL)
 
   explicit URL(nsIURI* aURI);
 
   // WebIDL methods
   bool
-  WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 
   static already_AddRefed<URL>
   Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
               URL& aBase, ErrorResult& aRv);
   static already_AddRefed<URL>
   Constructor(const GlobalObject& aGlobal, const nsAString& aUrl,
               const nsAString& aBase, ErrorResult& aRv);
 
--- a/dom/base/URLSearchParams.cpp
+++ b/dom/base/URLSearchParams.cpp
@@ -25,19 +25,19 @@ URLSearchParams::URLSearchParams()
 }
 
 URLSearchParams::~URLSearchParams()
 {
   DeleteAll();
 }
 
 JSObject*
-URLSearchParams::WrapObject(JSContext* aCx)
+URLSearchParams::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return URLSearchParamsBinding::Wrap(aCx, this);
+  return URLSearchParamsBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */ already_AddRefed<URLSearchParams>
 URLSearchParams::Constructor(const GlobalObject& aGlobal,
                              const nsAString& aInit,
                              ErrorResult& aRv)
 {
   nsRefPtr<URLSearchParams> sp = new URLSearchParams();
--- a/dom/base/URLSearchParams.h
+++ b/dom/base/URLSearchParams.h
@@ -39,17 +39,17 @@ public:
 
   // WebIDL methods
   nsISupports* GetParentObject() const
   {
     return nullptr;
   }
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static already_AddRefed<URLSearchParams>
   Constructor(const GlobalObject& aGlobal, const nsAString& aInit,
               ErrorResult& aRv);
 
   static already_AddRefed<URLSearchParams>
   Constructor(const GlobalObject& aGlobal, URLSearchParams& aInit,
               ErrorResult& aRv);
--- a/dom/base/WebSocket.cpp
+++ b/dom/base/WebSocket.cpp
@@ -904,19 +904,19 @@ WebSocket::WebSocket(nsPIDOMWindow* aOwn
   mIsMainThread = mImpl->mIsMainThread;
 }
 
 WebSocket::~WebSocket()
 {
 }
 
 JSObject*
-WebSocket::WrapObject(JSContext* cx)
+WebSocket::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return WebSocketBinding::Wrap(cx, this);
+  return WebSocketBinding::Wrap(cx, this, aGivenProto);
 }
 
 //---------------------------------------------------------------------------
 // WebIDL
 //---------------------------------------------------------------------------
 
 // Constructor:
 already_AddRefed<WebSocket>
--- a/dom/base/WebSocket.h
+++ b/dom/base/WebSocket.h
@@ -57,17 +57,17 @@ public:
   virtual void EventListenerAdded(nsIAtom* aType) MOZ_OVERRIDE;
   virtual void EventListenerRemoved(nsIAtom* aType) MOZ_OVERRIDE;
 
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
 
   // nsWrapperCache
   nsPIDOMWindow* GetParentObject() { return GetOwner(); }
 
-  virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 public: // static helpers:
 
   // Determine if preferences allow WebSocket
   static bool PrefEnabled(JSContext* aCx = nullptr, JSObject* aGlobal = nullptr);
 
 public: // WebIDL interface:
 
--- a/dom/base/nsContentList.cpp
+++ b/dom/base/nsContentList.cpp
@@ -142,19 +142,19 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(nsSim
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsSimpleContentList)
 NS_INTERFACE_MAP_END_INHERITING(nsBaseContentList)
 
 
 NS_IMPL_ADDREF_INHERITED(nsSimpleContentList, nsBaseContentList)
 NS_IMPL_RELEASE_INHERITED(nsSimpleContentList, nsBaseContentList)
 
 JSObject*
-nsSimpleContentList::WrapObject(JSContext *cx)
+nsSimpleContentList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return NodeListBinding::Wrap(cx, this);
+  return NodeListBinding::Wrap(cx, this, aGivenProto);
 }
 
 // Hashtable for storing nsContentLists
 static PLDHashTable gContentListHashTable;
 
 #define RECENTLY_USED_CONTENT_LIST_CACHE_SIZE 31
 static nsContentList*
   sRecentlyUsedContentLists[RECENTLY_USED_CONTENT_LIST_CACHE_SIZE] = {};
@@ -254,26 +254,26 @@ NS_GetContentList(nsINode* aRootNode,
 #ifdef DEBUG
 const nsCacheableFuncStringContentList::ContentListType
   nsCacheableFuncStringNodeList::sType = nsCacheableFuncStringContentList::eNodeList;
 const nsCacheableFuncStringContentList::ContentListType
   nsCacheableFuncStringHTMLCollection::sType = nsCacheableFuncStringContentList::eHTMLCollection;
 #endif
 
 JSObject*
-nsCacheableFuncStringNodeList::WrapObject(JSContext *cx)
+nsCacheableFuncStringNodeList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return NodeListBinding::Wrap(cx, this);
+  return NodeListBinding::Wrap(cx, this, aGivenProto);
 }
 
 
 JSObject*
-nsCacheableFuncStringHTMLCollection::WrapObject(JSContext *cx)
+nsCacheableFuncStringHTMLCollection::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLCollectionBinding::Wrap(cx, this);
+  return HTMLCollectionBinding::Wrap(cx, this, aGivenProto);
 }
 
 // Hashtable for storing nsCacheableFuncStringContentList
 static PLDHashTable gFuncStringContentListHashTable;
 
 struct FuncStringContentListHashEntry : public PLDHashEntryHdr
 {
   nsCacheableFuncStringContentList* mContentList;
@@ -464,19 +464,19 @@ nsContentList::~nsContentList()
 
   if (mDestroyFunc) {
     // Clean up mData
     (*mDestroyFunc)(mData);
   }
 }
 
 JSObject*
-nsContentList::WrapObject(JSContext *cx)
+nsContentList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLCollectionBinding::Wrap(cx, this);
+  return HTMLCollectionBinding::Wrap(cx, this, aGivenProto);
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(nsContentList, nsBaseContentList,
                             nsIHTMLCollection, nsIDOMHTMLCollection,
                             nsIMutationObserver)
 
 uint32_t
 nsContentList::Length(bool aDoFlush)
--- a/dom/base/nsContentList.h
+++ b/dom/base/nsContentList.h
@@ -82,17 +82,17 @@ public:
   }
 
   void Reset() {
     mElements.Clear();
   }
 
   virtual int32_t IndexOf(nsIContent *aContent, bool aDoFlush);
 
-  virtual JSObject* WrapObject(JSContext *cx)
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
     MOZ_OVERRIDE = 0;
 
   void SetCapacity(uint32_t aCapacity)
   {
     mElements.SetCapacity(aCapacity);
   }
 protected:
   virtual ~nsBaseContentList();
@@ -120,17 +120,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsSimpleContentList,
                                            nsBaseContentList)
 
   virtual nsINode* GetParentObject() MOZ_OVERRIDE
   {
     return mRoot;
   }
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 protected:
   virtual ~nsSimpleContentList() {}
 
 private:
   // This has to be a strong reference, the root might go away before the list.
   nsCOMPtr<nsINode> mRoot;
 };
@@ -246,17 +246,17 @@ public:
                 void* aData,
                 bool aDeep = true,
                 nsIAtom* aMatchAtom = nullptr,
                 int32_t aMatchNameSpaceId = kNameSpaceID_None,
                 bool aFuncMayDependOnAttr = true);
 
   // nsWrapperCache
   using nsWrapperCache::GetWrapperPreserveColor;
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 protected:
   virtual ~nsContentList();
 
   virtual JSObject* GetWrapperPreserveColorInternal() MOZ_OVERRIDE
   {
     return nsWrapperCache::GetWrapperPreserveColor();
   }
 public:
@@ -531,17 +531,17 @@ public:
     : nsCacheableFuncStringContentList(aRootNode, aFunc, aDestroyFunc,
                                        aDataAllocator, aString)
   {
 #ifdef DEBUG
     mType = eNodeList;
 #endif
   }
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 #ifdef DEBUG
   static const ContentListType sType;
 #endif
 };
 
 class nsCacheableFuncStringHTMLCollection
   : public nsCacheableFuncStringContentList
@@ -555,16 +555,16 @@ public:
     : nsCacheableFuncStringContentList(aRootNode, aFunc, aDestroyFunc,
                                        aDataAllocator, aString)
   {
 #ifdef DEBUG
     mType = eHTMLCollection;
 #endif
   }
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 #ifdef DEBUG
   static const ContentListType sType;
 #endif
 };
 
 #endif // nsContentList_h___
--- a/dom/base/nsDOMAttributeMap.cpp
+++ b/dom/base/nsDOMAttributeMap.cpp
@@ -582,12 +582,12 @@ nsDOMAttributeMap::SizeOfIncludingThis(M
                                             aMallocSizeOf)
      : 0;
 
   // NB: mContent is non-owning and thus not counted.
   return n;
 }
 
 /* virtual */ JSObject*
-nsDOMAttributeMap::WrapObject(JSContext* aCx)
+nsDOMAttributeMap::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return NamedNodeMapBinding::Wrap(aCx, this);
+  return NamedNodeMapBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/base/nsDOMAttributeMap.h
+++ b/dom/base/nsDOMAttributeMap.h
@@ -135,17 +135,17 @@ public:
    * @return The number of attribute nodes that aFunc was called for.
    */
   uint32_t Enumerate(AttrCache::EnumReadFunction aFunc, void *aUserArg) const;
 
   Element* GetParentObject() const
   {
     return mContent;
   }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL
   Attr* GetNamedItem(const nsAString& aAttrName);
   Attr* NamedGetter(const nsAString& aAttrName, bool& aFound);
   bool NameIsEnumerable(const nsAString& aName);
   already_AddRefed<Attr>
   SetNamedItem(Attr& aAttr, ErrorResult& aError)
   {
--- a/dom/base/nsDOMCaretPosition.cpp
+++ b/dom/base/nsDOMCaretPosition.cpp
@@ -51,19 +51,19 @@ nsDOMCaretPosition::GetClientRect() cons
   NS_ASSERTION(domRange, "unable to retrieve valid dom range from CaretPosition");
 
   rect = domRange->GetBoundingClientRect(false);
 
   return rect.forget();
 }
 
 JSObject*
-nsDOMCaretPosition::WrapObject(JSContext *aCx)
+nsDOMCaretPosition::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::CaretPositionBinding::Wrap(aCx, this);
+  return mozilla::dom::CaretPositionBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsDOMCaretPosition,
                                       mOffsetNode, mAnonymousContentNode)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMCaretPosition)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMCaretPosition)
 
--- a/dom/base/nsDOMCaretPosition.h
+++ b/dom/base/nsDOMCaretPosition.h
@@ -80,17 +80,17 @@ public:
     mAnonymousContentNode = aNode;
   }
 
   nsISupports* GetParentObject() const
   {
     return GetOffsetNode();
   }
 
-  virtual JSObject* WrapObject(JSContext *aCx)
+  virtual JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
     MOZ_OVERRIDE MOZ_FINAL;
 
 protected:
   virtual ~nsDOMCaretPosition();
 
   uint32_t mOffset;
   nsCOMPtr<nsINode> mOffsetNode;
   nsCOMPtr<nsINode> mAnonymousContentNode;
--- a/dom/base/nsDOMDataChannel.cpp
+++ b/dom/base/nsDOMDataChannel.cpp
@@ -48,19 +48,19 @@ nsDOMDataChannel::~nsDOMDataChannel()
   // one) once we block GC until all the (appropriate) onXxxx handlers
   // are dropped. (See WebRTC spec)
   LOG(("Close()ing %p", mDataChannel.get()));
   mDataChannel->SetListener(nullptr, nullptr);
   mDataChannel->Close();
 }
 
 /* virtual */ JSObject*
-nsDOMDataChannel::WrapObject(JSContext* aCx)
+nsDOMDataChannel::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DataChannelBinding::Wrap(aCx, this);
+  return DataChannelBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMDataChannel)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMDataChannel,
                                                   DOMEventTargetHelper)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
--- a/dom/base/nsDOMDataChannel.h
+++ b/dom/base/nsDOMDataChannel.h
@@ -37,17 +37,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMDATACHANNEL
 
   NS_REALLY_FORWARD_NSIDOMEVENTTARGET(mozilla::DOMEventTargetHelper)
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMDataChannel,
                                            mozilla::DOMEventTargetHelper)
 
-  virtual JSObject* WrapObject(JSContext* aCx)
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
     MOZ_OVERRIDE;
   nsPIDOMWindow* GetParentObject() const
   {
     return GetOwner();
   }
 
   // WebIDL
   // Uses XPIDL GetLabel.
--- a/dom/base/nsDOMFileReader.cpp
+++ b/dom/base/nsDOMFileReader.cpp
@@ -525,12 +525,12 @@ nsDOMFileReader::GetAsDataURL(nsIDOMBlob
   if (!AppendASCIItoUTF16(encodedData, aResult, fallible)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return NS_OK;
 }
 
 /* virtual */ JSObject*
-nsDOMFileReader::WrapObject(JSContext* aCx)
+nsDOMFileReader::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return FileReaderBinding::Wrap(aCx, this);
+  return FileReaderBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/base/nsDOMFileReader.h
+++ b/dom/base/nsDOMFileReader.h
@@ -57,17 +57,17 @@ public:
 
   virtual nsresult DoOnLoadEnd(nsresult aStatus, nsAString& aSuccessEvent,
                                nsAString& aTerminationEvent) MOZ_OVERRIDE;
 
   nsPIDOMWindow* GetParentObject() const
   {
     return GetOwner();
   }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL
   static already_AddRefed<nsDOMFileReader>
   Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
   void ReadAsArrayBuffer(JSContext* aCx, File& aBlob, ErrorResult& aRv)
   {
     ReadFileContent(aBlob, EmptyString(), FILE_AS_ARRAYBUFFER, aRv);
   }
--- a/dom/base/nsDOMMutationObserver.h
+++ b/dom/base/nsDOMMutationObserver.h
@@ -43,19 +43,19 @@ public:
   {
   }
 
   nsISupports* GetParentObject() const
   {
     return mOwner;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return mozilla::dom::MutationRecordBinding::Wrap(aCx, this);
+    return mozilla::dom::MutationRecordBinding::Wrap(aCx, this, aGivenProto);
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMMutationRecord)
 
   void GetType(mozilla::dom::DOMString& aRetVal) const
   {
     aRetVal.SetOwnedAtom(mType, mozilla::dom::DOMString::eNullNotExpected);
@@ -456,19 +456,19 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMMutationObserver)
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOM_MUTATION_OBSERVER_IID)
 
   static already_AddRefed<nsDOMMutationObserver>
   Constructor(const mozilla::dom::GlobalObject& aGlobal,
               mozilla::dom::MutationCallback& aCb,
               mozilla::ErrorResult& aRv);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return mozilla::dom::MutationObserverBinding::Wrap(aCx, this);
+    return mozilla::dom::MutationObserverBinding::Wrap(aCx, this, aGivenProto);
   }
 
   nsISupports* GetParentObject() const
   {
     return mOwner;
   }
 
   void Observe(nsINode& aTarget,
--- a/dom/base/nsDOMSerializer.h
+++ b/dom/base/nsDOMSerializer.h
@@ -43,19 +43,19 @@ public:
   SerializeToStream(nsINode& aRoot, nsIOutputStream* aStream,
                     const nsAString& aCharset, mozilla::ErrorResult& rv);
 
   nsISupports* GetParentObject() const
   {
     return mOwner;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return mozilla::dom::XMLSerializerBinding::Wrap(aCx, this);
+    return mozilla::dom::XMLSerializerBinding::Wrap(aCx, this, aGivenProto);
   }
 
 private:
   virtual ~nsDOMSerializer();
 
   explicit nsDOMSerializer(nsISupports* aOwner) : mOwner(aOwner)
   {
     MOZ_ASSERT(aOwner);
--- a/dom/base/nsDOMSettableTokenList.cpp
+++ b/dom/base/nsDOMSettableTokenList.cpp
@@ -16,12 +16,12 @@ nsDOMSettableTokenList::SetValue(const n
   if (!mElement) {
     return;
   }
 
   rv = mElement->SetAttr(kNameSpaceID_None, mAttrAtom, aValue, true);
 }
 
 JSObject*
-nsDOMSettableTokenList::WrapObject(JSContext *cx)
+nsDOMSettableTokenList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::DOMSettableTokenListBinding::Wrap(cx, this);
+  return mozilla::dom::DOMSettableTokenListBinding::Wrap(cx, this, aGivenProto);
 }
--- a/dom/base/nsDOMSettableTokenList.h
+++ b/dom/base/nsDOMSettableTokenList.h
@@ -17,17 +17,17 @@ class nsIAtom;
 // because nsDOMSettableTokenList is traversed by Element.
 class nsDOMSettableTokenList MOZ_FINAL : public nsDOMTokenList
 {
 public:
 
   nsDOMSettableTokenList(mozilla::dom::Element* aElement, nsIAtom* aAttrAtom)
     : nsDOMTokenList(aElement, aAttrAtom) {}
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL
   void GetValue(nsAString& aResult) { Stringify(aResult); }
   void SetValue(const nsAString& aValue, mozilla::ErrorResult& rv);
 };
 
 #endif // nsDOMSettableTokenList_h___
 
--- a/dom/base/nsDOMTokenList.cpp
+++ b/dom/base/nsDOMTokenList.cpp
@@ -304,13 +304,13 @@ nsDOMTokenList::Stringify(nsAString& aRe
     aResult.Truncate();
     return;
   }
 
   mElement->GetAttr(kNameSpaceID_None, mAttrAtom, aResult);
 }
 
 JSObject*
-nsDOMTokenList::WrapObject(JSContext *cx)
+nsDOMTokenList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DOMTokenListBinding::Wrap(cx, this);
+  return DOMTokenListBinding::Wrap(cx, this, aGivenProto);
 }
 
--- a/dom/base/nsDOMTokenList.h
+++ b/dom/base/nsDOMTokenList.h
@@ -32,17 +32,17 @@ protected:
   typedef mozilla::dom::Element Element;
 
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMTokenList)
 
   nsDOMTokenList(Element* aElement, nsIAtom* aAttrAtom);
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   Element* GetParentObject()
   {
     return mElement;
   }
 
   uint32_t Length();
   void Item(uint32_t aIndex, nsAString& aResult)
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2885,29 +2885,16 @@ nsDOMWindowUtils::LeafLayersPartitionWin
   if (!coveredRegion.IsEqual(root->GetVisibleRegion())) {
     *aResult = false;
   }
 #endif
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GetMayHaveTouchEventListeners(bool* aResult)
-{
-  MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
-
-  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
-  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
-
-  nsPIDOMWindow* innerWindow = window->GetCurrentInnerWindow();
-  *aResult = innerWindow ? innerWindow->HasTouchEventListeners() : false;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsDOMWindowUtils::CheckAndClearPaintedState(nsIDOMElement* aElement, bool* aResult)
 {
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
   if (!aElement) {
     return NS_ERROR_INVALID_ARG;
   }
 
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -7355,24 +7355,24 @@ nsDocument::InitializeFrameLoader(nsFram
       NS_NewRunnableMethod(this, &nsDocument::MaybeInitializeFinalizeFrameLoaders);
     NS_ENSURE_TRUE(mFrameLoaderRunner, NS_ERROR_OUT_OF_MEMORY);
     nsContentUtils::AddScriptRunner(mFrameLoaderRunner);
   }
   return NS_OK;
 }
 
 nsresult
-nsDocument::FinalizeFrameLoader(nsFrameLoader* aLoader)
+nsDocument::FinalizeFrameLoader(nsFrameLoader* aLoader, nsIRunnable* aFinalizer)
 {
   mInitializableFrameLoaders.RemoveElement(aLoader);
   if (mInDestructor) {
     return NS_ERROR_FAILURE;
   }
 
-  mFinalizableFrameLoaders.AppendElement(aLoader);
+  mFrameLoaderFinalizers.AppendElement(aFinalizer);
   if (!mFrameLoaderRunner) {
     mFrameLoaderRunner =
       NS_NewRunnableMethod(this, &nsDocument::MaybeInitializeFinalizeFrameLoaders);
     NS_ENSURE_TRUE(mFrameLoaderRunner, NS_ERROR_OUT_OF_MEMORY);
     nsContentUtils::AddScriptRunner(mFrameLoaderRunner);
   }
   return NS_OK;
 }
@@ -7387,17 +7387,17 @@ nsDocument::MaybeInitializeFinalizeFrame
     return;
   }
 
   // We're not in an update, but it is not safe to run scripts, so
   // postpone frameloader initialization and finalization.
   if (!nsContentUtils::IsSafeToRunScript()) {
     if (!mInDestructor && !mFrameLoaderRunner &&
         (mInitializableFrameLoaders.Length() ||
-         mFinalizableFrameLoaders.Length())) {
+         mFrameLoaderFinalizers.Length())) {
       mFrameLoaderRunner =
         NS_NewRunnableMethod(this, &nsDocument::MaybeInitializeFinalizeFrameLoaders);
       nsContentUtils::AddScriptRunner(mFrameLoaderRunner);
     }
     return;
   }
   mFrameLoaderRunner = nullptr;
 
@@ -7406,52 +7406,38 @@ nsDocument::MaybeInitializeFinalizeFrame
   // array. But be careful to keep the loader alive when starting the load!
   while (mInitializableFrameLoaders.Length()) {
     nsRefPtr<nsFrameLoader> loader = mInitializableFrameLoaders[0];
     mInitializableFrameLoaders.RemoveElementAt(0);
     NS_ASSERTION(loader, "null frameloader in the array?");
     loader->ReallyStartLoading();
   }
 
-  uint32_t length = mFinalizableFrameLoaders.Length();
+  uint32_t length = mFrameLoaderFinalizers.Length();
   if (length > 0) {
-    nsTArray<nsRefPtr<nsFrameLoader> > loaders;
-    mFinalizableFrameLoaders.SwapElements(loaders);
+    nsTArray<nsCOMPtr<nsIRunnable> > finalizers;
+    mFrameLoaderFinalizers.SwapElements(finalizers);
     for (uint32_t i = 0; i < length; ++i) {
-      loaders[i]->Finalize();
+      finalizers[i]->Run();
     }
   }
 }
 
 void
 nsDocument::TryCancelFrameLoaderInitialization(nsIDocShell* aShell)
 {
   uint32_t length = mInitializableFrameLoaders.Length();
   for (uint32_t i = 0; i < length; ++i) {
     if (mInitializableFrameLoaders[i]->GetExistingDocShell() == aShell) {
       mInitializableFrameLoaders.RemoveElementAt(i);
       return;
     }
   }
 }
 
-bool
-nsDocument::FrameLoaderScheduledToBeFinalized(nsIDocShell* aShell)
-{
-  if (aShell) {
-    uint32_t length = mFinalizableFrameLoaders.Length();
-    for (uint32_t i = 0; i < length; ++i) {
-      if (mFinalizableFrameLoaders[i]->GetExistingDocShell() == aShell) {
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
 nsIDocument*
 nsDocument::RequestExternalResource(nsIURI* aURI,
                                     nsINode* aRequestingNode,
                                     ExternalResourceLoad** aPendingLoad)
 {
   NS_PRECONDITION(aURI, "Must have a URI");
   NS_PRECONDITION(aRequestingNode, "Must have a node");
   if (mDisplayDocument) {
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -1030,19 +1030,18 @@ public:
                                                    float aBottomSize, float aLeftSize,
                                                    bool aIgnoreRootScrollFrame,
                                                    bool aFlushLayout,
                                                    nsIDOMNodeList** aReturn) MOZ_OVERRIDE;
 
   virtual void FlushSkinBindings() MOZ_OVERRIDE;
 
   virtual nsresult InitializeFrameLoader(nsFrameLoader* aLoader) MOZ_OVERRIDE;
-  virtual nsresult FinalizeFrameLoader(nsFrameLoader* aLoader) MOZ_OVERRIDE;
+  virtual nsresult FinalizeFrameLoader(nsFrameLoader* aLoader, nsIRunnable* aFinalizer) MOZ_OVERRIDE;
   virtual void TryCancelFrameLoaderInitialization(nsIDocShell* aShell) MOZ_OVERRIDE;
-  virtual bool FrameLoaderScheduledToBeFinalized(nsIDocShell* aShell) MOZ_OVERRIDE;
   virtual nsIDocument*
     RequestExternalResource(nsIURI* aURI,
                             nsINode* aRequestingNode,
                             ExternalResourceLoad** aPendingLoad) MOZ_OVERRIDE;
   virtual void
     EnumerateExternalResources(nsSubDocEnumFunc aCallback, void* aData) MOZ_OVERRIDE;
 
   nsTArray<nsCString> mHostObjectURIs;
@@ -1765,17 +1764,17 @@ private:
   // AddStyleRelevantLink.
   bool mStyledLinksCleared;
 #endif
 
   // Member to store out last-selected stylesheet set.
   nsString mLastStyleSheetSet;
 
   nsTArray<nsRefPtr<nsFrameLoader> > mInitializableFrameLoaders;
-  nsTArray<nsRefPtr<nsFrameLoader> > mFinalizableFrameLoaders;
+  nsTArray<nsCOMPtr<nsIRunnable> > mFrameLoaderFinalizers;
   nsRefPtr<nsRunnableMethod<nsDocument> > mFrameLoaderRunner;
 
   nsRevocableEventPtr<nsRunnableMethod<nsDocument, void, false> >
     mPendingTitleChangeEvent;
 
   nsExternalResourceMap mExternalResourceMap;
 
   // All images in process of being preloaded.  This is a hashtable so
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -1805,20 +1805,16 @@ nsFocusManager::Focus(nsPIDOMWindow* aWi
   }
 #endif
 
   if (aIsNewDocument) {
     // if this is a new document, update the parent chain of frames so that
     // focus can be traversed from the top level down to the newly focused
     // window.
     AdjustWindowFocus(aWindow, false);
-
-    // Update the window touch registration to reflect the state of
-    // the new document that got focus
-    aWindow->UpdateTouchState();
   }
 
   // indicate that the window has taken focus.
   if (aWindow->TakeFocus(true, focusMethod))
     aIsNewDocument = true;
 
   SetFocusedWindowInternal(aWindow);
 
--- a/dom/base/nsFormData.cpp
+++ b/dom/base/nsFormData.cpp
@@ -259,19 +259,19 @@ nsFormData::Append(const nsAString& aNam
   nsString valAsString;
   valAsString.Adopt(stringData, stringLen);
 
   Append(aName, valAsString);
   return NS_OK;
 }
 
 /* virtual */ JSObject*
-nsFormData::WrapObject(JSContext* aCx)
+nsFormData::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return FormDataBinding::Wrap(aCx, this);
+  return FormDataBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */ already_AddRefed<nsFormData>
 nsFormData::Constructor(const GlobalObject& aGlobal,
                         const Optional<NonNull<HTMLFormElement> >& aFormElement,
                         ErrorResult& aRv)
 {
   nsRefPtr<nsFormData> formData = new nsFormData(aGlobal.GetAsSupports());
--- a/dom/base/nsFormData.h
+++ b/dom/base/nsFormData.h
@@ -75,17 +75,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsFormData,
                                                          nsIDOMFormData)
 
   NS_DECL_NSIDOMFORMDATA
   NS_DECL_NSIXHRSENDABLE
 
   // nsWrapperCache
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL
   nsISupports*
   GetParentObject() const
   {
     return mOwner;
   }
   static already_AddRefed<nsFormData>
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -102,35 +102,16 @@
 using namespace mozilla;
 using namespace mozilla::hal;
 using namespace mozilla::dom;
 using namespace mozilla::dom::ipc;
 using namespace mozilla::layers;
 using namespace mozilla::layout;
 typedef FrameMetrics::ViewID ViewID;
 
-class nsAsyncDocShellDestroyer : public nsRunnable
-{
-public:
-  explicit nsAsyncDocShellDestroyer(nsIDocShell* aDocShell)
-    : mDocShell(aDocShell)
-  {
-  }
-
-  NS_IMETHOD Run()
-  {
-    nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
-    if (base_win) {
-      base_win->Destroy();
-    }
-    return NS_OK;
-  }
-  nsRefPtr<nsIDocShell> mDocShell;
-};
-
 // Bug 136580: Limit to the number of nested content frames that can have the
 //             same URL. This is to stop content that is recursively loading
 //             itself.  Note that "#foo" on the end of URL doesn't affect
 //             whether it's considered identical, but "?foo" or ";foo" are
 //             considered and compared.
 // Bug 228829: Limit this to 1, like IE does.
 #define MAX_SAME_URL_CONTENT_FRAMES 1
 
@@ -176,17 +157,16 @@ nsFrameLoader::nsFrameLoader(Element* aO
   , mChildID(0)
   , mEventMode(EVENT_MODE_NORMAL_DISPATCH)
 {
   ResetPermissionManagerStatus();
 }
 
 nsFrameLoader::~nsFrameLoader()
 {
-  mNeedsAsyncDestroy = true;
   if (mMessageManager) {
     mMessageManager->Disconnect();
   }
   MOZ_RELEASE_ASSERT(mDestroyCalled);
 }
 
 nsFrameLoader*
 nsFrameLoader::Create(Element* aOwner, bool aNetworkCreated)
@@ -518,26 +498,16 @@ nsFrameLoader::GetDocShell(nsIDocShell *
   }
 
   *aDocShell = mDocShell;
   NS_IF_ADDREF(*aDocShell);
 
   return rv;
 }
 
-void
-nsFrameLoader::Finalize()
-{
-  nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
-  if (base_win) {
-    base_win->Destroy();
-  }
-  mDocShell = nullptr;
-}
-
 static void
 FirePageHideEvent(nsIDocShellTreeItem* aItem,
                   EventTarget* aChromeEventHandler)
 {
   nsCOMPtr<nsIDocument> doc = aItem->GetDocument();
   NS_ASSERTION(doc, "What happened here?");
   doc->OnPageHide(true, aChromeEventHandler);
 
@@ -1353,51 +1323,80 @@ nsFrameLoader::SwapWithOtherLoader(nsFra
 
   FirePageShowEvent(ourDocshell, ourEventTarget, true);
   FirePageShowEvent(otherDocshell, otherEventTarget, true);
 
   mInSwap = aOther->mInSwap = false;
   return NS_OK;
 }
 
-void
-nsFrameLoader::DestroyChild()
-{
-  if (mRemoteBrowser) {
-    mRemoteBrowser->SetOwnerElement(nullptr);
-    mRemoteBrowser->Destroy();
-    mRemoteBrowser = nullptr;
-  }
-}
-
 NS_IMETHODIMP
 nsFrameLoader::Destroy()
 {
+  StartDestroy();
+  return NS_OK;
+}
+
+class nsFrameLoaderDestroyRunnable : public nsRunnable
+{
+  enum DestroyPhase
+  {
+    // See the implementation of Run for an explanation of these phases.
+    eDestroyDocShell,
+    eWaitForUnloadMessage,
+    eDestroyComplete
+  };
+
+  nsRefPtr<nsFrameLoader> mFrameLoader;
+  DestroyPhase mPhase;
+
+public:
+  explicit nsFrameLoaderDestroyRunnable(nsFrameLoader* aFrameLoader)
+   : mFrameLoader(aFrameLoader), mPhase(eDestroyDocShell) {}
+
+  NS_IMETHODIMP Run() MOZ_OVERRIDE;
+};
+
+void
+nsFrameLoader::StartDestroy()
+{
+  // nsFrameLoader::StartDestroy is called just before the frameloader is
+  // detached from the <browser> element. Destruction continues in phases via
+  // the nsFrameLoaderDestroyRunnable.
+
   if (mDestroyCalled) {
-    return NS_OK;
+    return;
   }
   mDestroyCalled = true;
 
+  // After this point, we return an error when trying to send a message using
+  // the message manager on the frame.
   if (mMessageManager) {
-    mMessageManager->Disconnect();
+    mMessageManager->Close();
   }
-  if (mChildMessageManager) {
-    static_cast<nsInProcessTabChildGlobal*>(mChildMessageManager.get())->Disconnect();
+
+  // Retain references to the <browser> element and the frameloader in case we
+  // receive any messages from the message manager on the frame. These
+  // references are dropped in DestroyComplete.
+  if (mChildMessageManager || mRemoteBrowser) {
+    mOwnerContentStrong = mOwnerContent;
+    if (mRemoteBrowser) {
+      mRemoteBrowser->CacheFrameLoader(this);
+    }
   }
 
   nsCOMPtr<nsIDocument> doc;
   bool dynamicSubframeRemoval = false;
   if (mOwnerContent) {
     doc = mOwnerContent->OwnerDoc();
     dynamicSubframeRemoval = !mIsTopLevelContent && !doc->InUnlinkOrDeletion();
     doc->SetSubDocumentFor(mOwnerContent, nullptr);
 
     SetOwnerContent(nullptr);
   }
-  DestroyChild();
 
   // Seems like this is a dynamic frame removal.
   if (dynamicSubframeRemoval) {
     if (mDocShell) {
       mDocShell->RemoveFromSessionHistory();
     }
   }
 
@@ -1407,42 +1406,141 @@ nsFrameLoader::Destroy()
       nsCOMPtr<nsIDocShellTreeItem> parentItem;
       mDocShell->GetParent(getter_AddRefs(parentItem));
       nsCOMPtr<nsIDocShellTreeOwner> owner = do_GetInterface(parentItem);
       if (owner) {
         owner->ContentShellRemoved(mDocShell);
       }
     }
   }
-  
+
   // Let our window know that we are gone
   if (mDocShell) {
     nsCOMPtr<nsPIDOMWindow> win_private(mDocShell->GetWindow());
     if (win_private) {
       win_private->SetFrameElementInternal(nullptr);
     }
   }
 
-  if ((mNeedsAsyncDestroy || !doc ||
-       NS_FAILED(doc->FinalizeFrameLoader(this))) && mDocShell) {
-    nsCOMPtr<nsIRunnable> event = new nsAsyncDocShellDestroyer(mDocShell);
-    NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
-    NS_DispatchToCurrentThread(event);
-
-    // Let go of our docshell now that the async destroyer holds on to
-    // the docshell.
-
-    mDocShell = nullptr;
+  nsCOMPtr<nsIRunnable> destroyRunnable = new nsFrameLoaderDestroyRunnable(this);
+  if (mNeedsAsyncDestroy || !doc ||
+      NS_FAILED(doc->FinalizeFrameLoader(this, destroyRunnable))) {
+    NS_DispatchToCurrentThread(destroyRunnable);
   }
-
-  // NOTE: 'this' may very well be gone by now.
+}
+
+nsresult
+nsFrameLoaderDestroyRunnable::Run()
+{
+  switch (mPhase) {
+  case eDestroyDocShell:
+    mFrameLoader->DestroyDocShell();
+
+    // In the out-of-process case, TabParent will eventually call
+    // DestroyComplete once it receives a __delete__ message from the child. In
+    // the in-process case, we dispatch a series of runnables to ensure that
+    // DestroyComplete gets called at the right time. The frame loader is kept
+    // alive by mFrameLoader during this time.
+    if (mFrameLoader->mChildMessageManager) {
+      // When the docshell is destroyed, NotifyWindowIDDestroyed is called to
+      // asynchronously notify {outer,inner}-window-destroyed via a runnable. We
+      // don't want DestroyComplete to run until after those runnables have
+      // run. Since we're enqueueing ourselves after the window-destroyed
+      // runnables are enqueued, we're guaranteed to run after.
+      mPhase = eWaitForUnloadMessage;
+      NS_DispatchToCurrentThread(this);
+    }
+    break;
+
+   case eWaitForUnloadMessage:
+     // The *-window-destroyed observers have finished running at this
+     // point. However, it's possible that a *-window-destroyed observer might
+     // have sent a message using the message manager. These messages might not
+     // have been processed yet. So we enqueue ourselves again to ensure that
+     // DestroyComplete runs after all messages sent by *-window-destroyed
+     // observers have been processed.
+     mPhase = eDestroyComplete;
+     NS_DispatchToCurrentThread(this);
+     break;
+
+   case eDestroyComplete:
+     // Now that all messages sent by unload listeners and window destroyed
+     // observers have been processed, we disconnect the message manager and
+     // finish destruction.
+     mFrameLoader->DestroyComplete();
+     break;
+  }
 
   return NS_OK;
 }
 
+void
+nsFrameLoader::DestroyDocShell()
+{
+  // This code runs after the frameloader has been detached from the <browser>
+  // element. We postpone this work because we may not be allowed to run
+  // script at that time.
+
+  // Ask the TabChild to fire the frame script "unload" event, destroy its
+  // docshell, and finally destroy the PBrowser actor. This eventually leads to
+  // nsFrameLoader::DestroyComplete being called.
+  if (mRemoteBrowser) {
+    mRemoteBrowser->Destroy();
+  }
+
+  // Fire the "unload" event if we're in-process.
+  if (mChildMessageManager) {
+    static_cast<nsInProcessTabChildGlobal*>(mChildMessageManager.get())->FireUnloadEvent();
+  }
+
+  // Destroy the docshell.
+  nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell));
+  if (base_win) {
+    base_win->Destroy();
+  }
+  mDocShell = nullptr;
+
+  if (mChildMessageManager) {
+    // Stop handling events in the in-process frame script.
+    static_cast<nsInProcessTabChildGlobal*>(mChildMessageManager.get())->DisconnectEventListeners();
+  }
+}
+
+void
+nsFrameLoader::DestroyComplete()
+{
+  // We get here, as part of StartDestroy, after the docshell has been destroyed
+  // and all message manager messages sent during docshell destruction have been
+  // dispatched.  We also get here if the child process crashes. In the latter
+  // case, StartDestroy might not have been called.
+
+  // Drop the strong references created in StartDestroy.
+  if (mChildMessageManager || mRemoteBrowser) {
+    mOwnerContentStrong = nullptr;
+    if (mRemoteBrowser) {
+      mRemoteBrowser->CacheFrameLoader(nullptr);
+    }
+  }
+
+  // Call TabParent::Destroy if we haven't already (in case of a crash).
+  if (mRemoteBrowser) {
+    mRemoteBrowser->SetOwnerElement(nullptr);
+    mRemoteBrowser->Destroy();
+    mRemoteBrowser = nullptr;
+  }
+
+  if (mMessageManager) {
+    mMessageManager->Disconnect();
+  }
+
+  if (mChildMessageManager) {
+    static_cast<nsInProcessTabChildGlobal*>(mChildMessageManager.get())->Disconnect();
+  }
+}
+
 NS_IMETHODIMP
 nsFrameLoader::GetDepthTooGreat(bool* aDepthTooGreat)
 {
   *aDepthTooGreat = mDepthTooGreat;
   return NS_OK;
 }
 
 void
--- a/dom/base/nsFrameLoader.h
+++ b/dom/base/nsFrameLoader.h
@@ -73,17 +73,19 @@ public:
                                bool aNetworkCreated);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFrameLoader, nsIFrameLoader)
   NS_DECL_NSIFRAMELOADER
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
   nsresult CheckForRecursiveLoad(nsIURI* aURI);
   nsresult ReallyStartLoading();
-  void Finalize();
+  void StartDestroy();
+  void DestroyDocShell();
+  void DestroyComplete();
   nsIDocShell* GetExistingDocShell() { return mDocShell; }
   mozilla::dom::EventTarget* GetTabChildGlobalAsEventTarget();
   nsresult CreateStaticClone(nsIFrameLoader* aDest);
 
   /**
    * MessageManagerCallback methods that we override.
    */
   virtual bool DoLoadMessageManagerScript(const nsAString& aURL,
@@ -314,16 +316,21 @@ private:
   void ResetPermissionManagerStatus();
 
   void InitializeBrowserAPI();
 
   nsCOMPtr<nsIDocShell> mDocShell;
   nsCOMPtr<nsIURI> mURIToLoad;
   mozilla::dom::Element* mOwnerContent; // WEAK
 
+  // After the frameloader has been removed from the DOM but before all of the
+  // messages from the frame have been received, we keep a strong reference to
+  // our <browser> element.
+  nsRefPtr<mozilla::dom::Element> mOwnerContentStrong;
+
   // Note: this variable must be modified only by ResetPermissionManagerStatus()
   uint32_t mAppIdSentToPermissionManager;
 
 public:
   // public because a callback needs these.
   nsRefPtr<nsFrameMessageManager> mMessageManager;
   nsCOMPtr<nsIInProcessContentFrameMessageManager> mChildMessageManager;
 private:
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -296,17 +296,18 @@ SameProcessCpowHolder::ToObject(JSContex
   aObjp.set(mObj);
   return JS_WrapObject(aCx, aObjp);
 }
 
 // nsIMessageListenerManager
 
 NS_IMETHODIMP
 nsFrameMessageManager::AddMessageListener(const nsAString& aMessage,
-                                          nsIMessageListener* aListener)
+                                          nsIMessageListener* aListener,
+                                          bool aListenWhenClosed)
 {
   nsAutoTObserverArray<nsMessageListenerInfo, 1>* listeners =
     mListeners.Get(aMessage);
   if (!listeners) {
     listeners = new nsAutoTObserverArray<nsMessageListenerInfo, 1>();
     mListeners.Put(aMessage, listeners);
   } else {
     uint32_t len = listeners->Length();
@@ -315,16 +316,17 @@ nsFrameMessageManager::AddMessageListene
         return NS_OK;
       }
     }
   }
 
   nsMessageListenerInfo* entry = listeners->AppendElement();
   NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
   entry->mStrongListener = aListener;
+  entry->mListenWhenClosed = aListenWhenClosed;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFrameMessageManager::RemoveMessageListener(const nsAString& aMessage,
                                              nsIMessageListener* aListener)
 {
   nsAutoTObserverArray<nsMessageListenerInfo, 1>* listeners =
@@ -402,16 +404,17 @@ nsFrameMessageManager::AddWeakMessageLis
       if (listeners->ElementAt(i).mWeakListener == weak) {
         return NS_OK;
       }
     }
   }
 
   nsMessageListenerInfo* entry = listeners->AppendElement();
   entry->mWeakListener = weak;
+  entry->mListenWhenClosed = false;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFrameMessageManager::RemoveWeakMessageListener(const nsAString& aMessage,
                                                  nsIMessageListener* aListener)
 {
   nsWeakPtr weak = do_GetWeakReference(aListener);
@@ -979,16 +982,30 @@ nsresult
 nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
                                       const nsAString& aMessage,
                                       bool aIsSync,
                                       const StructuredCloneData* aCloneData,
                                       mozilla::jsipc::CpowHolder* aCpows,
                                       nsIPrincipal* aPrincipal,
                                       InfallibleTArray<nsString>* aJSONRetVal)
 {
+  return ReceiveMessage(aTarget, mClosed, aMessage, aIsSync,
+                        aCloneData, aCpows, aPrincipal, aJSONRetVal);
+}
+
+nsresult
+nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
+                                      bool aTargetClosed,
+                                      const nsAString& aMessage,
+                                      bool aIsSync,
+                                      const StructuredCloneData* aCloneData,
+                                      mozilla::jsipc::CpowHolder* aCpows,
+                                      nsIPrincipal* aPrincipal,
+                                      InfallibleTArray<nsString>* aJSONRetVal)
+{
   nsAutoTObserverArray<nsMessageListenerInfo, 1>* listeners =
     mListeners.Get(aMessage);
   if (listeners) {
 
     MMListenerRemover lr(this);
 
     nsAutoTObserverArray<nsMessageListenerInfo, 1>::EndLimitedIterator
       iter(*listeners);
@@ -999,16 +1016,20 @@ nsFrameMessageManager::ReceiveMessage(ns
       if (listener.mWeakListener) {
         weakListener = do_QueryReferent(listener.mWeakListener);
         if (!weakListener) {
           listeners->RemoveElement(listener);
           continue;
         }
       }
 
+      if (!listener.mListenWhenClosed && aTargetClosed) {
+        continue;
+      }
+
       nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS;
       if (weakListener) {
         wrappedJS = do_QueryInterface(weakListener);
       } else {
         wrappedJS = do_QueryInterface(listener.mStrongListener);
       }
 
       if (!wrappedJS) {
@@ -1149,17 +1170,17 @@ nsFrameMessageManager::ReceiveMessage(ns
             continue;
           }
           aJSONRetVal->AppendElement(json);
         }
       }
     }
   }
   nsRefPtr<nsFrameMessageManager> kungfuDeathGrip = mParentManager;
-  return mParentManager ? mParentManager->ReceiveMessage(aTarget, aMessage,
+  return mParentManager ? mParentManager->ReceiveMessage(aTarget, aTargetClosed, aMessage,
                                                          aIsSync, aCloneData,
                                                          aCpows, aPrincipal,
                                                          aJSONRetVal) : NS_OK;
 }
 
 void
 nsFrameMessageManager::AddChildManager(nsFrameMessageManager* aManager)
 {
@@ -1230,32 +1251,48 @@ nsFrameMessageManager::RemoveFromParent(
     mParentManager->RemoveChildManager(this);
   }
   mParentManager = nullptr;
   mCallback = nullptr;
   mOwnedCallback = nullptr;
 }
 
 void
+nsFrameMessageManager::Close()
+{
+  if (!mClosed) {
+    nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+    if (obs) {
+      obs->NotifyObservers(NS_ISUPPORTS_CAST(nsIContentFrameMessageManager*, this),
+                            "message-manager-close", nullptr);
+    }
+  }
+  mClosed = true;
+  mCallback = nullptr;
+  mOwnedCallback = nullptr;
+}
+
+void
 nsFrameMessageManager::Disconnect(bool aRemoveFromParent)
 {
+  // Notify message-manager-close if we haven't already.
+  Close();
+
   if (!mDisconnected) {
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (obs) {
        obs->NotifyObservers(NS_ISUPPORTS_CAST(nsIContentFrameMessageManager*, this),
                             "message-manager-disconnect", nullptr);
     }
   }
   if (mParentManager && aRemoveFromParent) {
     mParentManager->RemoveChildManager(this);
   }
   mDisconnected = true;
   mParentManager = nullptr;
-  mCallback = nullptr;
-  mOwnedCallback = nullptr;
   if (!mHandlingMessage) {
     mListeners.Clear();
   }
 }
 
 namespace {
 
 struct MessageManagerReferentCount
@@ -1598,23 +1635,23 @@ nsMessageManagerScriptExecutor::TryCache
 
     JSAutoCompartment ac(cx, global);
     JS::CompileOptions options(cx, JSVERSION_LATEST);
     options.setFileAndLine(url.get(), 1);
     options.setNoScriptRval(true);
     JS::Rooted<JSScript*> script(cx);
 
     if (aRunInGlobalScope) {
-      if (!JS::Compile(cx, JS::NullPtr(), options, srcBuf, &script)) {
+      if (!JS::Compile(cx, options, srcBuf, &script)) {
         return;
       }
     } else {
       // We can't clone compile-and-go scripts.
       options.setCompileAndGo(false);
-      if (!JS::Compile(cx, JS::NullPtr(), options, srcBuf, &script)) {
+      if (!JS::Compile(cx, options, srcBuf, &script)) {
         return;
       }
     }
 
     aScriptp.set(script);
 
     nsAutoCString scheme;
     uri->GetScheme(scheme);
--- a/dom/base/nsFrameMessageManager.h
+++ b/dom/base/nsFrameMessageManager.h
@@ -128,16 +128,17 @@ struct nsMessageListenerInfo
   bool operator==(const nsMessageListenerInfo& aOther) const
   {
     return &aOther == this;
   }
 
   // Exactly one of mStrongListener and mWeakListener must be non-null.
   nsCOMPtr<nsIMessageListener> mStrongListener;
   nsWeakPtr mWeakListener;
+  bool mListenWhenClosed;
 };
 
 
 class MOZ_STACK_CLASS SameProcessCpowHolder : public mozilla::jsipc::CpowHolder
 {
 public:
   SameProcessCpowHolder(JSRuntime *aRuntime, JS::Handle<JSObject*> aObj)
     : mObj(aRuntime, aObj)
@@ -164,16 +165,17 @@ public:
                         nsFrameMessageManager* aParentManager,
                         /* mozilla::dom::ipc::MessageManagerFlags */ uint32_t aFlags)
   : mChrome(!!(aFlags & mozilla::dom::ipc::MM_CHROME)),
     mGlobal(!!(aFlags & mozilla::dom::ipc::MM_GLOBAL)),
     mIsProcessManager(!!(aFlags & mozilla::dom::ipc::MM_PROCESSMANAGER)),
     mIsBroadcaster(!!(aFlags & mozilla::dom::ipc::MM_BROADCASTER)),
     mOwnsCallback(!!(aFlags & mozilla::dom::ipc::MM_OWNSCALLBACK)),
     mHandlingMessage(false),
+    mClosed(false),
     mDisconnected(false),
     mCallback(aCallback),
     mParentManager(aParentManager)
   {
     NS_ASSERTION(mChrome || !aParentManager, "Should not set parent manager!");
     NS_ASSERTION(!mIsBroadcaster || !mCallback,
                  "Broadcasters cannot have callbacks!");
     // This is a bit hackish. When parent manager is global, we want
@@ -233,16 +235,17 @@ public:
                           InfallibleTArray<nsString>* aJSONRetVal);
 
   void AddChildManager(nsFrameMessageManager* aManager);
   void RemoveChildManager(nsFrameMessageManager* aManager)
   {
     mChildManagers.RemoveObject(aManager);
   }
   void Disconnect(bool aRemoveFromParent = true);
+  void Close();
 
   void InitWithCallback(mozilla::dom::ipc::MessageManagerCallback* aCallback);
   void SetCallback(mozilla::dom::ipc::MessageManagerCallback* aCallback);
   mozilla::dom::ipc::MessageManagerCallback* GetCallback()
   {
     return mCallback;
   }
 
@@ -285,16 +288,21 @@ private:
                        JS::Handle<JS::Value> aJSON,
                        JS::Handle<JS::Value> aObjects,
                        nsIPrincipal* aPrincipal,
                        JSContext* aCx,
                        uint8_t aArgc,
                        JS::MutableHandle<JS::Value> aRetval,
                        bool aIsSync);
 
+  nsresult ReceiveMessage(nsISupports* aTarget, bool aTargetClosed, const nsAString& aMessage,
+                          bool aIsSync, const StructuredCloneData* aCloneData,
+                          mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal,
+                          InfallibleTArray<nsString>* aJSONRetVal);
+
   NS_IMETHOD LoadScript(const nsAString& aURL,
                         bool aAllowDelayedLoad,
                         bool aRunInGlobalScope);
   NS_IMETHOD RemoveDelayedScript(const nsAString& aURL);
   NS_IMETHOD GetDelayedScripts(JSContext* aCx, JS::MutableHandle<JS::Value> aList);
 
 protected:
   friend class MMListenerRemover;
@@ -304,16 +312,17 @@ protected:
                    nsAutoTObserverArray<nsMessageListenerInfo, 1>> mListeners;
   nsCOMArray<nsIContentFrameMessageManager> mChildManagers;
   bool mChrome;     // true if we're in the chrome process
   bool mGlobal;     // true if we're the global frame message manager
   bool mIsProcessManager; // true if the message manager belongs to the process realm
   bool mIsBroadcaster; // true if the message manager is a broadcaster
   bool mOwnsCallback;
   bool mHandlingMessage;
+  bool mClosed;    // true if we can no longer send messages
   bool mDisconnected;
   mozilla::dom::ipc::MessageManagerCallback* mCallback;
   nsAutoPtr<mozilla::dom::ipc::MessageManagerCallback> mOwnedCallback;
   nsFrameMessageManager* mParentManager;
   nsTArray<nsString> mPendingScripts;
   nsTArray<bool> mPendingScriptsGlobalStates;
 
   void LoadPendingScripts(nsFrameMessageManager* aManager,
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -569,17 +569,17 @@ extern uint64_t
 NextWindowID();
 }
 }
 
 nsPIDOMWindow::nsPIDOMWindow(nsPIDOMWindow *aOuterWindow)
 : mFrameElement(nullptr), mDocShell(nullptr), mModalStateDepth(0),
   mRunningTimeout(nullptr), mMutationBits(0), mIsDocumentLoaded(false),
   mIsHandlingResizeEvent(false), mIsInnerWindow(aOuterWindow != nullptr),
-  mMayHavePaintEventListener(false), mMayHaveTouchEventListener(false),
+  mMayHavePaintEventListener(false),
   mMayHaveMouseEnterLeaveEventListener(false),
   mMayHavePointerEnterLeaveEventListener(false),
   mIsModalContentWindow(false),
   mIsActive(false), mIsBackground(false),
   mAudioMuted(false), mAudioVolume(1.0),
   mDesktopModeViewport(false), mInnerWindow(nullptr),
   mOuterWindow(aOuterWindow),
   // Make sure no actual window ends up with mWindowID == 0
@@ -8012,17 +8012,17 @@ PostMessageReadTransferStructuredClone(J
   StructuredCloneInfo* scInfo = static_cast<StructuredCloneInfo*>(aClosure);
   NS_ASSERTION(scInfo, "Must have scInfo!");
 
   if (tag == SCTAG_DOM_MAP_MESSAGEPORT) {
     MessagePort* port = static_cast<MessagePort*>(aData);
     port->BindToOwner(scInfo->window);
     scInfo->ports.Put(port, nullptr);
 
-    JS::Rooted<JSObject*> obj(aCx, port->WrapObject(aCx));
+    JS::Rooted<JSObject*> obj(aCx, port->WrapObject(aCx, JS::NullPtr()));
     if (JS_WrapObject(aCx, &obj)) {
       MOZ_ASSERT(port->GetOwner() == scInfo->window);
       returnObject.set(obj);
     }
 
     return true;
   }
 
@@ -9839,57 +9839,16 @@ void nsGlobalWindow::SetIsBackground(boo
     nsGlobalWindow* inner = GetCurrentInnerWindowInternal();
     if (inner) {
       inner->SyncGamepadState();
     }
   }
 #endif
 }
 
-void nsGlobalWindow::MaybeUpdateTouchState()
-{
-  FORWARD_TO_INNER_VOID(MaybeUpdateTouchState, ());
-
-  nsIFocusManager* fm = nsFocusManager::GetFocusManager();
-
-  nsCOMPtr<nsIDOMWindow> focusedWindow;
-  fm->GetFocusedWindow(getter_AddRefs(focusedWindow));
-
-  if(this == focusedWindow) {
-    UpdateTouchState();
-  }
-
-  if (mMayHaveTouchEventListener) {
-    nsCOMPtr<nsIObserverService> observerService =
-      services::GetObserverService();
-
-    if (observerService) {
-      observerService->NotifyObservers(static_cast<nsIDOMWindow*>(this),
-                                       DOM_TOUCH_LISTENER_ADDED,
-                                       nullptr);
-    }
-  }
-}
-
-void nsGlobalWindow::UpdateTouchState()
-{
-  FORWARD_TO_INNER_VOID(UpdateTouchState, ());
-
-  nsCOMPtr<nsIWidget> mainWidget = GetMainWidget();
-  if (!mainWidget) {
-    return;
-  }
-
-  if (mMayHaveTouchEventListener) {
-    mainWidget->RegisterTouchWindow();
-  } else {
-    mainWidget->UnregisterTouchWindow();
-  }
-}
-
 void
 nsGlobalWindow::EnableGamepadUpdates()
 {
   MOZ_ASSERT(IsInnerWindow());
 
   if (mHasGamepad) {
 #ifdef MOZ_GAMEPAD
     nsRefPtr<GamepadService> gamepadsvc(GamepadService::GetService());
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -350,17 +350,17 @@ public:
 
   // callback for close event
   void ReallyCloseWindow();
 
   // nsISupports
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   // nsWrapperCache
-  virtual JSObject *WrapObject(JSContext *cx) MOZ_OVERRIDE
+  virtual JSObject *WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
     return IsInnerWindow() || EnsureInnerWindow() ? GetWrapper() : nullptr;
   }
 
   // nsIGlobalJSObjectHolder
   virtual JSObject* GetGlobalJSObject() MOZ_OVERRIDE;
 
   // nsIScriptGlobalObject
@@ -463,19 +463,16 @@ public:
 
   virtual void EnterModalState() MOZ_OVERRIDE;
   virtual void LeaveModalState() MOZ_OVERRIDE;
 
   // Outer windows only.
   virtual bool CanClose() MOZ_OVERRIDE;
   virtual void ForceClose() MOZ_OVERRIDE;
 
-  virtual void MaybeUpdateTouchState() MOZ_OVERRIDE;
-  virtual void UpdateTouchState() MOZ_OVERRIDE;
-
   // Outer windows only.
   virtual bool DispatchCustomEvent(const nsAString& aEventName) MOZ_OVERRIDE;
   bool DispatchResizeEvent(const mozilla::CSSIntSize& aSize);
 
   // Inner windows only.
   virtual void RefreshCompartmentPrincipal() MOZ_OVERRIDE;
 
   // Outer windows only.
--- a/dom/base/nsHistory.cpp
+++ b/dom/base/nsHistory.cpp
@@ -55,19 +55,19 @@ nsHistory::~nsHistory()
 nsPIDOMWindow*
 nsHistory::GetParentObject() const
 {
   nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
   return win;
 }
 
 JSObject*
-nsHistory::WrapObject(JSContext* aCx)
+nsHistory::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HistoryBinding::Wrap(aCx, this);
+  return HistoryBinding::Wrap(aCx, this, aGivenProto);
 }
 
 uint32_t
 nsHistory::GetLength(ErrorResult& aRv) const
 {
   nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
   if (!win || !win->HasActiveDocument()) {
     aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
--- a/dom/base/nsHistory.h
+++ b/dom/base/nsHistory.h
@@ -28,17 +28,17 @@ class nsHistory MOZ_FINAL : public nsIDO
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsHistory)
 
 public:
   explicit nsHistory(nsPIDOMWindow* aInnerWindow);
 
   nsPIDOMWindow* GetParentObject() const;
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   uint32_t GetLength(mozilla::ErrorResult& aRv) const;
   void GetState(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
                 mozilla::ErrorResult& aRv) const;
   void Go(int32_t aDelta, mozilla::ErrorResult& aRv);
   void Back(mozilla::ErrorResult& aRv);
   void Forward(mozilla::ErrorResult& aRv);
   void PushState(JSContext* aCx, JS::Handle<JS::Value> aData,
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -58,16 +58,17 @@ class nsIDOMNodeList;
 class nsIHTMLCollection;
 class nsILayoutHistoryState;
 class nsILoadContext;
 class nsIObjectLoadingContent;
 class nsIObserver;
 class nsIPresShell;
 class nsIPrincipal;
 class nsIRequest;
+class nsIRunnable;
 class nsIStreamListener;
 class nsIStructuredCloneContainer;
 class nsIStyleRule;
 class nsIStyleSheet;
 class nsIURI;
 class nsIVariant;
 class nsLocation;
 class nsViewManager;
@@ -1659,21 +1660,19 @@ public:
   already_AddRefed<nsIDocumentEncoder> GetCachedEncoder();
 
   void SetCachedEncoder(already_AddRefed<nsIDocumentEncoder> aEncoder);
 
   // In case of failure, the document really can't initialize the frame loader.
   virtual nsresult InitializeFrameLoader(nsFrameLoader* aLoader) = 0;
   // In case of failure, the caller must handle the error, for example by
   // finalizing frame loader asynchronously.
-  virtual nsresult FinalizeFrameLoader(nsFrameLoader* aLoader) = 0;
+  virtual nsresult FinalizeFrameLoader(nsFrameLoader* aLoader, nsIRunnable* aFinalizer) = 0;
   // Removes the frame loader of aShell from the initialization list.
   virtual void TryCancelFrameLoaderInitialization(nsIDocShell* aShell) = 0;
-  //  Returns true if the frame loader of aShell is in the finalization list.
-  virtual bool FrameLoaderScheduledToBeFinalized(nsIDocShell* aShell) = 0;
 
   /**
    * Check whether this document is a root document that is not an
    * external resource.
    */
   bool IsRootDisplayDocument() const
   {
     return !mParentDocument && !mDisplayDocument;
--- a/dom/base/nsIMessageManager.idl
+++ b/dom/base/nsIMessageManager.idl
@@ -196,31 +196,38 @@ interface nsIMessageListener : nsISuppor
    * returned as JSON (will be changed to use structured clones).
    * When there are multiple listeners to sync messages, each
    * listener's return value is sent back as an array.  |undefined|
    * return values show up as undefined values in the array.
    */
   void receiveMessage();
 };
 
-[scriptable, builtinclass, uuid(aae827bd-acf1-45fe-a556-ea545d4c0804)]
+[scriptable, builtinclass, uuid(b949bfec-bb7d-47bc-b387-ac6a9b655072)]
 interface nsIMessageListenerManager : nsISupports
 {
   /**
    * Register |listener| to receive |messageName|.  All listener
    * callbacks for a particular message are invoked when that message
    * is received.
    *
    * The message manager holds a strong ref to |listener|.
    *
    * If the same listener registers twice for the same message, the
    * second registration is ignored.
+   *
+   * Pass true for listenWhenClosed if you want to receive messages
+   * during the short period after a frame has been removed from the
+   * DOM and before its frame script has finished unloading. This
+   * parameter only has an effect for frame message managers in
+   * the main process. Default is false.
    */
   void addMessageListener(in AString messageName,
-                          in nsIMessageListener listener);
+                          in nsIMessageListener listener,
+                          [optional] in boolean listenWhenClosed);
 
   /**
    * Undo an |addMessageListener| call -- that is, calling this causes us to no
    * longer invoke |listener| when |messageName| is received.
    *
    * removeMessageListener does not remove a message listener added via
    * addWeakMessageListener; use removeWeakMessageListener for that.
    */
@@ -247,17 +254,17 @@ interface nsIMessageListenerManager : ns
 };
 
 /**
  * Message "senders" have a single "other side" to which messages are
  * sent.  For example, a child-process message manager will send
  * messages that are only delivered to its one parent-process message
  * manager.
  */
-[scriptable, builtinclass, uuid(d6b0d851-43e6-426d-9f13-054bc0198175)]
+[scriptable, builtinclass, uuid(bb5d79e4-e73c-45e7-9651-4d718f4b994c)]
 interface nsIMessageSender : nsIMessageListenerManager
 {
   /**
    * Send |messageName| and |obj| to the "other side" of this message
    * manager.  This invokes listeners who registered for
    * |messageName|.
    *
    * See nsIMessageListener::receiveMessage() for the format of the
@@ -279,17 +286,17 @@ interface nsIMessageSender : nsIMessageL
 
 /**
  * Message "broadcasters" don't have a single "other side" that they
  * send messages to, but rather a set of subordinate message managers.
  * For example, broadcasting a message through a window message
  * manager will broadcast the message to all frame message managers
  * within its window.
  */
-[scriptable, builtinclass, uuid(d36346b9-5d3b-497d-9c28-ffbc3e4f6d0d)]
+[scriptable, builtinclass, uuid(4d7d62ad-4725-4f39-86cf-8fb22bf9c1d8)]
 interface nsIMessageBroadcaster : nsIMessageListenerManager
 {
   /**
    * Like |sendAsyncMessage()|, but also broadcasts this message to
    * all "child" message managers of this message manager.  See long
    * comment above for details.
    *
    * WARNING: broadcasting messages can be very expensive and leak
@@ -306,17 +313,17 @@ interface nsIMessageBroadcaster : nsIMes
   readonly attribute unsigned long childCount;
 
   /**
    * Return a single subordinate message manager.
    */
   nsIMessageListenerManager getChildAt(in unsigned long aIndex);
 };
 
-[scriptable, builtinclass, uuid(7fda0941-9dcc-448b-bd39-16373c5b4003)]
+[scriptable, builtinclass, uuid(0e602c9e-1977-422a-a8e4-fe0d4a4f78d0)]
 interface nsISyncMessageSender : nsIMessageSender
 {
   /**
    * Like |sendAsyncMessage()|, except blocks the sender until all
    * listeners of the message have been invoked.  Returns an array
    * containing return values from each listener invoked.
    */
   [implicit_jscontext, optional_argc]
@@ -336,17 +343,17 @@ interface nsISyncMessageSender : nsIMess
    */
   [implicit_jscontext, optional_argc]
   jsval sendRpcMessage([optional] in AString messageName,
                        [optional] in jsval obj,
                        [optional] in jsval objects,
                        [optional] in nsIPrincipal principal);
 };
 
-[scriptable, builtinclass, uuid(e04a7ade-c61a-46ec-9f13-efeabedd9d3d)]
+[scriptable, builtinclass, uuid(13f3555f-769e-44ea-b607-5239230c3162)]
 interface nsIMessageManagerGlobal : nsISyncMessageSender
 {
   /**
    * Print a string to stdout.
    */
   void dump(in DOMString aStr);
 
   /**
@@ -371,23 +378,23 @@ interface nsIContentFrameMessageManager 
   readonly attribute nsIDOMWindow content;
 
   /**
    * The top level docshell or null.
    */
   readonly attribute nsIDocShell docShell;
 };
 
-[uuid(a2325927-9c0c-437d-9215-749c79235031)]
+[uuid(a9e07e89-7125-48e3-bf73-2cbae7fc5b1c)]
 interface nsIInProcessContentFrameMessageManager : nsIContentFrameMessageManager
 {
   [notxpcom] nsIContent getOwnerContent();
 };
 
-[scriptable, builtinclass, uuid(9ca95410-b253-11e4-ab27-0800200c9a66)]
+[scriptable, builtinclass, uuid(d0c799a2-d5ff-4a75-acbb-b8c8347944a6)]
 interface nsIContentProcessMessageManager : nsIMessageManagerGlobal
 {
 };
 
 [scriptable, builtinclass, uuid(6fb78110-45ae-11e3-8f96-0800200c9a66)]
 interface nsIFrameScriptLoader : nsISupports
 {
   /**
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -2659,17 +2659,17 @@ nsINode::GetElementById(const nsAString&
     if (id && id->Equals(aId)) {
       return kid->AsElement();
     }
   }
   return nullptr;
 }
 
 JSObject*
-nsINode::WrapObject(JSContext *aCx)
+nsINode::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
   // Make sure one of these is true
   // (1) our owner document has a script handling object,
   // (2) Our owner document has had a script handling object, or has been marked
   //     to have had one,
   // (3) we are running a privileged script.
   // Event handling is possible only if (1). If (2) event handling is
   // prevented.
@@ -2678,17 +2678,17 @@ nsINode::WrapObject(JSContext *aCx)
   bool hasHadScriptHandlingObject = false;
   if (!OwnerDoc()->GetScriptHandlingObject(hasHadScriptHandlingObject) &&
       !hasHadScriptHandlingObject &&
       !nsContentUtils::IsCallerChrome()) {
     Throw(aCx, NS_ERROR_UNEXPECTED);
     return nullptr;
   }
 
-  JS::Rooted<JSObject*> obj(aCx, WrapNode(aCx));
+  JS::Rooted<JSObject*> obj(aCx, WrapNode(aCx, aGivenProto));
   MOZ_ASSERT_IF(ChromeOnlyAccess(),
                 xpc::IsInContentXBLScope(obj) || !xpc::UseContentXBLScope(js::GetObjectCompartment(obj)));
   return obj;
 }
 
 already_AddRefed<nsINode>
 nsINode::CloneNode(bool aDeep, ErrorResult& aError)
 {
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -362,31 +362,35 @@ public:
    * type, such as Text, Document, Comment ...  Use this when you can instead of
    * checking the tag.
    *
    * @param aFlags what types you want to test for (see above)
    * @return whether the content matches ALL flags passed in
    */
   virtual bool IsNodeOfType(uint32_t aFlags) const = 0;
 
-  virtual JSObject* WrapObject(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   /**
    * returns true if we are in priviliged code or
    * layout.css.getBoxQuads.enabled == true.
    */
   static bool HasBoxQuadsSupport(JSContext* aCx, JSObject* /* unused */);
 
 protected:
   /**
    * WrapNode is called from WrapObject to actually wrap this node, WrapObject
    * does some additional checks and fix-up that's common to all nodes. WrapNode
    * should just call the DOM binding's Wrap function.
+   *
+   * aGivenProto is the prototype to use (or null if the default one should be
+   * used) and should just be passed directly on to the DOM binding's Wrap
+   * function.
    */
-  virtual JSObject* WrapNode(JSContext *aCx) = 0;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) = 0;
 
 public:
   mozilla::dom::ParentObject GetParentObject() const; // Implemented in nsIDocument.h
 
   /**
    * Return the scope chain parent for this node, for use in things
    * like event handler compilation.  Returning null means to use the
    * global object as the scope chain parent.
--- a/dom/base/nsInProcessTabChildGlobal.cpp
+++ b/dom/base/nsInProcessTabChildGlobal.cpp
@@ -96,16 +96,17 @@ nsInProcessTabChildGlobal::DoSendAsyncMe
   NS_DispatchToCurrentThread(ev);
   return true;
 }
 
 nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell,
                                                      nsIContent* aOwner,
                                                      nsFrameMessageManager* aChrome)
 : mDocShell(aShell), mInitialized(false), mLoadingScript(false),
+  mPreventEventsEscaping(false),
   mOwner(aOwner), mChromeMessageManager(aChrome)
 {
   SetIsNotDOMBinding();
   mozilla::HoldJSObjects(this);
 
   // If owner corresponds to an <iframe mozbrowser> or <iframe mozapp>, we'll
   // have to tweak our PreHandleEvent implementation.
   nsCOMPtr<nsIMozBrowserFrame> browserFrame = do_QueryInterface(mOwner);
@@ -202,89 +203,100 @@ nsInProcessTabChildGlobal::GetContent(ns
 NS_IMETHODIMP
 nsInProcessTabChildGlobal::GetDocShell(nsIDocShell** aDocShell)
 {
   NS_IF_ADDREF(*aDocShell = mDocShell);
   return NS_OK;
 }
 
 void
-nsInProcessTabChildGlobal::Disconnect()
+nsInProcessTabChildGlobal::FireUnloadEvent()
 {
-  // Let the frame scripts know the child is being closed. We do any other
-  // cleanup after the event has been fired. See DelayedDisconnect
-  nsContentUtils::AddScriptRunner(
-     NS_NewRunnableMethod(this, &nsInProcessTabChildGlobal::DelayedDisconnect)
-  );
+  // We're called from nsDocument::MaybeInitializeFinalizeFrameLoaders, so it
+  // should be safe to run script.
+  MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
+
+  // Don't let the unload event propagate to chrome event handlers.
+  mPreventEventsEscaping = true;
+  DOMEventTargetHelper::DispatchTrustedEvent(NS_LITERAL_STRING("unload"));
+
+  // Allow events fired during docshell destruction (pagehide, unload) to
+  // propagate to the <browser> element since chrome code depends on this.
+  mPreventEventsEscaping = false;
 }
 
 void
-nsInProcessTabChildGlobal::DelayedDisconnect()
+nsInProcessTabChildGlobal::DisconnectEventListeners()
 {
-  // Don't let the event escape
-  mOwner = nullptr;
-
-  // Fire the "unload" event
-  DOMEventTargetHelper::DispatchTrustedEvent(NS_LITERAL_STRING("unload"));
-
-  // Continue with the Disconnect cleanup
   if (mDocShell) {
     nsCOMPtr<nsPIDOMWindow> win = mDocShell->GetWindow();
     if (win) {
       MOZ_ASSERT(win->IsOuterWindow());
       win->SetChromeEventHandler(win->GetChromeEventHandler());
     }
   }
+  if (mListenerManager) {
+    mListenerManager->Disconnect();
+  }
+
   mDocShell = nullptr;
+}
+
+void
+nsInProcessTabChildGlobal::Disconnect()
+{
   mChromeMessageManager = nullptr;
+  mOwner = nullptr;
   if (mMessageManager) {
     static_cast<nsFrameMessageManager*>(mMessageManager.get())->Disconnect();
     mMessageManager = nullptr;
   }
-  if (mListenerManager) {
-    mListenerManager->Disconnect();
-  }
 }
 
 NS_IMETHODIMP_(nsIContent *)
 nsInProcessTabChildGlobal::GetOwnerContent()
 {
   return mOwner;
 }
 
 nsresult
 nsInProcessTabChildGlobal::PreHandleEvent(EventChainPreVisitor& aVisitor)
 {
   aVisitor.mCanHandle = true;
 
-  if (mIsBrowserOrAppFrame &&
-      (!mOwner || !nsContentUtils::IsInChromeDocshell(mOwner->OwnerDoc()))) {
-    if (mOwner) {
-      nsPIDOMWindow* innerWindow = mOwner->OwnerDoc()->GetInnerWindow();
-      if (innerWindow) {
-        aVisitor.mParentTarget = innerWindow->GetParentTarget();
-      }
-    }
-  } else {
-    aVisitor.mParentTarget = mOwner;
-  }
-
 #ifdef DEBUG
   if (mOwner) {
     nsCOMPtr<nsIFrameLoaderOwner> owner = do_QueryInterface(mOwner);
     nsRefPtr<nsFrameLoader> fl = owner->GetFrameLoader();
     if (fl) {
       NS_ASSERTION(this == fl->GetTabChildGlobalAsEventTarget(),
                    "Wrong event target!");
       NS_ASSERTION(fl->mMessageManager == mChromeMessageManager,
                    "Wrong message manager!");
     }
   }
 #endif
 
+  if (mPreventEventsEscaping) {
+    aVisitor.mParentTarget = nullptr;
+    return NS_OK;
+  }
+
+  if (mIsBrowserOrAppFrame &&
+      (!mOwner || !nsContentUtils::IsInChromeDocshell(mOwner->OwnerDoc()))) {
+    if (mOwner) {
+      nsPIDOMWindow* innerWindow = mOwner->OwnerDoc()->GetInnerWindow();
+      if (innerWindow) {
+        aVisitor.mParentTarget = innerWindow->GetParentTarget();
+      }
+    }
+  } else {
+    aVisitor.mParentTarget = mOwner;
+  }
+
   return NS_OK;
 }
 
 nsresult
 nsInProcessTabChildGlobal::InitTabChildGlobal()
 {
   // If you change this, please change GetCompartmentName() in XPCJSRuntime.cpp
   // accordingly.
--- a/dom/base/nsInProcessTabChildGlobal.h
+++ b/dom/base/nsInProcessTabChildGlobal.h
@@ -1,9 +1,9 @@
-/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
+/* -*- Mode: C++; c-basic-offset: 2; 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/. */
 
 #ifndef nsInProcessTabChildGlobal_h
 #define nsInProcessTabChildGlobal_h
 
@@ -113,16 +113,18 @@ public:
                                                            aWantsUntrusted,
                                                            optional_argc);
   }
   using mozilla::DOMEventTargetHelper::AddEventListener;
 
   virtual JSContext* GetJSContextForEventHandlers() MOZ_OVERRIDE { return nsContentUtils::GetSafeJSContext(); }
   virtual nsIPrincipal* GetPrincipal() MOZ_OVERRIDE { return mPrincipal; }
   void LoadFrameScript(const nsAString& aURL, bool aRunInGlobalScope);
+  void FireUnloadEvent();
+  void DisconnectEventListeners();
   void Disconnect();
   void SendMessageToParent(const nsString& aMessage, bool aSync,
                            const nsString& aJSON,
                            nsTArray<nsString>* aJSONRetVal);
   nsFrameMessageManager* GetInnerManager()
   {
     return static_cast<nsFrameMessageManager*>(mMessageManager.get());
   }
@@ -132,26 +134,24 @@ public:
   {
     return mChromeMessageManager;
   }
   void SetChromeMessageManager(nsFrameMessageManager* aParent)
   {
     mChromeMessageManager = aParent;
   }
 
-  void DelayedDisconnect();
-
   virtual JSObject* GetGlobalJSObject() MOZ_OVERRIDE {
     if (!mGlobal) {
       return nullptr;
     }
 
     return mGlobal->GetJSObject();
   }
-  virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
     MOZ_CRASH("nsInProcessTabChildGlobal doesn't use DOM bindings!");
   }
 protected:
   virtual ~nsInProcessTabChildGlobal();
 
   nsresult Init();
   nsresult InitTabChildGlobal();
@@ -159,15 +159,16 @@ protected:
   nsCOMPtr<nsIDocShell> mDocShell;
   bool mInitialized;
   bool mLoadingScript;
 
   // Is this the message manager for an in-process <iframe mozbrowser> or
   // <iframe mozapp>?  This affects where events get sent, so it affects
   // PreHandleEvent.
   bool mIsBrowserOrAppFrame;
+  bool mPreventEventsEscaping;
 public:
   nsIContent* mOwner;
   nsFrameMessageManager* mChromeMessageManager;
   nsTArray<nsCOMPtr<nsIRunnable> > mASyncMessages;
 };
 
 #endif
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -2468,17 +2468,17 @@ NS_DOMReadStructuredClone(JSContext* cx,
 
     // Prevent the return value from being trashed by a GC during ~nsRefPtr.
     JS::Rooted<JSObject*> result(cx);
     {
       nsRefPtr<CryptoKey> key = new CryptoKey(global);
       if (!key->ReadStructuredClone(reader)) {
         result = nullptr;
       } else {
-        result = key->WrapObject(cx);
+        result = key->WrapObject(cx, JS::NullPtr());
       }
     }
     return result;
   } else if (tag == SCTAG_DOM_NULL_PRINCIPAL ||
              tag == SCTAG_DOM_SYSTEM_PRINCIPAL ||
              tag == SCTAG_DOM_CONTENT_PRINCIPAL) {
     mozilla::ipc::PrincipalInfo info;
     if (tag == SCTAG_DOM_SYSTEM_PRINCIPAL) {
@@ -2524,17 +2524,17 @@ NS_DOMReadStructuredClone(JSContext* cx,
       return nullptr;
     }
 
     // Prevent the return value from being trashed by a GC during ~nsRefPtr.
     JS::Rooted<JSObject*> result(cx);
     {
       nsRefPtr<MozNDEFRecord> ndefRecord = new MozNDEFRecord(global);
       result = ndefRecord->ReadStructuredClone(cx, reader) ?
-               ndefRecord->WrapObject(cx) : nullptr;
+               ndefRecord->WrapObject(cx, JS::NullPtr()) : nullptr;
     }
     return result;
 #else
     return nullptr;
 #endif
   }
 
   // Don't know what this is. Bail.
--- a/dom/base/nsLocation.cpp
+++ b/dom/base/nsLocation.cpp
@@ -1048,19 +1048,19 @@ nsLocation::CallerSubsumes()
   nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(outer);
   bool subsumes = false;
   nsresult rv = nsContentUtils::SubjectPrincipal()->SubsumesConsideringDomain(sop->GetPrincipal(), &subsumes);
   NS_ENSURE_SUCCESS(rv, false);
   return subsumes;
 }
 
 JSObject*
-nsLocation::WrapObject(JSContext* aCx)
+nsLocation::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return LocationBinding::Wrap(aCx, this);
+  return LocationBinding::Wrap(aCx, this, aGivenProto);
 }
 
 URLSearchParams*
 nsLocation::GetDocShellSearchParams()
 {
   nsCOMPtr<nsIDocShell> docShell = GetDocShell();
   if (!docShell) {
     return nullptr;
--- a/dom/base/nsLocation.h
+++ b/dom/base/nsLocation.h
@@ -137,17 +137,17 @@ public:
   void Stringify(nsAString& aRetval, ErrorResult& aError)
   {
     GetHref(aRetval, aError);
   }
   nsPIDOMWindow* GetParentObject() const
   {
     return mInnerWindow;
   }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // URLSearchParamsObserver
   void URLSearchParamsUpdated(mozilla::dom::URLSearchParams* aSearchParams) MOZ_OVERRIDE;
 
 protected:
   virtual ~nsLocation();
 
   nsresult SetSearchInternal(const nsAString& aSearch);
--- a/dom/base/nsMimeTypeArray.cpp
+++ b/dom/base/nsMimeTypeArray.cpp
@@ -35,19 +35,19 @@ nsMimeTypeArray::nsMimeTypeArray(nsPIDOM
 {
 }
 
 nsMimeTypeArray::~nsMimeTypeArray()
 {
 }
 
 JSObject*
-nsMimeTypeArray::WrapObject(JSContext* aCx)
+nsMimeTypeArray::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MimeTypeArrayBinding::Wrap(aCx, this);
+  return MimeTypeArrayBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 nsMimeTypeArray::Refresh()
 {
   mMimeTypes.Clear();
   mHiddenMimeTypes.Clear();
 }
@@ -249,19 +249,19 @@ nsMimeType::~nsMimeType()
 nsPIDOMWindow*
 nsMimeType::GetParentObject() const
 {
   MOZ_ASSERT(mWindow);
   return mWindow;
 }
 
 JSObject*
-nsMimeType::WrapObject(JSContext* aCx)
+nsMimeType::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MimeTypeBinding::Wrap(aCx, this);
+  return MimeTypeBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 nsMimeType::GetDescription(nsString& retval) const
 {
   retval.Truncate();
 
   if (mPluginElement) {
--- a/dom/base/nsMimeTypeArray.h
+++ b/dom/base/nsMimeTypeArray.h
@@ -21,17 +21,17 @@ class nsMimeTypeArray MOZ_FINAL : public
 {
 public:
   explicit nsMimeTypeArray(nsPIDOMWindow* aWindow);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsMimeTypeArray)
 
   nsPIDOMWindow* GetParentObject() const;
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void Refresh();
 
   // MimeTypeArray WebIDL methods
   nsMimeType* Item(uint32_t index);
   nsMimeType* NamedItem(const nsAString& name);
   nsMimeType* IndexedGetter(uint32_t index, bool &found);
   nsMimeType* NamedGetter(const nsAString& name, bool &found);
@@ -64,17 +64,17 @@ class nsMimeType MOZ_FINAL : public nsWr
 public:
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsMimeType)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(nsMimeType)
 
   nsMimeType(nsPIDOMWindow* aWindow, nsPluginElement* aPluginElement,
              uint32_t aPluginTagMimeIndex, const nsAString& aMimeType);
   nsMimeType(nsPIDOMWindow* aWindow, const nsAString& aMimeType);
   nsPIDOMWindow* GetParentObject() const;
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   const nsString& Type() const
   {
     return mType;
   }
 
   // MimeType WebIDL methods
   void GetDescription(nsString& retval) const;
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -514,19 +514,16 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
       nsPIDOMWindow* window = newDoc->GetInnerWindow();
       if (window) {
         EventListenerManager* elm = aNode->GetExistingListenerManager();
         if (elm) {
           window->SetMutationListeners(elm->MutationListenerBits());
           if (elm->MayHavePaintEventListener()) {
             window->SetHasPaintEventListeners();
           }
-          if (elm->MayHaveTouchEventListener()) {
-            window->SetHasTouchEventListeners();
-          }
           if (elm->MayHaveMouseEnterLeaveEventListener()) {
             window->SetHasMouseEnterLeaveEventListeners();
           }
           if (elm->MayHavePointerEnterLeaveEventListener()) {
             window->SetHasPointerEnterLeaveEventListeners();
           }
         }
       }
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -58,18 +58,18 @@ enum PopupControlState {
 enum UIStateChangeType
 {
   UIStateChangeType_NoChange,
   UIStateChangeType_Set,
   UIStateChangeType_Clear
 };
 
 #define NS_PIDOMWINDOW_IID \
-{ 0x19fb3019, 0x7b5d, 0x4235, \
-  { 0xa9, 0x59, 0xa2, 0x31, 0xa2, 0xe7, 0x94, 0x79 } }
+{ 0x4178bd68, 0xa3f7, 0x4ff7, \
+  { 0xa6, 0x27, 0x4a, 0x99, 0xa1, 0xe0, 0x42, 0x37 } }
 
 class nsPIDOMWindow : public nsIDOMWindowInternal
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMWINDOW_IID)
 
   virtual nsPIDOMWindow* GetPrivateRoot() = 0;
 
@@ -155,19 +155,16 @@ public:
       NS_ERROR("HasMutationListeners() called on orphan inner window!");
 
       return;
     }
 
     mMutationBits |= aType;
   }
 
-  virtual void MaybeUpdateTouchState() {}
-  virtual void UpdateTouchState() {}
-
   nsIDocument* GetExtantDoc() const
   {
     return mDoc;
   }
   nsIURI* GetDocumentURI() const;
   nsIURI* GetDocBaseURI() const;
 
   nsIDocument* GetDoc()
@@ -435,31 +432,16 @@ public:
    * or content in that document) has a paint event listener.
    */
   bool HasPaintEventListeners()
   {
     return mMayHavePaintEventListener;
   }
   
   /**
-   * Call this to indicate that some node (this window, its document,
-   * or content in that document) has a touch event listener.
-   */
-  void SetHasTouchEventListeners()
-  {
-    mMayHaveTouchEventListener = true;
-    MaybeUpdateTouchState();
-  }
-
-  bool HasTouchEventListeners()
-  {
-    return mMayHaveTouchEventListener;
-  }
-
-  /**
    * Moves the top-level window into fullscreen mode if aIsFullScreen is true,
    * otherwise exits fullscreen. If aRequireTrust is true, this method only
    * changes window state in a context trusted for write.
    *
    * If aHMD is not null, the window is made full screen on the given VR HMD
    * device instead of its currrent display.
    *
    * Outer windows only.
@@ -769,17 +751,16 @@ protected:
   nsTimeout             *mRunningTimeout;
 
   uint32_t               mMutationBits;
 
   bool                   mIsDocumentLoaded;
   bool                   mIsHandlingResizeEvent;
   bool                   mIsInnerWindow;
   bool                   mMayHavePaintEventListener;
-  bool                   mMayHaveTouchEventListener;
   bool                   mMayHaveMouseEnterLeaveEventListener;
   bool                   mMayHavePointerEnterLeaveEventListener;
 
   // This variable is used on both inner and outer windows (and they
   // should match).
   bool                   mIsModalContentWindow;
 
   // Tracks activation state that's used for :-moz-window-inactive.
--- a/dom/base/nsPerformance.cpp
+++ b/dom/base/nsPerformance.cpp
@@ -356,19 +356,19 @@ nsPerformanceTiming::ResponseEnd()
 
 bool
 nsPerformanceTiming::IsInitialized() const
 {
   return mInitialized;
 }
 
 JSObject*
-nsPerformanceTiming::WrapObject(JSContext *cx)
+nsPerformanceTiming::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PerformanceTimingBinding::Wrap(cx, this);
+  return PerformanceTimingBinding::Wrap(cx, this, aGivenProto);
 }
 
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsPerformanceNavigation, mPerformance)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsPerformanceNavigation, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsPerformanceNavigation, Release)
 
@@ -378,19 +378,19 @@ nsPerformanceNavigation::nsPerformanceNa
   MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
 }
 
 nsPerformanceNavigation::~nsPerformanceNavigation()
 {
 }
 
 JSObject*
-nsPerformanceNavigation::WrapObject(JSContext *cx)
+nsPerformanceNavigation::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PerformanceNavigationBinding::Wrap(cx, this);
+  return PerformanceNavigationBinding::Wrap(cx, this, aGivenProto);
 }
 
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(nsPerformance, DOMEventTargetHelper,
                                    mWindow, mTiming,
                                    mNavigation, mEntries,
                                    mParentPerformance)
 NS_IMPL_ADDREF_INHERITED(nsPerformance, DOMEventTargetHelper)
@@ -461,19 +461,19 @@ nsPerformance::Navigation()
 
 DOMHighResTimeStamp
 nsPerformance::Now()
 {
   return GetDOMTiming()->TimeStampToDOMHighRes(TimeStamp::Now());
 }
 
 JSObject*
-nsPerformance::WrapObject(JSContext *cx)
+nsPerformance::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PerformanceBinding::Wrap(cx, this);
+  return PerformanceBinding::Wrap(cx, this, aGivenProto);
 }
 
 void
 nsPerformance::GetEntries(nsTArray<nsRefPtr<PerformanceEntry> >& retval)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   retval = mEntries;
--- a/dom/base/nsPerformance.h
+++ b/dom/base/nsPerformance.h
@@ -112,17 +112,17 @@ public:
   inline DOMHighResTimeStamp TimeStampToDOMHighRes(TimeStamp aStamp) const
   {
     MOZ_ASSERT(!aStamp.IsNull());
     mozilla::TimeDuration duration =
         aStamp - GetDOMTiming()->GetNavigationStartTimeStamp();
     return duration.ToMilliseconds() + mZeroTime;
   }
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // PerformanceNavigation WebIDL methods
   DOMTimeMilliSec NavigationStart() const {
     if (!nsContentUtils::IsPerformanceTimingEnabled()) {
       return 0;
     }
     return GetDOMTiming()->GetNavigationStart();
   }
@@ -266,17 +266,17 @@ public:
   nsDOMNavigationTiming* GetDOMTiming() const;
   nsPerformanceTiming* GetPerformanceTiming() const;
 
   nsPerformance* GetParentObject() const
   {
     return mPerformance;
   }
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // PerformanceNavigation WebIDL methods
   uint16_t Type() const {
     return GetDOMTiming()->GetType();
   }
   uint16_t RedirectCount() const {
     return GetPerformanceTiming()->GetRedirectCount();
   }
@@ -314,17 +314,17 @@ public:
     return mParentPerformance;
   }
 
   nsPIDOMWindow* GetParentObject() const
   {
     return mWindow.get();
   }
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // Performance WebIDL methods
   DOMHighResTimeStamp Now();
   nsPerformanceTiming* Timing();
   nsPerformanceNavigation* Navigation();
 
   void GetEntries(nsTArray<nsRefPtr<PerformanceEntry> >& retval);
   void GetEntriesByType(const nsAString& entryType,
--- a/dom/base/nsPluginArray.cpp
+++ b/dom/base/nsPluginArray.cpp
@@ -46,19 +46,19 @@ nsPluginArray::~nsPluginArray()
 nsPIDOMWindow*
 nsPluginArray::GetParentObject() const
 {
   MOZ_ASSERT(mWindow);
   return mWindow;
 }
 
 JSObject*
-nsPluginArray::WrapObject(JSContext* aCx)
+nsPluginArray::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PluginArrayBinding::Wrap(aCx, this);
+  return PluginArrayBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPluginArray)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPluginArray)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPluginArray)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
@@ -394,19 +394,19 @@ nsPluginElement::~nsPluginElement()
 nsPIDOMWindow*
 nsPluginElement::GetParentObject() const
 {
   MOZ_ASSERT(mWindow);
   return mWindow;
 }
 
 JSObject*
-nsPluginElement::WrapObject(JSContext* aCx)
+nsPluginElement::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PluginBinding::Wrap(aCx, this);
+  return PluginBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 nsPluginElement::GetDescription(nsString& retval) const
 {
   CopyUTF8toUTF16(mPluginTag->mDescription, retval);
 }
 
--- a/dom/base/nsPluginArray.h
+++ b/dom/base/nsPluginArray.h
@@ -26,17 +26,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsPluginArray,
                                                          nsIObserver)
 
   // nsIObserver
   NS_DECL_NSIOBSERVER
 
   explicit nsPluginArray(nsPIDOMWindow* aWindow);
   nsPIDOMWindow* GetParentObject() const;
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // nsPluginArray registers itself as an observer with a weak reference.
   // This can't be done in the constructor, because at that point its
   // refcount is 0 (and it gets destroyed upon registration). So, Init()
   // must be called after construction.
   void Init();
   void Invalidate();
 
@@ -80,17 +80,17 @@ class nsPluginElement MOZ_FINAL : public
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsPluginElement)
 
   nsPluginElement(nsPIDOMWindow* aWindow, nsPluginTag* aPluginTag);
 
   nsPIDOMWindow* GetParentObject() const;
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsPluginTag* PluginTag() const
   {
     return mPluginTag;
   }
 
   // Plugin WebIDL methods
 
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -33,19 +33,19 @@
 #include "mozilla/Telemetry.h"
 #include "mozilla/Likely.h"
 #include "nsCSSFrameConstructor.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 JSObject*
-nsRange::WrapObject(JSContext* aCx)
+nsRange::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return RangeBinding::Wrap(aCx, this);
+  return RangeBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /******************************************************
  * stack based utilty class for managing monitor
  ******************************************************/
 
 static void InvalidateAllFrames(nsINode* aNode)
 {
--- a/dom/base/nsRange.h
+++ b/dom/base/nsRange.h
@@ -239,17 +239,17 @@ public:
   void SetStartBefore(nsINode& aNode, ErrorResult& aErr);
   void SurroundContents(nsINode& aNode, ErrorResult& aErr);
   already_AddRefed<DOMRect> GetBoundingClientRect(bool aClampToEdge = true,
                                                   bool aFlushLayout = true);
   already_AddRefed<DOMRectList> GetClientRects(bool aClampToEdge = true,
                                                bool aFlushLayout = true);
 
   nsINode* GetParentObject() const { return mOwner; }
-  virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE MOZ_FINAL;
+  virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE MOZ_FINAL;
 
 private:
   // no copy's or assigns
   nsRange(const nsRange&);
   nsRange& operator=(const nsRange&);
 
   /**
    * Cut or delete the range's contents.
--- a/dom/base/nsScreen.cpp
+++ b/dom/base/nsScreen.cpp
@@ -330,19 +330,19 @@ nsScreen::IsDeviceSizePageSize()
       return docShell->GetDeviceSizeIsPageSize();
     }
   }
   return false;
 }
 
 /* virtual */
 JSObject*
-nsScreen::WrapObject(JSContext* aCx)
+nsScreen::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return ScreenBinding::Wrap(aCx, this);
+  return ScreenBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_ISUPPORTS(nsScreen::FullScreenEventListener, nsIDOMEventListener)
 
 NS_IMETHODIMP
 nsScreen::FullScreenEventListener::HandleEvent(nsIDOMEvent* aEvent)
 {
 #ifdef DEBUG
--- a/dom/base/nsScreen.h
+++ b/dom/base/nsScreen.h
@@ -117,17 +117,17 @@ public:
   void GetMozOrientation(nsString& aOrientation);
 
   IMPL_EVENT_HANDLER(mozorientationchange)
 
   bool MozLockOrientation(const nsAString& aOrientation, ErrorResult& aRv);
   bool MozLockOrientation(const mozilla::dom::Sequence<nsString>& aOrientations, ErrorResult& aRv);
   void MozUnlockOrientation();
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void Notify(const mozilla::hal::ScreenConfiguration& aConfiguration) MOZ_OVERRIDE;
 
 protected:
   nsDeviceContext* GetDeviceContext();
   nsresult GetRect(nsRect& aRect);
   nsresult GetAvailRect(nsRect& aRect);
 
--- a/dom/base/nsTextNode.cpp
+++ b/dom/base/nsTextNode.cpp
@@ -95,19 +95,19 @@ private:
 nsTextNode::~nsTextNode()
 {
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(nsTextNode, nsGenericDOMDataNode, nsIDOMNode,
                             nsIDOMText, nsIDOMCharacterData)
 
 JSObject*
-nsTextNode::WrapNode(JSContext *aCx)
+nsTextNode::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return TextBinding::Wrap(aCx, this);
+  return TextBinding::Wrap(aCx, this, aGivenProto);
 }
 
 bool
 nsTextNode::IsNodeOfType(uint32_t aFlags) const
 {
   return !(aFlags & ~(eCONTENT | eTEXT | eDATA_NODE));
 }
 
--- a/dom/base/nsTextNode.h
+++ b/dom/base/nsTextNode.h
@@ -76,12 +76,12 @@ public:
 #ifdef DEBUG
   virtual void List(FILE* out, int32_t aIndent) const MOZ_OVERRIDE;
   virtual void DumpContent(FILE* out, int32_t aIndent, bool aDumpAll) const MOZ_OVERRIDE;
 #endif
 
 protected:
   virtual ~nsTextNode();
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 };
 
 #endif // nsTextNode_h
--- a/dom/base/nsWindowRoot.cpp
+++ b/dom/base/nsWindowRoot.cpp
@@ -365,19 +365,19 @@ nsWindowRoot::SetPopupNode(nsIDOMNode* a
 
 nsIGlobalObject*
 nsWindowRoot::GetParentObject()
 {
   return xpc::NativeGlobal(xpc::PrivilegedJunkScope());
 }
 
 JSObject*
-nsWindowRoot::WrapObject(JSContext* aCx)
+nsWindowRoot::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::WindowRootBinding::Wrap(aCx, this);
+  return mozilla::dom::WindowRootBinding::Wrap(aCx, this, aGivenProto);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////
 
 already_AddRefed<EventTarget>
 NS_NewWindowRoot(nsPIDOMWindow* aWindow)
 {
   nsCOMPtr<EventTarget> result = new nsWindowRoot(aWindow);
--- a/dom/base/nsWindowRoot.h
+++ b/dom/base/nsWindowRoot.h
@@ -64,17 +64,17 @@ public:
   {
     mParent = aTarget;
   }
   virtual mozilla::dom::EventTarget* GetParentTarget() MOZ_OVERRIDE { return mParent; }
   virtual nsIDOMWindow* GetOwnerGlobal() MOZ_OVERRIDE;
 
   nsIGlobalObject* GetParentObject();
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsWindowRoot,
                                                          nsIDOMEventTarget)
 
 protected:
   virtual ~nsWindowRoot();
 
   void GetEnabledDisabledCommandsForControllers(nsIControllers* aControllers,
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -147,17 +147,17 @@ public:
   {
     return !HasWrapperFlag(WRAPPER_IS_NOT_DOM_BINDING);
   }
 
   /**
    * Wrap the object corresponding to this wrapper cache. If non-null is
    * returned, the object has already been stored in the wrapper cache.
    */
-  virtual JSObject* WrapObject(JSContext* cx) = 0;
+  virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) = 0;
 
   /**
    * Returns true if the object has a non-gray wrapper.
    */
   bool IsBlack();
 
   /**
    * Returns true if the object has a black wrapper,
--- a/dom/base/nsXMLHttpRequest.cpp
+++ b/dom/base/nsXMLHttpRequest.cpp
@@ -270,19 +270,19 @@ nsXHREventTarget::DisconnectFromOwner()
 NS_INTERFACE_MAP_BEGIN(nsXMLHttpRequestUpload)
   NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequestUpload)
 NS_INTERFACE_MAP_END_INHERITING(nsXHREventTarget)
 
 NS_IMPL_ADDREF_INHERITED(nsXMLHttpRequestUpload, nsXHREventTarget)
 NS_IMPL_RELEASE_INHERITED(nsXMLHttpRequestUpload, nsXHREventTarget)
 
 /* virtual */ JSObject*
-nsXMLHttpRequestUpload::WrapObject(JSContext* aCx)
+nsXMLHttpRequestUpload::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return XMLHttpRequestUploadBinding::Wrap(aCx, this);
+  return XMLHttpRequestUploadBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /////////////////////////////////////////////
 //
 //
 /////////////////////////////////////////////
 
 bool
--- a/dom/base/nsXMLHttpRequest.h
+++ b/dom/base/nsXMLHttpRequest.h
@@ -155,17 +155,17 @@ public:
   {
   }
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_FORWARD_NSIXMLHTTPREQUESTEVENTTARGET(nsXHREventTarget::)
   NS_REALLY_FORWARD_NSIDOMEVENTTARGET(nsXHREventTarget)
   NS_DECL_NSIXMLHTTPREQUESTUPLOAD
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   nsISupports* GetParentObject()
   {
     return GetOwner();
   }
 
   bool HasListeners()
   {
     return mListenerManager && mListenerManager->HasListeners();
@@ -191,19 +191,19 @@ class nsXMLHttpRequest MOZ_FINAL : publi
                                    public nsISizeOfEventTarget
 {
   friend class nsXHRParseEndListener;
   friend class nsXMLHttpRequestXPCOMifier;
 
 public:
   nsXMLHttpRequest();
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return mozilla::dom::XMLHttpRequestBinding::Wrap(cx, this);
+    return mozilla::dom::XMLHttpRequestBinding::Wrap(cx, this, aGivenProto);
   }
   nsISupports* GetParentObject()
   {
     return GetOwner();
   }
 
   // The WebIDL constructors.
   static already_AddRefed<nsXMLHttpRequest>
--- a/dom/base/test/browser.ini
+++ b/dom/base/test/browser.ini
@@ -1,12 +1,17 @@
 [DEFAULT]
+support-files =
+  file_messagemanager_unload.html
 
 [browser_bug593387.js]
 skip-if = e10s # Bug ?????? - test directly touches content (contentWindow.iframe.addEventListener)
 [browser_bug902350.js]
 skip-if = e10s # Bug ?????? - test e10s utils don't support load events from iframe etc, which this test relies on.
 [browser_messagemanager_loadprocessscript.js]
+[browser_pagehide_on_tab_close.js]
+skip-if = e10s # this tests non-e10s behavior. it's not expected to work in e10s.
+[browser_messagemanager_unload.js]
 [browser_state_notifications.js]
 # skip-if = e10s # Bug ?????? - content-document-* notifications come while document's URI is still about:blank, but test expects real URL.
 skip-if = true # Intermittent failures - bug 987493. Restore the skip-if above once fixed
 [browser_bug1058164.js]
 skip-if = e10s # We need bug 918634 to land before this can be tested with e10s.
new file mode 100644
--- /dev/null
+++ b/dom/base/test/browser_messagemanager_unload.js
@@ -0,0 +1,98 @@
+function frameScript()
+{
+  Components.utils.import("resource://gre/modules/Services.jsm");
+
+  function eventHandler(e) {
+    if (!docShell) {
+      sendAsyncMessage("Test:Fail", "docShell is null");
+    }
+
+    sendAsyncMessage("Test:Event", [e.type, e.target === content.document, e.eventPhase]);
+  }
+
+  let outerID = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
+        getInterface(Components.interfaces.nsIDOMWindowUtils).outerWindowID;
+  function onOuterWindowDestroyed(subject, topic, data) {
+    if (docShell) {
+      sendAsyncMessage("Test:Fail", "docShell is non-null");
+    }
+
+    let id = subject.QueryInterface(Components.interfaces.nsISupportsPRUint64).data;
+    sendAsyncMessage("Test:Event", ["outer-window-destroyed", id == outerID]);
+    if (id == outerID) {
+      Services.obs.removeObserver(onOuterWindowDestroyed, "outer-window-destroyed");
+    }
+  }
+
+  let url = "https://example.com/browser/dom/base/test/file_messagemanager_unload.html";
+
+  content.location = url;
+  addEventListener("load", (e) => {
+    if (e.target.location != url) {
+      return;
+    }
+
+    addEventListener("unload", eventHandler, false);
+    addEventListener("unload", eventHandler, true);
+    addEventListener("pagehide", eventHandler, false);
+    addEventListener("pagehide", eventHandler, true);
+    Services.obs.addObserver(onOuterWindowDestroyed, "outer-window-destroyed", false);
+
+    sendAsyncMessage("Test:Ready");
+  }, true);
+}
+
+const EXPECTED = [
+  // Unload events on the TabChildGlobal. These come first so that the
+  // docshell is available.
+  ["unload", false, 2],
+  ["unload", false, 2],
+
+  // pagehide and unload events for the top-level page.
+  ["pagehide", true, 1],
+  ["pagehide", true, 3],
+  ["unload", true, 1],
+
+  // pagehide and unload events for the iframe.
+  ["pagehide", false, 1],
+  ["pagehide", false, 3],
+  ["unload", false, 1],
+
+  // outer-window-destroyed for both pages.
+  ["outer-window-destroyed", false],
+  ["outer-window-destroyed", true],
+];
+
+function test() {
+  waitForExplicitFinish();
+
+  var newTab = gBrowser.addTab("about:blank");
+  gBrowser.selectedTab = newTab;
+
+  let browser = newTab.linkedBrowser;
+
+  browser.messageManager.loadFrameScript("data:,(" + frameScript.toString() + ")()", false);
+
+  browser.messageManager.addMessageListener("Test:Fail", (msg) => {
+    ok(false, msg.data);
+  }, true);
+
+  let index = 0;
+  browser.messageManager.addMessageListener("Test:Event", (msg) => {
+    ok(msg.target === browser, "<browser> is correct");
+
+    info(JSON.stringify(msg.data));
+
+    is(JSON.stringify(msg.data), JSON.stringify(EXPECTED[index]), "results match");
+    index++;
+
+    if (index == EXPECTED.length) {
+      finish();
+    }
+  }, true);
+
+  browser.messageManager.addMessageListener("Test:Ready", () => {
+    info("Got ready message");
+    gBrowser.removeCurrentTab();
+  });
+}
new file mode 100644
--- /dev/null
+++ b/dom/base/test/browser_pagehide_on_tab_close.js
@@ -0,0 +1,17 @@
+function test() {
+  waitForExplicitFinish();
+
+  var tab = gBrowser.addTab();
+  gBrowser.selectedTab = tab;
+
+  tab.linkedBrowser.addEventListener("load", function onload() {
+    tab.linkedBrowser.removeEventListener("load", onload);
+
+    tab.linkedBrowser.addEventListener("pagehide", function() {
+      ok(true, "got page hide event");
+      finish();
+    });
+
+    executeSoon(() => { gBrowser.removeTab(tab); });
+  }, true);
+}
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_messagemanager_unload.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <iframe id="frame" src="about:robots"></iframe>
+  </body>
+</html>
--- a/dom/battery/BatteryManager.cpp
+++ b/dom/battery/BatteryManager.cpp
@@ -45,19 +45,19 @@ BatteryManager::Init()
 
 void
 BatteryManager::Shutdown()
 {
   hal::UnregisterBatteryObserver(this);
 }
 
 JSObject*
-BatteryManager::WrapObject(JSContext* aCx)
+BatteryManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BatteryManagerBinding::Wrap(aCx, this);
+  return BatteryManagerBinding::Wrap(aCx, this, aGivenProto);
 }
 
 double
 BatteryManager::DischargingTime() const
 {
   if (mCharging || mRemainingTime == kUnknownRemainingTime) {
     return std::numeric_limits<double>::infinity();
   }
--- a/dom/battery/BatteryManager.h
+++ b/dom/battery/BatteryManager.h
@@ -39,17 +39,17 @@ public:
    * WebIDL Interface
    */
 
   nsPIDOMWindow* GetParentObject() const
   {
      return GetOwner();
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   bool Charging() const
   {
     return mCharging;
   }
 
   double ChargingTime() const;
 
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -747,17 +747,17 @@ NativeInterface2JSObjectAndThrowIfFailed
   nsresult rv;
   // Inline some logic from XPCConvert::NativeInterfaceToJSObject that we need
   // on all threads.
   nsWrapperCache *cache = aHelper.GetWrapperCache();
 
   if (cache && cache->IsDOMBinding()) {
       JS::Rooted<JSObject*> obj(aCx, cache->GetWrapper());
       if (!obj) {
-          obj = cache->WrapObject(aCx);
+        obj = cache->WrapObject(aCx, JS::NullPtr());
       }
 
       if (obj && aAllowNativeWrapper && !JS_WrapObject(aCx, &obj)) {
         return false;
       }
 
       if (obj) {
         aRetval.setObject(*obj);
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -925,17 +925,17 @@ DoGetOrCreateDOMReflector(JSContext* cx,
   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);
+    obj = value->WrapObject(cx, JS::NullPtr());
     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;
     }
   }
 
@@ -1033,17 +1033,17 @@ WrapNewBindingNonWrapperCachedObject(JSC
     if (js::IsWrapper(scope)) {
       scope = js::CheckedUnwrap(scope, /* stopAtOuter = */ false);
       if (!scope)
         return false;
       ac.emplace(cx, scope);
     }
 
     MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
-    if (!value->WrapObject(cx, &obj)) {
+    if (!value->WrapObject(cx, JS::NullPtr(), &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);
@@ -1079,17 +1079,17 @@ WrapNewBindingNonWrapperCachedObject(JSC
     if (js::IsWrapper(scope)) {
       scope = js::CheckedUnwrap(scope, /* stopAtOuter = */ false);
       if (!scope)
         return false;
       ac.emplace(cx, scope);
     }
 
     MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
-    if (!value->WrapObject(cx, &obj)) {
+    if (!value->WrapObject(cx, JS::NullPtr(), &obj)) {
       return false;
     }
 
     value.forget();
   }
 
   // We can end up here in all sorts of compartments, per above.  Make
   // sure to JS_WrapValue!
@@ -1515,17 +1515,17 @@ struct WrapNativeParentHelper
     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, parent, cache);
     } else {
-      obj = parent->WrapObject(cx);
+      obj = parent->WrapObject(cx, JS::NullPtr());
     }
 
     return obj;
   }
 };
 
 // Wrapping of our native parent, for cases when it's not a WebIDL object.  In
 // this case it must be nsISupports.
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -3177,21 +3177,18 @@ def CopyUnforgeablePropertiesToInstance(
     # unforgeable holder for those with the right JSClass.  Luckily, there
     # aren't too many globals being created.
     if descriptor.isGlobal():
         copyFunc = "JS_CopyPropertiesFrom"
     else:
         copyFunc = "JS_InitializePropertiesFromCompatibleNativeObject"
     copyCode.append(CGGeneric(fill(
         """
-        // XXXbz Once we allow subclassing, we'll want to make sure that
-        // this uses the canonical proto, not whatever random passed-in
-        // proto we end up using for the object.
         JS::Rooted<JSObject*> unforgeableHolder(aCx,
-          &js::GetReservedSlot(proto, DOM_INTERFACE_PROTO_SLOTS_BASE).toObject());
+          &js::GetReservedSlot(canonicalProto, DOM_INTERFACE_PROTO_SLOTS_BASE).toObject());
         if (!${copyFunc}(aCx, ${obj}, unforgeableHolder)) {
           $*{cleanup}
           return false;
         }
         """,
         copyFunc=copyFunc,
         obj=obj,
         cleanup=cleanup)))
@@ -3238,124 +3235,150 @@ def InitMemberSlots(descriptor, wrapperC
         if (!UpdateMemberSlots(aCx, aReflector, aObject)) {
           $*{clearWrapper}
           return false;
         }
         """,
         clearWrapper=clearWrapper)
 
 
+def DeclareProto():
+    """
+    Declare the canonicalProto and proto we have for our wrapping operation.
+    """
+    return dedent(
+        """
+        JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx, global);
+        if (!canonicalProto) {
+          return false;
+        }
+        JS::Rooted<JSObject*> proto(aCx);
+        if (aGivenProto) {
+          proto = aGivenProto;
+          if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
+            if (!JS_WrapObject(aCx, &proto)) {
+              return false;
+            }
+          }
+        } else {
+          proto = canonicalProto;
+        }
+        """)
+
+
 class CGWrapWithCacheMethod(CGAbstractMethod):
     """
     Create a wrapper JSObject for a given native that implements nsWrapperCache.
 
     properties should be a PropertyArrays instance.
     """
     def __init__(self, descriptor, properties):
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
                 Argument(descriptor.nativeType + '*', 'aObject'),
                 Argument('nsWrapperCache*', 'aCache'),
+                Argument('JS::Handle<JSObject*>', 'aGivenProto'),
                 Argument('JS::MutableHandle<JSObject*>', 'aReflector')]
         CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'bool', args)
         self.properties = properties
 
     def definition_body(self):
         return fill(
             """
-            $*{assertion}
+            $*{assertInheritance}
+            MOZ_ASSERT_IF(aGivenProto, !aCache->GetWrapper());
 
             MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
                        "nsISupports must be on our primary inheritance chain");
 
             JS::Rooted<JSObject*> parent(aCx, WrapNativeParent(aCx, aObject->GetParentObject()));
             if (!parent) {
               return false;
             }
 
             // That might have ended up wrapping us already, due to the wonders
             // of XBL.  Check for that, and bail out as needed.
             aReflector.set(aCache->GetWrapper());
             if (aReflector) {
+              MOZ_ASSERT(!aGivenProto,
+                         "How are we supposed to change the proto now?");
               return true;
             }
 
             JSAutoCompartment ac(aCx, parent);
             JS::Rooted<JSObject*> global(aCx, js::GetGlobalForObjectCrossCompartment(parent));
-            JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx, global);
-            if (!proto) {
-              return false;
-            }
+            $*{declareProto}
 
             $*{createObject}
 
             aCache->SetWrapper(aReflector);
             $*{unforgeable}
             $*{slots}
             creator.InitializationSucceeded();
             return true;
             """,
-            assertion=AssertInheritanceChain(self.descriptor),
+            assertInheritance=AssertInheritanceChain(self.descriptor),
+            declareProto=DeclareProto(),
             createObject=CreateBindingJSObject(self.descriptor, self.properties),
             unforgeable=CopyUnforgeablePropertiesToInstance(self.descriptor, True),
             slots=InitMemberSlots(self.descriptor, True))
 
 
 class CGWrapMethod(CGAbstractMethod):
     def __init__(self, descriptor):
         # XXX can we wrap if we don't have an interface prototype object?
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
-                Argument('T*', 'aObject')]
+                Argument('T*', 'aObject'),
+                Argument('JS::Handle<JSObject*>', 'aGivenProto')]
         CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'JSObject*', args,
                                   inline=True, templateArgs=["class T"])
 
     def definition_body(self):
         return dedent("""
             JS::Rooted<JSObject*> reflector(aCx);
-            return Wrap(aCx, aObject, aObject, &reflector) ? reflector.get() : nullptr;
+            return Wrap(aCx, aObject, aObject, aGivenProto, &reflector) ? reflector.get() : nullptr;
             """)
 
 
 class CGWrapNonWrapperCacheMethod(CGAbstractMethod):
     """
     Create a wrapper JSObject for a given native that does not implement
     nsWrapperCache.
 
     properties should be a PropertyArrays instance.
     """
     def __init__(self, descriptor, properties):
         # XXX can we wrap if we don't have an interface prototype object?
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
                 Argument(descriptor.nativeType + '*', 'aObject'),
+                Argument('JS::Handle<JSObject*>', 'aGivenProto'),
                 Argument('JS::MutableHandle<JSObject*>', 'aReflector')]
         CGAbstractMethod.__init__(self, descriptor, 'Wrap', 'bool', args)
         self.properties = properties
 
     def definition_body(self):
         return fill(
             """
             $*{assertions}
 
             JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
-            JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx, global);
-            if (!proto) {
-              return false;
-            }
+            $*{declareProto}
 
             $*{createObject}
 
             $*{unforgeable}
 
             $*{slots}
             creator.InitializationSucceeded();
             return true;
             """,
             assertions=AssertInheritanceChain(self.descriptor),
+            declareProto=DeclareProto(),
             createObject=CreateBindingJSObject(self.descriptor, self.properties),
             unforgeable=CopyUnforgeablePropertiesToInstance(self.descriptor, False),
             slots=InitMemberSlots(self.descriptor, False))
 
 
 class CGWrapGlobalMethod(CGAbstractMethod):
     """
     Create a wrapper JSObject for a global.  The global must implement
@@ -3389,20 +3412,20 @@ class CGWrapGlobalMethod(CGAbstractMetho
         if self.descriptor.workers:
             fireOnNewGlobal = """// XXXkhuey can't do this yet until workers can lazy resolve.
 // JS_FireOnNewGlobalObject(aCx, aReflector);
 """
         else:
             fireOnNewGlobal = ""
 
         if self.descriptor.hasUnforgeableMembers:
-            declareProto = "JS::Handle<JSObject*> proto =\n"
+            declareProto = "JS::Handle<JSObject*> canonicalProto =\n"
             assertProto = (
-                "MOZ_ASSERT(proto &&\n"
-                "           IsDOMIfaceAndProtoClass(js::GetObjectClass(proto)));\n")
+                "MOZ_ASSERT(canonicalProto &&\n"
+                "           IsDOMIfaceAndProtoClass(js::GetObjectClass(canonicalProto)));\n")
         else:
             declareProto = ""
             assertProto = ""
 
         return fill(
             """
             $*{assertions}
             MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
@@ -13078,17 +13101,18 @@ class CGBindingImplClass(CGClass):
                     descriptor, FakeMember(),
                     "NameIsEnumerable",
                     (BuiltinTypes[IDLBuiltinType.Types.boolean],
                      [FakeArgument(BuiltinTypes[IDLBuiltinType.Types.domstring],
                                    FakeMember(),
                                    name="aName")]),
                     { "infallible": True }))
 
-        wrapArgs = [Argument('JSContext*', 'aCx')]
+        wrapArgs = [Argument('JSContext*', 'aCx'),
+                    Argument('JS::Handle<JSObject*>', 'aGivenProto')]
         self.methodDecls.insert(0,
                                 ClassMethod(wrapMethodName, "JSObject*",
                                             wrapArgs, virtual=descriptor.wrapperCache,
                                             breakAfterReturnDecl=" ",
                                             override=descriptor.wrapperCache,
                                             body=self.getWrapObjectBody()))
         if wantGetParent:
             self.methodDecls.insert(0,
@@ -13198,19 +13222,19 @@ class CGExampleClass(CGBindingImplClass)
                   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
                   NS_INTERFACE_MAP_ENTRY(nsISupports)
                 NS_INTERFACE_MAP_END
 
                 """)
 
         classImpl = ccImpl + ctordtor + "\n" + dedent("""
             JSObject*
-            ${nativeType}::WrapObject(JSContext* aCx)
+            ${nativeType}::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
             {
-              return ${ifaceName}Binding::Wrap(aCx, this);
+              return ${ifaceName}Binding::Wrap(aCx, this, aGivenProto);
             }
 
             """)
         return string.Template(classImpl).substitute(
             ifaceName=self.descriptor.name,
             nativeType=self.nativeLeafName(self.descriptor),
             parentType=self.nativeLeafName(self.parentDesc) if self.parentIface else "")
 
@@ -13568,17 +13592,17 @@ class CGJSImplClass(CGBindingImplClass):
                          methods=self.methodDecls,
                          decorators=decorators,
                          extradeclarations=extradeclarations,
                          extradefinitions=extradefinitions)
 
     def getWrapObjectBody(self):
         return fill(
             """
-            JS::Rooted<JSObject*> obj(aCx, ${name}Binding::Wrap(aCx, this));
+            JS::Rooted<JSObject*> obj(aCx, ${name}Binding::Wrap(aCx, this, aGivenProto));
             if (!obj) {
               return nullptr;
             }
 
             // Now define it on our chrome object
             JSAutoCompartment ac(aCx, mImpl->Callback());
             if (!JS_WrapObject(aCx, &obj)) {
               return nullptr;
@@ -14961,17 +14985,17 @@ class CGEventClass(CGBindingImplClass):
 
         CGClass.__init__(self, className,
                          bases=[ClassBase(self.parentType)],
                          methods=[asConcreteTypeMethod]+self.methodDecls,
                          members=members,
                          extradeclarations=baseDeclarations)
 
     def getWrapObjectBody(self):
-        return "return %sBinding::Wrap(aCx, this);\n" % self.descriptor.name
+        return "return %sBinding::Wrap(aCx, this, aGivenProto);\n" % self.descriptor.name
 
     def implTraverse(self):
         retVal = ""
         for m in self.descriptor.interface.members:
             # Unroll the type so we pick up sequences of interfaces too.
             if m.isAttr() and idlTypeNeedsCycleCollection(m.type):
                 retVal += ("  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(" +
                            CGDictionary.makeMemberName(m.identifier.name) +
--- a/dom/bindings/StructuredClone.cpp
+++ b/dom/bindings/StructuredClone.cpp
@@ -27,17 +27,17 @@ ReadStructuredCloneImageData(JSContext* 
 
   // Protect the result from a moving GC in ~nsRefPtr.
   JS::Rooted<JSObject*> result(aCx);
   {
     // Construct the ImageData.
     nsRefPtr<ImageData> imageData = new ImageData(width, height,
                                                   dataArray.toObject());
     // Wrap it in a JS::Value.
-    if (!imageData->WrapObject(aCx, &result)) {
+    if (!imageData->WrapObject(aCx, JS::NullPtr(), &result)) {
       return nullptr;
     }
   }
   return result;
 }
 
 bool
 WriteStructuredCloneImageData(JSContext* aCx, JSStructuredCloneWriter* aWriter,
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -85,17 +85,17 @@ public:
 
 NS_DEFINE_STATIC_IID_ACCESSOR(TestExternalInterface, NS_TEST_EXTERNAL_INTERFACE_IID)
 
 class TestNonWrapperCacheInterface : public nsISupports
 {
 public:
   NS_DECL_ISUPPORTS
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 };
 
 class OnlyForUseInConstructor : public nsISupports,
                                 public nsWrapperCache
 {
 public:
   NS_DECL_ISUPPORTS
   // We need a GetParentObject to make binding codegen happy
--- a/dom/bindings/test/test_Object.prototype_props.html
+++ b/dom/bindings/test/test_Object.prototype_props.html
@@ -2,19 +2,16 @@
 <meta charset=utf-8>
 <title>Test for bug 987110</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <div id="log"></div>
 <script>
 test(function() {
   var props = Object.getOwnPropertyNames(Object.prototype);
-  // getOwnPropertyNames intentionally filters out the non-standard
-  // "__proto__" property.
-  props.push("__proto__");
   // If you change this list, make sure it continues to match the list in
   // Codegen.py's CGDictionary.getMemberDefinition method.
   var expected = [
       "constructor", "toSource", "toString", "toLocaleString", "valueOf",
       "watch", "unwatch", "hasOwnProperty", "isPrototypeOf",
       "propertyIsEnumerable", "__defineGetter__", "__defineSetter__",
       "__lookupGetter__", "__lookupSetter__", "__proto__"
     ];
--- a/dom/bluetooth/BluetoothAdapter.cpp
+++ b/dom/bluetooth/BluetoothAdapter.cpp
@@ -1062,12 +1062,12 @@ BluetoothAdapter::SendMediaPlayStatus(co
                      aMediaPlayStatus.mPosition,
                      aMediaPlayStatus.mPlayStatus,
                      results);
 
   return request.forget();
 }
 
 JSObject*
-BluetoothAdapter::WrapObject(JSContext* aCx)
+BluetoothAdapter::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothAdapterBinding::Wrap(aCx, this);
+  return BluetoothAdapterBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/bluetooth/BluetoothAdapter.h
+++ b/dom/bluetooth/BluetoothAdapter.h
@@ -164,17 +164,17 @@ public:
   IMPL_EVENT_HANDLER(scostatuschanged);
 
   nsPIDOMWindow* GetParentObject() const
   {
      return GetOwner();
   }
 
   virtual JSObject*
-    WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+    WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   BluetoothAdapter(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
   ~BluetoothAdapter();
 
   void Root();
 
   already_AddRefed<mozilla::dom::DOMRequest>
--- a/dom/bluetooth/BluetoothDevice.cpp
+++ b/dom/bluetooth/BluetoothDevice.cpp
@@ -229,12 +229,12 @@ BluetoothDevice::GetServices(JSContext* 
     return;
   }
 
   JS::ExposeObjectToActiveJS(mJsServices);
   aServices.setObject(*mJsServices);
 }
 
 JSObject*
-BluetoothDevice::WrapObject(JSContext* aContext)
+BluetoothDevice::WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothDeviceBinding::Wrap(aContext, this);
+  return BluetoothDeviceBinding::Wrap(aContext, this, aGivenProto);
 }
--- a/dom/bluetooth/BluetoothDevice.h
+++ b/dom/bluetooth/BluetoothDevice.h
@@ -82,17 +82,17 @@ public:
   void Unroot();
 
   nsPIDOMWindow* GetParentObject() const
   {
      return GetOwner();
   }
 
   virtual JSObject*
-    WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+    WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
 
 private:
   BluetoothDevice(nsPIDOMWindow* aOwner, const nsAString& aAdapterPath,
                   const BluetoothValue& aValue);
   ~BluetoothDevice();
   void Root();
--- a/dom/bluetooth/BluetoothManager.cpp
+++ b/dom/bluetooth/BluetoothManager.cpp
@@ -205,12 +205,12 @@ BluetoothManager::Notify(const Bluetooth
     warningMsg.AssignLiteral("Not handling manager signal: ");
     warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
     BT_WARNING(warningMsg.get());
 #endif
   }
 }
 
 JSObject*
-BluetoothManager::WrapObject(JSContext* aCx)
+BluetoothManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothManagerBinding::Wrap(aCx, this);
+  return BluetoothManagerBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/bluetooth/BluetoothManager.h
+++ b/dom/bluetooth/BluetoothManager.h
@@ -47,17 +47,17 @@ public:
   IMPL_EVENT_HANDLER(adapteradded);
 
   nsPIDOMWindow* GetParentObject() const
   {
      return GetOwner();
   }
 
   virtual JSObject*
-    WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+    WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
 
 private:
   BluetoothManager(nsPIDOMWindow* aWindow);
   ~BluetoothManager();
 };
 
--- a/dom/bluetooth2/BluetoothAdapter.cpp
+++ b/dom/bluetooth2/BluetoothAdapter.cpp
@@ -1317,12 +1317,12 @@ BluetoothAdapter::SendMediaPlayStatus(co
                      aMediaPlayStatus.mPosition,
                      aMediaPlayStatus.mPlayStatus,
                      results);
 
   return request.forget();
 }
 
 JSObject*
-BluetoothAdapter::WrapObject(JSContext* aCx)
+BluetoothAdapter::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothAdapterBinding::Wrap(aCx, this);
+  return BluetoothAdapterBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/bluetooth2/BluetoothAdapter.h
+++ b/dom/bluetooth2/BluetoothAdapter.h
@@ -159,17 +159,17 @@ public:
     Create(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
 
   void Notify(const BluetoothSignal& aParam); // BluetoothSignalObserver
   nsPIDOMWindow* GetParentObject() const
   {
      return GetOwner();
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
 
   /**
    * Set this adapter's discovery handle in use (mDiscoveryHandleInUse).
    *
    * |mDiscoveryHandleInUse| is set to the latest discovery handle when adapter
    * just starts discovery, and is reset to nullptr when discovery is stopped
    * by some adapter.
--- a/dom/bluetooth2/BluetoothClassOfDevice.cpp
+++ b/dom/bluetooth2/BluetoothClassOfDevice.cpp
@@ -90,12 +90,12 @@ BluetoothClassOfDevice::Create(nsPIDOMWi
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aOwner);
 
   nsRefPtr<BluetoothClassOfDevice> cod = new BluetoothClassOfDevice(aOwner);
   return cod.forget();
 }
 
 JSObject*
-BluetoothClassOfDevice::WrapObject(JSContext* aCx)
+BluetoothClassOfDevice::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothClassOfDeviceBinding::Wrap(aCx, this);
+  return BluetoothClassOfDeviceBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/bluetooth2/BluetoothClassOfDevice.h
+++ b/dom/bluetooth2/BluetoothClassOfDevice.h
@@ -64,17 +64,17 @@ public:
    * @param aValue [in] CoD value to update
    */
   void Update(const uint32_t aValue);
 
   nsPIDOMWindow* GetParentObject() const
   {
     return mOwnerWindow;
   }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   BluetoothClassOfDevice(nsPIDOMWindow* aOwner);
   ~BluetoothClassOfDevice();
 
   /**
    * Reset CoD to default value.
    */
--- a/dom/bluetooth2/BluetoothDevice.cpp
+++ b/dom/bluetooth2/BluetoothDevice.cpp
@@ -315,12 +315,12 @@ BluetoothDevice::GetGatt()
   if (!mGatt) {
     mGatt = new BluetoothGatt(GetOwner(), mAddress);
   }
 
   return mGatt;
 }
 
 JSObject*
-BluetoothDevice::WrapObject(JSContext* aContext)
+BluetoothDevice::WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothDeviceBinding::Wrap(aContext, this);
+  return BluetoothDeviceBinding::Wrap(aContext, this, aGivenProto);
 }
--- a/dom/bluetooth2/BluetoothDevice.h
+++ b/dom/bluetooth2/BluetoothDevice.h
@@ -89,17 +89,17 @@ public:
     Create(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
 
   void Notify(const BluetoothSignal& aParam); // BluetoothSignalObserver
   nsPIDOMWindow* GetParentObject() const
   {
      return GetOwner();
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
 
 private:
   BluetoothDevice(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
   ~BluetoothDevice();
 
   /**
    * Set device properties according to properties array
--- a/dom/bluetooth2/BluetoothDiscoveryHandle.cpp
+++ b/dom/bluetooth2/BluetoothDiscoveryHandle.cpp
@@ -53,12 +53,12 @@ BluetoothDiscoveryHandle::DispatchDevice
   nsRefPtr<BluetoothDeviceEvent> event =
     BluetoothDeviceEvent::Constructor(this,
                                       NS_LITERAL_STRING("devicefound"),
                                       init);
   DispatchTrustedEvent(event);
 }
 
 JSObject*
-BluetoothDiscoveryHandle::WrapObject(JSContext* aCx)
+BluetoothDiscoveryHandle::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothDiscoveryHandleBinding::Wrap(aCx, this);
+  return BluetoothDiscoveryHandleBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/bluetooth2/BluetoothDiscoveryHandle.h
+++ b/dom/bluetooth2/BluetoothDiscoveryHandle.h
@@ -25,17 +25,17 @@ public:
 
   static already_AddRefed<BluetoothDiscoveryHandle>
     Create(nsPIDOMWindow* aWindow);
 
   void DispatchDeviceEvent(BluetoothDevice* aDevice);
 
   IMPL_EVENT_HANDLER(devicefound);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   BluetoothDiscoveryHandle(nsPIDOMWindow* aWindow);
   ~BluetoothDiscoveryHandle();
 };
 
 END_BLUETOOTH_NAMESPACE
 
--- a/dom/bluetooth2/BluetoothGatt.cpp
+++ b/dom/bluetooth2/BluetoothGatt.cpp
@@ -255,12 +255,12 @@ BluetoothGatt::Notify(const BluetoothSig
     UpdateConnectionState(state);
   } else {
     BT_WARNING("Not handling GATT signal: %s",
                NS_ConvertUTF16toUTF8(aData.name()).get());
   }
 }
 
 JSObject*
-BluetoothGatt::WrapObject(JSContext* aContext)
+BluetoothGatt::WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothGattBinding::Wrap(aContext, this);
+  return BluetoothGattBinding::Wrap(aContext, this, aGivenProto);
 }
--- a/dom/bluetooth2/BluetoothGatt.h
+++ b/dom/bluetooth2/BluetoothGatt.h
@@ -58,17 +58,17 @@ public:
    ***************************************************************************/
   void Notify(const BluetoothSignal& aParam); // BluetoothSignalObserver
 
   nsPIDOMWindow* GetParentObject() const
   {
      return GetOwner();
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
 
   BluetoothGatt(nsPIDOMWindow* aOwner,
                 const nsAString& aDeviceAddr);
 
 private:
   ~BluetoothGatt();
 
--- a/dom/bluetooth2/BluetoothManager.cpp
+++ b/dom/bluetooth2/BluetoothManager.cpp
@@ -282,12 +282,12 @@ BluetoothManager::Notify(const Bluetooth
     HandleAdapterRemoved(aData.value());
   } else {
     BT_WARNING("Not handling manager signal: %s",
                NS_ConvertUTF16toUTF8(aData.name()).get());
   }
 }
 
 JSObject*
-BluetoothManager::WrapObject(JSContext* aCx)
+BluetoothManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothManagerBinding::Wrap(aCx, this);
+  return BluetoothManagerBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/bluetooth2/BluetoothManager.h
+++ b/dom/bluetooth2/BluetoothManager.h
@@ -58,17 +58,17 @@ public:
   static bool CheckPermission(nsPIDOMWindow* aWindow);
 
   void Notify(const BluetoothSignal& aData); // BluetoothSignalObserver
   nsPIDOMWindow* GetParentObject() const
   {
     return GetOwner();
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
 
   /**
    * Create a BluetoothAdapter object based on properties array
    * and append it into adapters array.
    *
    * @param aValue [in] Properties array to create BluetoothAdapter object
    */
--- a/dom/bluetooth2/BluetoothPairingHandle.cpp
+++ b/dom/bluetooth2/BluetoothPairingHandle.cpp
@@ -116,12 +116,12 @@ BluetoothPairingHandle::SetPairingConfir
 
   bs->SetPairingConfirmationInternal(mDeviceAddress,
                                      aConfirm,
                                      result);
   return promise.forget();
 }
 
 JSObject*
-BluetoothPairingHandle::WrapObject(JSContext* aCx)
+BluetoothPairingHandle::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothPairingHandleBinding::Wrap(aCx, this);
+  return BluetoothPairingHandleBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/bluetooth2/BluetoothPairingHandle.h
+++ b/dom/bluetooth2/BluetoothPairingHandle.h
@@ -34,17 +34,17 @@ public:
            const nsAString& aType,
            const nsAString& aPasskey);
 
   nsPIDOMWindow* GetParentObject() const
   {
     return mOwner;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void GetPasskey(nsString& aPasskey) const
   {
     aPasskey = mPasskey;
   }
 
   already_AddRefed<Promise>
     SetPinCode(const nsAString& aPinCode, ErrorResult& aRv);
--- a/dom/bluetooth2/BluetoothPairingListener.cpp
+++ b/dom/bluetooth2/BluetoothPairingListener.cpp
@@ -103,19 +103,19 @@ BluetoothPairingListener::Notify(const B
     DispatchPairingEvent(name, address, passkey, type);
   } else {
     BT_WARNING("Not handling pairing listener signal: %s",
                NS_ConvertUTF16toUTF8(aData.name()).get());
   }
 }
 
 JSObject*
-BluetoothPairingListener::WrapObject(JSContext* aCx)
+BluetoothPairingListener::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BluetoothPairingListenerBinding::Wrap(aCx, this);
+  return BluetoothPairingListenerBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 BluetoothPairingListener::DisconnectFromOwner()
 {
   DOMEventTargetHelper::DisconnectFromOwner();
 
   BluetoothService* bs = BluetoothService::Get();
--- a/dom/bluetooth2/BluetoothPairingListener.h
+++ b/dom/bluetooth2/BluetoothPairingListener.h
@@ -32,17 +32,17 @@ public:
 
   void Notify(const BluetoothSignal& aParam); // BluetoothSignalObserver
 
   nsPIDOMWindow* GetParentObject() const
   {
     return GetOwner();
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
   virtual void EventListenerAdded(nsIAtom* aType) MOZ_OVERRIDE;
 
   IMPL_EVENT_HANDLER(displaypasskeyreq);
   IMPL_EVENT_HANDLER(enterpincodereq);
   IMPL_EVENT_HANDLER(pairingconfirmationreq);
   IMPL_EVENT_HANDLER(pairingconsentreq);
 
--- a/dom/broadcastchannel/BroadcastChannel.cpp
+++ b/dom/broadcastchannel/BroadcastChannel.cpp
@@ -411,19 +411,19 @@ BroadcastChannel::BroadcastChannel(nsPID
 
 BroadcastChannel::~BroadcastChannel()
 {
   Shutdown();
   MOZ_ASSERT(!mWorkerFeature);
 }
 
 JSObject*
-BroadcastChannel::WrapObject(JSContext* aCx)
+BroadcastChannel::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return BroadcastChannelBinding::Wrap(aCx, this);
+  return BroadcastChannelBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */ already_AddRefed<BroadcastChannel>
 BroadcastChannel::Constructor(const GlobalObject& aGlobal,
                               const nsAString& aChannel,
                               ErrorResult& aRv)
 {
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
--- a/dom/broadcastchannel/BroadcastChannel.h
+++ b/dom/broadcastchannel/BroadcastChannel.h
@@ -44,17 +44,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BroadcastChannel,
                                            DOMEventTargetHelper)
 
   static bool IsEnabled(JSContext* aCx, JSObject* aGlobal);
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static already_AddRefed<BroadcastChannel>
   Constructor(const GlobalObject& aGlobal, const nsAString& aChannel,
               ErrorResult& aRv);
 
   void GetName(nsAString& aName) const
   {
     aName = mChannel;
--- a/dom/cache/Cache.cpp
+++ b/dom/cache/Cache.cpp
@@ -370,19 +370,19 @@ Cache::PrefEnabled(JSContext* aCx, JSObj
 
 nsISupports*
 Cache::GetParentObject() const
 {
   return mGlobal;
 }
 
 JSObject*
-Cache::WrapObject(JSContext* aContext)
+Cache::WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto)
 {
-  return CacheBinding::Wrap(aContext, this);
+  return CacheBinding::Wrap(aContext, this, aGivenProto);
 }
 
 void
 Cache::DestroyInternal(CacheChild* aActor)
 {
   MOZ_ASSERT(mActor);
   MOZ_ASSERT(mActor == aActor);
   mActor->ClearListener();
--- a/dom/cache/Cache.h
+++ b/dom/cache/Cache.h
@@ -66,17 +66,17 @@ public:
   already_AddRefed<Promise>
   Keys(const Optional<RequestOrUSVString>& aRequest,
        const CacheQueryOptions& aParams, ErrorResult& aRv);
 
   // binding methods
   static bool PrefEnabled(JSContext* aCx, JSObject* aObj);
 
   nsISupports* GetParentObject() const;
-  virtual JSObject* WrapObject(JSContext* aContext) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // Called when CacheChild actor is being destroyed
   void DestroyInternal(CacheChild* aActor);
 
   // methods forwarded from CacheChild
   void RecvMatchResponse(RequestId aRequestId, nsresult aRv,
                          const PCacheResponseOrVoid& aResponse);
   void RecvMatchAllResponse(RequestId aRequestId, nsresult aRv,
--- a/dom/cache/CacheStorage.cpp
+++ b/dom/cache/CacheStorage.cpp
@@ -309,19 +309,19 @@ CacheStorage::PrefEnabled(JSContext* aCx
 
 nsISupports*
 CacheStorage::GetParentObject() const
 {
   return mGlobal;
 }
 
 JSObject*
-CacheStorage::WrapObject(JSContext* aContext)
+CacheStorage::WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::CacheStorageBinding::Wrap(aContext, this);
+  return mozilla::dom::CacheStorageBinding::Wrap(aContext, this, aGivenProto);
 }
 
 void
 CacheStorage::ActorCreated(PBackgroundChild* aActor)
 {
   NS_ASSERT_OWNINGTHREAD(CacheStorage);
   MOZ_ASSERT(aActor);
 
--- a/dom/cache/CacheStorage.h
+++ b/dom/cache/CacheStorage.h
@@ -67,17 +67,17 @@ public:
   already_AddRefed<Promise> Open(const nsAString& aKey, ErrorResult& aRv);
   already_AddRefed<Promise> Delete(const nsAString& aKey, ErrorResult& aRv);
   already_AddRefed<Promise> Keys(ErrorResult& aRv);
 
   // binding methods
   static bool PrefEnabled(JSContext* aCx, JSObject* aObj);
 
   nsISupports* GetParentObject() const;
-  virtual JSObject* WrapObject(JSContext* aContext) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aContext, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // nsIIPCbackgroundChildCreateCallback methods
   virtual void ActorCreated(PBackgroundChild* aActor) MOZ_OVERRIDE;
   virtual void ActorFailed() MOZ_OVERRIDE;
 
   // Called when CacheStorageChild actor is being destroyed
   void DestroyInternal(CacheStorageChild* aActor);
 
--- a/dom/cache/Manager.cpp
+++ b/dom/cache/Manager.cpp
@@ -92,21 +92,18 @@ public:
   }
 
   virtual void
   RunOnTarget(Resolver* aResolver, const QuotaInfo& aQuotaInfo) MOZ_OVERRIDE
   {
     MOZ_ASSERT(aResolver);
     MOZ_ASSERT(aQuotaInfo.mDir);
 
-    if (IsCanceled()) {
-      // TODO: handle orphaned files (bug 1110446)
-      aResolver->Resolve(NS_ERROR_ABORT);
-      return;
-    }
+    // Note that since DeleteOrphanedBodyAction isn't used while the context is
+    // being initialized, we don't need to check for cancellation here.
 
     nsCOMPtr<nsIFile> dbDir;
     nsresult rv = aQuotaInfo.mDir->Clone(getter_AddRefs(dbDir));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       aResolver->Resolve(rv);
       return;
     }
 
--- a/dom/cache/test/mochitest/test_cache_matchAll_request.js
+++ b/dom/cache/test/mochitest/test_cache_matchAll_request.js
@@ -70,16 +70,36 @@ function testRequest(request1, request2,
         })
     );
   }).then(function() {
     return c.matchAll(request1);
   }).then(function(r) {
     is(r.length, 1, "Should only find 1 item");
     return checkResponse(r[0], response1, response1Text);
   }).then(function() {
+    return c.matchAll(new Request(request1, {method: "HEAD"}));
+  }).then(function(r) {
+    is(r.length, 1, "Should only find 1 item");
+    return checkResponse(r[0], response1, response1Text);
+  }).then(function() {
+    return Promise.all(
+      ["POST", "PUT", "DELETE", "OPTIONS"]
+        .map(function(method) {
+          var req = new Request(request1, {method: method});
+          return c.matchAll(req)
+            .then(function(r) {
+              is(r.length, 0, "Searching for a request with a non-GET/HEAD method should not succeed");
+              return c.matchAll(req, {ignoreMethod: true});
+            }).then(function(r) {
+              is(r.length, 1, "Should only find 1 item");
+              return checkResponse(r[0], response1, response1Text);
+            });
+        })
+    );
+  }).then(function() {
     return c.matchAll(requestWithDifferentFragment);
   }).then(function(r) {
     is(r.length, 1, "Should only find 1 item");
     return checkResponse(r[0], response1, response1Text);
   }).then(function() {
     return c.matchAll(requestWithAlternateQueryString,
                       {ignoreSearch: true, cacheName: name});
   }).then(function(r) {
--- a/dom/cache/test/mochitest/test_cache_match_request.js
+++ b/dom/cache/test/mochitest/test_cache_match_request.js
@@ -56,16 +56,34 @@ function testRequest(request, unknownReq
             });
         })
     );
   }).then(function() {
     return c.match(request);
   }).then(function(r) {
     return checkResponse(r);
   }).then(function() {
+    return c.match(new Request(request, {method: "HEAD"}));
+  }).then(function(r) {
+    return checkResponse(r);
+  }).then(function() {
+    return Promise.all(
+      ["POST", "PUT", "DELETE", "OPTIONS"]
+        .map(function(method) {
+          var req = new Request(request, {method: method});
+          return c.match(req)
+            .then(function(r) {
+              is(typeof r, "undefined", "Searching for a request with a non-GET/HEAD method should not succeed");
+              return c.match(req, {ignoreMethod: true});
+            }).then(function(r) {
+              return checkResponse(r);
+            });
+        })
+    );
+  }).then(function() {
     return caches.match(request);
   }).then(function(r) {
     return checkResponse(r);
   }).then(function() {
     return caches.match(requestWithDifferentFragment);
   }).then(function(r) {
     return checkResponse(r);
   }).then(function() {
--- a/dom/camera/DOMCameraCapabilities.cpp
+++ b/dom/camera/DOMCameraCapabilities.cpp
@@ -89,19 +89,19 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(CameraRe
 NS_IMPL_CYCLE_COLLECTING_RELEASE(CameraRecorderVideoProfile)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CameraRecorderVideoProfile)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 JSObject*
-CameraRecorderVideoProfile::WrapObject(JSContext* aCx)
+CameraRecorderVideoProfile::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CameraRecorderVideoProfileBinding::Wrap(aCx, this);
+  return CameraRecorderVideoProfileBinding::Wrap(aCx, this, aGivenProto);
 }
 
 CameraRecorderVideoProfile::CameraRecorderVideoProfile(nsISupports* aParent,
     const ICameraControl::RecorderProfile::Video& aProfile)
   : mParent(aParent)
   , mCodec(aProfile.GetCodec())
   , mBitrate(aProfile.GetBitsPerSecond())
   , mFramerate(aProfile.GetFramesPerSecond())
@@ -129,19 +129,19 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(CameraRe
 NS_IMPL_CYCLE_COLLECTING_RELEASE(CameraRecorderAudioProfile)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CameraRecorderAudioProfile)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 JSObject*
-CameraRecorderAudioProfile::WrapObject(JSContext* aCx)
+CameraRecorderAudioProfile::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CameraRecorderAudioProfileBinding::Wrap(aCx, this);
+  return CameraRecorderAudioProfileBinding::Wrap(aCx, this, aGivenProto);
 }
 
 CameraRecorderAudioProfile::CameraRecorderAudioProfile(nsISupports* aParent,
     const ICameraControl::RecorderProfile::Audio& aProfile)
   : mParent(aParent)
   , mCodec(aProfile.GetCodec())
   , mBitrate(aProfile.GetBitsPerSecond())
   , mSamplerate(aProfile.GetSamplesPerSecond())
@@ -169,19 +169,19 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(CameraRe
 NS_IMPL_CYCLE_COLLECTING_RELEASE(CameraRecorderProfile)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CameraRecorderProfile)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 JSObject*
-CameraRecorderProfile::WrapObject(JSContext* aCx)
+CameraRecorderProfile::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CameraRecorderProfileBinding::Wrap(aCx, this);
+  return CameraRecorderProfileBinding::Wrap(aCx, this, aGivenProto);
 }
 
 CameraRecorderProfile::CameraRecorderProfile(nsISupports* aParent,
                                              const ICameraControl::RecorderProfile& aProfile)
   : mParent(aParent)
   , mName(aProfile.GetName())
   , mContainerFormat(aProfile.GetContainer())
   , mMimeType(aProfile.GetMimeType())
@@ -211,19 +211,19 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(CameraRe
 NS_IMPL_CYCLE_COLLECTING_RELEASE(CameraRecorderProfiles)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CameraRecorderProfiles)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 JSObject*
-CameraRecorderProfiles::WrapObject(JSContext* aCx)
+CameraRecorderProfiles::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CameraRecorderProfilesBinding::Wrap(aCx, this);
+  return CameraRecorderProfilesBinding::Wrap(aCx, this, aGivenProto);
 }
 
 CameraRecorderProfiles::CameraRecorderProfiles(nsISupports* aParent,
                                                ICameraControl* aCameraControl)
   : mParent(aParent)
   , mCameraControl(aCameraControl)
 {
   DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
@@ -344,19 +344,19 @@ CameraCapabilities::OnHardwareClosed()
   if (mCameraControl) {
     mCameraControl->RemoveListener(mListener);
     mCameraControl = nullptr;
   }
   mListener = nullptr;
 }
 
 JSObject*
-CameraCapabilities::WrapObject(JSContext* aCx)
+CameraCapabilities::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CameraCapabilitiesBinding::Wrap(aCx, this);
+  return CameraCapabilitiesBinding::Wrap(aCx, this, aGivenProto);
 }
 
 #define LOG_IF_ERROR(rv, param)                               \
   do {                                                        \
     if (NS_FAILED(rv)) {                                      \
       DOM_CAMERA_LOGW("Error %x trying to get " #param "\n",  \
         (rv));                                                \
     }                                                         \
--- a/dom/camera/DOMCameraCapabilities.h
+++ b/dom/camera/DOMCameraCapabilities.h
@@ -34,17 +34,17 @@ class CameraRecorderVideoProfile MOZ_FIN
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CameraRecorderVideoProfile)
 
   explicit CameraRecorderVideoProfile(nsISupports* aParent,
     const ICameraControl::RecorderProfile::Video& aProfile);
   nsISupports* GetParentObject() const        { return mParent; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   uint32_t BitsPerSecond() const              { return mBitrate; }
   uint32_t FramesPerSecond() const            { return mFramerate; }
   void GetCodec(nsAString& aCodec) const      { aCodec = mCodec; }
 
   void GetSize(dom::CameraSize& aSize) const  { aSize = mSize; }
 
   // XXXmikeh - legacy, remove these when the Camera app is updated
@@ -73,17 +73,17 @@ class CameraRecorderAudioProfile MOZ_FIN
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CameraRecorderAudioProfile)
 
   explicit CameraRecorderAudioProfile(nsISupports* aParent,
     const ICameraControl::RecorderProfile::Audio& aProfile);
   nsISupports* GetParentObject() const    { return mParent; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   uint32_t BitsPerSecond() const          { return mBitrate; }
   uint32_t SamplesPerSecond() const       { return mSamplerate; }
   uint32_t Channels() const               { return mChannels; }
   void GetCodec(nsAString& aCodec) const  { aCodec = mCodec; }
 
 protected:
   virtual ~CameraRecorderAudioProfile();
@@ -107,17 +107,17 @@ class CameraRecorderProfile MOZ_FINAL : 
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CameraRecorderProfile)
 
   explicit CameraRecorderProfile(nsISupports* aParent,
                                  const ICameraControl::RecorderProfile& aProfile);
   nsISupports* GetParentObject() const          { return mParent; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void GetMimeType(nsAString& aMimeType) const  { aMimeType = mMimeType; }
 
   CameraRecorderVideoProfile* Video()           { return mVideo; }
   CameraRecorderAudioProfile* Audio()           { return mAudio; }
 
   void GetName(nsAString& aName) const          { aName = mName; }
 
@@ -153,17 +153,17 @@ class CameraRecorderProfiles MOZ_FINAL :
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CameraRecorderProfiles)
 
   explicit CameraRecorderProfiles(nsISupports* aParent,
                                   ICameraControl* aCameraControl);
   nsISupports* GetParentObject() const { return mParent; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   CameraRecorderProfile* NamedGetter(const nsAString& aName, bool& aFound);
   bool NameIsEnumerable(const nsAString& aName);
   void GetSupportedNames(unsigned aFlags, nsTArray<nsString>& aNames);
 
   virtual void OnHardwareClosed();
 
 protected:
@@ -195,17 +195,17 @@ public:
   // Great Renaming proposed in bug 983177.
   static bool HasSupport(JSContext* aCx, JSObject* aGlobal);
 
   explicit CameraCapabilities(nsPIDOMWindow* aWindow,
                               ICameraControl* aCameraControl);
 
   nsPIDOMWindow* GetParentObject() const { return mWindow; }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void GetPreviewSizes(nsTArray<CameraSize>& aRetVal);
   void GetPictureSizes(nsTArray<CameraSize>& aRetVal);
   void GetThumbnailSizes(nsTArray<CameraSize>& aRetVal);
   void GetVideoSizes(nsTArray<CameraSize>& aRetVal);
   void GetFileFormats(nsTArray<nsString>& aRetVal);
   void GetWhiteBalanceModes(nsTArray<nsString>& aRetVal);
   void GetSceneModes(nsTArray<nsString>& aRetVal);
--- a/dom/camera/DOMCameraControl.cpp
+++ b/dom/camera/DOMCameraControl.cpp
@@ -306,19 +306,19 @@ nsDOMCameraControl::nsDOMCameraControl(u
 nsDOMCameraControl::~nsDOMCameraControl()
 {
   DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
   /*invoke DOMMdediastream destroy*/
   Destroy();
 }
 
 JSObject*
-nsDOMCameraControl::WrapObject(JSContext* aCx)
+nsDOMCameraControl::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CameraControlBinding::Wrap(aCx, this);
+  return CameraControlBinding::Wrap(aCx, this, aGivenProto);
 }
 
 bool
 nsDOMCameraControl::IsWindowStillActive()
 {
   return nsDOMCameraManager::IsWindowStillActive(mWindow->WindowID());
 }
 
--- a/dom/camera/DOMCameraControl.h
+++ b/dom/camera/DOMCameraControl.h
@@ -118,17 +118,17 @@ public:
                                                 nsDOMDeviceStorage& storageArea,
                                                 const nsAString& filename,
                                                 ErrorResult& aRv);
   void StopRecording(ErrorResult& aRv);
   void ResumePreview(ErrorResult& aRv);
   already_AddRefed<dom::Promise> ReleaseHardware(ErrorResult& aRv);
   void ResumeContinuousFocus(ErrorResult& aRv);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   operator nsISupports*() { return static_cast<DOMMediaStream*>(this); }
 
 #ifdef MOZ_WIDGET_GONK
   static void PreinitCameraHardware();
   static void DiscardCachedCameraInstance(nsITimer* aTimer, void* aClosure);
 #endif
 
--- a/dom/camera/DOMCameraDetectedFace.cpp
+++ b/dom/camera/DOMCameraDetectedFace.cpp
@@ -21,19 +21,19 @@ NS_INTERFACE_MAP_END
 /* static */
 bool
 DOMCameraDetectedFace::HasSupport(JSContext* aCx, JSObject* aGlobal)
 {
   return Navigator::HasCameraSupport(aCx, aGlobal);
 }
 
 JSObject*
-DOMCameraDetectedFace::WrapObject(JSContext* aCx)
+DOMCameraDetectedFace::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CameraDetectedFaceBinding::Wrap(aCx, this);
+  return CameraDetectedFaceBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /* static */
 already_AddRefed<DOMCameraDetectedFace>
 DOMCameraDetectedFace::Constructor(const GlobalObject& aGlobal,
                                    const dom::CameraDetectedFaceInit& aFace,
                                    ErrorResult& aRv)
 {
--- a/dom/camera/DOMCameraDetectedFace.h
+++ b/dom/camera/DOMCameraDetectedFace.h
@@ -50,17 +50,17 @@ public:
 
   nsISupports*
   GetParentObject() const
   {
     MOZ_ASSERT(mParent);
     return mParent;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 protected:
   DOMCameraDetectedFace(nsISupports* aParent, const dom::CameraDetectedFaceInit& aFace);
   virtual ~DOMCameraDetectedFace() { }
 
   nsCOMPtr<nsISupports> mParent;
 
   uint32_t mId;
--- a/dom/camera/DOMCameraManager.cpp
+++ b/dom/camera/DOMCameraManager.cpp
@@ -431,12 +431,12 @@ nsDOMCameraManager::IsWindowStillActive(
   if (!sActiveWindows) {
     return false;
   }
 
   return !!sActiveWindows->Get(aWindowId);
 }
 
 JSObject*
-nsDOMCameraManager::WrapObject(JSContext* aCx)
+nsDOMCameraManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CameraManagerBinding::Wrap(aCx, this);
+  return CameraManagerBinding::Wrap(aCx, this, aGivenProto);
 }
--- a/dom/camera/DOMCameraManager.h
+++ b/dom/camera/DOMCameraManager.h
@@ -69,17 +69,17 @@ public:
   // WebIDL
   already_AddRefed<mozilla::dom::Promise>
   GetCamera(const nsAString& aCamera,
             const mozilla::dom::CameraConfiguration& aOptions,
             mozilla::ErrorResult& aRv);
   void GetListOfCameras(nsTArray<nsString>& aList, mozilla::ErrorResult& aRv);
 
   nsPIDOMWindow* GetParentObject() const { return mWindow; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 #ifdef MOZ_WIDGET_GONK
   static void PreinitCameraHardware();
 #endif
 
 protected:
   void XpComShutdown();
   void Shutdown(uint64_t aWindowId);
--- a/dom/canvas/CanvasGradient.h
+++ b/dom/canvas/CanvasGradient.h
@@ -46,19 +46,19 @@ public:
                                                       gfx::ExtendMode::CLAMP);
 
     return mStops;
   }
 
   // WebIDL
   void AddColorStop(float offset, const nsAString& colorstr, ErrorResult& rv);
 
-  JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return CanvasGradientBinding::Wrap(aCx, this);
+    return CanvasGradientBinding::Wrap(aCx, this, aGivenProto);
   }
 
   CanvasRenderingContext2D* GetParentObject()
   {
     return mContext;
   }
 
 protected:
--- a/dom/canvas/CanvasPath.h
+++ b/dom/canvas/CanvasPath.h
@@ -22,17 +22,17 @@ class CanvasPath MOZ_FINAL :
   public nsWrapperCache
 {
 public:
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CanvasPath)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CanvasPath)
 
   nsCOMPtr<nsISupports> GetParentObject() { return mParent; }
 
-  JSObject* WrapObject(JSContext* aCx);
+  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
                                                   ErrorResult& rv);
   static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
                                                   CanvasPath& aCanvasPath,
                                                   ErrorResult& rv);
   static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
                                                   const nsAString& aPathString,
--- a/dom/canvas/CanvasPattern.h
+++ b/dom/canvas/CanvasPattern.h
@@ -47,19 +47,19 @@ public:
     , mPrincipal(principalForSecurityCheck)
     , mTransform()
     , mForceWriteOnly(forceWriteOnly)
     , mCORSUsed(CORSUsed)
     , mRepeat(aRepeat)
   {
   }
 
-  JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return CanvasPatternBinding::Wrap(aCx, this);
+    return CanvasPatternBinding::Wrap(aCx, this, aGivenProto);
   }
 
   CanvasRenderingContext2D* GetParentObject()
   {
     return mContext;
   }
 
   // WebIDL
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -974,19 +974,19 @@ CanvasRenderingContext2D::~CanvasRenderi
     gfxPlatform::GetPlatform()->GetSkiaGLGlue()->GetGLContext()->fDeleteTextures(1, &mVideoTexture);
   }
 #endif
 
   RemoveDemotableContext(this);
 }
 
 JSObject*
-CanvasRenderingContext2D::WrapObject(JSContext *cx)
+CanvasRenderingContext2D::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CanvasRenderingContext2DBinding::Wrap(cx, this);
+  return CanvasRenderingContext2DBinding::Wrap(cx, this, aGivenProto);
 }
 
 bool
 CanvasRenderingContext2D::ParseColor(const nsAString& aString,
                                      nscolor* aColor)
 {
   nsIDocument* document = mCanvasElement
                           ? mCanvasElement->OwnerDoc()
@@ -5388,19 +5388,19 @@ CanvasPath::CanvasPath(nsISupports* aPar
   : mParent(aParent), mPathBuilder(aPathBuilder)
 {
   if (!mPathBuilder) {
     mPathBuilder = gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget()->CreatePathBuilder();
   }
 }
 
 JSObject*
-CanvasPath::WrapObject(JSContext* aCx)
+CanvasPath::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return Path2DBinding::Wrap(aCx, this);
+  return Path2DBinding::Wrap(aCx, this, aGivenProto);
 }
 
 already_AddRefed<CanvasPath>
 CanvasPath::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsRefPtr<CanvasPath> path = new CanvasPath(aGlobal.GetAsSupports());
   return path.forget();
 }
--- a/dom/canvas/CanvasRenderingContext2D.h
+++ b/dom/canvas/CanvasRenderingContext2D.h
@@ -64,17 +64,17 @@ class CanvasRenderingContext2D MOZ_FINAL
 typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement
   HTMLImageOrCanvasOrVideoElement;
 
   virtual ~CanvasRenderingContext2D();
 
 public:
   CanvasRenderingContext2D();
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   HTMLCanvasElement* GetCanvas() const
   {
     // corresponds to changes to the old bindings made in bug 745025
     return mCanvasElement->GetOriginalCanvas();
   }
 
   void Save();
--- a/dom/canvas/ImageData.cpp
+++ b/dom/canvas/ImageData.cpp
@@ -104,15 +104,15 @@ ImageData::DropData()
 {
   if (mData) {
     mData = nullptr;
     mozilla::DropJSObjects(this);
   }
 }
 
 bool
-ImageData::WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+ImageData::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
 {
-  return ImageDataBinding::Wrap(aCx, this, aReflector);
+  return ImageDataBinding::Wrap(aCx, this, aGivenProto, aReflector);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/canvas/ImageData.h
+++ b/dom/canvas/ImageData.h
@@ -68,17 +68,17 @@ public:
     aData.set(GetDataObject());
   }
   JSObject* GetDataObject() const
   {
     JS::ExposeObjectToActiveJS(mData);
     return mData;
   }
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+  bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 
 private:
   void HoldData();
   void DropData();
 
   ImageData() = delete;
 
   uint32_t mWidth, mHeight;
--- a/dom/canvas/TextMetrics.h
+++ b/dom/canvas/TextMetrics.h
@@ -25,19 +25,19 @@ public:
     MOZ_COUNT_DTOR(TextMetrics);
   }
 
   float Width() const
   {
     return width;
   }
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+  bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
   {
-    return TextMetricsBinding::Wrap(aCx, this, aReflector);
+    return TextMetricsBinding::Wrap(aCx, this, aGivenProto, aReflector);
   }
 
 private:
   float width;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/canvas/WebGL1Context.cpp
+++ b/dom/canvas/WebGL1Context.cpp
@@ -21,19 +21,19 @@ WebGL1Context::WebGL1Context()
 {
 }
 
 WebGL1Context::~WebGL1Context()
 {
 }
 
 JSObject*
-WebGL1Context::WrapObject(JSContext* cx)
+WebGL1Context::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLRenderingContextBinding::Wrap(cx, this);
+    return dom::WebGLRenderingContextBinding::Wrap(cx, this, aGivenProto);
 }
 
 } // namespace mozilla
 
 nsresult
 NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** out_result)
 {
     mozilla::Telemetry::Accumulate(mozilla::Telemetry::CANVAS_WEBGL_USED, 1);
--- a/dom/canvas/WebGL1Context.h
+++ b/dom/canvas/WebGL1Context.h
@@ -22,17 +22,17 @@ private:
 public:
     virtual ~WebGL1Context();
 
     virtual bool IsWebGL2() const MOZ_OVERRIDE {
         return false;
     }
 
     // nsWrapperCache
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
     virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) MOZ_OVERRIDE;
     virtual bool ValidateBufferTarget(GLenum target, const char* info) MOZ_OVERRIDE;
     virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) MOZ_OVERRIDE;
     virtual bool ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, const char* info) MOZ_OVERRIDE;
 };
 
--- a/dom/canvas/WebGL2Context.cpp
+++ b/dom/canvas/WebGL2Context.cpp
@@ -35,19 +35,19 @@ WebGL2Context::IsSupported()
 
 /*static*/ WebGL2Context*
 WebGL2Context::Create()
 {
     return new WebGL2Context();
 }
 
 JSObject*
-WebGL2Context::WrapObject(JSContext* cx)
+WebGL2Context::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGL2RenderingContextBinding::Wrap(cx, this);
+    return dom::WebGL2RenderingContextBinding::Wrap(cx, this, aGivenProto);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // WebGL 2 initialisation
 
 // These WebGL 1 extensions are natively supported by WebGL 2.
 static const WebGLExtensionID kNativelySupportedExtensions[] = {
     WebGLExtensionID::ANGLE_instanced_arrays,
--- a/dom/canvas/WebGL2Context.h
+++ b/dom/canvas/WebGL2Context.h
@@ -32,17 +32,17 @@ public:
     virtual bool IsWebGL2() const MOZ_OVERRIDE
     {
         return true;
     }
 
     // -------------------------------------------------------------------------
     // IMPLEMENT nsWrapperCache
 
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     // -------------------------------------------------------------------------
     // Buffer objects - WebGL2ContextBuffers.cpp
 
     void CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
                            GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
     void GetBufferSubData(GLenum target, GLintptr offset, const dom::ArrayBuffer& returnedData);
     void GetBufferSubData(GLenum target, GLintptr offset, const dom::ArrayBufferView& returnedData);
--- a/dom/canvas/WebGLActiveInfo.cpp
+++ b/dom/canvas/WebGLActiveInfo.cpp
@@ -82,19 +82,19 @@ WebGLActiveInfo::WebGLActiveInfo(WebGLCo
     , mIsArray(isArray)
     , mElemSize(ElemSizeFromType(elemType))
     , mBaseMappedName(baseMappedName)
 { }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 JSObject*
-WebGLActiveInfo::WrapObject(JSContext* js)
+WebGLActiveInfo::WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLActiveInfoBinding::Wrap(js, this);
+    return dom::WebGLActiveInfoBinding::Wrap(js, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLActiveInfo)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLActiveInfo, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLActiveInfo, Release)
 
 } // namespace mozilla
--- a/dom/canvas/WebGLActiveInfo.h
+++ b/dom/canvas/WebGLActiveInfo.h
@@ -20,17 +20,17 @@ class WebGLContext;
 
 class WebGLActiveInfo MOZ_FINAL
     : public nsWrapperCache
 {
 public:
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLActiveInfo)
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLActiveInfo)
 
-    virtual JSObject* WrapObject(JSContext* js) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     WebGLContext* GetParentObject() const {
         return mWebGL;
     }
 
 
     WebGLContext* const mWebGL;
 
--- a/dom/canvas/WebGLBuffer.cpp
+++ b/dom/canvas/WebGLBuffer.cpp
@@ -77,19 +77,19 @@ WebGLBuffer::Validate(GLenum type, uint3
 
 bool
 WebGLBuffer::IsElementArrayUsedWithMultipleTypes() const
 {
     return mCache->BeenUsedWithMultipleTypes();
 }
 
 JSObject*
-WebGLBuffer::WrapObject(JSContext* cx)
+WebGLBuffer::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLBufferBinding::Wrap(cx, this);
+    return dom::WebGLBufferBinding::Wrap(cx, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLBuffer)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLBuffer, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLBuffer, Release)
 
 } // namespace mozilla
--- a/dom/canvas/WebGLBuffer.h
+++ b/dom/canvas/WebGLBuffer.h
@@ -45,17 +45,17 @@ public:
                   uint32_t* const out_upperBound);
 
     bool IsElementArrayUsedWithMultipleTypes() const;
 
     WebGLContext* GetParentObject() const {
         return Context();
     }
 
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLBuffer)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLBuffer)
 
 protected:
     ~WebGLBuffer();
 
     virtual void OnTargetChanged() MOZ_OVERRIDE;
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -192,17 +192,17 @@ public:
 
     MOZ_DECLARE_REFCOUNTED_TYPENAME(WebGLContext)
 
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(WebGLContext,
                                                            nsIDOMWebGLRenderingContext)
 
-    virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE = 0;
+    virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE = 0;
 
     NS_DECL_NSIDOMWEBGLRENDERINGCONTEXT
 
     // nsICanvasRenderingContextInternal
 #ifdef DEBUG
     virtual int32_t GetWidth() const MOZ_OVERRIDE;
     virtual int32_t GetHeight() const MOZ_OVERRIDE;
 #endif
--- a/dom/canvas/WebGLExtensions.h
+++ b/dom/canvas/WebGLExtensions.h
@@ -36,22 +36,22 @@ public:
 
 protected:
     virtual ~WebGLExtensionBase();
 
     bool mIsLost;
 };
 
 #define DECL_WEBGL_EXTENSION_GOOP \
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 #define IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionType)            \
     JSObject*                                                    \
-    WebGLExtensionType::WrapObject(JSContext* cx) {              \
-        return dom::WebGLExtensionType##Binding::Wrap(cx, this); \
+    WebGLExtensionType::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) {              \
+        return dom::WebGLExtensionType##Binding::Wrap(cx, this, aGivenProto); \
     }
 
 class WebGLExtensionCompressedTextureATC
     : public WebGLExtensionBase
 {
 public:
     explicit WebGLExtensionCompressedTextureATC(WebGLContext*);
     virtual ~WebGLExtensionCompressedTextureATC();
--- a/dom/canvas/WebGLFramebuffer.cpp
+++ b/dom/canvas/WebGLFramebuffer.cpp
@@ -11,19 +11,19 @@
 #include "WebGLContextUtils.h"
 #include "WebGLExtensions.h"
 #include "WebGLRenderbuffer.h"
 #include "WebGLTexture.h"
 
 namespace mozilla {
 
 JSObject*
-WebGLFramebuffer::WrapObject(JSContext* cx)
+WebGLFramebuffer::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLFramebufferBinding::Wrap(cx, this);
+    return dom::WebGLFramebufferBinding::Wrap(cx, this, aGivenProto);
 }
 
 WebGLFramebuffer::WebGLFramebuffer(WebGLContext* webgl, GLuint fbo)
     : WebGLBindableName<FBTarget>(fbo)
     , WebGLContextBoundObject(webgl)
     , mStatus(0)
     , mDepthAttachment(LOCAL_GL_DEPTH_ATTACHMENT)
     , mStencilAttachment(LOCAL_GL_STENCIL_ATTACHMENT)
--- a/dom/canvas/WebGLFramebuffer.h
+++ b/dom/canvas/WebGLFramebuffer.h
@@ -152,17 +152,17 @@ public:
     const WebGLRectangleObject& RectangleObject() const;
 
     WebGLContext* GetParentObject() const {
         return Context();
     }
 
     void FinalizeAttachments() const;
 
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLFramebuffer)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLFramebuffer)
 
     // mask mirrors glClear.
     bool HasCompletePlanes(GLbitfield mask);
 
     bool CheckAndInitializeAttachments();
--- a/dom/canvas/WebGLProgram.cpp
+++ b/dom/canvas/WebGLProgram.cpp
@@ -705,19 +705,19 @@ WebGLProgram::FindUniformByMappedName(co
         return true;
 
     return false;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 JSObject*
-WebGLProgram::WrapObject(JSContext* js)
+WebGLProgram::WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLProgramBinding::Wrap(js, this);
+    return dom::WebGLProgramBinding::Wrap(js, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLProgram, mVertShader, mFragShader)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLProgram, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLProgram, Release)
 
 } // namespace mozilla
--- a/dom/canvas/WebGLProgram.h
+++ b/dom/canvas/WebGLProgram.h
@@ -133,17 +133,17 @@ public:
     const webgl::LinkedProgramInfo* LinkInfo() const {
         return mMostRecentLinkInfo.get();
     }
 
     WebGLContext* GetParentObject() const {
         return Context();
     }
 
-    virtual JSObject* WrapObject(JSContext* js) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
     ~WebGLProgram() {
         DeleteOnce();
     }
 
     bool LinkAndUpdate();
 
--- a/dom/canvas/WebGLQuery.cpp
+++ b/dom/canvas/WebGLQuery.cpp
@@ -8,19 +8,19 @@
 #include "GLContext.h"
 #include "mozilla/dom/WebGL2RenderingContextBinding.h"
 #include "nsContentUtils.h"
 #include "WebGLContext.h"
 
 namespace mozilla {
 
 JSObject*
-WebGLQuery::WrapObject(JSContext* cx)
+WebGLQuery::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLQueryBinding::Wrap(cx, this);
+    return dom::WebGLQueryBinding::Wrap(cx, this, aGivenProto);
 }
 
 WebGLQuery::WebGLQuery(WebGLContext* webgl)
     : WebGLContextBoundObject(webgl)
     , mGLName(0)
     , mType(0)
 {
     mContext->mQueries.insertBack(this);
--- a/dom/canvas/WebGLQuery.h
+++ b/dom/canvas/WebGLQuery.h
@@ -31,17 +31,17 @@ public:
     void Delete();
 
     // nsWrapperCache
     WebGLContext* GetParentObject() const {
         return Context();
     }
 
     // NS
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLQuery)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLQuery)
 
 
 private:
     ~WebGLQuery() {
         DeleteOnce();
--- a/dom/canvas/WebGLRenderbuffer.cpp
+++ b/dom/canvas/WebGLRenderbuffer.cpp
@@ -36,19 +36,19 @@ NeedsDepthStencilEmu(gl::GLContext* gl, 
     MOZ_ASSERT(internalFormat != LOCAL_GL_DEPTH_STENCIL);
     if (internalFormat != LOCAL_GL_DEPTH24_STENCIL8)
         return false;
 
     return !SupportsDepthStencil(gl);
 }
 
 JSObject*
-WebGLRenderbuffer::WrapObject(JSContext* cx)
+WebGLRenderbuffer::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLRenderbufferBinding::Wrap(cx, this);
+    return dom::WebGLRenderbufferBinding::Wrap(cx, this, aGivenProto);
 }
 
 WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext* webgl)
     : WebGLBindable<RBTarget>()
     , WebGLContextBoundObject(webgl)
     , mPrimaryRB(0)
     , mSecondaryRB(0)
     , mInternalFormat(0)
--- a/dom/canvas/WebGLRenderbuffer.h
+++ b/dom/canvas/WebGLRenderbuffer.h
@@ -59,17 +59,17 @@ public:
 
     void BindRenderbuffer() const;
     void RenderbufferStorage(GLsizei samples, GLenum internalFormat,
                              GLsizei width, GLsizei height) const;
     void FramebufferRenderbuffer(FBAttachment attachment) const;
     // Only handles a subset of `pname`s.
     GLint GetRenderbufferParameter(RBTarget target, RBParam pname) const;
 
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLRenderbuffer)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLRenderbuffer)
 
 protected:
     ~WebGLRenderbuffer() {
         DeleteOnce();
     }
--- a/dom/canvas/WebGLSampler.cpp
+++ b/dom/canvas/WebGLSampler.cpp
@@ -34,19 +34,19 @@ WebGLSampler::Delete()
 
 WebGLContext*
 WebGLSampler::GetParentObject() const
 {
     return Context();
 }
 
 JSObject*
-WebGLSampler::WrapObject(JSContext* cx)
+WebGLSampler::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLSamplerBinding::Wrap(cx, this);
+    return dom::WebGLSamplerBinding::Wrap(cx, this, aGivenProto);
 }
 
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLSampler)
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLSampler, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLSampler, Release)
 
 } // namespace mozilla
--- a/dom/canvas/WebGLSampler.h
+++ b/dom/canvas/WebGLSampler.h
@@ -23,17 +23,17 @@ class WebGLSampler MOZ_FINAL
     friend class WebGLContext2;
 
 public:
     explicit WebGLSampler(WebGLContext* webgl, GLuint sampler);
 
     void Delete();
     WebGLContext* GetParentObject() const;
 
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLSampler)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLSampler)
 
 private:
     ~WebGLSampler();
--- a/dom/canvas/WebGLShader.cpp
+++ b/dom/canvas/WebGLShader.cpp
@@ -344,19 +344,19 @@ WebGLShader::FindUniformByMappedName(con
     *out_userName = userNameStr.c_str();
     return true;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Boilerplate
 
 JSObject*
-WebGLShader::WrapObject(JSContext* js)
+WebGLShader::WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLShaderBinding::Wrap(js, this);
+    return dom::WebGLShaderBinding::Wrap(js, this, aGivenProto);
 }
 
 size_t
 WebGLShader::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const
 {
     size_t validatorSize = mValidator ? mallocSizeOf(mValidator.get())
                                       : 0;
     return mallocSizeOf(this) +
--- a/dom/canvas/WebGLShader.h
+++ b/dom/canvas/WebGLShader.h
@@ -57,17 +57,17 @@ public:
     }
 
     // Other funcs
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     void Delete();
 
     WebGLContext* GetParentObject() const { return Context(); }
 
-    virtual JSObject* WrapObject(JSContext* js) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLShader)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLShader)
 
 public:
     const GLuint mGLName;
     const GLenum mType;
 protected:
--- a/dom/canvas/WebGLShaderPrecisionFormat.cpp
+++ b/dom/canvas/WebGLShaderPrecisionFormat.cpp
@@ -7,14 +7,15 @@
 
 #include "mozilla/dom/WebGLRenderingContextBinding.h"
 #include "WebGLContext.h"
 
 namespace mozilla {
 
 bool
 WebGLShaderPrecisionFormat::WrapObject(JSContext* aCx,
+                                       JS::Handle<JSObject*> aGivenProto,
                                        JS::MutableHandle<JSObject*> aReflector)
 {
-    return dom::WebGLShaderPrecisionFormatBinding::Wrap(aCx, this, aReflector);
+    return dom::WebGLShaderPrecisionFormatBinding::Wrap(aCx, this, aGivenProto, aReflector);
 }
 
 } // namespace mozilla
--- a/dom/canvas/WebGLShaderPrecisionFormat.h
+++ b/dom/canvas/WebGLShaderPrecisionFormat.h
@@ -19,17 +19,17 @@ public:
     WebGLShaderPrecisionFormat(WebGLContext* context, GLint rangeMin,
                                GLint rangeMax, GLint precision)
         : WebGLContextBoundObject(context)
         , mRangeMin(rangeMin)
         , mRangeMax(rangeMax)
         , mPrecision(precision)
     { }
 
-    bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector);
+    bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 
     // WebIDL WebGLShaderPrecisionFormat API
     GLint RangeMin() const {
         return mRangeMin;
     }
 
     GLint RangeMax() const {
         return mRangeMax;
--- a/dom/canvas/WebGLSync.cpp
+++ b/dom/canvas/WebGLSync.cpp
@@ -29,18 +29,18 @@ WebGLSync::GetParentObject() const
 {
     MOZ_CRASH("Not Implemented.");
     return nullptr;
 }
 
 // -------------------------------------------------------------------------
 // IMPLEMENT NS
 JSObject*
-WebGLSync::WrapObject(JSContext* cx)
+WebGLSync::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLSyncBinding::Wrap(cx, this);
+    return dom::WebGLSyncBinding::Wrap(cx, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLSync)
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLSync, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLSync, Release);
 
 } // namespace mozilla
--- a/dom/canvas/WebGLSync.h
+++ b/dom/canvas/WebGLSync.h
@@ -21,17 +21,17 @@ class WebGLSync MOZ_FINAL
     friend class WebGL2Context;
 
 public:
     explicit WebGLSync(WebGLContext* webgl);
 
     void Delete();
     WebGLContext* GetParentObject() const;
 
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLSync)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLSync)
 
 private:
     ~WebGLSync();
 };
 
--- a/dom/canvas/WebGLTexture.cpp
+++ b/dom/canvas/WebGLTexture.cpp
@@ -13,18 +13,18 @@
 #include "ScopedGLHelpers.h"
 #include "WebGLContext.h"
 #include "WebGLContextUtils.h"
 #include "WebGLTexelConversions.h"
 
 namespace mozilla {
 
 JSObject*
-WebGLTexture::WrapObject(JSContext* cx) {
-    return dom::WebGLTextureBinding::Wrap(cx, this);
+WebGLTexture::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) {
+    return dom::WebGLTextureBinding::Wrap(cx, this, aGivenProto);
 }
 
 WebGLTexture::WebGLTexture(WebGLContext* webgl, GLuint tex)
     : WebGLBindableName<TexTarget>(tex)
     , WebGLContextBoundObject(webgl)
     , mMinFilter(LOCAL_GL_NEAREST_MIPMAP_LINEAR)
     , mMagFilter(LOCAL_GL_LINEAR)
     , mWrapS(LOCAL_GL_REPEAT)
--- a/dom/canvas/WebGLTexture.h
+++ b/dom/canvas/WebGLTexture.h
@@ -41,17 +41,17 @@ public:
     explicit WebGLTexture(WebGLContext* webgl, GLuint tex);
 
     void Delete();
 
     WebGLContext* GetParentObject() const {
         return Context();
     }
 
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTexture)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTexture)
 
 protected:
     ~WebGLTexture() {
         DeleteOnce();
     }
--- a/dom/canvas/WebGLTransformFeedback.cpp
+++ b/dom/canvas/WebGLTransformFeedback.cpp
@@ -40,19 +40,19 @@ WebGLTransformFeedback::Delete()
 
 WebGLContext*
 WebGLTransformFeedback::GetParentObject() const
 {
     return Context();
 }
 
 JSObject*
-WebGLTransformFeedback::WrapObject(JSContext* cx)
+WebGLTransformFeedback::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLTransformFeedbackBinding::Wrap(cx, this);
+    return dom::WebGLTransformFeedbackBinding::Wrap(cx, this, aGivenProto);
 }
 
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLTransformFeedback)
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLTransformFeedback, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLTransformFeedback, Release)
 
 } // namespace mozilla
--- a/dom/canvas/WebGLTransformFeedback.h
+++ b/dom/canvas/WebGLTransformFeedback.h
@@ -23,17 +23,17 @@ class WebGLTransformFeedback MOZ_FINAL
     friend class WebGLContext;
     friend class WebGL2Context;
 
 public:
     explicit WebGLTransformFeedback(WebGLContext* webgl, GLuint tf);
 
     void Delete();
     WebGLContext* GetParentObject() const;
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTransformFeedback)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTransformFeedback)
 
 private:
     ~WebGLTransformFeedback();
     GLenum mMode;
     bool mIsActive;
--- a/dom/canvas/WebGLUniformLocation.cpp
+++ b/dom/canvas/WebGLUniformLocation.cpp
@@ -260,19 +260,19 @@ WebGLUniformLocation::GetUniform(JSConte
     default:
         MOZ_CRASH("Invalid elemType.");
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 JSObject*
-WebGLUniformLocation::WrapObject(JSContext* js)
+WebGLUniformLocation::WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLUniformLocationBinding::Wrap(js, this);
+    return dom::WebGLUniformLocationBinding::Wrap(js, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLUniformLocation)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLUniformLocation, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLUniformLocation, Release)
 
 } // namespace mozilla
--- a/dom/canvas/WebGLUniformLocation.h
+++ b/dom/canvas/WebGLUniformLocation.h
@@ -27,17 +27,17 @@ struct LinkedProgramInfo;
 class WebGLUniformLocation MOZ_FINAL
     : public nsWrapperCache
     , public WebGLContextBoundObject
 {
 public:
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLUniformLocation)
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLUniformLocation)
 
-    virtual JSObject* WrapObject(JSContext* js) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     WebGLContext* GetParentObject() const {
         return mContext;
     }
 
 
     const WeakPtr<const webgl::LinkedProgramInfo> mLinkInfo;
     const GLuint mLoc;
--- a/dom/canvas/WebGLVertexArray.cpp
+++ b/dom/canvas/WebGLVertexArray.cpp
@@ -10,19 +10,19 @@
 #include "WebGLBuffer.h"
 #include "WebGLContext.h"
 #include "WebGLVertexArrayGL.h"
 #include "WebGLVertexArrayFake.h"
 
 namespace mozilla {
 
 JSObject*
-WebGLVertexArray::WrapObject(JSContext* cx)
+WebGLVertexArray::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
 {
-    return dom::WebGLVertexArrayBinding::Wrap(cx, this);
+    return dom::WebGLVertexArrayBinding::Wrap(cx, this, aGivenProto);
 }
 
 WebGLVertexArray::WebGLVertexArray(WebGLContext* webgl)
     : WebGLBindable<VAOBinding>()
     , WebGLContextBoundObject(webgl)
     , mGLName(0)
 {
     mContext->mVertexArrays.insertBack(this);
--- a/dom/canvas/WebGLVertexArray.h
+++ b/dom/canvas/WebGLVertexArray.h
@@ -49,17 +49,17 @@ public:
 
     // Implement parent classes:
     void Delete();
 
     WebGLContext* GetParentObject() const {
         return Context();
     }
 
-    virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
+    virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLVertexArray)
     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLVertexArray)
 
     GLuint GLName() const { return mGLName; }
 
 protected:
     explicit WebGLVertexArray(WebGLContext* webgl);
--- a/dom/cellbroadcast/CellBroadcast.cpp
+++ b/dom/cellbroadcast/CellBroadcast.cpp
@@ -97,19 +97,19 @@ CellBroadcast::~CellBroadcast()
   }
 
   mListener = nullptr;
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(CellBroadcast, DOMEventTargetHelper)
 
 JSObject*
-CellBroadcast::WrapObject(JSContext* aCx)
+CellBroadcast::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MozCellBroadcastBinding::Wrap(aCx, this);
+  return MozCellBroadcastBinding::Wrap(aCx, this, aGivenProto);
 }
 
 // Forwarded nsICellBroadcastListener methods
 
 NS_IMETHODIMP
 CellBroadcast::NotifyMessageReceived(uint32_t aServiceId,
                                      uint32_t aGsmGeographicalScope,
                                      uint16_t aMessageCode,
--- a/dom/cellbroadcast/CellBroadcast.h
+++ b/dom/cellbroadcast/CellBroadcast.h
@@ -44,17 +44,17 @@ public:
   CellBroadcast() = delete;
   CellBroadcast(nsPIDOMWindow *aWindow,
                 nsICellBroadcastService* aService);
 
   nsPIDOMWindow*
   GetParentObject() const { return GetOwner(); }
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   IMPL_EVENT_HANDLER(received)
 
 private:
   nsRefPtr<Listener> mListener;
 };
 
 } // namespace dom
--- a/dom/cellbroadcast/CellBroadcastMessage.cpp
+++ b/dom/cellbroadcast/CellBroadcastMessage.cpp
@@ -97,19 +97,19 @@ CellBroadcastMessage::CellBroadcastMessa
 
   // CdmaServiceCategory represents a 16bit unsigned value.
   if (aCdmaServiceCategory <= 0xFFFFU) {
     mCdmaServiceCategory.SetValue(static_cast<uint16_t>(aCdmaServiceCategory));
   }
 }
 
 JSObject*
-CellBroadcastMessage::WrapObject(JSContext* aCx)
+CellBroadcastMessage::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MozCellBroadcastMessageBinding::Wrap(aCx, this);
+  return MozCellBroadcastMessageBinding::Wrap(aCx, this, aGivenProto);
 }
 
 already_AddRefed<CellBroadcastEtwsInfo>
 CellBroadcastMessage::GetEtws() const
 {
   nsRefPtr<CellBroadcastEtwsInfo> etwsInfo = mEtwsInfo;
   return etwsInfo.forget();
 }
@@ -139,15 +139,15 @@ CellBroadcastEtwsInfo::CellBroadcastEtws
   if (aWarningType <
       static_cast<uint32_t>(CellBroadcastEtwsWarningType::EndGuard_)) {
     mWarningType.SetValue(
       ToWebidlEnum<CellBroadcastEtwsWarningType>(aWarningType));
   }
 }
 
 JSObject*
-CellBroadcastEtwsInfo::WrapObject(JSContext* aCx)
+CellBroadcastEtwsInfo::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MozCellBroadcastEtwsInfoBinding::Wrap(aCx, this);
+  return MozCellBroadcastEtwsInfoBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/cellbroadcast/CellBroadcastMessage.h
+++ b/dom/cellbroadcast/CellBroadcastMessage.h
@@ -39,17 +39,17 @@ public:
                        bool aHasEtwsInfo,
                        uint32_t aEtwsWarningType,
                        bool aEtwsEmergencyUserAlert,
                        bool aEtwsPopup);
 
   nsPIDOMWindow*
   GetParentObject() const { return mWindow; }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL interface
 
   uint32_t ServiceId() const { return mServiceId; }
 
   const Nullable<CellBroadcastGsmGeographicalScope>&
   GetGsmGeographicalScope() { return mGsmGeographicalScope; }
 
@@ -101,17 +101,17 @@ public:
   CellBroadcastEtwsInfo(nsPIDOMWindow* aWindow,
                         uint32_t aWarningType,
                         bool aEmergencyUserAlert,
                         bool aPopup);
 
   nsPIDOMWindow*
   GetParentObject() const { return mWindow; }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL interface
 
   const Nullable<CellBroadcastEtwsWarningType>&
   GetWarningType()  { return mWarningType; }
 
   bool EmergencyUserAlert() const { return mEmergencyUserAlert; }
 
--- a/dom/crypto/CryptoKey.cpp
+++ b/dom/crypto/CryptoKey.cpp
@@ -78,19 +78,19 @@ CryptoKey::~CryptoKey()
   if (isAlreadyShutDown()) {
     return;
   }
   destructorSafeDestroyNSSReference();
   shutdown(calledFromObject);
 }
 
 JSObject*
-CryptoKey::WrapObject(JSContext* aCx)
+CryptoKey::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CryptoKeyBinding::Wrap(aCx, this);
+  return CryptoKeyBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 CryptoKey::GetType(nsString& aRetVal) const
 {
   uint32_t type = mAttributes & TYPE_MASK;
   switch (type) {
     case PUBLIC:  aRetVal.AssignLiteral(WEBCRYPTO_KEY_TYPE_PUBLIC); break;
--- a/dom/crypto/CryptoKey.h
+++ b/dom/crypto/CryptoKey.h
@@ -93,17 +93,17 @@ public:
 
   explicit CryptoKey(nsIGlobalObject* aWindow);
 
   nsIGlobalObject* GetParentObject() const
   {
     return mGlobal;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // WebIDL methods
   void GetType(nsString& aRetVal) const;
   bool Extractable() const;
   void GetAlgorithm(JSContext* cx, JS::MutableHandle<JSObject*> aRetVal,
                     ErrorResult& aRv) const;
   void GetUsages(nsTArray<nsString>& aRetVal) const;
 
--- a/dom/datastore/DataStore.cpp
+++ b/dom/datastore/DataStore.cpp
@@ -42,19 +42,19 @@ DataStore::Constructor(GlobalObject& aGl
     return nullptr;
   }
 
   nsRefPtr<DataStore> store = new DataStore(window);
   return store.forget();
 }
 
 JSObject*
-DataStore::WrapObject(JSContext* aCx)
+DataStore::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DataStoreBinding::Wrap(aCx, this);
+  return DataStoreBinding::Wrap(aCx, this, aGivenProto);
 }
 
 /*static*/ bool
 DataStore::EnabledForScope(JSContext* aCx, JS::Handle<JSObject*> aObj)
 {
   // Only expose the interface when it is:
   // 1. enabled by the preference and
   // 2. accessed by the chrome codes in Gecko.
--- a/dom/datastore/DataStore.h
+++ b/dom/datastore/DataStore.h
@@ -28,17 +28,17 @@ public:
 
   explicit DataStore(nsPIDOMWindow* aWindow);
 
   // WebIDL (internal functions)
 
   static already_AddRefed<DataStore> Constructor(GlobalObject& aGlobal,
                                                  ErrorResult& aRv);
 
-  virtual JSObject* WrapObject(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static bool EnabledForScope(JSContext* aCx, JS::Handle<JSObject*> aObj);
 
   // WebIDL (public APIs)
 
   void GetName(nsAString& aName, ErrorResult& aRv);
 
   void GetOwner(nsAString& aOwner, ErrorResult& aRv);
--- a/dom/datastore/DataStoreCursor.cpp
+++ b/dom/datastore/DataStoreCursor.cpp
@@ -26,19 +26,20 @@ already_AddRefed<DataStoreCursor>
 DataStoreCursor::Constructor(GlobalObject& aGlobal, ErrorResult& aRv)
 {
   nsRefPtr<DataStoreCursor> cursor = new DataStoreCursor();
   return cursor.forget();
 }
 
 bool
 DataStoreCursor::WrapObject(JSContext* aCx,
+                            JS::Handle<JSObject*> aGivenProto,
                             JS::MutableHandle<JSObject*> aReflector)
 {
-  return DataStoreCursorBinding::Wrap(aCx, this, aReflector);
+  return DataStoreCursorBinding::Wrap(aCx, this, aGivenProto, aReflector);
 }
 
 already_AddRefed<DataStore>
 DataStoreCursor::GetStore(ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mCursor);
 
--- a/dom/datastore/DataStoreCursor.h
+++ b/dom/datastore/DataStoreCursor.h
@@ -28,17 +28,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(DataStoreCursor)
 
   // WebIDL (internal functions)
 
   static already_AddRefed<DataStoreCursor> Constructor(GlobalObject& aGlobal,
                                                        ErrorResult& aRv);
 
-  bool WrapObject(JSContext *aCx, JS::MutableHandle<JSObject*> aReflector);
+  bool WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
 
   // WebIDL (public APIs)
 
   already_AddRefed<DataStore> GetStore(ErrorResult& aRv);
 
   already_AddRefed<Promise> Next(ErrorResult& aRv);
 
   void Close(ErrorResult& aRv);
--- a/dom/datastore/DataStoreService.cpp
+++ b/dom/datastore/DataStoreService.cpp
@@ -1015,17 +1015,17 @@ DataStoreService::GetDataStoresResolve(n
     nsRefPtr<DataStore> exposedStore = new DataStore(aWindow);
 
     ErrorResult error;
     exposedStore->SetDataStoreImpl(*dataStoreObj, error);
     if (error.Failed()) {
       return;
     }
 
-    JS::Rooted<JSObject*> obj(cx, exposedStore->WrapObject(cx));
+    JS::Rooted<JSObject*> obj(cx, exposedStore->WrapObject(cx, JS::NullPtr()));
     MOZ_ASSERT(obj);
 
     JS::Rooted<JS::Value> exposedObject(cx, JS::ObjectValue(*obj));
     dataStore->SetExposedObject(exposedObject);
 
     counter->AppendDataStore(cx, exposedStore, dataStore);
   }
 }
--- a/dom/devicestorage/DeviceStorage.h
+++ b/dom/devicestorage/DeviceStorage.h
@@ -210,17 +210,17 @@ public:
 
   // WebIDL
   nsPIDOMWindow*
   GetParentObject() const
   {
     return GetOwner();
   }
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   IMPL_EVENT_HANDLER(change)
 
   already_AddRefed<DOMRequest>
   Add(nsIDOMBlob* aBlob, ErrorResult& aRv);
   already_AddRefed<DOMRequest>
   AddNamed(nsIDOMBlob* aBlob, const nsAString& aPath, ErrorResult& aRv);
 
--- a/dom/devicestorage/DeviceStorageRequestChild.cpp
+++ b/dom/devicestorage/DeviceStorageRequestChild.cpp
@@ -103,17 +103,17 @@ DeviceStorageRequestChild::
     {
       BlobResponse r = aValue;
       BlobChild* actor = static_cast<BlobChild*>(r.blobChild());
       nsRefPtr<FileImpl> bloblImpl = actor->GetBlobImpl();
       nsRefPtr<File> blob = new File(mRequest->GetParentObject(), bloblImpl);
 
       AutoJSContext cx;
 
-      JS::Rooted<JSObject*> obj(cx, blob->WrapObject(cx));
+      JS::Rooted<JSObject*> obj(cx, blob->WrapObject(cx, JS::NullPtr()));
       MOZ_ASSERT(obj);
 
       JS::Rooted<JS::Value> result(cx, JS::ObjectValue(*obj));
       mRequest->FireSuccess(result);
       break;
     }
 
     case DeviceStorageResponseValue::TFreeSpaceStorageResponse:
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -3341,19 +3341,19 @@ nsDOMDeviceStorage::nsDOMDeviceStorage(n
   , mIsShareable(false)
   , mIsRemovable(false)
   , mIsWatchingFile(false)
   , mAllowedToWatchFile(false)
 {
 }
 
 /* virtual */ JSObject*
-nsDOMDeviceStorage::WrapObject(JSContext* aCx)
+nsDOMDeviceStorage::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DeviceStorageBinding::Wrap(aCx, this);
+  return DeviceStorageBinding::Wrap(aCx, this, aGivenProto);
 }
 
 nsresult
 nsDOMDeviceStorage::Init(nsPIDOMWindow* aWindow, const nsAString &aType,
                          const nsAString &aVolName)
 {
   DebugOnly<FileUpdateDispatcher*> observer
     = FileUpdateDispatcher::GetSingleton();
--- a/dom/encoding/TextDecoder.h
+++ b/dom/encoding/TextDecoder.h
@@ -44,19 +44,19 @@ public:
     MOZ_COUNT_CTOR(TextDecoder);
   }
 
   ~TextDecoder()
   {
     MOZ_COUNT_DTOR(TextDecoder);
   }
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+  bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
   {
-    return TextDecoderBinding::Wrap(aCx, this, aReflector);
+    return TextDecoderBinding::Wrap(aCx, this, aGivenProto, aReflector);
   }
 
   /**
    * Validates provided label and throws an exception if invalid label.
    *
    * @param aLabel       The encoding label (case insensitive) provided.
    * @param aFatal       indicates whether to throw an 'EncodingError'
    *                     exception or not when decoding.
--- a/dom/encoding/TextEncoder.h
+++ b/dom/encoding/TextEncoder.h
@@ -37,19 +37,19 @@ public:
   TextEncoder()
   {
   }
 
   virtual
   ~TextEncoder()
   {}
 
-  bool WrapObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector)
+  bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
   {
-    return TextEncoderBinding::Wrap(aCx, this, aReflector);
+    return TextEncoderBinding::Wrap(aCx, this, aGivenProto, aReflector);
   }
 
 protected:
 
   /**
    * Validates provided encoding and throws an exception if invalid encoding.
    * If no encoding is provided then mEncoding is default initialised to "utf-8".
    *
--- a/dom/events/AnimationEvent.h
+++ b/dom/events/AnimationEvent.h
@@ -28,19 +28,19 @@ public:
   NS_DECL_NSIDOMANIMATIONEVENT
 
   static already_AddRefed<AnimationEvent>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const AnimationEventInit& aParam,
               ErrorResult& aRv);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return AnimationEventBinding::Wrap(aCx, this);
+    return AnimationEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   // xpidl implementation
   // GetAnimationName(nsAString& aAnimationName);
   // GetPseudoElement(nsAString& aPseudoElement);
 
   float ElapsedTime();
 
--- a/dom/events/BeforeAfterKeyboardEvent.h
+++ b/dom/events/BeforeAfterKeyboardEvent.h
@@ -14,19 +14,19 @@ namespace dom {
 
 class BeforeAfterKeyboardEvent : public KeyboardEvent
 {
 public:
   BeforeAfterKeyboardEvent(EventTarget* aOwner,
                            nsPresContext* aPresContext,
                            InternalBeforeAfterKeyboardEvent* aEvent);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return BeforeAfterKeyboardEventBinding::Wrap(aCx, this);
+    return BeforeAfterKeyboardEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   static already_AddRefed<BeforeAfterKeyboardEvent>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const BeforeAfterKeyboardEventInit& aParam,
               ErrorResult& aRv);
 
--- a/dom/events/BeforeUnloadEvent.h
+++ b/dom/events/BeforeUnloadEvent.h
@@ -19,19 +19,19 @@ class BeforeUnloadEvent : public Event,
 public:
   BeforeUnloadEvent(EventTarget* aOwner,
                     nsPresContext* aPresContext,
                     WidgetEvent* aEvent)
     : Event(aOwner, aPresContext, aEvent)
   {
   }
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return BeforeUnloadEventBinding::Wrap(aCx, this);
+    return BeforeUnloadEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Forward to Event
   NS_FORWARD_TO_EVENT
 
   // nsIDOMBeforeUnloadEvent Interface
--- a/dom/events/ClipboardEvent.h
+++ b/dom/events/ClipboardEvent.h
@@ -25,19 +25,19 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMCLIPBOARDEVENT
 
   // Forward to base class
   NS_FORWARD_TO_EVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return ClipboardEventBinding::Wrap(aCx, this);
+    return ClipboardEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   static already_AddRefed<ClipboardEvent>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const ClipboardEventInit& aParam,
               ErrorResult& aRv);
 
--- a/dom/events/CommandEvent.h
+++ b/dom/events/CommandEvent.h
@@ -24,19 +24,19 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMCOMMANDEVENT
 
   // Forward to base class
   NS_FORWARD_TO_EVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return CommandEventBinding::Wrap(aCx, this);
+    return CommandEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   void InitCommandEvent(const nsAString& aType,
                         bool aCanBubble,
                         bool aCancelable,
                         const nsAString& aCommand,
                         ErrorResult& aRv)
   {
--- a/dom/events/CompositionEvent.h
+++ b/dom/events/CompositionEvent.h
@@ -22,19 +22,19 @@ public:
   CompositionEvent(EventTarget* aOwner,
                    nsPresContext* aPresContext,
                    WidgetCompositionEvent* aEvent);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_FORWARD_TO_UIEVENT
   NS_DECL_NSIDOMCOMPOSITIONEVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return CompositionEventBinding::Wrap(aCx, this);
+    return CompositionEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   void InitCompositionEvent(const nsAString& aType,
                             bool aCanBubble,
                             bool aCancelable,
                             nsIDOMWindow* aView,
                             const nsAString& aData,
                             const nsAString& aLocale,
--- a/dom/events/CustomEvent.cpp
+++ b/dom/events/CustomEvent.cpp
@@ -48,19 +48,19 @@ CustomEvent::Constructor(const GlobalObj
   bool trusted = e->Init(t);
   JS::Rooted<JS::Value> detail(aGlobal.Context(), aParam.mDetail);
   e->InitCustomEvent(aGlobal.Context(), aType, aParam.mBubbles, aParam.mCancelable, detail, aRv);
   e->SetTrusted(trusted);
   return e.forget();
 }
 
 JSObject*
-CustomEvent::WrapObjectInternal(JSContext* aCx)
+CustomEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::CustomEventBinding::Wrap(aCx, this);
+  return mozilla::dom::CustomEventBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMETHODIMP
 CustomEvent::InitCustomEvent(const nsAString& aType,
                              bool aCanBubble,
                              bool aCancelable,
                              nsIVariant* aDetail)
 {
--- a/dom/events/CustomEvent.h
+++ b/dom/events/CustomEvent.h
@@ -33,17 +33,17 @@ public:
 
   static already_AddRefed<CustomEvent>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const CustomEventInit& aParam,
               ErrorResult& aRv);
 
   virtual JSObject*
-  WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void
   GetDetail(JSContext* aCx,
             JS::MutableHandle<JS::Value> aRetval);
 
   void
   InitCustomEvent(JSContext* aCx,
                   const nsAString& aType,
--- a/dom/events/DataContainerEvent.h
+++ b/dom/events/DataContainerEvent.h
@@ -26,19 +26,19 @@ public:
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DataContainerEvent, Event)
 
   NS_FORWARD_TO_EVENT
 
   NS_DECL_NSIDOMDATACONTAINEREVENT
 
   virtual JSObject*
-  WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return DataContainerEventBinding::Wrap(aCx, this);
+    return DataContainerEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   already_AddRefed<nsIVariant> GetData(const nsAString& aKey)
   {
     nsCOMPtr<nsIVariant> val;
     GetData(aKey, getter_AddRefs(val));
     return val.forget();
   }
--- a/dom/events/DataTransfer.cpp
+++ b/dom/events/DataTransfer.cpp
@@ -162,19 +162,19 @@ DataTransfer::Constructor(const GlobalOb
   uint32_t eventType = nsContentUtils::GetEventId(eventTypeAtom);
   nsRefPtr<DataTransfer> transfer = new DataTransfer(aGlobal.GetAsSupports(),
                                                      eventType, aIsExternal,
                                                      -1);
   return transfer.forget();
 }
 
 JSObject*
-DataTransfer::WrapObject(JSContext* aCx)
+DataTransfer::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DataTransferBinding::Wrap(aCx, this);
+  return DataTransferBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMETHODIMP
 DataTransfer::GetDropEffect(nsAString& aDropEffect)
 {
   nsString dropEffect;
   GetDropEffect(dropEffect);
   aDropEffect = dropEffect;
--- a/dom/events/DataTransfer.h
+++ b/dom/events/DataTransfer.h
@@ -99,17 +99,17 @@ public:
   // latter will occur when an external drag occurs, that is, a drag where the
   // source is another application, or a drag is started by calling the drag
   // service directly. For clipboard operations, aClipboardType indicates
   // which clipboard to use, from nsIClipboard, or -1 for non-clipboard operations,
   // or if access to the system clipboard should not be allowed.
   DataTransfer(nsISupports* aParent, uint32_t aEventType, bool aIsExternal,
                int32_t aClipboardType);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   nsISupports* GetParentObject()
   {
     return mParent;
   }
 
   void SetParentObject(nsISupports* aNewParent)
   {
     MOZ_ASSERT(aNewParent);
--- a/dom/events/DeviceMotionEvent.h
+++ b/dom/events/DeviceMotionEvent.h
@@ -22,19 +22,19 @@ public:
                      Nullable<double> aAlpha, Nullable<double> aBeta,
                      Nullable<double> aGamma);
 
   DeviceMotionEvent* GetParentObject() const
   {
     return mOwner;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return DeviceRotationRateBinding::Wrap(aCx, this);
+    return DeviceRotationRateBinding::Wrap(aCx, this, aGivenProto);
   }
 
   Nullable<double> GetAlpha() const { return mAlpha; }
   Nullable<double> GetBeta() const { return mBeta; }
   Nullable<double> GetGamma() const { return mGamma; }
 
 private:
   ~DeviceRotationRate();
@@ -54,19 +54,19 @@ public:
                      Nullable<double> aX, Nullable<double> aY,
                      Nullable<double> aZ);
 
   DeviceMotionEvent* GetParentObject() const
   {
     return mOwner;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return DeviceAccelerationBinding::Wrap(aCx, this);
+    return DeviceAccelerationBinding::Wrap(aCx, this, aGivenProto);
   }
 
   Nullable<double> GetX() const { return mX; }
   Nullable<double> GetY() const { return mY; }
   Nullable<double> GetZ() const { return mZ; }
 
 private:
   ~DeviceAcceleration();
@@ -89,19 +89,19 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Forward to Event
   NS_FORWARD_TO_EVENT
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DeviceMotionEvent, Event)
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return DeviceMotionEventBinding::Wrap(aCx, this);
+    return DeviceMotionEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   DeviceAcceleration* GetAcceleration() const
   {
     return mAcceleration;
   }
 
   DeviceAcceleration* GetAccelerationIncludingGravity() const
--- a/dom/events/DragEvent.h
+++ b/dom/events/DragEvent.h
@@ -25,19 +25,19 @@ public:
             WidgetDragEvent* aEvent);
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMDRAGEVENT
 
   NS_FORWARD_TO_MOUSEEVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return DragEventBinding::Wrap(aCx, this);
+    return DragEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   DataTransfer* GetDataTransfer();
 
   void InitDragEvent(const nsAString& aType,
                      bool aCanBubble, bool aCancelable,
                      nsIDOMWindow* aView, int32_t aDetail,
                      int32_t aScreenX, int32_t aScreenY,
--- a/dom/events/Event.cpp
+++ b/dom/events/Event.cpp
@@ -229,28 +229,28 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresContext)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExplicitOriginalTarget)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 
 JSObject*
-Event::WrapObject(JSContext* aCx)
+Event::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   if (mIsMainThreadEvent && !GetWrapperPreserveColor()) {
     nsJSContext::LikelyShortLivingObjectCreated();
   }
-  return WrapObjectInternal(aCx);
+  return WrapObjectInternal(aCx, aGivenProto);
 }
 
 JSObject*
-Event::WrapObjectInternal(JSContext* aCx)
+Event::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return EventBinding::Wrap(aCx, this);
+  return EventBinding::Wrap(aCx, this, aGivenProto);
 }
 
 bool
 Event::IsChrome(JSContext* aCx) const
 {
   return mIsMainThreadEvent ?
     xpc::AccessCheck::isChrome(js::GetContextCompartment(aCx)) :
     mozilla::dom::workers::IsCurrentThreadRunningChromeWorker();
--- a/dom/events/Event.h
+++ b/dom/events/Event.h
@@ -85,19 +85,19 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Event)
 
   nsIGlobalObject* GetParentObject()
   {
     return mOwner;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE MOZ_FINAL;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE MOZ_FINAL;
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx);
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto);
 
 #define GENERATED_EVENT(EventClass_) \
   virtual EventClass_* As##EventClass_()  \
   {                                       \
     return nullptr;                       \
   }
 #include "mozilla/dom/GeneratedEventList.h"
 #undef GENERATED_EVENT
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -92,17 +92,16 @@ MutationBitForEventType(uint32_t aEventT
 
 uint32_t EventListenerManager::sMainThreadCreatedCount = 0;
 
 EventListenerManager::EventListenerManager(EventTarget* aTarget)
   : mMayHavePaintEventListener(false)
   , mMayHaveMutationListeners(false)
   , mMayHaveCapturingListeners(false)
   , mMayHaveSystemGroupListeners(false)
-  , mMayHaveTouchEventListener(false)
   , mMayHaveMouseEnterLeaveEventListener(false)
   , mMayHavePointerEnterLeaveEventListener(false)
   , mClearingListeners(false)
   , mIsMainThreadELM(NS_IsMainThread())
   , mNoListenerForEvent(0)
   , mTarget(aTarget)
 {
   NS_ASSERTION(aTarget, "unexpected null pointer");
@@ -323,27 +322,16 @@ EventListenerManager::AddEventListenerIn
       window->EnableNetworkEvent(NS_NETWORK_UPLOAD_EVENT);
     }
   } else if (aTypeAtom == nsGkAtoms::onmoznetworkdownload) {
     nsCOMPtr<nsPIDOMWindow> window = GetTargetAsInnerWindow();
     if (window) {
       window->EnableNetworkEvent(NS_NETWORK_DOWNLOAD_EVENT);
     }
 #endif // MOZ_B2G
-  } else if (aTypeAtom == nsGkAtoms::ontouchstart ||
-             aTypeAtom == nsGkAtoms::ontouchend ||
-             aTypeAtom == nsGkAtoms::ontouchmove ||
-             aTypeAtom == nsGkAtoms::ontouchcancel) {
-    mMayHaveTouchEventListener = true;
-    nsPIDOMWindow* window = GetInnerWindowForTarget();
-    // we don't want touchevent listeners added by scrollbars to flip this flag
-    // so we ignore listeners created with system event flag
-    if (window && !aFlags.mInSystemGroup) {
-      window->SetHasTouchEventListeners();
-    }
   } else if (aType >= NS_POINTER_EVENT_START && aType <= NS_POINTER_LOST_CAPTURE) {
     nsPIDOMWindow* window = GetInnerWindowForTarget();
     if (aTypeAtom == nsGkAtoms::onpointerenter ||
         aTypeAtom == nsGkAtoms::onpointerleave) {
       mMayHavePointerEnterLeaveEventListener = true;
       if (window) {
 #ifdef DEBUG
         nsCOMPtr<nsIDocument> d = window->GetExtantDoc();
--- a/dom/events/EventListenerManager.h
+++ b/dom/events/EventListenerManager.h
@@ -383,22 +383,16 @@ public:
   static void Shutdown();
 
   /**
    * Returns true if there may be a paint event listener registered,
    * false if there definitely isn't.
    */
   bool MayHavePaintEventListener() { return mMayHavePaintEventListener; }
 
-  /**
-   * Returns true if there may be a touch event listener registered,
-   * false if there definitely isn't.
-   */
-  bool MayHaveTouchEventListener() { return mMayHaveTouchEventListener; }
-
   bool MayHaveMouseEnterLeaveEventListener() { return mMayHaveMouseEnterLeaveEventListener; }
   bool MayHavePointerEnterLeaveEventListener() { return mMayHavePointerEnterLeaveEventListener; }
 
   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
 
   uint32_t ListenerCount() const
   {
     return mListeners.Length();
@@ -538,17 +532,16 @@ protected:
 
   already_AddRefed<nsIScriptGlobalObject>
   GetScriptGlobalAndDocument(nsIDocument** aDoc);
 
   uint32_t mMayHavePaintEventListener : 1;
   uint32_t mMayHaveMutationListeners : 1;
   uint32_t mMayHaveCapturingListeners : 1;
   uint32_t mMayHaveSystemGroupListeners : 1;
-  uint32_t mMayHaveTouchEventListener : 1;
   uint32_t mMayHaveMouseEnterLeaveEventListener : 1;
   uint32_t mMayHavePointerEnterLeaveEventListener : 1;
   uint32_t mClearingListeners : 1;
   uint32_t mIsMainThreadELM : 1;
   uint32_t mNoListenerForEvent : 23;
 
   nsAutoTObserverArray<Listener, 2> mListeners;
   dom::EventTarget* MOZ_NON_OWNING_REF mTarget;
--- a/dom/events/FocusEvent.h
+++ b/dom/events/FocusEvent.h
@@ -18,19 +18,19 @@ class FocusEvent : public UIEvent,
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMFOCUSEVENT
 
   // Forward to base class
   NS_FORWARD_TO_UIEVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return FocusEventBinding::Wrap(aCx, this);
+    return FocusEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   FocusEvent(EventTarget* aOwner,
              nsPresContext* aPresContext,
              InternalFocusEvent* aEvent);
 
   EventTarget* GetRelatedTarget();
 
--- a/dom/events/ImageCaptureError.cpp
+++ b/dom/events/ImageCaptureError.cpp
@@ -32,19 +32,19 @@ ImageCaptureError::~ImageCaptureError()
 
 nsISupports*
 ImageCaptureError::GetParentObject() const
 {
   return mParent;
 }
 
 JSObject*
-ImageCaptureError::WrapObject(JSContext* aCx)
+ImageCaptureError::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return ImageCaptureErrorBinding::Wrap(aCx, this);
+  return ImageCaptureErrorBinding::Wrap(aCx, this, aGivenProto);
 }
 
 uint16_t
 ImageCaptureError::Code() const
 {
   return mCode;
 }
 
--- a/dom/events/ImageCaptureError.h
+++ b/dom/events/ImageCaptureError.h
@@ -26,17 +26,17 @@ class ImageCaptureError MOZ_FINAL : publ
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ImageCaptureError)
 
   ImageCaptureError(nsISupports* aParent, uint16_t aCode, const nsAString& aMessage);
 
   nsISupports* GetParentObject() const;
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   uint16_t Code() const;
 
   enum {
     FRAME_GRAB_ERROR = 1,
     SETTINGS_ERROR = 2,
     PHOTO_ERROR = 3,
     ERROR_UNKNOWN = 4,
--- a/dom/events/InputEvent.h
+++ b/dom/events/InputEvent.h
@@ -26,19 +26,19 @@ public:
   NS_FORWARD_TO_UIEVENT
 
 
   static already_AddRefed<InputEvent> Constructor(const GlobalObject& aGlobal,
                                                   const nsAString& aType,
                                                   const InputEventInit& aParam,
                                                   ErrorResult& aRv);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return InputEventBinding::Wrap(aCx, this);
+    return InputEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   bool IsComposing();
 
 protected:
   ~InputEvent() {}
 };
 
--- a/dom/events/KeyboardEvent.h
+++ b/dom/events/KeyboardEvent.h
@@ -31,19 +31,19 @@ public:
   NS_FORWARD_TO_UIEVENT
 
   static already_AddRefed<KeyboardEvent> Constructor(
                                            const GlobalObject& aGlobal,
                                            const nsAString& aType,
                                            const KeyboardEventInit& aParam,
                                            ErrorResult& aRv);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return KeyboardEventBinding::Wrap(aCx, this);
+    return KeyboardEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   bool AltKey();
   bool CtrlKey();
   bool ShiftKey();
   bool MetaKey();
 
   bool GetModifierState(const nsAString& aKey)
--- a/dom/events/MessageEvent.cpp
+++ b/dom/events/MessageEvent.cpp
@@ -55,19 +55,19 @@ MessageEvent::MessageEvent(EventTarget* 
 
 MessageEvent::~MessageEvent()
 {
   mData.setUndefined();
   DropJSObjects(this);
 }
 
 JSObject*
-MessageEvent::WrapObjectInternal(JSContext* aCx)
+MessageEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::MessageEventBinding::Wrap(aCx, this);
+  return mozilla::dom::MessageEventBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMETHODIMP
 MessageEvent::GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData)
 {
   ErrorResult rv;
   GetData(aCx, aData, rv);
   return rv.ErrorCode();
--- a/dom/events/MessageEvent.h
+++ b/dom/events/MessageEvent.h
@@ -44,17 +44,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(MessageEvent, Event)
 
   NS_DECL_NSIDOMMESSAGEEVENT
 
   // Forward to base class
   NS_FORWARD_TO_EVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData,
                ErrorResult& aRv);
 
   void GetSource(Nullable<OwningWindowProxyOrMessagePortOrClient>& aValue) const;
 
   MessagePortList* GetPorts()
   {
--- a/dom/events/MouseEvent.h
+++ b/dom/events/MouseEvent.h
@@ -25,19 +25,19 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMMouseEvent Interface
   NS_DECL_NSIDOMMOUSEEVENT
 
   // Forward to base class
   NS_FORWARD_TO_UIEVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return MouseEventBinding::Wrap(aCx, this);
+    return MouseEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   // Web IDL binding methods
   virtual uint32_t Which() MOZ_OVERRIDE
   {
     return Button() + 1;
   }
 
--- a/dom/events/MouseScrollEvent.h
+++ b/dom/events/MouseScrollEvent.h
@@ -24,19 +24,19 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMMouseScrollEvent Interface
   NS_DECL_NSIDOMMOUSESCROLLEVENT
 
   // Forward to base class
   NS_FORWARD_TO_MOUSEEVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return MouseScrollEventBinding::Wrap(aCx, this);
+    return MouseScrollEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   int32_t Axis();
 
   void InitMouseScrollEvent(const nsAString& aType, bool aCanBubble,
                             bool aCancelable, nsIDOMWindow* aView,
                             int32_t aDetail, int32_t aScreenX, int32_t aScreenY,
                             int32_t aClientX, int32_t aClientY,
--- a/dom/events/MutationEvent.h
+++ b/dom/events/MutationEvent.h
@@ -25,19 +25,19 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMMUTATIONEVENT
 
   // Forward to base class
   NS_FORWARD_TO_EVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return MutationEventBinding::Wrap(aCx, this);
+    return MutationEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   // xpidl implementation
   // GetPrevValue(nsAString& aPrevValue);
   // GetNewValue(nsAString& aNewValue);
   // GetAttrName(nsAString& aAttrName);
 
   already_AddRefed<nsINode> GetRelatedNode();
--- a/dom/events/NotifyPaintEvent.h
+++ b/dom/events/NotifyPaintEvent.h
@@ -38,19 +38,19 @@ public:
   NS_FORWARD_TO_EVENT_NO_SERIALIZATION_NO_DUPLICATION
   NS_IMETHOD DuplicatePrivateData() MOZ_OVERRIDE
   {
     return Event::DuplicatePrivateData();
   }
   NS_IMETHOD_(void) Serialize(IPC::Message* aMsg, bool aSerializeInterfaceType) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) Deserialize(const IPC::Message* aMsg, void** aIter) MOZ_OVERRIDE;
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return NotifyPaintEventBinding::Wrap(aCx, this);
+    return NotifyPaintEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   already_AddRefed<DOMRectList> ClientRects();
 
   already_AddRefed<DOMRect> BoundingClientRect();
 
   already_AddRefed<PaintRequestList> PaintRequests();
 
--- a/dom/events/PaintRequest.cpp
+++ b/dom/events/PaintRequest.cpp
@@ -23,19 +23,19 @@ NS_INTERFACE_TABLE_HEAD(PaintRequest)
   NS_INTERFACE_TABLE(PaintRequest, nsIDOMPaintRequest)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(PaintRequest)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(PaintRequest)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(PaintRequest)
 
 /* virtual */ JSObject*
-PaintRequest::WrapObject(JSContext* aCx)
+PaintRequest::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PaintRequestBinding::Wrap(aCx, this);
+  return PaintRequestBinding::Wrap(aCx, this, aGivenProto);
 }
 
 already_AddRefed<DOMRect>
 PaintRequest::ClientRect()
 {
   nsRefPtr<DOMRect> clientRect = new DOMRect(this);
   clientRect->SetLayoutRect(mRequest.mRect);
   return clientRect.forget();
@@ -66,15 +66,15 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(PaintRequestList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(PaintRequestList)
 
 JSObject*
-PaintRequestList::WrapObject(JSContext* aCx)
+PaintRequestList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PaintRequestListBinding::Wrap(aCx, this);
+  return PaintRequestListBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/events/PaintRequest.h
+++ b/dom/events/PaintRequest.h
@@ -26,17 +26,17 @@ public:
   {
     mRequest.mFlags = 0;
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(PaintRequest)
   NS_DECL_NSIDOMPAINTREQUEST
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsIDOMEvent* GetParentObject() const
   {
     return mParent;
   }
 
   already_AddRefed<DOMRect> ClientRect();
   void GetReason(nsAString& aResult) const
@@ -60,17 +60,17 @@ class PaintRequestList MOZ_FINAL : publi
 public:
   explicit PaintRequestList(nsIDOMEvent *aParent) : mParent(aParent)
   {
   }
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(PaintRequestList)
   
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   nsISupports* GetParentObject()
   {
     return mParent;
   }
 
   void Append(PaintRequest* aElement)
   {
     mArray.AppendElement(aElement);
--- a/dom/events/PointerEvent.h
+++ b/dom/events/PointerEvent.h
@@ -17,19 +17,19 @@ namespace dom {
 
 class PointerEvent : public MouseEvent
 {
 public:
   PointerEvent(EventTarget* aOwner,
                nsPresContext* aPresContext,
                WidgetPointerEvent* aEvent);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return PointerEventBinding::Wrap(aCx, this);
+    return PointerEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   static already_AddRefed<PointerEvent>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const PointerEventInit& aParam,
               ErrorResult& aRv);
 
--- a/dom/events/ScrollAreaEvent.h
+++ b/dom/events/ScrollAreaEvent.h
@@ -33,19 +33,19 @@ public:
   NS_FORWARD_TO_EVENT_NO_SERIALIZATION_NO_DUPLICATION
   NS_IMETHOD DuplicatePrivateData() MOZ_OVERRIDE
   {
     return Event::DuplicatePrivateData();
   }
   NS_IMETHOD_(void) Serialize(IPC::Message* aMsg, bool aSerializeInterfaceType) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) Deserialize(const IPC::Message* aMsg, void** aIter) MOZ_OVERRIDE;
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return ScrollAreaEventBinding::Wrap(aCx, this);
+    return ScrollAreaEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   float X() const
   {
     return mClientArea->Left();
   }
 
   float Y() const
--- a/dom/events/SimpleGestureEvent.h
+++ b/dom/events/SimpleGestureEvent.h
@@ -25,19 +25,19 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIDOMSIMPLEGESTUREEVENT
 
   // Forward to base class
   NS_FORWARD_TO_MOUSEEVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return SimpleGestureEventBinding::Wrap(aCx, this);
+    return SimpleGestureEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   uint32_t AllowedDirections();
   uint32_t Direction();
   double Delta();
   uint32_t ClickCount();
 
   void InitSimpleGestureEvent(const nsAString& aType,
--- a/dom/events/SpeechRecognitionError.h
+++ b/dom/events/SpeechRecognitionError.h
@@ -21,19 +21,19 @@ public:
   virtual ~SpeechRecognitionError();
 
   static already_AddRefed<SpeechRecognitionError>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const SpeechRecognitionErrorInit& aParam,
               ErrorResult& aRv);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return mozilla::dom::SpeechRecognitionErrorBinding::Wrap(aCx, this);
+    return mozilla::dom::SpeechRecognitionErrorBinding::Wrap(aCx, this, aGivenProto);
   }
 
   void
   GetMessage(nsAString& aString)
   {
     aString = mMessage;
   }
 
--- a/dom/events/StorageEvent.cpp
+++ b/dom/events/StorageEvent.cpp
@@ -40,19 +40,19 @@ StorageEvent::~StorageEvent()
 
 StorageEvent*
 StorageEvent::AsStorageEvent()
 {
   return this;
 }
 
 JSObject*
-StorageEvent::WrapObjectInternal(JSContext* aCx)
+StorageEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return StorageEventBinding::Wrap(aCx, this);
+  return StorageEventBinding::Wrap(aCx, this, aGivenProto);
 }
 
 already_AddRefed<StorageEvent>
 StorageEvent::Constructor(EventTarget* aOwner,
                           const nsAString& aType,
                           const StorageEventInit& aEventInitDict)
 {
   nsRefPtr<StorageEvent> e = new StorageEvent(aOwner);
--- a/dom/events/StorageEvent.h
+++ b/dom/events/StorageEvent.h
@@ -37,17 +37,17 @@ protected:
   nsString mOldValue;
   nsString mNewValue;
   nsString mUrl;
   nsRefPtr<DOMStorage> mStorageArea;
 
 public:
   virtual StorageEvent* AsStorageEvent();
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static already_AddRefed<StorageEvent>
   Constructor(EventTarget* aOwner, const nsAString& aType,
               const StorageEventInit& aEventInitDict);
 
   static already_AddRefed<StorageEvent>
   Constructor(const GlobalObject& aGlobal, const nsAString& aType,
               const StorageEventInit& aEventInitDict, ErrorResult& aRv);
--- a/dom/events/Touch.cpp
+++ b/dom/events/Touch.cpp
@@ -125,19 +125,19 @@ Touch::Equals(Touch* aTouch)
   return mRefPoint == aTouch->mRefPoint &&
          mForce == aTouch->Force() &&
          mRotationAngle == aTouch->RotationAngle() &&
          mRadius.x == aTouch->RadiusX() &&
          mRadius.y == aTouch->RadiusY();
 }
 
 JSObject*
-Touch::WrapObject(JSContext* aCx)
+Touch::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return TouchBinding::Wrap(aCx, this);
+  return TouchBinding::Wrap(aCx, this, aGivenProto);
 }
 
 // Parent ourselves to the window of the target. This achieves the desirable
 // effects of parenting to the target, but avoids making the touch inaccessible
 // when the target happens to be NAC and therefore reflected into the XBL scope.
 EventTarget*
 Touch::GetParentObject()
 {
--- a/dom/events/Touch.h
+++ b/dom/events/Touch.h
@@ -49,17 +49,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Touch)
 
   void InitializePoints(nsPresContext* aPresContext, WidgetEvent* aEvent);
 
   void SetTarget(EventTarget* aTarget);
 
   bool Equals(Touch* aTouch);
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   EventTarget* GetParentObject();
 
   // WebIDL
   int32_t Identifier() const { return mIdentifier; }
   EventTarget* GetTarget() const;
   int32_t ScreenX() const { return mScreenPoint.x; }
   int32_t ScreenY() const { return mScreenPoint.y; }
--- a/dom/events/TouchEvent.cpp
+++ b/dom/events/TouchEvent.cpp
@@ -31,19 +31,19 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TouchList, mParent, mPoints)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(TouchList)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(TouchList)
 
 JSObject*
-TouchList::WrapObject(JSContext* aCx)
+TouchList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return TouchListBinding::Wrap(aCx, this);
+  return TouchListBinding::Wrap(aCx, this, aGivenProto);
 }
 
 // static
 bool
 TouchList::PrefEnabled(JSContext* aCx, JSObject* aGlobal)
 {
   return TouchEvent::PrefEnabled(aCx, aGlobal);
 }
--- a/dom/events/TouchEvent.h
+++ b/dom/events/TouchEvent.h
@@ -39,17 +39,17 @@ public:
     nsJSContext::LikelyShortLivingObjectCreated();
   }
 
   void Append(Touch* aPoint)
   {
     mPoints.AppendElement(aPoint);
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsISupports* GetParentObject() const
   {
     return mParent;
   }
 
   static bool PrefEnabled(JSContext* aCx = nullptr,
                           JSObject* aGlobal = nullptr);
@@ -84,19 +84,19 @@ class TouchEvent : public UIEvent
 public:
   TouchEvent(EventTarget* aOwner,
              nsPresContext* aPresContext,
              WidgetTouchEvent* aEvent);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TouchEvent, UIEvent)
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return TouchEventBinding::Wrap(aCx, this);
+    return TouchEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   TouchList* Touches();
   TouchList* TargetTouches();
   TouchList* ChangedTouches();
 
   bool AltKey();
   bool MetaKey();
--- a/dom/events/TransitionEvent.h
+++ b/dom/events/TransitionEvent.h
@@ -28,19 +28,19 @@ public:
   NS_DECL_NSIDOMTRANSITIONEVENT
 
   static already_AddRefed<TransitionEvent>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const TransitionEventInit& aParam,
               ErrorResult& aRv);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return TransitionEventBinding::Wrap(aCx, this);
+    return TransitionEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   // xpidl implementation
   // GetPropertyName(nsAString& aPropertyName)
   // GetPseudoElement(nsAString& aPreudoElement)
 
   float ElapsedTime();
 
--- a/dom/events/UIEvent.h
+++ b/dom/events/UIEvent.h
@@ -96,19 +96,19 @@ public:
     return CSSIntPoint::FromAppUnitsRounded(pt);
   }
 
   static already_AddRefed<UIEvent> Constructor(const GlobalObject& aGlobal,
                                                const nsAString& aType,
                                                const UIEventInit& aParam,
                                                ErrorResult& aRv);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return UIEventBinding::Wrap(aCx, this);
+    return UIEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   nsIDOMWindow* GetView() const
   {
     return mView;
   }
 
   int32_t Detail() const
--- a/dom/events/WheelEvent.h
+++ b/dom/events/WheelEvent.h
@@ -32,19 +32,19 @@ public:
   NS_FORWARD_TO_MOUSEEVENT
 
   static
   already_AddRefed<WheelEvent> Constructor(const GlobalObject& aGlobal,
                                            const nsAString& aType,
                                            const WheelEventInit& aParam,
                                            ErrorResult& aRv);
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return WheelEventBinding::Wrap(aCx, this);
+    return WheelEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   // NOTE: DeltaX(), DeltaY() and DeltaZ() return CSS pixels when deltaMode is
   //       DOM_DELTA_PIXEL. (The internal event's delta values are device pixels
   //       if it's dispatched by widget)
   double DeltaX();
   double DeltaY();
   double DeltaZ();
--- a/dom/events/XULCommandEvent.h
+++ b/dom/events/XULCommandEvent.h
@@ -26,19 +26,19 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(XULCommandEvent, UIEvent)
   NS_DECL_NSIDOMXULCOMMANDEVENT
 
   // Forward our inherited virtual methods to the base class
   NS_FORWARD_TO_UIEVENT
 
-  virtual JSObject* WrapObjectInternal(JSContext* aCx) MOZ_OVERRIDE
+  virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return XULCommandEventBinding::Wrap(aCx, this);
+    return XULCommandEventBinding::Wrap(aCx, this, aGivenProto);
   }
 
   bool AltKey();
   bool CtrlKey();
   bool ShiftKey();
   bool MetaKey();
 
   already_AddRefed<Event> GetSourceEvent()
--- a/dom/events/test/bug648573.html
+++ b/dom/events/test/bug648573.html
@@ -16,19 +16,16 @@ https://bugzilla.mozilla.org/show_bug.cg
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 648573 **/
 SimpleTest.waitForExplicitFinish();
 var utils = SpecialPowers.getDOMWindowUtils(window);
 
-ok(!utils.mayHaveTouchEventListeners,
-  "There shouldn't be any touch event listeners yet.");
-
 ok("createTouch" in document, "Should have createTouch function");
 ok("createTouchList" in document, "Should have createTouchList function");
 ok(document.createEvent("touchevent"), "Should be able to create TouchEvent objects");
 
 var t1 = document.createTouch(window, document, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
 is(t1.target, document, "Wrong target");
 is(t1.identifier, 1, "Wrong identifier");
 is(t1.pageX, 2, "Wrong pageX");
@@ -96,16 +93,14 @@ function runEventTest(type) {
   t.dispatchEvent(e);
   ok(t.didCall, "Should have called the listener(2)");
 }
 
 for (var i = 0; i < events.length; ++i) {
   runEventTest(events[i]);
 }
 
-ok(utils.mayHaveTouchEventListeners,
-  "There should be touch event listeners.");
 SimpleTest.finish();
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/fetch/Headers.cpp
+++ b/dom/fetch/Headers.cpp
@@ -70,18 +70,18 @@ Headers::Constructor(const GlobalObject&
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   return headers.forget();
 }
 
 JSObject*
-Headers::WrapObject(JSContext* aCx)
+Headers::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return mozilla::dom::HeadersBinding::Wrap(aCx, this);
+  return mozilla::dom::HeadersBinding::Wrap(aCx, this, aGivenProto);
 }
 
 Headers::~Headers()
 {
 }
 } // namespace dom
 } // namespace mozilla
--- a/dom/fetch/Headers.h
+++ b/dom/fetch/Headers.h
@@ -105,17 +105,17 @@ public:
     return mInternalHeaders->Guard();
   }
 
   void SetGuard(HeadersGuardEnum aGuard, ErrorResult& aRv)
   {
     mInternalHeaders->SetGuard(aGuard, aRv);
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   nsISupports* GetParentObject() const { return mOwner; }
 
 private:
   virtual ~Headers();
 
   InternalHeaders*
   GetInternalHeaders() const
   {
--- a/dom/fetch/Request.h
+++ b/dom/fetch/Request.h
@@ -32,19 +32,19 @@ class Request MOZ_FINAL : public nsISupp
 {
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Request)
 
 public:
   Request(nsIGlobalObject* aOwner, InternalRequest* aRequest);
 
   JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return RequestBinding::Wrap(aCx, this);
+    return RequestBinding::Wrap(aCx, this, aGivenProto);
   }
 
   void
   GetUrl(nsAString& aUrl) const
   {
     CopyUTF8toUTF16(mRequest->mURL, aUrl);
   }
 
--- a/dom/fetch/Response.h
+++ b/dom/fetch/Response.h
@@ -32,19 +32,19 @@ class Response MOZ_FINAL : public nsISup
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Response)
 
 public:
   Response(nsIGlobalObject* aGlobal, InternalResponse* aInternalResponse);
 
   Response(const Response& aOther) = delete;
 
   JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE
   {
-    return ResponseBinding::Wrap(aCx, this);
+    return ResponseBinding::Wrap(aCx, this, aGivenProto);
   }
 
   ResponseType
   Type() const
   {
     return mInternalResponse->Type();
   }
 
--- a/dom/filesystem/Directory.cpp
+++ b/dom/filesystem/Directory.cpp
@@ -70,19 +70,19 @@ Directory::~Directory()
 
 nsPIDOMWindow*
 Directory::GetParentObject() const
 {
   return mFileSystem->GetWindow();
 }
 
 JSObject*
-Directory::WrapObject(JSContext* aCx)
+Directory::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return DirectoryBinding::Wrap(aCx, this);
+  return DirectoryBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 Directory::GetName(nsString& aRetval) const
 {
   aRetval.Truncate();
 
   if (mPath.IsEmpty()) {
--- a/dom/filesystem/Directory.h
+++ b/dom/filesystem/Directory.h
@@ -51,17 +51,17 @@ public:
   Directory(FileSystemBase* aFileSystem, const nsAString& aPath);
 
   // ========= Begin WebIDL bindings. ===========
 
   nsPIDOMWindow*
   GetParentObject() const;
 
   virtual JSObject*
-  WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void
   GetName(nsString& aRetval) const;
 
   already_AddRefed<Promise>
   CreateFile(const nsAString& aPath, const CreateFileOptions& aOptions,
              ErrorResult& aRv);
 
--- a/dom/fmradio/FMRadio.cpp
+++ b/dom/fmradio/FMRadio.cpp
@@ -180,19 +180,19 @@ FMRadio::Shutdown()
   NS_ENSURE_TRUE_VOID(target);
   target->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"), this,
                                     /* useCapture = */ true);
 
   mIsShutdown = true;
 }
 
 JSObject*
-FMRadio::WrapObject(JSContext* aCx)
+FMRadio::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return FMRadioBinding::Wrap(aCx, this);
+  return FMRadioBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 FMRadio::Notify(const SwitchEvent& aEvent)
 {
   MOZ_ASSERT(!mHasInternalAntenna);
 
   if (mHeadphoneState != aEvent.status()) {
--- a/dom/fmradio/FMRadio.h
+++ b/dom/fmradio/FMRadio.h
@@ -46,17 +46,17 @@ public:
   /* FMRadioEventObserver */
   virtual void Notify(const FMRadioEventType& aType) MOZ_OVERRIDE;
 
   nsPIDOMWindow* GetParentObject() const
   {
     return GetOwner();
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   static bool Enabled();
 
   bool RdsEnabled();
 
   bool AntennaAvailable() const;
 
   Nullable<double> GetFrequency() const;
--- a/dom/gamepad/Gamepad.cpp
+++ b/dom/gamepad/Gamepad.cpp
@@ -115,15 +115,15 @@ Gamepad::Clone(nsISupports* aParent)
   nsRefPtr<Gamepad> out =
     new Gamepad(aParent, mID, mIndex, mMapping,
                 mButtons.Length(), mAxes.Length());
   out->SyncState(this);
   return out.forget();
 }
 
 /* virtual */ JSObject*
-Gamepad::WrapObject(JSContext* aCx)
+Gamepad::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return GamepadBinding::Wrap(aCx, this);
+  return GamepadBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/gamepad/Gamepad.h
+++ b/dom/gamepad/Gamepad.h
@@ -54,17 +54,17 @@ public:
   // parented to aParent.
   already_AddRefed<Gamepad> Clone(nsISupports* aParent);
 
   nsISupports* GetParentObject() const
   {
     return mParent;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void GetId(nsAString& aID) const
   {
     aID = mID;
   }
 
   DOMHighResTimeStamp Timestamp() const
   {
--- a/dom/gamepad/GamepadButton.cpp
+++ b/dom/gamepad/GamepadButton.cpp
@@ -14,15 +14,15 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(Gamepad
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GamepadButton)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(GamepadButton, mParent)
 
 /* virtual */ JSObject*
-GamepadButton::WrapObject(JSContext* aCx)
+GamepadButton::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return GamepadButtonBinding::Wrap(aCx, this);
+  return GamepadButtonBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/gamepad/GamepadButton.h
+++ b/dom/gamepad/GamepadButton.h
@@ -25,17 +25,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(GamepadButton)
 
   nsISupports* GetParentObject() const
   {
     return mParent;
   }
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void SetPressed(bool aPressed)
   {
     mPressed = aPressed;
   }
 
   void SetValue(double aValue)
   {
--- a/dom/geolocation/nsGeoPosition.cpp
+++ b/dom/geolocation/nsGeoPosition.cpp
@@ -166,19 +166,19 @@ Position::~Position()
 
 nsISupports*
 Position::GetParentObject() const
 {
   return mParent;
 }
 
 JSObject*
-Position::WrapObject(JSContext* aCx)
+Position::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PositionBinding::Wrap(aCx, this);
+  return PositionBinding::Wrap(aCx, this, aGivenProto);
 }
 
 Coordinates*
 Position::Coords()
 {
   if (!mCoordinates) {
     nsCOMPtr<nsIDOMGeoPositionCoords> coords;
     mGeoPosition->GetCoords(getter_AddRefs(coords));
@@ -219,19 +219,19 @@ Coordinates::~Coordinates()
 
 Position*
 Coordinates::GetParentObject() const
 {
   return mPosition;
 }
 
 JSObject*
-Coordinates::WrapObject(JSContext* aCx)
+Coordinates::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return CoordinatesBinding::Wrap(aCx, this);
+  return CoordinatesBinding::Wrap(aCx, this, aGivenProto);
 }
 
 #define GENERATE_COORDS_WRAPPED_GETTER(name) \
 double                                       \
 Coordinates::name() const                    \
 {                                            \
   double rv;                                 \
   mCoords->Get##name(&rv);                   \
--- a/dom/geolocation/nsGeoPosition.h
+++ b/dom/geolocation/nsGeoPosition.h
@@ -85,17 +85,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Position)
 
 public:
   Position(nsISupports* aParent, nsIDOMGeoPosition* aGeoPosition);
 
   nsISupports* GetParentObject() const;
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   Coordinates* Coords();
 
   uint64_t Timestamp() const;
 
   nsIDOMGeoPosition* GetWrappedGeoPosition() { return mGeoPosition; }
 
 private:
@@ -113,17 +113,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Coordinates)
 
 public:
   Coordinates(Position* aPosition, nsIDOMGeoPositionCoords* aCoords);
 
   Position* GetParentObject() const;
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   double Latitude() const;
 
   double Longitude() const;
 
   Nullable<double> GetAltitude() const;
 
   double Accuracy() const;
--- a/dom/geolocation/nsGeolocation.cpp
+++ b/dom/geolocation/nsGeolocation.cpp
@@ -310,19 +310,19 @@ PositionError::GetMessage(nsAString& aMe
 
 Geolocation*
 PositionError::GetParentObject() const
 {
   return mParent;
 }
 
 JSObject*
-PositionError::WrapObject(JSContext* aCx)
+PositionError::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return PositionErrorBinding::Wrap(aCx, this);
+  return PositionErrorBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 PositionError::NotifyCallback(const GeoPositionErrorCallback& aCallback)
 {
   nsAutoMicroTask mt;
   if (aCallback.HasWebIDLCallback()) {
     PositionErrorCallback* callback = aCallback.GetWebIDLCallback();
@@ -1618,12 +1618,12 @@ Geolocation::RegisterRequestWithPrompt(n
   }
 
   nsCOMPtr<nsIRunnable> ev  = new RequestPromptEvent(request, mOwner);
   NS_DispatchToMainThread(ev);
   return true;
 }
 
 JSObject*
-Geolocation::WrapObject(JSContext *aCtx)
+Geolocation::WrapObject(JSContext *aCtx, JS::Handle<JSObject*> aGivenProto)
 {
-  return GeolocationBinding::Wrap(aCtx, this);
+  return GeolocationBinding::Wrap(aCtx, this, aGivenProto);
 }
--- a/dom/geolocation/nsGeolocation.h
+++ b/dom/geolocation/nsGeolocation.h
@@ -135,17 +135,17 @@ public:
   NS_DECL_NSIGEOLOCATIONUPDATE
   NS_DECL_NSIDOMGEOGEOLOCATION
 
   Geolocation();
 
   nsresult Init(nsIDOMWindow* contentDom=nullptr);
 
   nsIDOMWindow* GetParentObject() const;
-  virtual JSObject* WrapObject(JSContext *aCtx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *aCtx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   int32_t WatchPosition(PositionCallback& aCallback, PositionErrorCallback* aErrorCallback, const PositionOptions& aOptions, ErrorResult& aRv);
   void GetCurrentPosition(PositionCallback& aCallback, PositionErrorCallback* aErrorCallback, const PositionOptions& aOptions, ErrorResult& aRv);
 
   // Returns true if any of the callbacks are repeating
   bool HasActiveCallbacks();
 
   // Register an allowed request
@@ -228,17 +228,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(PositionError)
 
   NS_DECL_NSIDOMGEOPOSITIONERROR
 
   PositionError(Geolocation* aParent, int16_t aCode);
 
   Geolocation* GetParentObject() const;
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   int16_t Code() const {
     return mCode;
   }
 
   void NotifyCallback(const GeoPositionErrorCallback& callback);
 private:
   ~PositionError();
--- a/dom/html/HTMLAllCollection.cpp
+++ b/dom/html/HTMLAllCollection.cpp
@@ -205,15 +205,15 @@ HTMLAllCollection::GetSupportedNames(uns
   aNames.SetCapacity(atoms.Length());
   for (uint32_t i = 0; i < atoms.Length(); ++i) {
     aNames.AppendElement(nsDependentAtomString(atoms[i]));
   }
 }
 
 
 JSObject*
-HTMLAllCollection::WrapObject(JSContext* aCx)
+HTMLAllCollection::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLAllCollectionBinding::Wrap(aCx, this);
+  return HTMLAllCollectionBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLAllCollection.h
+++ b/dom/html/HTMLAllCollection.h
@@ -35,17 +35,17 @@ class HTMLAllCollection MOZ_FINAL : publ
   ~HTMLAllCollection();
 
 public:
   explicit HTMLAllCollection(nsHTMLDocument* aDocument);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(HTMLAllCollection)
 
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   nsINode* GetParentObject() const;
 
   uint32_t Length();
   nsIContent* Item(uint32_t aIndex);
   void Item(const nsAString& aName, Nullable<OwningNodeOrHTMLCollection>& aResult)
   {
     NamedItem(aName, aResult);
   }
--- a/dom/html/HTMLAnchorElement.cpp
+++ b/dom/html/HTMLAnchorElement.cpp
@@ -64,19 +64,19 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
                                                 nsGenericHTMLElement)
   tmp->Link::Unlink();
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mRelList)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ELEMENT_CLONE(HTMLAnchorElement)
 
 JSObject*
-HTMLAnchorElement::WrapNode(JSContext *aCx)
+HTMLAnchorElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLAnchorElementBinding::Wrap(aCx, this);
+  return HTMLAnchorElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_STRING_ATTR(HTMLAnchorElement, Charset, charset)
 NS_IMPL_STRING_ATTR(HTMLAnchorElement, Coords, coords)
 NS_IMPL_URI_ATTR(HTMLAnchorElement, Href, href)
 NS_IMPL_STRING_ATTR(HTMLAnchorElement, Hreflang, hreflang)
 NS_IMPL_STRING_ATTR(HTMLAnchorElement, Name, name)
 NS_IMPL_STRING_ATTR(HTMLAnchorElement, Rel, rel)
--- a/dom/html/HTMLAnchorElement.h
+++ b/dom/html/HTMLAnchorElement.h
@@ -224,16 +224,16 @@ public:
     GetHref(aResult, aError);
   }
 
 protected:
   virtual ~HTMLAnchorElement();
 
   virtual void GetItemValueText(DOMString& text) MOZ_OVERRIDE;
   virtual void SetItemValueText(const nsAString& text) MOZ_OVERRIDE;
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
   nsRefPtr<nsDOMTokenList > mRelList;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_HTMLAnchorElement_h
--- a/dom/html/HTMLAreaElement.cpp
+++ b/dom/html/HTMLAreaElement.cpp
@@ -264,15 +264,15 @@ HTMLAreaElement::IntrinsicState() const
 size_t
 HTMLAreaElement::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
 {
   return nsGenericHTMLElement::SizeOfExcludingThis(aMallocSizeOf) +
          Link::SizeOfExcludingThis(aMallocSizeOf);
 }
 
 JSObject*
-HTMLAreaElement::WrapNode(JSContext* aCx)
+HTMLAreaElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLAreaElementBinding::Wrap(aCx, this);
+  return HTMLAreaElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLAreaElement.h
+++ b/dom/html/HTMLAreaElement.h
@@ -173,17 +173,17 @@ public:
   void Stringify(nsAString& aResult, ErrorResult& aError)
   {
     GetHref(aResult, aError);
   }
 
 protected:
   virtual ~HTMLAreaElement();
 
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   virtual void GetItemValueText(DOMString& text) MOZ_OVERRIDE;
   virtual void SetItemValueText(const nsAString& text) MOZ_OVERRIDE;
   nsRefPtr<nsDOMTokenList > mRelList;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLAudioElement.cpp
+++ b/dom/html/HTMLAudioElement.cpp
@@ -91,15 +91,15 @@ nsresult HTMLAudioElement::SetAcceptHead
       "video/*;q=0.6,*/*;q=0.5");
 
     return aChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
                                       value,
                                       false);
 }
 
 JSObject*
-HTMLAudioElement::WrapNode(JSContext* aCx)
+HTMLAudioElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLAudioElementBinding::Wrap(aCx, this);
+  return HTMLAudioElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLAudioElement.h
+++ b/dom/html/HTMLAudioElement.h
@@ -38,15 +38,15 @@ public:
 
   static already_AddRefed<HTMLAudioElement>
   Audio(const GlobalObject& aGlobal,
         const Optional<nsAString>& aSrc, ErrorResult& aRv);
 
 protected:
   virtual ~HTMLAudioElement();
 
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_HTMLAudioElement_h
--- a/dom/html/HTMLBRElement.cpp
+++ b/dom/html/HTMLBRElement.cpp
@@ -90,15 +90,15 @@ HTMLBRElement::IsAttributeMapped(const n
 
 nsMapRuleToAttributesFunc
 HTMLBRElement::GetAttributeMappingFunction() const
 {
   return &MapAttributesIntoRule;
 }
 
 JSObject*
-HTMLBRElement::WrapNode(JSContext *aCx)
+HTMLBRElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLBRElementBinding::Wrap(aCx, this);
+  return HTMLBRElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLBRElement.h
+++ b/dom/html/HTMLBRElement.h
@@ -38,17 +38,17 @@ public:
   {
     return GetBoolAttr(nsGkAtoms::clear);
   }
   void SetClear(const nsAString& aClear, ErrorResult& aError)
   {
     return SetHTMLAttr(nsGkAtoms::clear, aClear, aError);
   }
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   virtual ~HTMLBRElement();
 
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
 };
 
--- a/dom/html/HTMLBodyElement.cpp
+++ b/dom/html/HTMLBodyElement.cpp
@@ -184,19 +184,19 @@ BodyRule::List(FILE* out, int32_t aInden
 HTMLBodyElement::~HTMLBodyElement()
 {
   if (mContentStyleRule) {
     mContentStyleRule->mPart = nullptr;
   }
 }
 
 JSObject*
-HTMLBodyElement::WrapNode(JSContext *aCx)
+HTMLBodyElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLBodyElementBinding::Wrap(aCx, this);
+  return HTMLBodyElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(HTMLBodyElement, nsGenericHTMLElement,
                             nsIDOMHTMLBodyElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLBodyElement)
 
 NS_IMETHODIMP 
--- a/dom/html/HTMLBodyElement.h
+++ b/dom/html/HTMLBodyElement.h
@@ -129,17 +129,17 @@ public:
   virtual already_AddRefed<nsIEditor> GetAssociatedEditor() MOZ_OVERRIDE;
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   virtual bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
 
 protected:
   virtual ~HTMLBodyElement();
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsRefPtr<BodyRule> mContentStyleRule;
 
 private:
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
 };
 
--- a/dom/html/HTMLButtonElement.cpp
+++ b/dom/html/HTMLButtonElement.cpp
@@ -574,15 +574,15 @@ HTMLButtonElement::IntrinsicState() cons
   if (mForm && !mForm->GetValidity() && IsSubmitControl()) {
     state |= NS_EVENT_STATE_MOZ_SUBMITINVALID;
   }
 
   return state;
 }
 
 JSObject*
-HTMLButtonElement::WrapNode(JSContext* aCx)
+HTMLButtonElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLButtonElementBinding::Wrap(aCx, this);
+  return HTMLButtonElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLButtonElement.h
+++ b/dom/html/HTMLButtonElement.h
@@ -57,17 +57,17 @@ public:
 
   // nsIDOMEventTarget
   virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
   virtual nsresult PostHandleEvent(
                      EventChainPostVisitor& aVisitor) MOZ_OVERRIDE;
 
   // nsINode
   virtual nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers) MOZ_OVERRIDE;
   virtual void UnbindFromTree(bool aDeep = true,
                               bool aNullParent = true) MOZ_OVERRIDE;
   virtual void DoneCreatingElement() MOZ_OVERRIDE;
--- a/dom/html/HTMLCanvasElement.cpp
+++ b/dom/html/HTMLCanvasElement.cpp
@@ -67,19 +67,19 @@ HTMLCanvasPrintState::HTMLCanvasPrintSta
 {
 }
 
 HTMLCanvasPrintState::~HTMLCanvasPrintState()
 {
 }
 
 /* virtual */ JSObject*
-HTMLCanvasPrintState::WrapObject(JSContext* aCx)
+HTMLCanvasPrintState::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return MozCanvasPrintStateBinding::Wrap(aCx, this);
+  return MozCanvasPrintStateBinding::Wrap(aCx, this, aGivenProto);
 }
 
 nsISupports*
 HTMLCanvasPrintState::Context() const
 {
   return mContext;
 }
 
@@ -132,19 +132,19 @@ NS_IMPL_RELEASE_INHERITED(HTMLCanvasElem
 
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLCanvasElement)
   NS_INTERFACE_TABLE_INHERITED(HTMLCanvasElement, nsIDOMHTMLCanvasElement)
 NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLCanvasElement)
 
 /* virtual */ JSObject*
-HTMLCanvasElement::WrapNode(JSContext* aCx)
+HTMLCanvasElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLCanvasElementBinding::Wrap(aCx, this);
+  return HTMLCanvasElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 nsIntSize
 HTMLCanvasElement::GetWidthHeight()
 {
   nsIntSize size(DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT);
   const nsAttrValue* value;
 
--- a/dom/html/HTMLCanvasElement.h
+++ b/dom/html/HTMLCanvasElement.h
@@ -210,17 +210,17 @@ public:
   // take a snapshot of the canvas that needs to be "live" (e.g. -moz-element).
   void MarkContextClean();
 
   nsresult GetContext(const nsAString& aContextId, nsISupports** aContext);
 
 protected:
   virtual ~HTMLCanvasElement();
 
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   nsIntSize GetWidthHeight();
 
   nsresult UpdateContext(JSContext* aCx, JS::Handle<JS::Value> options);
   nsresult ParseParams(JSContext* aCx,
                        const nsAString& aType,
                        const JS::Value& aEncoderOptions,
                        nsAString& aParams,
@@ -274,17 +274,17 @@ public:
 
   void NotifyDone();
 
   bool mIsDone;
 
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(HTMLCanvasPrintState)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(HTMLCanvasPrintState)
 
-  virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   HTMLCanvasElement* GetParentObject()
   {
     return mCanvas;
   }
 
 private:
   ~HTMLCanvasPrintState();
--- a/dom/html/HTMLContentElement.cpp
+++ b/dom/html/HTMLContentElement.cpp
@@ -38,19 +38,19 @@ NS_IMPL_ADDREF_INHERITED(HTMLContentElem
 NS_IMPL_RELEASE_INHERITED(HTMLContentElement, Element)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLContentElement)
 NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLContentElement)
 
 JSObject*
-HTMLContentElement::WrapNode(JSContext *aCx)
+HTMLContentElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLContentElementBinding::Wrap(aCx, this);
+  return HTMLContentElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 nsresult
 HTMLContentElement::BindToTree(nsIDocument* aDocument,
                                nsIContent* aParent,
                                nsIContent* aBindingParent,
                                bool aCompileEventHandlers)
 {
@@ -357,13 +357,13 @@ DistributedContentList::GetLength(uint32
 
 int32_t
 DistributedContentList::IndexOf(nsIContent* aContent)
 {
   return mDistributedNodes.IndexOf(aContent);
 }
 
 JSObject*
-DistributedContentList::WrapObject(JSContext* aCx)
+DistributedContentList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return NodeListBinding::Wrap(aCx, this);
+  return NodeListBinding::Wrap(aCx, this, aGivenProto);
 }
 
--- a/dom/html/HTMLContentElement.h
+++ b/dom/html/HTMLContentElement.h
@@ -68,17 +68,17 @@ public:
   void SetSelect(const nsAString& aSelect)
   {
     Element::SetAttr(kNameSpaceID_None, nsGkAtoms::select, aSelect, true);
   }
 
 protected:
   virtual ~HTMLContentElement();
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   /**
    * Updates the destination insertion points of the fallback
    * content of this insertion point. If there are nodes matched
    * to this insertion point, then destination insertion points
    * of fallback are cleared, otherwise, this insertion point
    * is a destination insertion point.
    */
@@ -105,17 +105,17 @@ public:
 
   // nsIDOMNodeList
   NS_DECL_NSIDOMNODELIST
 
   // nsINodeList
   virtual nsIContent* Item(uint32_t aIndex) MOZ_OVERRIDE;
   virtual int32_t IndexOf(nsIContent* aContent) MOZ_OVERRIDE;
   virtual nsINode* GetParentObject() MOZ_OVERRIDE { return mParent; }
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 protected:
   virtual ~DistributedContentList();
   nsRefPtr<HTMLContentElement> mParent;
   nsCOMArray<nsIContent> mDistributedNodes;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLDataElement.cpp
+++ b/dom/html/HTMLDataElement.cpp
@@ -19,19 +19,19 @@ HTMLDataElement::HTMLDataElement(already
 
 HTMLDataElement::~HTMLDataElement()
 {
 }
 
 NS_IMPL_ELEMENT_CLONE(HTMLDataElement)
 
 JSObject*
-HTMLDataElement::WrapNode(JSContext* aCx)
+HTMLDataElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLDataElementBinding::Wrap(aCx, this);
+  return HTMLDataElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 HTMLDataElement::GetItemValueText(DOMString& text)
 {
   GetValue(text);
 }
 
--- a/dom/html/HTMLDataElement.h
+++ b/dom/html/HTMLDataElement.h
@@ -32,15 +32,15 @@ public:
 
   virtual void GetItemValueText(DOMString& text) MOZ_OVERRIDE;
   virtual void SetItemValueText(const nsAString& text) MOZ_OVERRIDE;
   virtual nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) const MOZ_OVERRIDE;
 
 protected:
   virtual ~HTMLDataElement();
 
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_HTMLDataElement_h
--- a/dom/html/HTMLDataListElement.cpp
+++ b/dom/html/HTMLDataListElement.cpp
@@ -11,19 +11,19 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(DataList)
 namespace mozilla {
 namespace dom {
 
 HTMLDataListElement::~HTMLDataListElement()
 {
 }
 
 JSObject*
-HTMLDataListElement::WrapNode(JSContext *aCx)
+HTMLDataListElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLDataListElementBinding::Wrap(aCx, this);
+  return HTMLDataListElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(HTMLDataListElement, nsGenericHTMLElement,
                                    mOptions)
 
 NS_IMPL_ADDREF_INHERITED(HTMLDataListElement, Element)
 NS_IMPL_RELEASE_INHERITED(HTMLDataListElement, Element)
 
--- a/dom/html/HTMLDataListElement.h
+++ b/dom/html/HTMLDataListElement.h
@@ -39,17 +39,17 @@ public:
   static bool MatchOptions(nsIContent* aContent, int32_t aNamespaceID,
                              nsIAtom* aAtom, void* aData);
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLDataListElement,
                                            nsGenericHTMLElement)
 protected:
   virtual ~HTMLDataListElement();
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   // <option>'s list inside the datalist element.
   nsRefPtr<nsContentList> mOptions;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/html/HTMLDivElement.cpp
+++ b/dom/html/HTMLDivElement.cpp
@@ -19,19 +19,19 @@ HTMLDivElement::~HTMLDivElement()
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(HTMLDivElement, nsGenericHTMLElement,
                             nsIDOMHTMLDivElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLDivElement)
 
 JSObject*
-HTMLDivElement::WrapNode(JSContext *aCx)
+HTMLDivElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return dom::HTMLDivElementBinding::Wrap(aCx, this);
+  return dom::HTMLDivElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 bool
 HTMLDivElement::ParseAttribute(int32_t aNamespaceID,
                                nsIAtom* aAttribute,
                                const nsAString& aValue,
                                nsAttrValue& aResult)
 {
--- a/dom/html/HTMLDivElement.h
+++ b/dom/html/HTMLDivElement.h
@@ -54,17 +54,17 @@ public:
                               nsAttrValue& aResult) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
 protected:
   virtual ~HTMLDivElement();
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLElement.cpp
+++ b/dom/html/HTMLElement.cpp
@@ -17,17 +17,17 @@ public:
   virtual ~HTMLElement();
 
   NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML) MOZ_OVERRIDE;
 
   virtual nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo,
                          nsINode** aResult) const MOZ_OVERRIDE;
 
 protected:
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 };
 
 HTMLElement::HTMLElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo)
 {
 }
 
 HTMLElement::~HTMLElement()
@@ -53,19 +53,19 @@ HTMLElement::GetInnerHTML(nsAString& aIn
     }
     return NS_OK;
   }
 
   return nsGenericHTMLElement::GetInnerHTML(aInnerHTML);
 }
 
 JSObject*
-HTMLElement::WrapNode(JSContext *aCx)
+HTMLElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return dom::HTMLElementBinding::Wrap(aCx, this);
+  return dom::HTMLElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
 
 // Here, we expand 'NS_IMPL_NS_NEW_HTML_ELEMENT()' by hand.
 // (Calling the macro directly (with no args) produces compiler warnings.)
 nsGenericHTMLElement*
--- a/dom/html/HTMLFieldSetElement.cpp
+++ b/dom/html/HTMLFieldSetElement.cpp
@@ -365,15 +365,15 @@ HTMLFieldSetElement::IntrinsicState() co
   } else {
     state |= NS_EVENT_STATE_VALID;
   }
 
   return state;
 }
 
 JSObject*
-HTMLFieldSetElement::WrapNode(JSContext* aCx)
+HTMLFieldSetElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLFieldSetElementBinding::Wrap(aCx, this);
+  return HTMLFieldSetElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLFieldSetElement.h
+++ b/dom/html/HTMLFieldSetElement.h
@@ -106,17 +106,17 @@ public:
    *
    * @param aElementValidityState the new validity state of the element
    */
   void UpdateValidity(bool aElementValidityState);
 
 protected:
   virtual ~HTMLFieldSetElement();
 
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
 
   /**
    * Notify all elements (in mElements) that the first legend of the fieldset
    * has now changed.
    */
   void NotifyElementsForFirstLegendChange(bool aNotify);
--- a/dom/html/HTMLFontElement.cpp
+++ b/dom/html/HTMLFontElement.cpp
@@ -16,19 +16,19 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Font)
 namespace mozilla {
 namespace dom {
 
 HTMLFontElement::~HTMLFontElement()
 {
 }
 
 JSObject*
-HTMLFontElement::WrapNode(JSContext *aCx)
+HTMLFontElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLFontElementBinding::Wrap(aCx, this);
+  return HTMLFontElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_ELEMENT_CLONE(HTMLFontElement)
 
 bool
 HTMLFontElement::ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
--- a/dom/html/HTMLFontElement.h
+++ b/dom/html/HTMLFontElement.h
@@ -50,17 +50,17 @@ public:
                                 nsAttrValue& aResult) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const MOZ_OVERRIDE;
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
 protected:
   virtual ~HTMLFontElement();
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLFormControlsCollection.cpp
+++ b/dom/html/HTMLFormControlsCollection.cpp
@@ -406,15 +406,15 @@ HTMLFormControlsCollection::GetSupported
   FlushPendingNotifications();
   // Just enumerate mNameLookupTable.  This won't guarantee order, but
   // that's OK, because the HTML5 spec doesn't define an order for
   // this enumeration.
   mNameLookupTable.EnumerateRead(CollectNames, &aNames);
 }
 
 /* virtual */ JSObject*
-HTMLFormControlsCollection::WrapObject(JSContext* aCx)
+HTMLFormControlsCollection::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLFormControlsCollectionBinding::Wrap(aCx, this);
+  return HTMLFormControlsCollectionBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLFormControlsCollection.h
+++ b/dom/html/HTMLFormControlsCollection.h
@@ -75,17 +75,17 @@ public:
    *
    * @param aControls The list of sorted controls[out].
    * @return NS_OK or NS_ERROR_OUT_OF_MEMORY.
    */
   nsresult GetSortedControls(nsTArray<nsGenericHTMLFormElement*>& aControls) const;
 
   // nsWrapperCache
   using nsWrapperCache::GetWrapperPreserveColor;
-  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 protected:
   virtual ~HTMLFormControlsCollection();
   virtual JSObject* GetWrapperPreserveColorInternal() MOZ_OVERRIDE
   {
     return nsWrapperCache::GetWrapperPreserveColor();
   }
 public:
 
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -2511,15 +2511,15 @@ HTMLFormElement::AddToPastNamesMap(const
   // previous entry with the same name, if any.
   nsCOMPtr<nsIContent> node = do_QueryInterface(aChild);
   if (node) {
     mPastNameLookupTable.Put(aName, aChild);
   }
 }
  
 JSObject*
-HTMLFormElement::WrapNode(JSContext* aCx)
+HTMLFormElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLFormElementBinding::Wrap(aCx, this);
+  return HTMLFormElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLFormElement.h
+++ b/dom/html/HTMLFormElement.h
@@ -405,17 +405,17 @@ public:
                       nsIContent* aForm);
 #endif
 
   js::ExpandoAndGeneration mExpandoAndGeneration;
 
   void RequestAutocomplete();
 
 protected:
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
   void PostPasswordEvent();
   void EventHandled() { mFormPasswordEventDispatcher = nullptr; }
 
   class FormPasswordEventDispatcher MOZ_FINAL : public AsyncEventDispatcher
   {
   public:
     FormPasswordEventDispatcher(HTMLFormElement* aEventNode,
--- a/dom/html/HTMLFrameElement.cpp
+++ b/dom/html/HTMLFrameElement.cpp
@@ -76,15 +76,15 @@ HTMLFrameElement::ParseAttribute(int32_t
     }
   }
 
   return nsGenericHTMLFrameElement::ParseAttribute(aNamespaceID, aAttribute,
                                                    aValue, aResult);
 }
 
 JSObject*
-HTMLFrameElement::WrapNode(JSContext* aCx)
+HTMLFrameElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLFrameElementBinding::Wrap(aCx, this);
+  return HTMLFrameElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace mozilla
 } // namespace dom
--- a/dom/html/HTMLFrameElement.h
+++ b/dom/html/HTMLFrameElement.h
@@ -91,17 +91,17 @@ public:
   }
 
   using nsGenericHTMLFrameElement::GetContentDocument;
   using nsGenericHTMLFrameElement::GetContentWindow;
 
 protected:
   virtual ~HTMLFrameElement();
 
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLFrameSetElement.cpp
+++ b/dom/html/HTMLFrameSetElement.cpp
@@ -13,19 +13,19 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(FrameSet)
 namespace mozilla {
 namespace dom {
 
 HTMLFrameSetElement::~HTMLFrameSetElement()
 {
 }
 
 JSObject*
-HTMLFrameSetElement::WrapNode(JSContext *aCx)
+HTMLFrameSetElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLFrameSetElementBinding::Wrap(aCx, this);
+  return HTMLFrameSetElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(HTMLFrameSetElement, nsGenericHTMLElement,
                             nsIDOMHTMLFrameSetElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLFrameSetElement)
 
 NS_IMETHODIMP 
--- a/dom/html/HTMLFrameSetElement.h
+++ b/dom/html/HTMLFrameSetElement.h
@@ -134,17 +134,17 @@ public:
   virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
                                               int32_t aModType) const MOZ_OVERRIDE;
 
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
 protected:
   virtual ~HTMLFrameSetElement();
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   nsresult ParseRowCol(const nsAString& aValue,
                        int32_t&         aNumSpecs,
                        nsFramesetSpec** aSpecs);
 
   /**
    * The number of size specs in our "rows" attr
--- a/dom/html/HTMLHRElement.cpp
+++ b/dom/html/HTMLHRElement.cpp
@@ -252,15 +252,15 @@ HTMLHRElement::IsAttributeMapped(const n
 
 nsMapRuleToAttributesFunc
 HTMLHRElement::GetAttributeMappingFunction() const
 {
   return &MapAttributesIntoRule;
 }
 
 JSObject*
-HTMLHRElement::WrapNode(JSContext* aCx)
+HTMLHRElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLHRElementBinding::Wrap(aCx, this);
+  return HTMLHRElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace mozilla
 } // namespace dom
--- a/dom/html/HTMLHRElement.h
+++ b/dom/html/HTMLHRElement.h
@@ -67,17 +67,17 @@ public:
   void SetWidth(const nsAString& aWidth, ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::width, aWidth, aError);
   }
 
 protected:
   virtual ~HTMLHRElement();
 
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLHeadingElement.cpp
+++ b/dom/html/HTMLHeadingElement.cpp
@@ -22,19 +22,19 @@ HTMLHeadingElement::~HTMLHeadingElement(
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(HTMLHeadingElement, nsGenericHTMLElement,
                             nsIDOMHTMLHeadingElement)
 
 NS_IMPL_ELEMENT_CLONE(HTMLHeadingElement)
 
 JSObject*
-HTMLHeadingElement::WrapNode(JSContext *aCx)
+HTMLHeadingElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLHeadingElementBinding::Wrap(aCx, this);
+  return HTMLHeadingElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_STRING_ATTR(HTMLHeadingElement, Align, align)
 
 
 bool
 HTMLHeadingElement::ParseAttribute(int32_t aNamespaceID,
                                    nsIAtom* aAttribute,
--- a/dom/html/HTMLHeadingElement.h
+++ b/dom/html/HTMLHeadingElement.h
@@ -37,17 +37,17 @@ public:
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // The XPCOM versions of GetAlign and SetAlign are fine for us for
   // use from WebIDL.
 
 protected:
   virtual ~HTMLHeadingElement();
 
-  virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
 };
 
 } // namespace mozilla
 } // namespace dom
--- a/dom/html/HTMLIFrameElement.cpp
+++ b/dom/html/HTMLIFrameElement.cpp
@@ -242,15 +242,15 @@ HTMLIFrameElement::UnsetAttr(int32_t aNa
 uint32_t
 HTMLIFrameElement::GetSandboxFlags()
 {
   const nsAttrValue* sandboxAttr = GetParsedAttr(nsGkAtoms::sandbox);
   return nsContentUtils::ParseSandboxAttributeToFlags(sandboxAttr);
 }
 
 JSObject*
-HTMLIFrameElement::WrapNode(JSContext* aCx)
+HTMLIFrameElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
-  return HTMLIFrameElementBinding::Wrap(aCx, this);
+  return HTMLIFrameElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLIFrameElement.h
+++ b/dom/html/HTMLIFrameElement.h
@@ -175,17 +175,17 @@ public:
   // nsGenericHTMLFrameElement::GetAppManifestURL is fine
 
 protected:
   virtual ~HTMLIFrameElement();
 
   virtual void GetItemValueText(DOMString& text) MOZ_OVERRIDE;
   virtual void SetItemValueText(const nsAString& text) MOZ_OVERRIDE;
 
-  virtual JSObject* WrapNode(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) MOZ_OVERRIDE;
 
 private:
   static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
                                     nsRuleData* aData);
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLImageElement.cpp
+++ b/dom/html/HTMLImageElement.cpp
@@ -797,19 +797,19 @@ HTMLImageElement::CopyInnerTo(Element* a
 
 CORSMode
 HTMLImageElement::GetCORSMode()
 {
   return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
 }