Merge mozilla-central to autoland. a=merge CLOSED TREE
authorGurzau Raul <rgurzau@mozilla.com>
Tue, 06 Feb 2018 23:59:03 +0200
changeset 402635 80fd16267d7f2da670f6e21253a99aaa096a0f84
parent 402634 ddb0033c54cb2175ffa1b58d0a3554808895c54f (current diff)
parent 402622 0790ec12200d5f663dd000a6ef3c72c795ca4ead (diff)
child 402636 b2bb8479fee84d1bd27923c466e553d716e6d84b
push id33394
push userrgurzau@mozilla.com
push dateWed, 07 Feb 2018 00:14:43 +0000
treeherdermozilla-central@f033d62a90ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone60.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 mozilla-central to autoland. a=merge CLOSED TREE
js/src/tests/test262/language/expressions/delete/11.4.1-3-a-1-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-1-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-10-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-11-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-12-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-13-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-14-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-15-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-16-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-17-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-18-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-19-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-2-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-20-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-21-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-22-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-23-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-24-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-25-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-26-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-3-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-4-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-5-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-6-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-7-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-8-s-strict.js
js/src/tests/test262/language/expressions/delete/11.4.1-5-a-9-s-strict.js
js/src/tests/test262/language/expressions/delete/S11.4.1_A1.js
js/src/tests/test262/language/expressions/object/11.1.5-1-s-strict.js
js/src/tests/test262/language/expressions/object/11.1.5-2-s-strict.js
js/src/tests/test262/language/expressions/object/11.1.5-3-s.js
js/src/tests/test262/language/expressions/object/11.1.5-4-4-a-1-s.js
js/src/tests/test262/language/expressions/object/11.1.5-4-s.js
js/src/tests/test262/language/expressions/object/11.1.5_4-4-a-2.js
js/src/tests/test262/language/expressions/object/11.1.5_4-4-b-2.js
js/src/tests/test262/language/expressions/object/11.1.5_4-4-c-1.js
js/src/tests/test262/language/expressions/object/11.1.5_4-4-c-2.js
js/src/tests/test262/language/expressions/object/11.1.5_4-4-d-1.js
js/src/tests/test262/language/expressions/object/11.1.5_4-4-d-2.js
js/src/tests/test262/language/expressions/object/11.1.5_4-4-d-3.js
js/src/tests/test262/language/expressions/object/11.1.5_4-4-d-4.js
js/src/tests/test262/language/expressions/object/11.1.5_6-2-1-s-strict.js
js/src/tests/test262/language/expressions/object/11.1.5_6-2-2-s.js
js/src/tests/test262/language/expressions/object/11.1.5_7-2-1-s-strict.js
js/src/tests/test262/language/expressions/object/11.1.5_7-2-2-s-strict.js
security/sandbox/chromium/sandbox/win/src/sidestep/ia32_modrm_map.cpp
security/sandbox/chromium/sandbox/win/src/sidestep/ia32_opcode_map.cpp
security/sandbox/chromium/sandbox/win/src/sidestep/mini_disassembler.cpp
security/sandbox/chromium/sandbox/win/src/sidestep/mini_disassembler.h
security/sandbox/chromium/sandbox/win/src/sidestep/mini_disassembler_types.h
security/sandbox/chromium/sandbox/win/src/sidestep/preamble_patcher.h
security/sandbox/chromium/sandbox/win/src/sidestep/preamble_patcher_with_stub.cpp
security/sandbox/chromium/sandbox/win/src/sidestep_resolver.cc
security/sandbox/chromium/sandbox/win/src/sidestep_resolver.h
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1857,16 +1857,20 @@
     <emItem blockID="i63" id="youtube@youtuber.com">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
     <emItem blockID="i820" id="{aab02ab1-33cf-4dfa-8a9f-f4e60e976d27}">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
+    <emItem blockID="646e2384-f894-41bf-b7fc-8879e0095109" id="/^(https|youtube)@vietbacsecurity\.com$/">
+      <prefs/>
+      <versionRange minVersion="0" maxVersion="*" severity="3"/>
+    </emItem>
     <emItem blockID="i521" id="/^({66b103a7-d772-4fcd-ace4-16f79a9056e0}|{6926c7f7-6006-42d1-b046-eba1b3010315}|{72cabc40-64b2-46ed-8648-26d831761150}|{73ee2cf2-7b76-4c49-b659-c3d8cf30825d}|{ca6446a5-73d5-4c35-8aa1-c71dc1024a18}|{5373a31d-9410-45e2-b299-4f61428f0be4})$/">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="1"/>
     </emItem>
     <emItem blockID="i322" id="jid0-Y6TVIzs0r7r4xkOogmJPNAGFGBw@jetpack">
       <prefs/>
       <versionRange minVersion="0" maxVersion="*" severity="3"/>
     </emItem>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -338,16 +338,20 @@ pref("browser.urlbar.oneOffSearches", tr
 // If changed to true, copying the entire URL from the location bar will put the
 // human readable (percent-decoded) URL on the clipboard.
 pref("browser.urlbar.decodeURLsOnCopy", false);
 
 // Whether or not to move tabs into the active window when using the "Switch to
 // Tab" feature of the awesomebar.
 pref("browser.urlbar.switchTabs.adoptIntoActiveWindow", false);
 
+// Whether addresses and search results typed into the address bar
+// should be opened in new tabs by default.
+pref("browser.urlbar.openintab", false);
+
 pref("browser.altClickSave", false);
 
 // Enable logging downloads operations to the Console.
 pref("browser.download.loglevel", "Error");
 
 // Number of milliseconds to wait for the http headers (and thus
 // the Content-Disposition filename) before giving up and falling back to
 // picking a filename without that info in hand so that the user sees some
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -138,17 +138,20 @@
            id="PopupAutoComplete"
            noautofocus="true"
            hidden="true"
            overflowpadding="4"
            norolluponanchor="true"
            nomaxresults="true" />
 
     <!-- for search with one-off buttons -->
-    <panel type="autocomplete" id="PopupSearchAutoComplete" noautofocus="true" hidden="true"/>
+    <panel type="autocomplete-richlistbox"
+           id="PopupSearchAutoComplete"
+           noautofocus="true"
+           hidden="true" />
 
     <!-- for url bar autocomplete -->
     <panel type="autocomplete-richlistbox"
            id="PopupAutoCompleteRichResult"
            noautofocus="true"
            hidden="true"
            flip="none"
            level="parent"
--- a/browser/base/content/test/performance/browser_urlbar_search_reflows.js
+++ b/browser/base/content/test/performance/browser_urlbar_search_reflows.js
@@ -165,17 +165,17 @@ add_task(async function() {
     };
 
     URLBar.controller.startSearch(URLBar.value);
     await BrowserTestUtils.waitForEvent(URLBar.popup, "popupshown");
     await BrowserTestUtils.waitForCondition(() => {
       return URLBar.controller.searchStatus >=
         Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH;
     });
-    let matchCount = URLBar.popup._matchCount;
+    let matchCount = URLBar.popup.matchCount;
     await BrowserTestUtils.waitForCondition(() => {
       return URLBar.popup.richlistbox.childNodes.length == matchCount;
     });
 
     URLBar.controller.stopSearch();
     // There are several setTimeout(fn, 0); calls inside autocomplete.xml
     // that we need to wait for. Since those have higher priority than
     // idle callbacks, we can be sure they will have run once this
--- a/browser/base/content/test/urlbar/Panel.jsm
+++ b/browser/base/content/test/urlbar/Panel.jsm
@@ -92,17 +92,17 @@ this.Panel.prototype = {
   },
 
   // This emulates the popup's own _appendCurrentResult method, except instead
   // of appending results to the popup, it emits "result" events to the iframe.
   _appendCurrentResult() {
     let controller = this.p.mInput.controller;
     for (let i = 0; i < this.p.maxResults; i++) {
       let idx = this._currentIndex;
-      if (idx >= this.p._matchCount) {
+      if (idx >= this.p.matchCount) {
         break;
       }
       let url = controller.getValueAt(idx);
       let action = this.urlbar._parseActionUrl(url);
       this._emit("result", {
         url,
         action,
         image: controller.getImageAt(idx),
--- a/browser/base/content/test/urlbar/browser.ini
+++ b/browser/base/content/test/urlbar/browser.ini
@@ -63,16 +63,17 @@ support-files =
 [browser_urlbarAutoFillTrimURLs.js]
 [browser_urlbarCopying.js]
 subsuite = clipboard
 support-files =
   authenticate.sjs
 [browser_urlbarDecode.js]
 [browser_urlbarDelete.js]
 [browser_urlbarEnter.js]
+[browser_urlbar_whereToOpen.js]
 [browser_urlbarEnterAfterMouseOver.js]
 skip-if = os == "linux" # Bug 1073339 - Investigate autocomplete test unreliability on Linux/e10s
 [browser_urlbarFocusedCmdK.js]
 [browser_urlbarHashChangeProxyState.js]
 [browser_urlbarKeepStateAcrossTabSwitches.js]
 [browser_urlbarOneOffs.js]
 support-files =
   searchSuggestionEngine.xml
--- a/browser/base/content/test/urlbar/browser_urlbarSearchSuggestions_opt-out.js
+++ b/browser/base/content/test/urlbar/browser_urlbarSearchSuggestions_opt-out.js
@@ -39,17 +39,17 @@ add_task(async function focus() {
   setupVisibleHint();
   gURLBar.blur();
   let popupPromise = promisePopupShown(gURLBar.popup);
   focusAndSelectUrlBar(true);
   await popupPromise;
   Assert.ok(gURLBar.popup.popupOpen, "popup should be open");
   assertVisible(true);
   assertFooterVisible(false);
-  Assert.equal(gURLBar.popup._matchCount, 0, "popup should have no results");
+  Assert.equal(gURLBar.popup.matchCount, 0, "popup should have no results");
 
   // Start searching.
   EventUtils.synthesizeKey("r", {});
   EventUtils.synthesizeKey("n", {});
   EventUtils.synthesizeKey("d", {});
   await promiseSearchComplete();
   Assert.ok(suggestionsPresent());
   assertVisible(true);
@@ -78,17 +78,17 @@ add_task(async function click_on_focused
 
   let popupPromise = promisePopupShown(gURLBar.popup);
   EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, {});
   await popupPromise;
 
   Assert.ok(gURLBar.popup.popupOpen, "popup should be open");
   assertVisible(true);
   assertFooterVisible(false);
-  Assert.equal(gURLBar.popup._matchCount, 0, "popup should have no results");
+  Assert.equal(gURLBar.popup.matchCount, 0, "popup should have no results");
   gURLBar.blur();
   Assert.ok(!gURLBar.popup.popupOpen, "popup should be closed");
 });
 
 add_task(async function new_tab() {
   // Opening a new tab when the urlbar is unfocused, should focus it but not
   // open the popup.
   setupVisibleHint();
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/urlbar/browser_urlbar_whereToOpen.js
@@ -0,0 +1,112 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const NON_EMPTY_TAB = "example.com/non-empty";
+const EMPTY_TAB = "about:blank";
+const META_KEY = AppConstants.platform == "macosx" ? "metaKey" : "ctrlKey";
+const ENTER = new KeyboardEvent("keydown", {});
+const ALT_ENTER = new KeyboardEvent("keydown", {altKey: true});
+const CLICK = new MouseEvent("click", {button: 0});
+const META_CLICK = new MouseEvent("click", {button: 0, [META_KEY]: true});
+const MIDDLE_CLICK = new MouseEvent("click", {button: 1});
+
+
+let old_openintab = Preferences.get("browser.urlbar.openintab");
+registerCleanupFunction(async function() {
+  Preferences.set("browser.urlbar.openintab", old_openintab);
+});
+
+add_task(async function openInTab() {
+  // Open a non-empty tab.
+  let tab = gBrowser.selectedTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, NON_EMPTY_TAB);
+
+  for (let test of [{pref: false, event: ALT_ENTER,
+                     desc: "Alt+Enter, non-empty tab, default prefs"},
+                    {pref: false, event: META_CLICK,
+                     desc: "Meta+click, non-empty tab, default prefs"},
+                    {pref: false, event: MIDDLE_CLICK,
+                     desc: "Middle click, non-empty tab, default prefs"},
+                    {pref: true, event: ENTER,
+                     desc: "Enter, non-empty tab, openInTab"},
+                    {pref: true, event: CLICK,
+                     desc: "Normal click, non-empty tab, openInTab"}]) {
+    info(test.desc);
+
+    Preferences.set("browser.urlbar.openintab", test.pref);
+    let where = gURLBar._whereToOpen(test.event);
+    is(where, "tab", "URL would be loaded in a new tab");
+  }
+
+  // Clean up.
+  await BrowserTestUtils.removeTab(tab);
+});
+
+add_task(async function keepEmptyTab() {
+  // Open an empty tab.
+  let tab = gBrowser.selectedTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, EMPTY_TAB);
+
+  for (let test of [{pref: false, event: META_CLICK,
+                     desc: "Meta+click, empty tab, default prefs"},
+                    {pref: false, event: MIDDLE_CLICK,
+                     desc: "Middle click, empty tab, default prefs"}]) {
+    info(test.desc);
+
+    Preferences.set("browser.urlbar.openintab", test.pref);
+    let where = gURLBar._whereToOpen(test.event);
+    is(where, "tab", "URL would be loaded in a new tab");
+  }
+
+  // Clean up.
+  await BrowserTestUtils.removeTab(tab);
+});
+
+add_task(async function reuseEmptyTab() {
+  // Open an empty tab.
+  let tab = gBrowser.selectedTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, EMPTY_TAB);
+
+  for (let test of [{pref: false, event: ALT_ENTER,
+                     desc: "Alt+Enter, empty tab, default prefs"},
+                    {pref: true, event: ENTER,
+                     desc: "Enter, empty tab, openInTab"},
+                    {pref: true, event: CLICK,
+                     desc: "Normal click, empty tab, openInTab"}]) {
+    info(test.desc);
+    Preferences.set("browser.urlbar.openintab", test.pref);
+    let where = gURLBar._whereToOpen(test.event);
+    is(where, "current", "New URL would reuse the current empty tab");
+  }
+
+  // Clean up.
+  await BrowserTestUtils.removeTab(tab);
+});
+
+add_task(async function openInCurrentTab() {
+  for (let test of [{pref: false, url: NON_EMPTY_TAB, event: ENTER,
+                     desc: "Enter, non-empty tab, default prefs"},
+                    {pref: false, url: NON_EMPTY_TAB, event: CLICK,
+                     desc: "Normal click, non-empty tab, default prefs"},
+                    {pref: false, url: EMPTY_TAB, event: ENTER,
+                     desc: "Enter, empty tab, default prefs"},
+                    {pref: false, url: EMPTY_TAB, event: CLICK,
+                     desc: "Normal click, empty tab, default prefs"},
+                    {pref: true, url: NON_EMPTY_TAB, event: ALT_ENTER,
+                     desc: "Alt+Enter, non-empty tab, openInTab"},
+                    {pref: true, url: NON_EMPTY_TAB, event: META_CLICK,
+                     desc: "Meta+click, non-empty tab, openInTab"},
+                    {pref: true, url: NON_EMPTY_TAB, event: MIDDLE_CLICK,
+                     desc: "Middle click, non-empty tab, openInTab"}]) {
+    info(test.desc);
+
+    // Open a new tab.
+    let tab = gBrowser.selectedTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, test.url);
+
+    Preferences.set("browser.urlbar.openintab", test.pref);
+    let where = gURLBar._whereToOpen(test.event);
+    is(where, "current", "URL would open in the current tab");
+
+    // Clean up.
+    await BrowserTestUtils.removeTab(tab);
+  }
+});
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -68,16 +68,17 @@ file, You can obtain one at http://mozil
 
         this._defaultPrefs = Components.classes["@mozilla.org/preferences-service;1"]
                                        .getService(Components.interfaces.nsIPrefService)
                                        .getDefaultBranch("browser.urlbar.");
 
         Services.prefs.addObserver("browser.search.suggest.enabled", this);
         this.browserSearchSuggestEnabled = Services.prefs.getBoolPref("browser.search.suggest.enabled");
 
+        this.openInTab = this._prefs.getBoolPref("openintab");
         this.clickSelectsAll = this._prefs.getBoolPref("clickSelectsAll");
         this.doubleClickSelectsAll = this._prefs.getBoolPref("doubleClickSelectsAll");
         this.completeDefaultIndex = this._prefs.getBoolPref("autoFill");
         this.speculativeConnectEnabled = this._prefs.getBoolPref("speculativeConnect.enabled");
         this.urlbarSearchSuggestEnabled = this._prefs.getBoolPref("suggest.searches");
         this.timeout = this._prefs.getIntPref("delay");
         this._formattingEnabled = this._prefs.getBoolPref("formatting.enabled");
         this._mayTrimURLs = this._prefs.getBoolPref("trimURLs");
@@ -310,19 +311,19 @@ file, You can obtain one at http://mozil
             // In this case, the popup is closed and the user pressed the Tab
             // key.  The focus should move out of the urlbar immediately.
             return false;
           }
           if (!this.gotResultForCurrentQuery || !this.popupOpen) {
             return true;
           }
           let maxResultsRemaining =
-            this.popup.maxResults - this.popup._matchCount;
+            this.popup.maxResults - this.popup.matchCount;
           let lastResultSelected =
-            this.popup.selectedIndex + 1 == this.popup._matchCount;
+            this.popup.selectedIndex + 1 == this.popup.matchCount;
           return maxResultsRemaining > 0 && lastResultSelected;
         ]]></body>
       </method>
 
       <!--
         Adds a key event to the deferred event queue.
 
         @param event
@@ -513,16 +514,43 @@ file, You can obtain one at http://mozil
           }
 
           // tell widget to revert to last typed text only if the user
           // was scrolling when they hit escape
           return !isScrolling;
         ]]></body>
       </method>
 
+      <method name="_whereToOpen">
+        <parameter name="event"/>
+        <body><![CDATA[
+          let isMouseEvent = event instanceof MouseEvent;
+          let reuseEmpty = !isMouseEvent;
+          let where = undefined;
+          if (isMouseEvent) {
+            where = whereToOpenLink(event, false, false);
+          } else {
+            let altEnter = event && event.altKey;
+            where = altEnter ? "tab" : "current";
+          }
+          if (this.openInTab) {
+            if (where == "current") {
+              where = "tab";
+            } else if (where == "tab") {
+              where = "current";
+            }
+            reuseEmpty = true;
+          }
+          if (where == "tab" && reuseEmpty && isTabEmpty(gBrowser.selectedTab)) {
+            where = "current";
+          }
+          return where;
+        ]]></body>
+      </method>
+
       <!--
         This is ultimately called by the autocomplete controller as the result
         of handleEnter when the Return key is pressed in the textbox.  Since
         onPopupClick also calls handleEnter, this is also called as a result in
         that case.
 
         @param event
                The event that triggered the command.
@@ -561,29 +589,17 @@ file, You can obtain one at http://mozil
           }
 
           // Do the command of the selected one-off if it's not an engine.
           if (selectedOneOff && !selectedOneOff.engine) {
             selectedOneOff.doCommand();
             return;
           }
 
-          let where = openUILinkWhere;
-          if (!where) {
-            if (isMouseEvent) {
-              where = whereToOpenLink(event, false, false);
-            } else {
-              // If the current tab is empty, ignore Alt+Enter (reuse this tab)
-              let altEnter = !isMouseEvent &&
-                             event &&
-                             event.altKey &&
-                             !isTabEmpty(gBrowser.selectedTab);
-              where = altEnter ? "tab" : "current";
-            }
-          }
+          let where = openUILinkWhere || this._whereToOpen(event);
 
           let url = this.value;
           if (!url) {
             return;
           }
 
           let mayInheritPrincipal = false;
           let postData = null;
@@ -1114,16 +1130,19 @@ file, You can obtain one at http://mozil
                 this.timeout = this._prefs.getIntPref(aData);
                 break;
               case "formatting.enabled":
                 this._formattingEnabled = this._prefs.getBoolPref(aData);
                 break;
               case "speculativeConnect.enabled":
                 this.speculativeConnectEnabled = this._prefs.getBoolPref(aData);
                 break;
+              case "openintab":
+                this.openInTab = this._prefs.getBoolPref(aData);
+                break;
               case "browser.search.suggest.enabled":
                 this.browserSearchSuggestEnabled = Services.prefs.getBoolPref(aData);
                 break;
               case "suggest.searches":
                 this.urlbarSearchSuggestEnabled = this._prefs.getBoolPref(aData);
               case "userMadeSearchSuggestionsChoice":
                 // Mirror the value for future use, see the comment in the
                 // binding's constructor.
@@ -2012,18 +2031,18 @@ file, You can obtain one at http://mozil
           // sometimes fails to complete, leaving the popup too tall.  Work
           // around that problem by disabling the listbox animation.
           this.richlistbox.flex = 0;
           this.setAttribute("dontanimate", "true");
 
           this.classList.add("showSearchSuggestionsNotification");
           // Don't show the one-off buttons if we are showing onboarding and
           // there's no result, since it would be ugly and pointless.
-          this.footer.collapsed = this._matchCount == 0;
-          this.input.tabScrolling = this._matchCount != 0;
+          this.footer.collapsed = this.matchCount == 0;
+          this.input.tabScrolling = this.matchCount != 0;
 
           // This event allows accessibility APIs to see the notification.
           if (!this.popupOpen) {
             let event = document.createEvent("Events");
             event.initEvent("AlertActive", true, true);
             this.searchSuggestionsNotification.dispatchEvent(event);
           }
           ]]>
@@ -2032,17 +2051,17 @@ file, You can obtain one at http://mozil
 
       <method name="_hideSearchSuggestionsNotification">
         <body>
           <![CDATA[
           this.classList.remove("showSearchSuggestionsNotification");
           this.richlistbox.flex = 1;
           this.removeAttribute("dontanimate");
           this.searchSuggestionsNotification.removeAttribute("animate");
-          if (this._matchCount) {
+          if (this.matchCount) {
             // Update popup height.
             this._invalidate();
           } else {
             this.closePopup();
           }
           ]]>
         </body>
       </method>
@@ -2067,17 +2086,17 @@ file, You can obtain one at http://mozil
       </method>
 
       <!-- This handles keypress changes to the selection among the one-off
            search buttons and between the one-offs and the listbox.  It returns
            true if the keypress was consumed and false if not. -->
       <method name="handleKeyPress">
         <parameter name="aEvent"/>
         <body><![CDATA[
-          this.oneOffSearchButtons.handleKeyPress(aEvent, this._matchCount,
+          this.oneOffSearchButtons.handleKeyPress(aEvent, this.matchCount,
                                                   !this._isFirstResultHeuristic,
                                                   gBrowser.userTypedValue);
           return aEvent.defaultPrevented && !aEvent.urlbarDeferred;
         ]]></body>
       </method>
 
       <!-- This is called when a one-off is clicked and when "search in new tab"
            is selected from a one-off context menu. -->
--- a/browser/components/enterprisepolicies/EnterprisePolicies.js
+++ b/browser/components/enterprisepolicies/EnterprisePolicies.js
@@ -77,40 +77,49 @@ EnterprisePoliciesManager.prototype = {
   _xpcom_factory: EnterprisePoliciesFactory,
 
   _initialize() {
     if (!Services.prefs.getBoolPref(PREF_ENABLED, false)) {
       this.status = Ci.nsIEnterprisePolicies.INACTIVE;
       return;
     }
 
-    this._file = new JSONFileReader(getConfigurationFile());
-    this._file.readData();
+    let provider = this._chooseProvider();
 
-    if (!this._file.exists) {
+    if (!provider) {
       this.status = Ci.nsIEnterprisePolicies.INACTIVE;
       return;
     }
 
-    if (this._file.failed) {
+    if (provider.failed) {
       this.status = Ci.nsIEnterprisePolicies.FAILED;
       return;
     }
 
     this.status = Ci.nsIEnterprisePolicies.ACTIVE;
-    this._activatePolicies();
+    this._activatePolicies(provider.policies);
   },
 
-  _activatePolicies() {
-    let { schema } = ChromeUtils.import("resource:///modules/policies/schema.jsm", {});
-    let json = this._file.json;
+  _chooseProvider() {
+    // TODO: Bug 1433136 - Add GPO provider with higher precendence here
+
+    let jsonProvider = new JSONPoliciesProvider();
+    if (jsonProvider.hasPolicies) {
+      return jsonProvider;
+    }
 
-    for (let policyName of Object.keys(json.policies)) {
+    return null;
+  },
+
+  _activatePolicies(unparsedPolicies) {
+    let { schema } = ChromeUtils.import("resource:///modules/policies/schema.jsm", {});
+
+    for (let policyName of Object.keys(unparsedPolicies)) {
       let policySchema = schema.properties[policyName];
-      let policyParameters = json.policies[policyName];
+      let policyParameters = unparsedPolicies[policyName];
 
       if (!policySchema) {
         log.error(`Unknown policy: ${policyName}`);
         continue;
       }
 
       let [parametersAreValid, parsedParameters] =
         PoliciesValidator.validateAndParseParameters(policyParameters,
@@ -270,89 +279,80 @@ EnterprisePoliciesManager.prototype = {
 
   isAllowed: function BG_sanitize(feature) {
     return !(feature in DisallowedFeatures);
   },
 };
 
 let DisallowedFeatures = {};
 
-function JSONFileReader(file) {
-  this._file = file;
-  this._data = {
-    exists: null,
-    failed: false,
-    json: null,
-  };
-}
+
+/*
+ * JSON PROVIDER OF POLICIES
+ *
+ * This is a platform-agnostic provider which looks for
+ * policies specified through a policies.json file stored
+ * in the installation's distribution folder.
+ */
 
-JSONFileReader.prototype = {
-  get exists() {
-    if (this._data.exists === null) {
-      this.readData();
-    }
+class JSONPoliciesProvider {
+  constructor() {
+    this._policies = null;
+    this._failed = false;
+    this._readData();
+  }
 
-    return this._data.exists;
-  },
+  get hasPolicies() {
+    return this._policies !== null || this._failed;
+  }
+
+  get policies() {
+    return this._policies;
+  }
 
   get failed() {
-    return this._data.failed;
-  },
+    return this._failed;
+  }
+
+  _getConfigurationFile() {
+    let configFile = Services.dirsvc.get("XREAppDist", Ci.nsIFile);
+    configFile.append(POLICIES_FILENAME);
+
+    let alternatePath = Services.prefs.getStringPref(PREF_ALTERNATE_PATH, "");
 
-  get json() {
-    if (this._data.failed) {
-      return null;
-    }
-
-    if (this._data.json === null) {
-      this.readData();
+    if (alternatePath && !configFile.exists()) {
+      // We only want to use the alternate file path if the file on the install
+      // folder doesn't exist. Otherwise it'd be possible for a user to override
+      // the admin-provided policies by changing the user-controlled prefs.
+      // This pref is only meant for tests, so it's fine to use this extra
+      // synchronous configFile.exists() above.
+      configFile = Cc["@mozilla.org/file/local;1"]
+                     .createInstance(Ci.nsIFile);
+      configFile.initWithPath(alternatePath);
     }
 
-    return this._data.json;
-  },
+    return configFile;
+  }
 
-  readData() {
+  _readData() {
     try {
-      let data = Cu.readUTF8File(this._file);
+      let data = Cu.readUTF8File(this._getConfigurationFile());
       if (data) {
-        this._data.exists = true;
-        this._data.json = JSON.parse(data);
-      } else {
-        this._data.exists = false;
+        this._policies = JSON.parse(data).policies;
       }
     } catch (ex) {
       if (ex instanceof Components.Exception &&
           ex.result == Cr.NS_ERROR_FILE_NOT_FOUND) {
-        this._data.exists = false;
+        // Do nothing, _policies will remain null
       } else if (ex instanceof SyntaxError) {
         log.error("Error parsing JSON file");
-        this._data.failed = true;
+        this._failed = true;
       } else {
         log.error("Error reading file");
-        this._data.failed = true;
+        this._failed = true;
       }
     }
   }
-};
-
-function getConfigurationFile() {
-  let configFile = Services.dirsvc.get("XREAppDist", Ci.nsIFile);
-  configFile.append(POLICIES_FILENAME);
-
-  let prefType = Services.prefs.getPrefType(PREF_ALTERNATE_PATH);
+}
 
-  if ((prefType == Services.prefs.PREF_STRING) && !configFile.exists()) {
-    // We only want to use the alternate file path if the file on the install
-    // folder doesn't exist. Otherwise it'd be possible for a user to override
-    // the admin-provided policies by changing the user-controlled prefs.
-    // This pref is only meant for tests, so it's fine to use this extra
-    // synchronous configFile.exists() above.
-    configFile = Cc["@mozilla.org/file/local;1"]
-                   .createInstance(Ci.nsIFile);
-    let alternatePath = Services.prefs.getStringPref(PREF_ALTERNATE_PATH);
-    configFile.initWithPath(alternatePath);
-  }
-
-  return configFile;
-}
 
 var components = [EnterprisePoliciesManager];
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
--- a/browser/components/enterprisepolicies/Policies.jsm
+++ b/browser/components/enterprisepolicies/Policies.jsm
@@ -87,16 +87,24 @@ this.Policies = {
   "DisableFirefoxScreenshots": {
     onBeforeAddons(manager, param) {
       if (param == true) {
         setAndLockPref("extensions.screenshots.disabled", true);
       }
     }
   },
 
+  "DisableFirefoxStudies": {
+    onBeforeAddons(manager, param) {
+      if (param == true) {
+        manager.disallowFeature("Shield");
+      }
+    }
+  },
+
   "dont_check_default_browser": {
     onBeforeUIStartup(manager, param) {
       setAndLockPref("browser.shell.checkDefaultBrowser", false);
     }
   },
 
   "flash_plugin": {
     onBeforeUIStartup(manager, param) {
--- a/browser/components/enterprisepolicies/schemas/policies-schema.json
+++ b/browser/components/enterprisepolicies/schemas/policies-schema.json
@@ -37,16 +37,24 @@
     "DisableFirefoxScreenshots": {
       "description": "Prevents usage of the Firefox Screenshots feature.",
       "first_available": "60.0",
 
       "type": "boolean",
       "enum": [true]
     },
 
+    "DisableFirefoxStudies": {
+      "description": "Prevents Firefox from running studies.",
+      "first_available": "60.0",
+
+      "type": "boolean",
+      "enum": [true]
+    },
+
     "dont_check_default_browser": {
       "description": "Don't check for the default browser on startup.",
       "first_available": "60.0",
 
       "type": "boolean",
       "enum": [true]
     },
 
--- a/browser/components/enterprisepolicies/tests/browser/browser.ini
+++ b/browser/components/enterprisepolicies/tests/browser/browser.ini
@@ -11,9 +11,10 @@ support-files =
 [browser_policies_setAndLockPref_API.js]
 [browser_policies_simple_policies.js]
 [browser_policies_validate_and_parse_API.js]
 [browser_policy_block_set_desktop_background.js]
 [browser_policy_default_browser_check.js]
 [browser_policy_disable_fxscreenshots.js]
 [browser_policy_display_bookmarks.js]
 [browser_policy_display_menu.js]
+[browser_policy_disable_shield.js]
 
new file mode 100644
--- /dev/null
+++ b/browser/components/enterprisepolicies/tests/browser/browser_policy_disable_shield.js
@@ -0,0 +1,24 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+add_task(async function test_policy_disable_shield() {
+  const { RecipeRunner } = ChromeUtils.import("resource://shield-recipe-client/lib/RecipeRunner.jsm", {});
+
+  await SpecialPowers.pushPrefEnv({ set: [["extensions.shield-recipe-client.api_url",
+                                            "https://localhost/selfsupport-dummy/"]] });
+
+  ok(RecipeRunner, "RecipeRunner exists");
+  RecipeRunner.checkPrefs();
+  is(RecipeRunner.enabled, true, "RecipeRunner is enabled");
+
+  await setupPolicyEngineWithJson({
+    "policies": {
+      "DisableFirefoxStudies": true
+    }
+  });
+
+  RecipeRunner.checkPrefs();
+  is(RecipeRunner.enabled, false, "RecipeRunner is disabled");
+});
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -737,33 +737,36 @@
             popup.hidden = false;
 
             // Don't roll up on mouse click in the anchor for the search UI.
             if (popup.id == "PopupSearchAutoComplete") {
               popup.setAttribute("norolluponanchor", "true");
             }
 
             popup.mInput = this;
-            popup.view = this.controller.QueryInterface(Ci.nsITreeView);
-            popup.invalidate();
+            // clear any previous selection, see bugs 400671 and 488357
+            popup.selectedIndex = -1;
 
             popup.showCommentColumn = this.showCommentColumn;
             popup.showImageColumn = this.showImageColumn;
 
             document.popupNode = null;
 
             const isRTL = getComputedStyle(this, "").direction == "rtl";
 
             var outerRect = this.getBoundingClientRect();
             var innerRect = this.inputField.getBoundingClientRect();
             let width = isRTL ?
                         innerRect.right - outerRect.left :
                         outerRect.right - innerRect.left;
             popup.setAttribute("width", width > 100 ? width : 100);
 
+            // invalidate() depends on the width attribute
+            popup._invalidate();
+
             var yOffset = outerRect.bottom - innerRect.bottom;
             popup.openPopup(this.inputField, "after_start", 0, yOffset, false, false);
           }
         ]]></body>
       </method>
 
       <method name="openSearch">
         <body>
@@ -803,18 +806,17 @@
           let oneOff = this.selectedButton;
           if (oneOff) {
             if (!oneOff.engine) {
               oneOff.doCommand();
               return;
             }
             engine = oneOff.engine;
           }
-          if (this._selectionDetails &&
-              this._selectionDetails.currentIndex != -1) {
+          if (this._selectionDetails) {
             BrowserSearch.searchBar.telemetrySearchDetails = this._selectionDetails;
             this._selectionDetails = null;
           }
           document.getBindingParent(this).handleSearchCommand(aEvent, engine);
         ]]></body>
       </method>
 
       <property name="selectedButton">
@@ -834,18 +836,18 @@
             return;
 
           // accel + up/down changes the default engine and shouldn't affect
           // the selection on the one-off buttons.
           if (aEvent.getModifierState("Accel"))
             return;
 
           let suggestionsHidden =
-            popup.tree.getAttribute("collapsed") == "true";
-          let numItems = suggestionsHidden ? 0 : this.popup.view.rowCount;
+            popup.richlistbox.getAttribute("collapsed") == "true";
+          let numItems = suggestionsHidden ? 0 : this.popup.matchCount;
           this.popup.oneOffButtons.handleKeyPress(aEvent, numItems, true);
         ]]></body>
       </method>
 
       <!-- nsIController -->
       <field name="searchbarController" readonly="true"><![CDATA[({
         _self: this,
         supportsCommand(aCommand) {
@@ -922,36 +924,29 @@
           document.getBindingParent(this).openSuggestionsPanel();
         }
       ]]>
       </handler>
 
     </handlers>
   </binding>
 
-  <binding id="browser-search-autocomplete-result-popup" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete-result-popup">
+  <binding id="browser-search-autocomplete-result-popup" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete-rich-result-popup">
     <resources>
       <stylesheet src="chrome://browser/content/search/searchbarBindings.css"/>
       <stylesheet src="chrome://browser/skin/searchbar.css"/>
     </resources>
     <content ignorekeys="true" level="top" consumeoutsideclicks="never">
       <xul:hbox anonid="searchbar-engine" xbl:inherits="showonlysettings"
                 class="search-panel-header search-panel-current-engine">
         <xul:image class="searchbar-engine-image" xbl:inherits="src"/>
         <xul:label anonid="searchbar-engine-name" flex="1" crop="end"
                    role="presentation"/>
       </xul:hbox>
-      <xul:tree anonid="tree" flex="1"
-                class="autocomplete-tree plain search-panel-tree"
-                hidecolumnpicker="true" seltype="single">
-        <xul:treecols anonid="treecols">
-          <xul:treecol id="treecolAutoCompleteValue" class="autocomplete-treecol" flex="1" overflow="true"/>
-        </xul:treecols>
-        <xul:treechildren class="autocomplete-treebody searchbar-treebody" noSelectOnMouseMove="true"/>
-      </xul:tree>
+      <xul:richlistbox anonid="richlistbox" class="autocomplete-richlistbox search-panel-tree" flex="1"/>
       <xul:vbox anonid="search-one-off-buttons" class="search-one-offs"/>
     </content>
     <implementation>
       <method name="openAutocompletePopup">
         <parameter name="aInput"/>
         <parameter name="aElement"/>
         <body><![CDATA[
           // initially the panel is hidden
@@ -971,17 +966,17 @@
             return;
 
           var controller = this.view.QueryInterface(Components.interfaces.nsIAutoCompleteController);
 
           var searchBar = BrowserSearch.searchBar;
           var popupForSearchBar = searchBar && searchBar.textbox == this.mInput;
           if (popupForSearchBar) {
             searchBar.telemetrySearchDetails = {
-              index: controller.selection.currentIndex,
+              index: this.selectedIndex,
               kind: "mouse"
             };
           }
 
           // Check for unmodified left-click, and use default behavior
           if (aEvent.button == 0 && !aEvent.shiftKey && !aEvent.ctrlKey &&
               !aEvent.altKey && !aEvent.metaKey) {
             controller.handleEnter(true, aEvent);
@@ -1109,24 +1104,24 @@
         // glass icon has been clicked if the text field is empty.
         let searchbar = document.getElementById("searchbar");
         if (searchbar.hasAttribute("showonlysettings")) {
           searchbar.removeAttribute("showonlysettings");
           this.setAttribute("showonlysettings", "true");
 
           // Setting this with an xbl-inherited attribute gets overridden the
           // second time the user clicks the glass icon for some reason...
-          this.tree.collapsed = true;
+          this.richlistbox.collapsed = true;
         } else {
           this.removeAttribute("showonlysettings");
-          // Uncollapse as long as we have a tree with a view which has >= 1 row.
+          // Uncollapse as long as we have a view which has >= 1 row.
           // The autocomplete binding itself will take care of uncollapsing later,
           // if we currently have no rows but end up having some in the future
           // when the search string changes
-          this.tree.collapsed = !this.tree.view || !this.tree.view.rowCount;
+          this.richlistbox.collapsed = (this.matchCount == 0);
         }
 
         // Show the current default engine in the top header of the panel.
         this.updateHeader();
       ]]></handler>
 
       <handler event="popuphiding"><![CDATA[
         this._isHiding = true;
--- a/browser/components/search/test/browser_426329.js
+++ b/browser/components/search/test/browser_426329.js
@@ -28,26 +28,20 @@ function simulateClick(aEvent, aTarget) 
 function checkMenuEntries(expectedValues) {
   var actualValues = getMenuEntries();
   is(actualValues.length, expectedValues.length, "Checking length of expected menu");
   for (var i = 0; i < expectedValues.length; i++)
     is(actualValues[i], expectedValues[i], "Checking menu entry #" + i);
 }
 
 function getMenuEntries() {
-  var entries = [];
-  var autocompleteMenu = searchBar.textbox.popup;
   // Could perhaps pull values directly from the controller, but it seems
-  // more reliable to test the values that are actually in the tree?
-  var column = autocompleteMenu.tree.columns[0];
-  var numRows = autocompleteMenu.tree.view.rowCount;
-  for (var i = 0; i < numRows; i++) {
-    entries.push(autocompleteMenu.tree.view.getValueAt(i, column));
-  }
-  return entries;
+  // more reliable to test the values that are actually in the richlistbox?
+  return Array.map(searchBar.textbox.popup.richlistbox.children,
+                   item => item.getAttribute("ac-value"));
 }
 
 function countEntries(name, value) {
   return new Promise(resolve => {
     let count = 0;
     let obj = name && value ? {fieldname: name, value} : {};
     FormHistory.count(obj,
                       { handleResult(result) { count = result; },
--- a/browser/components/search/test/browser_private_search_perwindowpb.js
+++ b/browser/components/search/test/browser_private_search_perwindowpb.js
@@ -58,19 +58,13 @@ add_task(async function() {
   searchBar.value = "";
 
   windowsToClose.forEach(function(win) {
     win.close();
   });
 });
 
 function getMenuEntries(searchBar) {
-  let entries = [];
-  let autocompleteMenu = searchBar.textbox.popup;
   // Could perhaps pull values directly from the controller, but it seems
-  // more reliable to test the values that are actually in the tree?
-  let column = autocompleteMenu.tree.columns[0];
-  let numRows = autocompleteMenu.tree.view.rowCount;
-  for (let i = 0; i < numRows; i++) {
-    entries.push(autocompleteMenu.tree.view.getValueAt(i, column));
-  }
-  return entries;
+  // more reliable to test the values that are actually in the richlistbox?
+  return Array.map(searchBar.textbox.popup.richlistbox.children,
+                   item => item.getAttribute("ac-value"));
 }
--- a/browser/extensions/shield-recipe-client/lib/RecipeRunner.jsm
+++ b/browser/extensions/shield-recipe-client/lib/RecipeRunner.jsm
@@ -144,16 +144,22 @@ this.RecipeRunner = {
     }
 
     if (!Services.prefs.getBoolPref(SHIELD_ENABLED_PREF)) {
       log.debug(`Disabling Shield because ${SHIELD_ENABLED_PREF} is set to false`);
       this.disable();
       return;
     }
 
+    if (!Services.policies.isAllowed("Shield")) {
+      log.debug("Disabling Shield because it's blocked by policy.");
+      this.disable();
+      return;
+    }
+
     const apiUrl = Services.prefs.getCharPref(API_URL_PREF);
     if (!apiUrl || !apiUrl.startsWith("https://")) {
       log.warn(`Disabling shield because ${API_URL_PREF} is not an HTTPS url: ${apiUrl}.`);
       this.disable();
       return;
     }
 
     this.enable();
--- a/browser/extensions/shield-recipe-client/lib/ShieldPreferences.jsm
+++ b/browser/extensions/shield-recipe-client/lib/ShieldPreferences.jsm
@@ -105,36 +105,45 @@ this.ShieldPreferences = {
     const hContainer = doc.createElementNS(XUL_NS, "hbox");
     hContainer.setAttribute("align", "center");
     container.appendChild(hContainer);
 
     const checkbox = doc.createElementNS(XUL_NS, "checkbox");
     checkbox.setAttribute("id", "optOutStudiesEnabled");
     checkbox.setAttribute("class", "tail-with-learn-more");
     checkbox.setAttribute("label", "Allow Firefox to install and run studies");
-    checkbox.setAttribute("preference", OPT_OUT_STUDIES_ENABLED_PREF);
+
+    let allowedByPolicy = Services.policies.isAllowed("Shield");
+    if (allowedByPolicy) {
+      // If Shield is not allowed by policy, don't tie this checkbox to the preference,
+      // so that the checkbox remains unchecked.
+      // Otherwise, it would be grayed out but still checked, which looks confusing
+      // because it appears it's enabled with no way to disable it.
+      checkbox.setAttribute("preference", OPT_OUT_STUDIES_ENABLED_PREF);
+    }
     checkbox.setAttribute("disabled", Services.prefs.prefIsLocked(FHR_UPLOAD_ENABLED_PREF) ||
-      !AppConstants.MOZ_TELEMETRY_REPORTING);
+                                      !AppConstants.MOZ_TELEMETRY_REPORTING ||
+                                      !allowedByPolicy);
     hContainer.appendChild(checkbox);
 
     const viewStudies = doc.createElementNS(XUL_NS, "label");
     viewStudies.setAttribute("id", "viewShieldStudies");
     viewStudies.setAttribute("href", "about:studies");
     viewStudies.setAttribute("useoriginprincipal", true);
     viewStudies.textContent = "View Firefox Studies";
     viewStudies.classList.add("learnMore", "text-link");
     hContainer.appendChild(viewStudies);
 
     // Preference instances for prefs that we need to monitor while the page is open.
     doc.defaultView.Preferences.add({ id: OPT_OUT_STUDIES_ENABLED_PREF, type: "bool" });
 
     // Weirdly, FHR doesn't have a Preference instance on the page, so we create it.
     const fhrPref = doc.defaultView.Preferences.add({ id: FHR_UPLOAD_ENABLED_PREF, type: "bool" });
     function onChangeFHRPref(event) {
-      checkbox.disabled = !Services.prefs.getBoolPref(FHR_UPLOAD_ENABLED_PREF);
+      checkbox.disabled = !Services.prefs.getBoolPref(FHR_UPLOAD_ENABLED_PREF) || !allowedByPolicy;
     }
     fhrPref.on("change", onChangeFHRPref);
     doc.defaultView.addEventListener("unload", () => fhrPref.off("change", onChangeFHRPref), { once: true });
 
     // Actually inject the elements we've created.
     const parent = doc.getElementById("submitHealthReportBox").closest("description");
     parent.appendChild(container);
   },
--- a/browser/modules/test/browser/browser_UsageTelemetry_searchbar.js
+++ b/browser/modules/test/browser/browser_UsageTelemetry_searchbar.js
@@ -35,37 +35,23 @@ let searchInSearchbar = async function(i
 
 /**
  * Click one of the entries in the search suggestion popup.
  *
  * @param {String} entryName
  *        The name of the elemet to click on.
  */
 function clickSearchbarSuggestion(entryName) {
-  let popup = BrowserSearch.searchBar.textbox.popup;
-  let column = popup.tree.columns[0];
-
-  for (let rowID = 0; rowID < popup.tree.view.rowCount; rowID++) {
-    const suggestion = popup.tree.view.getValueAt(rowID, column);
-    if (suggestion !== entryName) {
-      continue;
-    }
+  let richlistbox = BrowserSearch.searchBar.textbox.popup.richlistbox;
+  let richlistitem = Array.prototype.find.call(richlistbox.children,
+                     item => item.getAttribute("ac-value") == entryName);
 
-    // Make sure the suggestion is visible, just in case.
-    let tbo = popup.tree.treeBoxObject;
-    tbo.ensureRowIsVisible(rowID);
-    // Calculate the click coordinates.
-    let rect = tbo.getCoordsForCellItem(rowID, column, "text");
-    let x = rect.x + rect.width / 2;
-    let y = rect.y + rect.height / 2;
-    // Simulate the click.
-    EventUtils.synthesizeMouse(popup.tree.body, x, y, {},
-                               popup.tree.ownerGlobal);
-    break;
-  }
+  // Make sure the suggestion is visible and simulate the click.
+  richlistbox.ensureElementIsVisible(richlistitem);
+  EventUtils.synthesizeMouseAtCenter(richlistitem, {});
 }
 
 add_task(async function setup() {
   await SpecialPowers.pushPrefEnv({ set: [
     ["browser.search.widget.inNavBar", true],
   ]});
 
   // Create two new search engines. Mark one as the default engine, so
--- a/browser/themes/shared/autocomplete.inc.css
+++ b/browser/themes/shared/autocomplete.inc.css
@@ -23,39 +23,23 @@
   font: icon;
   margin-inline-start: 4px;
 }
 
 #PopupAutoComplete > richlistbox {
   padding: 0;
 }
 
-.autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
-  color: GrayText;
-}
-
-.autocomplete-treebody::-moz-tree-cell-text(suggesthint, treecolAutoCompleteComment),
-.autocomplete-treebody::-moz-tree-cell-text(suggestfirst, treecolAutoCompleteComment) {
-  color: GrayText;
-  font-size: smaller;
-}
-
-.autocomplete-treebody::-moz-tree-cell(suggesthint) {
-  border-top: 1px solid GrayText;
-}
-
 /* Popup states */
 
-.autocomplete-richlistitem:hover,
-treechildren.searchbar-treebody::-moz-tree-row(hover) {
+.autocomplete-richlistitem:hover {
   background-color: var(--arrowpanel-dimmed);
 }
 
-.autocomplete-richlistitem[selected],
-treechildren.searchbar-treebody::-moz-tree-row(selected) {
+.autocomplete-richlistitem[selected] {
   background-color: Highlight;
   color: HighlightText;
 }
 
 /* Login form autocompletion */
 #PopupAutoComplete > richlistbox > richlistitem[originaltype="login"] > .ac-site-icon {
   display: initial;
   list-style-image: url(chrome://browser/skin/notification-icons/login.svg);
--- a/browser/themes/shared/searchbar.inc.css
+++ b/browser/themes/shared/searchbar.inc.css
@@ -195,47 +195,47 @@
 }
 
 .addengine-item[type=menu] > .toolbarbutton-menu-dropmarker {
   display: -moz-box;
   -moz-appearance: menuarrow !important;
   list-style-image: none;
 }
 
-.search-panel-tree > .autocomplete-treebody,
-.search-panel-tree > .autocomplete-treebody::-moz-tree-row {
-  background: none;
+.search-panel-tree {
+  background: transparent;
+  color: inherit;
 }
 
-.search-panel-tree > .autocomplete-treebody::-moz-tree-cell {
-  border-top: none !important;
+.search-panel-tree > .autocomplete-richlistitem {
+  padding: 1px;
 }
 
-.search-panel-tree > .autocomplete-treebody::-moz-tree-cell-text {
-  color: var(--autocomplete-popup-color) !important;
-}
-
-.search-panel-tree > .autocomplete-treebody::-moz-tree-image {
-  padding-inline-start: 2px;
-  padding-inline-end: 2px;
+.search-panel-tree > .autocomplete-richlistitem > .ac-type-icon {
   width: 14px;
   height: 14px;
 }
 
-.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory) {
+.search-panel-tree > .autocomplete-richlistitem[originaltype="fromhistory"] > .ac-type-icon {
   list-style-image: url("chrome://browser/skin/history.svg");
   -moz-context-properties: fill;
   fill: currentColor;
   fill-opacity: 0.6;
 }
 
-.search-panel-tree > .autocomplete-treebody::-moz-tree-image(fromhistory, selected) {
+.search-panel-tree > .autocomplete-richlistitem[originaltype="fromhistory"][selected] > .ac-type-icon {
   fill-opacity: 1;
 }
 
+.search-panel-tree > .autocomplete-richlistitem > .ac-site-icon,
+.search-panel-tree > .autocomplete-richlistitem > .ac-separator,
+.search-panel-tree > .autocomplete-richlistitem > .ac-url {
+  display: none;
+}
+
 .search-setting-button {
   -moz-appearance: none;
   margin: 0;
   min-height: 32px;
 }
 
 .search-setting-button:hover,
 .search-setting-button[selected] {
--- a/browser/themes/shared/urlbar-autocomplete.inc.css
+++ b/browser/themes/shared/urlbar-autocomplete.inc.css
@@ -6,20 +6,16 @@
 
 :root {
   --autocomplete-popup-background: -moz-field;
   --autocomplete-popup-color: -moz-fieldtext;
   --autocomplete-popup-highlight-background: Highlight;
   --autocomplete-popup-highlight-color: HighlightText;
 }
 
-#treecolAutoCompleteImage {
-  max-width: 36px;
-}
-
 #PopupAutoCompleteRichResult,
 #PopupSearchAutoComplete {
   background: var(--autocomplete-popup-background);
   color: var(--autocomplete-popup-color);
 }
 
 #PopupAutoCompleteRichResult .autocomplete-richlistbox {
   padding: 4px 3px;
@@ -35,25 +31,21 @@
   /* For the space after the autocomplete text we have to use a transparent
      border instead of padding, because the latter would considered part of the
      scrollable area when generating the overflow events that we use to
      constrain the autocomplete result item size. */
   border-inline-end: var(--item-padding-end) solid transparent;
 }
 
 #PopupAutoCompleteRichResult .autocomplete-richlistitem[selected],
-.search-panel-tree > .autocomplete-treebody::-moz-tree-row(selected) {
+#PopupSearchAutoComplete .autocomplete-richlistitem[selected] {
   background: var(--autocomplete-popup-highlight-background);
   color: var(--autocomplete-popup-highlight-color);
 }
 
-.search-panel-tree > .autocomplete-treebody::-moz-tree-cell-text(selected) {
-  color: var(--autocomplete-popup-highlight-color) !important;
-}
-
 :root[uidensity=touch] #PopupAutoCompleteRichResult .autocomplete-richlistitem {
   min-height: 40px;
 }
 
 /* Awesomebar popup items */
 
 .ac-separator:not([selected=true]) {
   color: GrayText;
--- a/dom/canvas/ImageBitmap.cpp
+++ b/dom/canvas/ImageBitmap.cpp
@@ -543,16 +543,17 @@ ImageBitmap::WrapObject(JSContext* aCx, 
   return ImageBitmapBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 ImageBitmap::Close()
 {
   mData = nullptr;
   mSurface = nullptr;
+  mDataWrapper = nullptr;
   mPictureRect.SetEmpty();
 }
 
 void
 ImageBitmap::OnShutdown()
 {
   mShutdownObserver = nullptr;
 
@@ -1567,17 +1568,20 @@ ImageBitmap::WriteStructuredClone(JSStru
   return true;
 }
 
 // ImageBitmap extensions.
 ImageBitmapFormat
 ImageBitmap::FindOptimalFormat(const Optional<Sequence<ImageBitmapFormat>>& aPossibleFormats,
                                ErrorResult& aRv)
 {
-  MOZ_ASSERT(mDataWrapper, "No ImageBitmapFormatUtils functionalities.");
+  if (!mDataWrapper) {
+    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+    return ImageBitmapFormat::EndGuard_;
+  }
 
   ImageBitmapFormat platformFormat = mDataWrapper->GetFormat();
 
   if (!aPossibleFormats.WasPassed() ||
       aPossibleFormats.Value().Contains(platformFormat)) {
     return platformFormat;
   } else {
     // If no matching is found, FindBestMatchingFromat() returns
@@ -1591,17 +1595,20 @@ ImageBitmap::FindOptimalFormat(const Opt
 
     return optimalFormat;
   }
 }
 
 int32_t
 ImageBitmap::MappedDataLength(ImageBitmapFormat aFormat, ErrorResult& aRv)
 {
-  MOZ_ASSERT(mDataWrapper, "No ImageBitmapFormatUtils functionalities.");
+  if (!mDataWrapper) {
+    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+    return 0;
+  }
 
   if (aFormat == mDataWrapper->GetFormat()) {
     return mDataWrapper->GetBufferLength();
   } else {
     return CalculateImageBufferSize(aFormat, Width(), Height());
   }
 }
 
@@ -1627,16 +1634,22 @@ protected:
   }
 
   virtual ~MapDataIntoBufferSource() = default;
 
   void DoMapDataIntoBufferSource()
   {
     ErrorResult error;
 
+    if (!mImageBitmap->mDataWrapper) {
+      error.ThrowWithCustomCleanup(NS_ERROR_NOT_AVAILABLE);
+      mPromise->MaybeReject(error);
+      return;
+    }
+
     // Prepare destination buffer.
     uint8_t* bufferData = nullptr;
     uint32_t bufferLength = 0;
     bool isSharedMemory = false;
     if (JS_IsArrayBufferObject(mBuffer)) {
       js::GetArrayBufferLengthAndData(mBuffer, &bufferLength, &isSharedMemory, &bufferData);
     } else if (JS_IsArrayBufferViewObject(mBuffer)) {
       js::GetArrayBufferViewLengthAndData(mBuffer, &bufferLength, &isSharedMemory, &bufferData);
@@ -1779,25 +1792,30 @@ void AsyncMapDataIntoBufferSource(JSCont
 }
 
 already_AddRefed<Promise>
 ImageBitmap::MapDataInto(JSContext* aCx,
                          ImageBitmapFormat aFormat,
                          const ArrayBufferViewOrArrayBuffer& aBuffer,
                          int32_t aOffset, ErrorResult& aRv)
 {
-  MOZ_ASSERT(mDataWrapper, "No ImageBitmapFormatUtils functionalities.");
   MOZ_ASSERT(aCx, "No JSContext while calling ImageBitmap::MapDataInto().");
 
   RefPtr<Promise> promise = Promise::Create(mParent, aRv);
 
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
+  if (!mDataWrapper) {
+    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+    return promise.forget();
+
+  }
+
   // Check for cases that should throws.
   // Case 1:
   // If image bitmap was cropped to the source rectangle so that it contains any
   // transparent black pixels (cropping area is outside of the source image),
   // then reject promise with IndexSizeError and abort these steps.
   if (mIsCroppingAreaOutSideOfSourceImage) {
     aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
     return promise.forget();
--- a/dom/serviceworkers/test/mochitest.ini
+++ b/dom/serviceworkers/test/mochitest.ini
@@ -336,16 +336,15 @@ tags = openwindow
 [test_strict_mode_warning.html]
 [test_third_party_iframes.html]
 [test_unregister.html]
 [test_unresolved_fetch_interception.html]
 [test_update_missing_imported_script.html]
 [test_workerUnregister.html]
 [test_workerUpdate.html]
 [test_workerupdatefoundevent.html]
-skip-if = !e10s # Bug 1433276
 [test_xslt.html]
 [test_async_waituntil.html]
 [test_worker_reference_gc_timeout.html]
 [test_nofetch_handler.html]
 [test_bad_script_cache.html]
 [test_file_upload.html]
 support-files = script_file_upload.js sw_file_upload.js server_file_upload.sjs
--- a/dom/serviceworkers/test/test_workerupdatefoundevent.html
+++ b/dom/serviceworkers/test/test_workerupdatefoundevent.html
@@ -17,37 +17,43 @@
 <script class="testbody" type="text/javascript">
   var registration;
   var promise;
 
   async function start() {
     registration = await navigator.serviceWorker.register("worker_updatefoundevent.js",
                                                           { scope: "./updatefoundevent.html" })
     await waitForState(registration.installing, 'activated');
+
+    content = document.getElementById("content");
+    iframe = document.createElement("iframe");
+    content.appendChild(iframe);
+    iframe.setAttribute("src", "./updatefoundevent.html");
+
+    await new Promise(function(resolve) { iframe.onload = resolve; });
+    ok(iframe.contentWindow.navigator.serviceWorker.controller, "Controlled client.");
+
+    return Promise.resolve();
+
   }
 
   function startWaitForUpdateFound() {
     registration.onupdatefound = function(e) {
     }
 
     promise = new Promise(function(resolve, reject) {
       window.onmessage = function(e) {
 
         if (e.data == "finish") {
           ok(true, "Received updatefound");
           resolve();
         }
       }
     });
 
-    content = document.getElementById("content");
-    iframe = document.createElement("iframe");
-    content.appendChild(iframe);
-    iframe.setAttribute("src", "./updatefoundevent.html");
-
     return Promise.resolve();
   }
 
   function registerNext() {
     return navigator.serviceWorker.register("worker_updatefoundevent2.js",
                                             { scope: "./updatefoundevent.html" });
   }
 
--- a/dom/serviceworkers/test/worker_updatefoundevent.js
+++ b/dom/serviceworkers/test/worker_updatefoundevent.js
@@ -1,17 +1,19 @@
 /**
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 registration.onupdatefound = function(e) {
   clients.matchAll().then(function(clients) {
     if (!clients.length) {
-      reject("No clients found");
+      // We don't control any clients when the first update event is fired
+      // because we haven't reached the 'activated' state.
+      return;
     }
 
     if (registration.scope.match(/updatefoundevent\.html$/)) {
       clients[0].postMessage("finish");
     } else {
       dump("Scope did not match");
     }
   });
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -1750,16 +1750,19 @@ private:
   static StaticRefPtr<ID3D11Device> mD3D11Device;
   static StaticRefPtr<IDWriteFactory> mDWriteFactory;
   static bool mDWriteFactoryInitialized;
 
 protected:
   // This guards access to the singleton devices above, as well as the
   // singleton devices in DrawTargetD2D1.
   static StaticMutex mDeviceLock;
+  // This synchronizes access between different D2D drawtargets and their
+  // implied dependency graph.
+  static StaticMutex mDTDependencyLock;
 
   friend class DrawTargetD2D1;
 #endif
 
 private:
   static DrawEventRecorder *mRecorder;
 };
 
--- a/gfx/2d/DrawTargetD2D1.cpp
+++ b/gfx/2d/DrawTargetD2D1.cpp
@@ -71,26 +71,31 @@ DrawTargetD2D1::~DrawTargetD2D1()
 
   if (mDC && IsDeviceContextValid()) {
     // The only way mDC can be null is if Init failed, but it can happen and the
     // destructor is the only place where we need to check for it since the
     // DrawTarget will destroyed right after Init fails.
     mDC->EndDraw();
   }
 
-  // Targets depending on us can break that dependency, since we're obviously not going to
-  // be modified in the future.
-  for (auto iter = mDependentTargets.begin();
-       iter != mDependentTargets.end(); iter++) {
-    (*iter)->mDependingOnTargets.erase(this);
-  }
-  // Our dependencies on other targets no longer matter.
-  for (TargetSet::iterator iter = mDependingOnTargets.begin();
-       iter != mDependingOnTargets.end(); iter++) {
-    (*iter)->mDependentTargets.erase(this);
+  {
+    // Until this point in the destructor it -must- still be valid for FlushInternal
+    // to be called on this.
+    StaticMutexAutoLock lock(Factory::mDTDependencyLock);
+    // Targets depending on us can break that dependency, since we're obviously not going to
+    // be modified in the future.
+    for (auto iter = mDependentTargets.begin();
+      iter != mDependentTargets.end(); iter++) {
+      (*iter)->mDependingOnTargets.erase(this);
+    }
+    // Our dependencies on other targets no longer matter.
+    for (TargetSet::iterator iter = mDependingOnTargets.begin();
+      iter != mDependingOnTargets.end(); iter++) {
+      (*iter)->mDependentTargets.erase(this);
+    }
   }
 }
 
 already_AddRefed<SourceSurface>
 DrawTargetD2D1::Snapshot()
 {
   MutexAutoLock lock(*mSnapshotLock);
   if (mSnapshot) {
@@ -151,38 +156,17 @@ DrawTargetD2D1::IntoLuminanceSource(Lumi
 // this can cause issues with memory usage (see bug 1238328). EndDraw/BeginDraw
 // are expensive though, especially relatively when little work is done, so
 // we try to reduce the amount of times we execute these purges.
 static const uint32_t kPushedLayersBeforePurge = 25;
 
 void
 DrawTargetD2D1::Flush()
 {
-  if (IsDeviceContextValid()) {
-    if ((mUsedCommandListsSincePurge >= kPushedLayersBeforePurge) &&
-        mPushedLayers.size() == 1) {
-      // It's important to pop all clips as otherwise layers can forget about
-      // their clip when doing an EndDraw. When we have layers pushed we cannot
-      // easily pop all underlying clips to delay the purge until we have no
-      // layers pushed.
-      PopAllClips();
-      mUsedCommandListsSincePurge = 0;
-      mDC->EndDraw();
-      mDC->BeginDraw();
-    } else {
-      mDC->Flush();
-    }
-  }
-
-  // We no longer depend on any target.
-  for (TargetSet::iterator iter = mDependingOnTargets.begin();
-       iter != mDependingOnTargets.end(); iter++) {
-    (*iter)->mDependentTargets.erase(this);
-  }
-  mDependingOnTargets.clear();
+  FlushInternal();
 }
 
 void
 DrawTargetD2D1::DrawSurface(SourceSurface *aSurface,
                             const Rect &aDest,
                             const Rect &aSource,
                             const DrawSurfaceOptions &aSurfOptions,
                             const DrawOptions &aOptions)
@@ -1267,38 +1251,77 @@ DrawTargetD2D1::CleanupD2D()
   if (mFactory) {
     RadialGradientEffectD2D1::Unregister(mFactory);
     ExtendInputEffectD2D1::Unregister(mFactory);
     mFactory = nullptr;
   }
 }
 
 void
+DrawTargetD2D1::FlushInternal(bool aHasDependencyMutex /* = false */)
+{
+  if (IsDeviceContextValid()) {
+    if ((mUsedCommandListsSincePurge >= kPushedLayersBeforePurge) &&
+      mPushedLayers.size() == 1) {
+      // It's important to pop all clips as otherwise layers can forget about
+      // their clip when doing an EndDraw. When we have layers pushed we cannot
+      // easily pop all underlying clips to delay the purge until we have no
+      // layers pushed.
+      PopAllClips();
+      mUsedCommandListsSincePurge = 0;
+      mDC->EndDraw();
+      mDC->BeginDraw();
+    }
+    else {
+      mDC->Flush();
+    }
+  }
+
+  Maybe<StaticMutexAutoLock> lock;
+
+  if (!aHasDependencyMutex) {
+    lock.emplace(Factory::mDTDependencyLock);
+  }
+
+  Factory::mDTDependencyLock.AssertCurrentThreadOwns();
+  // We no longer depend on any target.
+  for (TargetSet::iterator iter = mDependingOnTargets.begin();
+    iter != mDependingOnTargets.end(); iter++) {
+    (*iter)->mDependentTargets.erase(this);
+  }
+  mDependingOnTargets.clear();
+}
+
+void
 DrawTargetD2D1::MarkChanged()
 {
   if (mSnapshot) {
     MutexAutoLock lock(*mSnapshotLock);
     if (mSnapshot->hasOneRef()) {
       // Just destroy it, since no-one else knows about it.
       mSnapshot = nullptr;
     } else {
       mSnapshot->DrawTargetWillChange();
       // The snapshot will no longer depend on this target.
       MOZ_ASSERT(!mSnapshot);
     }
   }
-  if (mDependentTargets.size()) {
-    // Copy mDependentTargets since the Flush()es below will modify it.
-    TargetSet tmpTargets = mDependentTargets;
-    for (TargetSet::iterator iter = tmpTargets.begin();
-         iter != tmpTargets.end(); iter++) {
-      (*iter)->Flush();
+
+  {
+    StaticMutexAutoLock lock(Factory::mDTDependencyLock);
+    if (mDependentTargets.size()) {
+      // Copy mDependentTargets since the Flush()es below will modify it.
+      TargetSet tmpTargets = mDependentTargets;
+      for (TargetSet::iterator iter = tmpTargets.begin();
+        iter != tmpTargets.end(); iter++) {
+        (*iter)->FlushInternal(true);
+      }
+      // The Flush() should have broken all dependencies on this target.
+      MOZ_ASSERT(!mDependentTargets.size());
     }
-    // The Flush() should have broken all dependencies on this target.
-    MOZ_ASSERT(!mDependentTargets.size());
   }
 }
 
 bool
 DrawTargetD2D1::ShouldClipTemporarySurfaceDrawing(CompositionOp aOp,
                                                   const Pattern& aPattern,
                                                   bool aClipIsComplex)
 {
@@ -1459,19 +1482,28 @@ DrawTargetD2D1::FinalizeDrawing(Composit
   radialGradientEffect->SetInput(0, source);
 
   mDC->DrawImage(radialGradientEffect, D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR, D2DCompositionMode(aOp));
 }
 
 void
 DrawTargetD2D1::AddDependencyOnSource(SourceSurfaceD2D1* aSource)
 {
-  if (aSource->mDrawTarget && !mDependingOnTargets.count(aSource->mDrawTarget)) {
-    aSource->mDrawTarget->mDependentTargets.insert(this);
-    mDependingOnTargets.insert(aSource->mDrawTarget);
+  Maybe<MutexAutoLock> snapshotLock;
+  // We grab the SnapshotLock as well, this guaranteeds aSource->mDrawTarget
+  // cannot be cleared in between the if statement and the dereference.
+  if (aSource->mSnapshotLock) {
+    snapshotLock.emplace(*aSource->mSnapshotLock);
+  }
+  {
+    StaticMutexAutoLock lock(Factory::mDTDependencyLock);
+    if (aSource->mDrawTarget && !mDependingOnTargets.count(aSource->mDrawTarget)) {
+      aSource->mDrawTarget->mDependentTargets.insert(this);
+      mDependingOnTargets.insert(aSource->mDrawTarget);
+    }
   }
 }
 
 static D2D1_RECT_F
 IntersectRect(const D2D1_RECT_F& aRect1, const D2D1_RECT_F& aRect2)
 {
   D2D1_RECT_F result;
   result.left = max(aRect1.left, aRect2.left);
--- a/gfx/2d/DrawTargetD2D1.h
+++ b/gfx/2d/DrawTargetD2D1.h
@@ -168,16 +168,18 @@ public:
   }
 
   static uint64_t mVRAMUsageDT;
   static uint64_t mVRAMUsageSS;
 
 private:
   friend class SourceSurfaceD2D1;
 
+  void FlushInternal(bool aHasDependencyMutex = false);
+
   typedef std::unordered_set<DrawTargetD2D1*> TargetSet;
 
   // This function will mark the surface as changing, and make sure any
   // copy-on-write snapshots are notified.
   void MarkChanged();
   bool ShouldClipTemporarySurfaceDrawing(CompositionOp aOp, const Pattern& aPattern, bool aClipIsComplex);
   void PrepareForDrawing(CompositionOp aOp, const Pattern &aPattern);
   void FinalizeDrawing(CompositionOp aOp, const Pattern &aPattern);
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -217,16 +217,17 @@ Mutex* Factory::mFTLock = nullptr;
 #ifdef WIN32
 // Note: mDeviceLock must be held when mutating these values.
 static uint32_t mDeviceSeq = 0;
 StaticRefPtr<ID3D11Device> Factory::mD3D11Device;
 StaticRefPtr<ID2D1Device> Factory::mD2D1Device;
 StaticRefPtr<IDWriteFactory> Factory::mDWriteFactory;
 bool Factory::mDWriteFactoryInitialized = false;
 StaticMutex Factory::mDeviceLock;
+StaticMutex Factory::mDTDependencyLock;
 #endif
 
 DrawEventRecorder *Factory::mRecorder;
 
 mozilla::gfx::Config* Factory::sConfig = nullptr;
 
 void
 Factory::Init(const Config& aConfig)
--- a/js/src/builtin/intl/PluralRules.cpp
+++ b/js/src/builtin/intl/PluralRules.cpp
@@ -102,16 +102,17 @@ PluralRules(JSContext* cx, unsigned argc
 
     Rooted<PluralRulesObject*> pluralRules(cx);
     pluralRules = NewObjectWithGivenProto<PluralRulesObject>(cx, proto);
     if (!pluralRules)
         return false;
 
     pluralRules->setReservedSlot(PluralRulesObject::INTERNALS_SLOT, NullValue());
     pluralRules->setReservedSlot(PluralRulesObject::UPLURAL_RULES_SLOT, PrivateValue(nullptr));
+    pluralRules->setReservedSlot(PluralRulesObject::UNUMBER_FORMAT_SLOT, PrivateValue(nullptr));
 
     HandleValue locales = args.get(0);
     HandleValue options = args.get(1);
 
     // Step 3.
     if (!intl::InitializeObject(cx, pluralRules, cx->names().InitializePluralRules, locales,
                                 options))
     {
@@ -122,20 +123,29 @@ PluralRules(JSContext* cx, unsigned argc
     return true;
 }
 
 void
 js::PluralRulesObject::finalize(FreeOp* fop, JSObject* obj)
 {
     MOZ_ASSERT(fop->onActiveCooperatingThread());
 
-    const Value& slot =
-        obj->as<PluralRulesObject>().getReservedSlot(PluralRulesObject::UPLURAL_RULES_SLOT);
-    if (UPluralRules* pr = static_cast<UPluralRules*>(slot.toPrivate()))
+    PluralRulesObject* pluralRules = &obj->as<PluralRulesObject>();
+
+    const Value& prslot = pluralRules->getReservedSlot(PluralRulesObject::UPLURAL_RULES_SLOT);
+    UPluralRules* pr = static_cast<UPluralRules*>(prslot.toPrivate());
+
+    const Value& nfslot = pluralRules->getReservedSlot(PluralRulesObject::UNUMBER_FORMAT_SLOT);
+    UNumberFormat* nf = static_cast<UNumberFormat*>(nfslot.toPrivate());
+
+    if (pr)
         uplrules_close(pr);
+
+    if (nf)
+        unum_close(nf);
 }
 
 JSObject*
 js::CreatePluralRulesPrototype(JSContext* cx, HandleObject Intl, Handle<GlobalObject*> global)
 {
     RootedFunction ctor(cx);
     ctor = global->createConstructor(cx, &PluralRules, cx->names().PluralRules, 0);
     if (!ctor)
@@ -247,110 +257,120 @@ NewUNumberFormatForPluralRules(JSContext
         unum_setAttribute(nf, UNUM_MIN_INTEGER_DIGITS, uMinimumIntegerDigits);
         unum_setAttribute(nf, UNUM_MIN_FRACTION_DIGITS, uMinimumFractionDigits);
         unum_setAttribute(nf, UNUM_MAX_FRACTION_DIGITS, uMaximumFractionDigits);
     }
 
     return toClose.forget();
 }
 
+/**
+ * Returns a new UPluralRules with the locale and type options of the given
+ * PluralRules.
+ */
+static UPluralRules*
+NewUPluralRules(JSContext* cx, Handle<PluralRulesObject*> pluralRules)
+{
+    RootedObject internals(cx, intl::GetInternalsObject(cx, pluralRules));
+    if (!internals)
+        return nullptr;
+
+    RootedValue value(cx);
+
+    if (!GetProperty(cx, internals, internals, cx->names().locale, &value))
+        return nullptr;
+    JSAutoByteString locale(cx, value.toString());
+    if (!locale)
+        return nullptr;
+
+    if (!GetProperty(cx, internals, internals, cx->names().type, &value))
+        return nullptr;
+
+    UPluralType category;
+    {
+        JSLinearString* type = value.toString()->ensureLinear(cx);
+        if (!type)
+            return nullptr;
+
+        if (StringEqualsAscii(type, "cardinal")) {
+            category = UPLURAL_TYPE_CARDINAL;
+        } else {
+            MOZ_ASSERT(StringEqualsAscii(type, "ordinal"));
+            category = UPLURAL_TYPE_ORDINAL;
+        }
+    }
+
+    UErrorCode status = U_ZERO_ERROR;
+    UPluralRules* pr = uplrules_openForType(IcuLocale(locale.ptr()), category, &status);
+    if (U_FAILURE(status)) {
+        intl::ReportInternalError(cx);
+        return nullptr;
+    }
+    return pr;
+}
+
 bool
 js::intl_SelectPluralRule(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 2);
 
     Rooted<PluralRulesObject*> pluralRules(cx, &args[0].toObject().as<PluralRulesObject>());
 
     double x = args[1].toNumber();
 
-    UNumberFormat* nf = NewUNumberFormatForPluralRules(cx, pluralRules);
-    if (!nf)
-        return false;
-
-    ScopedICUObject<UNumberFormat, unum_close> closeNumberFormat(nf);
-
-    RootedObject internals(cx, intl::GetInternalsObject(cx, pluralRules));
-    if (!internals)
-        return false;
-
-    RootedValue value(cx);
-
-    if (!GetProperty(cx, internals, internals, cx->names().locale, &value))
-        return false;
-    JSAutoByteString locale(cx, value.toString());
-    if (!locale)
-        return false;
-
-    if (!GetProperty(cx, internals, internals, cx->names().type, &value))
-        return false;
-
-    UPluralType category;
-    {
-        JSLinearString* type = value.toString()->ensureLinear(cx);
-        if (!type)
+    // Obtain a cached UPluralRules object.
+    void* priv = pluralRules->getReservedSlot(PluralRulesObject::UPLURAL_RULES_SLOT).toPrivate();
+    UPluralRules* pr = static_cast<UPluralRules*>(priv);
+    if (!pr) {
+        pr = NewUPluralRules(cx, pluralRules);
+        if (!pr)
             return false;
-
-        if (StringEqualsAscii(type, "cardinal")) {
-            category = UPLURAL_TYPE_CARDINAL;
-        } else {
-            MOZ_ASSERT(StringEqualsAscii(type, "ordinal"));
-            category = UPLURAL_TYPE_ORDINAL;
-        }
+        pluralRules->setReservedSlot(PluralRulesObject::UPLURAL_RULES_SLOT, PrivateValue(pr));
     }
 
-    // TODO: Cache UPluralRules in PluralRulesObject::UPluralRulesSlot.
-    UErrorCode status = U_ZERO_ERROR;
-    UPluralRules* pr = uplrules_openForType(IcuLocale(locale.ptr()), category, &status);
-    if (U_FAILURE(status)) {
-        intl::ReportInternalError(cx);
-        return false;
+    // Obtain a cached UNumberFormat object.
+    priv = pluralRules->getReservedSlot(PluralRulesObject::UNUMBER_FORMAT_SLOT).toPrivate();
+    UNumberFormat* nf = static_cast<UNumberFormat*>(priv);
+    if (!nf) {
+        nf = NewUNumberFormatForPluralRules(cx, pluralRules);
+        if (!nf)
+            return false;
+        pluralRules->setReservedSlot(PluralRulesObject::UNUMBER_FORMAT_SLOT, PrivateValue(nf));
     }
-    ScopedICUObject<UPluralRules, uplrules_close> closePluralRules(pr);
 
     JSString* str = CallICU(cx, [pr, x, nf](UChar* chars, int32_t size, UErrorCode* status) {
         return uplrules_selectWithFormat(pr, x, nf, chars, size, status);
     });
     if (!str)
         return false;
 
     args.rval().setString(str);
     return true;
 }
 
 bool
 js::intl_GetPluralCategories(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-    MOZ_ASSERT(args.length() == 2);
+    MOZ_ASSERT(args.length() == 1);
 
-    JSAutoByteString locale(cx, args[0].toString());
-    if (!locale)
-        return false;
+    Rooted<PluralRulesObject*> pluralRules(cx, &args[0].toObject().as<PluralRulesObject>());
 
-    JSLinearString* type = args[1].toString()->ensureLinear(cx);
-    if (!type)
-        return false;
-
-    UPluralType category;
-    if (StringEqualsAscii(type, "cardinal")) {
-        category = UPLURAL_TYPE_CARDINAL;
-    } else {
-        MOZ_ASSERT(StringEqualsAscii(type, "ordinal"));
-        category = UPLURAL_TYPE_ORDINAL;
+    // Obtain a cached UPluralRules object.
+    void* priv = pluralRules->getReservedSlot(PluralRulesObject::UPLURAL_RULES_SLOT).toPrivate();
+    UPluralRules* pr = static_cast<UPluralRules*>(priv);
+    if (!pr) {
+        pr = NewUPluralRules(cx, pluralRules);
+        if (!pr)
+            return false;
+        pluralRules->setReservedSlot(PluralRulesObject::UPLURAL_RULES_SLOT, PrivateValue(pr));
     }
 
     UErrorCode status = U_ZERO_ERROR;
-    UPluralRules* pr = uplrules_openForType(IcuLocale(locale.ptr()), category, &status);
-    if (U_FAILURE(status)) {
-        intl::ReportInternalError(cx);
-        return false;
-    }
-    ScopedICUObject<UPluralRules, uplrules_close> closePluralRules(pr);
-
     UEnumeration* ue = uplrules_getKeywords(pr, &status);
     if (U_FAILURE(status)) {
         intl::ReportInternalError(cx);
         return false;
     }
     ScopedICUObject<UEnumeration, uenum_close> closeEnum(ue);
 
     RootedObject res(cx, NewDenseEmptyArray(cx));
--- a/js/src/builtin/intl/PluralRules.h
+++ b/js/src/builtin/intl/PluralRules.h
@@ -20,17 +20,18 @@ class FreeOp;
 
 class PluralRulesObject : public NativeObject
 {
   public:
     static const Class class_;
 
     static constexpr uint32_t INTERNALS_SLOT = 0;
     static constexpr uint32_t UPLURAL_RULES_SLOT = 1;
-    static constexpr uint32_t SLOT_COUNT = 2;
+    static constexpr uint32_t UNUMBER_FORMAT_SLOT = 2;
+    static constexpr uint32_t SLOT_COUNT = 3;
 
     static_assert(INTERNALS_SLOT == INTL_INTERNALS_OBJECT_SLOT,
                   "INTERNALS_SLOT must match self-hosting define for internals object slot");
 
   private:
     static const ClassOps classOps_;
 
     static void finalize(FreeOp* fop, JSObject* obj);
@@ -59,23 +60,23 @@ intl_PluralRules_availableLocales(JSCont
  * (such as "one", "two", "few" etc.).
  *
  * Usage: rule = intl_SelectPluralRule(pluralRules, x)
  */
 extern MOZ_MUST_USE bool
 intl_SelectPluralRule(JSContext* cx, unsigned argc, JS::Value* vp);
 
 /**
- * Returns an array of plural rules categories for a given
- * locale and type.
+ * Returns an array of plural rules categories for a given pluralRules object.
  *
- * Usage: categories = intl_GetPluralCategories(locale, type)
+ * Usage: categories = intl_GetPluralCategories(pluralRules)
  *
  * Example:
  *
- * intl_getPluralCategories('pl', 'cardinal'); // ['one', 'few', 'many', 'other']
+ * pluralRules = new Intl.PluralRules('pl', {type: 'cardinal'});
+ * intl_getPluralCategories(pluralRules); // ['one', 'few', 'many', 'other']
  */
 extern MOZ_MUST_USE bool
 intl_GetPluralCategories(JSContext* cx, unsigned argc, JS::Value* vp);
 
 } // namespace js
 
 #endif /* builtin_intl_PluralRules_h */
--- a/js/src/builtin/intl/PluralRules.js
+++ b/js/src/builtin/intl/PluralRules.js
@@ -43,19 +43,17 @@ function resolvePluralRulesInternals(laz
                           lazyPluralRulesData.requestedLocales,
                           lazyPluralRulesData.opt,
                           PluralRules.relevantExtensionKeys, PluralRules.localeData);
 
     // Step 14.
     internalProps.locale = r.locale;
     internalProps.type = lazyPluralRulesData.type;
 
-    internalProps.pluralCategories = intl_GetPluralCategories(
-        internalProps.locale,
-        internalProps.type);
+    internalProps.pluralCategories = null;
 
     internalProps.minimumIntegerDigits = lazyPluralRulesData.minimumIntegerDigits;
     internalProps.minimumFractionDigits = lazyPluralRulesData.minimumFractionDigits;
     internalProps.maximumFractionDigits = lazyPluralRulesData.maximumFractionDigits;
 
     if ("minimumSignificantDigits" in lazyPluralRulesData) {
         assert("maximumSignificantDigits" in lazyPluralRulesData, "min/max sig digits mismatch");
         internalProps.minimumSignificantDigits = lazyPluralRulesData.minimumSignificantDigits;
@@ -210,16 +208,19 @@ function Intl_PluralRules_resolvedOption
     if (!IsObject(this) || !IsPluralRules(this)) {
         ThrowTypeError(JSMSG_INTL_OBJECT_NOT_INITED, "PluralRules", "resolvedOptions",
                        "PluralRules");
     }
 
     var internals = getPluralRulesInternals(this);
 
     var internalsPluralCategories = internals.pluralCategories;
+    if (internalsPluralCategories === null)
+        internals.pluralCategories = internalsPluralCategories = intl_GetPluralCategories(this);
+
     var pluralCategories = [];
     for (var i = 0; i < internalsPluralCategories.length; i++)
         _DefineDataProperty(pluralCategories, i, internalsPluralCategories[i]);
 
     var result = {
         locale: internals.locale,
         type: internals.type,
         pluralCategories,
--- a/js/src/builtin/intl/RelativeTimeFormat.cpp
+++ b/js/src/builtin/intl/RelativeTimeFormat.cpp
@@ -101,17 +101,18 @@ RelativeTimeFormat(JSContext* cx, unsign
     }
 
     Rooted<RelativeTimeFormatObject*> relativeTimeFormat(cx);
     relativeTimeFormat = NewObjectWithGivenProto<RelativeTimeFormatObject>(cx, proto);
     if (!relativeTimeFormat)
         return false;
 
     relativeTimeFormat->setReservedSlot(RelativeTimeFormatObject::INTERNALS_SLOT, NullValue());
-    relativeTimeFormat->setReservedSlot(RelativeTimeFormatObject::URELATIVE_TIME_FORMAT_SLOT, PrivateValue(nullptr));
+    relativeTimeFormat->setReservedSlot(RelativeTimeFormatObject::URELATIVE_TIME_FORMAT_SLOT,
+                                        PrivateValue(nullptr));
 
     HandleValue locales = args.get(0);
     HandleValue options = args.get(1);
 
     // Step 3.
     if (!intl::InitializeObject(cx, relativeTimeFormat, cx->names().InitializeRelativeTimeFormat,
                                 locales, options))
     {
@@ -122,18 +123,18 @@ RelativeTimeFormat(JSContext* cx, unsign
     return true;
 }
 
 void
 js::RelativeTimeFormatObject::finalize(FreeOp* fop, JSObject* obj)
 {
     MOZ_ASSERT(fop->onActiveCooperatingThread());
 
-    const Value& slot =
-        obj->as<RelativeTimeFormatObject>().getReservedSlot(RelativeTimeFormatObject::URELATIVE_TIME_FORMAT_SLOT);
+    constexpr auto RT_FORMAT_SLOT = RelativeTimeFormatObject::URELATIVE_TIME_FORMAT_SLOT;
+    const Value& slot = obj->as<RelativeTimeFormatObject>().getReservedSlot(RT_FORMAT_SLOT);
     if (URelativeDateTimeFormatter* rtf = static_cast<URelativeDateTimeFormatter*>(slot.toPrivate()))
         ureldatefmt_close(rtf);
 }
 
 JSObject*
 js::CreateRelativeTimeFormatPrototype(JSContext* cx, HandleObject Intl,
                                       Handle<GlobalObject*> global)
 {
@@ -203,16 +204,65 @@ js::intl_RelativeTimeFormat_availableLoc
     // We're going to use ULocale availableLocales as per ICU recommendation:
     // https://ssl.icu-project.org/trac/ticket/12756
     if (!GetAvailableLocales(cx, uloc_countAvailable, uloc_getAvailable, &result))
         return false;
     args.rval().set(result);
     return true;
 }
 
+/**
+ * Returns a new URelativeDateTimeFormatter with the locale and options of the
+ * given RelativeTimeFormatObject.
+ */
+static URelativeDateTimeFormatter*
+NewURelativeDateTimeFormatter(JSContext* cx, Handle<RelativeTimeFormatObject*> relativeTimeFormat)
+{
+    RootedObject internals(cx, intl::GetInternalsObject(cx, relativeTimeFormat));
+    if (!internals)
+        return nullptr;
+
+    RootedValue value(cx);
+
+    if (!GetProperty(cx, internals, internals, cx->names().locale, &value))
+        return nullptr;
+    JSAutoByteString locale(cx, value.toString());
+    if (!locale)
+        return nullptr;
+
+    if (!GetProperty(cx, internals, internals, cx->names().style, &value))
+        return nullptr;
+
+    UDateRelativeDateTimeFormatterStyle relDateTimeStyle;
+    {
+        JSLinearString* style = value.toString()->ensureLinear(cx);
+        if (!style)
+            return nullptr;
+
+        if (StringEqualsAscii(style, "short")) {
+            relDateTimeStyle = UDAT_STYLE_SHORT;
+        } else if (StringEqualsAscii(style, "narrow")) {
+            relDateTimeStyle = UDAT_STYLE_NARROW;
+        } else {
+            MOZ_ASSERT(StringEqualsAscii(style, "long"));
+            relDateTimeStyle = UDAT_STYLE_LONG;
+        }
+    }
+
+    UErrorCode status = U_ZERO_ERROR;
+    URelativeDateTimeFormatter* rtf =
+        ureldatefmt_open(IcuLocale(locale.ptr()), nullptr, relDateTimeStyle,
+                         UDISPCTX_CAPITALIZATION_FOR_STANDALONE, &status);
+    if (U_FAILURE(status)) {
+        intl::ReportInternalError(cx);
+        return nullptr;
+    }
+    return rtf;
+}
+
 enum class RelativeTimeType
 {
     /**
      * Only strings with numeric components like `1 day ago`.
      */
     Numeric,
     /**
      * Natural-language strings like `yesterday` when possible,
@@ -220,68 +270,37 @@ enum class RelativeTimeType
      */
     Text,
 };
 
 bool
 js::intl_FormatRelativeTime(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-    MOZ_ASSERT(args.length() == 3);
+    MOZ_ASSERT(args.length() == 4);
 
-    RootedObject relativeTimeFormat(cx, &args[0].toObject());
+    Rooted<RelativeTimeFormatObject*> relativeTimeFormat(cx);
+    relativeTimeFormat = &args[0].toObject().as<RelativeTimeFormatObject>();
 
     double t = args[1].toNumber();
 
-    RootedObject internals(cx, intl::GetInternalsObject(cx, relativeTimeFormat));
-    if (!internals)
-        return false;
-
-    RootedValue value(cx);
-
-    if (!GetProperty(cx, internals, internals, cx->names().locale, &value))
-        return false;
-    JSAutoByteString locale(cx, value.toString());
-    if (!locale)
-        return false;
-
-    if (!GetProperty(cx, internals, internals, cx->names().style, &value))
-        return false;
-
-    UDateRelativeDateTimeFormatterStyle relDateTimeStyle;
-    {
-        JSLinearString* style = value.toString()->ensureLinear(cx);
-        if (!style)
-            return false;
+    // ICU doesn't handle -0 well: work around this by converting it to +0.
+    // See: http://bugs.icu-project.org/trac/ticket/12936
+    if (IsNegativeZero(t))
+        t = +0.0;
 
-        if (StringEqualsAscii(style, "short")) {
-            relDateTimeStyle = UDAT_STYLE_SHORT;
-        } else if (StringEqualsAscii(style, "narrow")) {
-            relDateTimeStyle = UDAT_STYLE_NARROW;
-        } else {
-            MOZ_ASSERT(StringEqualsAscii(style, "long"));
-            relDateTimeStyle = UDAT_STYLE_LONG;
-        }
-    }
-
-    if (!GetProperty(cx, internals, internals, cx->names().type, &value))
-        return false;
-
-    RelativeTimeType relDateTimeType;
-    {
-        JSLinearString* type = value.toString()->ensureLinear(cx);
-        if (!type)
+    // Obtain a cached URelativeDateTimeFormatter object.
+    constexpr auto RT_FORMAT_SLOT = RelativeTimeFormatObject::URELATIVE_TIME_FORMAT_SLOT;
+    void* priv = relativeTimeFormat->getReservedSlot(RT_FORMAT_SLOT).toPrivate();
+    URelativeDateTimeFormatter* rtf = static_cast<URelativeDateTimeFormatter*>(priv);
+    if (!rtf) {
+        rtf = NewURelativeDateTimeFormatter(cx, relativeTimeFormat);
+        if (!rtf)
             return false;
-
-        if (StringEqualsAscii(type, "text")) {
-            relDateTimeType = RelativeTimeType::Text;
-        } else {
-            MOZ_ASSERT(StringEqualsAscii(type, "numeric"));
-            relDateTimeType = RelativeTimeType::Numeric;
-        }
+        relativeTimeFormat->setReservedSlot(RT_FORMAT_SLOT, PrivateValue(rtf));
     }
 
     URelativeDateTimeUnit relDateTimeUnit;
     {
         JSLinearString* unit = args[2].toString()->ensureLinear(cx);
         if (!unit)
             return false;
 
@@ -300,32 +319,30 @@ js::intl_FormatRelativeTime(JSContext* c
         } else if (StringEqualsAscii(unit, "quarter")) {
             relDateTimeUnit = UDAT_REL_UNIT_QUARTER;
         } else {
             MOZ_ASSERT(StringEqualsAscii(unit, "year"));
             relDateTimeUnit = UDAT_REL_UNIT_YEAR;
         }
     }
 
-    // ICU doesn't handle -0 well: work around this by converting it to +0.
-    // See: http://bugs.icu-project.org/trac/ticket/12936
-    if (IsNegativeZero(t))
-        t = +0.0;
+    RelativeTimeType relDateTimeType;
+    {
+        JSLinearString* type = args[3].toString()->ensureLinear(cx);
+        if (!type)
+            return false;
 
-    UErrorCode status = U_ZERO_ERROR;
-    URelativeDateTimeFormatter* rtf =
-        ureldatefmt_open(IcuLocale(locale.ptr()), nullptr, relDateTimeStyle,
-                         UDISPCTX_CAPITALIZATION_FOR_STANDALONE, &status);
-    if (U_FAILURE(status)) {
-        intl::ReportInternalError(cx);
-        return false;
+        if (StringEqualsAscii(type, "text")) {
+            relDateTimeType = RelativeTimeType::Text;
+        } else {
+            MOZ_ASSERT(StringEqualsAscii(type, "numeric"));
+            relDateTimeType = RelativeTimeType::Numeric;
+        }
     }
 
-    ScopedICUObject<URelativeDateTimeFormatter, ureldatefmt_close> closeRelativeTimeFormat(rtf);
-
     JSString* str =
         CallICU(cx, [rtf, t, relDateTimeUnit, relDateTimeType](UChar* chars, int32_t size,
                                                                UErrorCode* status)
         {
             auto fmt = relDateTimeType == RelativeTimeType::Text
                        ? ureldatefmt_format
                        : ureldatefmt_formatNumeric;
             return fmt(rtf, t, relDateTimeUnit, chars, size, status);
--- a/js/src/builtin/intl/RelativeTimeFormat.h
+++ b/js/src/builtin/intl/RelativeTimeFormat.h
@@ -53,17 +53,18 @@ extern MOZ_MUST_USE bool
 intl_RelativeTimeFormat_availableLocales(JSContext* cx, unsigned argc, JS::Value* vp);
 
 /**
  * Returns a relative time as a string formatted according to the effective
  * locale and the formatting options of the given RelativeTimeFormat.
  *
  * t should be a number representing a number to be formatted.
  * unit should be "second", "minute", "hour", "day", "week", "month", "quarter", or "year".
+ * type should be "text" or "numeric".
  *
- * Usage: formatted = intl_FormatRelativeTime(relativeTimeFormat, t, unit)
+ * Usage: formatted = intl_FormatRelativeTime(relativeTimeFormat, t, unit, type)
  */
 extern MOZ_MUST_USE bool
 intl_FormatRelativeTime(JSContext* cx, unsigned argc, JS::Value* vp);
 
 } // namespace js
 
 #endif /* builtin_intl_RelativeTimeFormat_h */
--- a/js/src/builtin/intl/RelativeTimeFormat.js
+++ b/js/src/builtin/intl/RelativeTimeFormat.js
@@ -170,17 +170,17 @@ function Intl_RelativeTimeFormat_format(
     // Step 1.
     let relativeTimeFormat = this;
 
     // Step 2.
     if (!IsObject(relativeTimeFormat) || !IsRelativeTimeFormat(relativeTimeFormat))
         ThrowTypeError(JSMSG_INTL_OBJECT_NOT_INITED, "RelativeTimeFormat", "format", "RelativeTimeFormat");
 
     // Ensure the RelativeTimeFormat internals are resolved.
-    getRelativeTimeFormatInternals(relativeTimeFormat);
+    var internals = getRelativeTimeFormatInternals(relativeTimeFormat);
 
     // Step 3.
     let t = ToNumber(value);
 
     // Step 4.
     let u = ToString(unit);
 
     switch (u) {
@@ -193,17 +193,17 @@ function Intl_RelativeTimeFormat_format(
       case "quarter":
       case "year":
         break;
       default:
         ThrowRangeError(JSMSG_INVALID_OPTION_VALUE, "unit", u);
     }
 
     // Step 5.
-    return intl_FormatRelativeTime(relativeTimeFormat, t, u);
+    return intl_FormatRelativeTime(relativeTimeFormat, t, u, internals.type);
 }
 
 /**
  * Returns the resolved options for a PluralRules object.
  *
  * Spec: ECMAScript 402 API, RelativeTimeFormat, 1.4.4.
  */
 function Intl_RelativeTimeFormat_resolvedOptions() {
--- a/js/src/jit-test/tests/coverage/simple.js
+++ b/js/src/jit-test/tests/coverage/simple.js
@@ -534,10 +534,45 @@ checkLcov(function () { //FN:$,top-level
   //FNF:1
   //FNH:1
   //LF:6
   //LH:3
   //BRF:4
   //BRH:1
 });
 
+// These tests are not included in ../debug/Script-getOffsetsCoverage-01.js
+// because we're specifically testing a feature of Lcov output that
+// Debugger.Script doesn't have (the aggregation of hits that are on the
+// same line but in different functions).
+{
+    checkLcov(function () { //FN:$,top-level //FNDA:1,%
+        function f() { return 0; } var l = f(); //DA:$,2
+        //FNF:2
+        //FNH:2
+        //LF:1
+        //LH:1
+    });
+
+    // A single line has two functions on it, and both hit.
+    checkLcov(function () { //FN:$,top-level //FNDA:1,%
+        function f() { return 0; } function g() { return 1; } //DA:$,2
+        var v = f() + g(); //DA:$,1
+        //FNF:3
+        //FNH:3
+        //LF:2
+        //LH:2
+    });
+
+    // A line has both function code and toplevel code, and only one of them hits.
+    checkLcov(function () { //FN:$,top-level //FNDA:1,%
+        if (1 === 2)  //DA:$,1
+            throw "0 hits here"; function f() { return "1 hit here"; } //DA:$,1
+        f();  //DA:$,1
+        //FNF:2
+        //FNH:2
+        //LF:3
+        //LH:3
+    });
+}
+
 // If you add a test case here, do the same in
 // jit-test/tests/debug/Script-getOffsetsCoverage-01.js
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-1435295.js
@@ -0,0 +1,11 @@
+if (helperThreadCount() === 0)
+    quit();
+if (!('oomTest' in this))
+    quit();
+
+oomTest(new Function(`function execOffThread(source) {
+    offThreadCompileModule(source);
+    return finishOffThreadModule();
+}
+b = execOffThread("[1, 2, 3]")
+`));
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/modules/bug-1435327.js
@@ -0,0 +1,32 @@
+if (!('oomTest' in this))
+    quit();
+
+lfLogBuffer = `
+  let moduleRepo = {};
+  setModuleResolveHook(function(x, specifier) {
+        return moduleRepo[specifier];
+  });
+  let c = moduleRepo['c'] = parseModule("");
+  let d = moduleRepo['d'] = parseModule("import { a } from 'c'; a;");
+  d.declarationInstantiation();
+`;
+lfLogBuffer = lfLogBuffer.split('\n');
+var lfCodeBuffer = "";
+while (true) {
+    var line = lfLogBuffer.shift();
+    if (line == null) {
+        break;
+    } else {
+        lfCodeBuffer += line + "\n";
+    }
+}
+if (lfCodeBuffer) loadFile(lfCodeBuffer);
+function loadFile(lfVarx) {
+    try {
+        oomTest(function() {
+            let m = parseModule(lfVarx);
+            m.declarationInstantiation();
+            m.evaluation();
+        });
+    } catch (lfVare) {}
+}
--- a/js/src/jit/CacheIRSpewer.cpp
+++ b/js/src/jit/CacheIRSpewer.cpp
@@ -73,20 +73,20 @@ CacheIRSpewer::init()
     return true;
 }
 
 void
 CacheIRSpewer::beginCache(LockGuard<Mutex>&, const IRGenerator& gen)
 {
     MOZ_ASSERT(enabled());
     JSONPrinter& j = json.ref();
-
+    const char* filename = gen.script_->filename();
     j.beginObject();
     j.property("name", CacheKindNames[uint8_t(gen.cacheKind_)]);
-    j.property("file", gen.script_->filename());
+    j.property("file", filename ? filename : "null");
     j.property("mode", int(gen.mode_));
     if (jsbytecode* pc = gen.pc_) {
         unsigned column;
         j.property("line", PCToLineNumber(gen.script_, pc, &column));
         j.property("column", column);
         j.formatProperty("pc", "%p", pc);
     }
 }
--- a/js/src/jit/LIR.h
+++ b/js/src/jit/LIR.h
@@ -651,28 +651,41 @@ using LInt64Definition = LInt64Value<LDe
 class LSnapshot;
 class LSafepoint;
 class LInstruction;
 class LElementVisitor;
 
 // The common base class for LPhi and LInstruction.
 class LNode
 {
-    uint32_t id_;
-    LBlock* block_;
-
   protected:
     MDefinition* mir_;
 
+  private:
+    LBlock* block_;
+    uint32_t id_;
+
+  protected:
+    // Bitfields below are all uint32_t to make sure MSVC packs them correctly.
+    uint32_t isCall_ : 1;
+    uint32_t numDefs_ : 4;
+    uint32_t numTemps_ : 4;
+
   public:
-    LNode()
-      : id_(0),
+    LNode(uint32_t numDefs, uint32_t numTemps)
+      : mir_(nullptr),
         block_(nullptr),
-        mir_(nullptr)
-    { }
+        id_(0),
+        isCall_(false),
+        numDefs_(numDefs),
+        numTemps_(numTemps)
+    {
+        MOZ_ASSERT(numDefs_ == numDefs, "numDefs must fit in bitfield");
+        MOZ_ASSERT(numTemps_ == numTemps, "numTemps must fit in bitfield");
+    }
 
     enum Opcode {
 #   define LIROP(name) LOp_##name,
         LIR_OPCODE_LIST(LIROP)
 #   undef LIROP
         LOp_Invalid
     };
 
@@ -698,40 +711,44 @@ class LNode
     bool isInstruction() const {
         return op() != LOp_Phi;
     }
     inline LInstruction* toInstruction();
     inline const LInstruction* toInstruction() const;
 
     // Returns the number of outputs of this instruction. If an output is
     // unallocated, it is an LDefinition, defining a virtual register.
-    virtual size_t numDefs() const = 0;
+    size_t numDefs() const {
+        return numDefs_;
+    }
     virtual LDefinition* getDef(size_t index) = 0;
     virtual void setDef(size_t index, const LDefinition& def) = 0;
 
     // Returns information about operands.
     virtual size_t numOperands() const = 0;
     virtual LAllocation* getOperand(size_t index) = 0;
     virtual void setOperand(size_t index, const LAllocation& a) = 0;
 
     // Returns information about temporary registers needed. Each temporary
     // register is an LDefinition with a fixed or virtual register and
     // either GENERAL, FLOAT32, or DOUBLE type.
-    virtual size_t numTemps() const = 0;
+    size_t numTemps() const {
+        return numTemps_;
+    }
     virtual LDefinition* getTemp(size_t index) = 0;
     virtual void setTemp(size_t index, const LDefinition& a) = 0;
 
     // Returns the number of successors of this instruction, if it is a control
     // transfer instruction, or zero otherwise.
     virtual size_t numSuccessors() const = 0;
     virtual MBasicBlock* getSuccessor(size_t i) const = 0;
     virtual void setSuccessor(size_t i, MBasicBlock* successor) = 0;
 
-    virtual bool isCall() const {
-        return false;
+    bool isCall() const {
+        return isCall_;
     }
 
     // Does this call preserve the given register?
     // By default, it is assumed that all registers are clobbered by a call.
     virtual bool isCallPreserved(AnyRegister reg) const {
         return false;
     }
 
@@ -805,24 +822,29 @@ class LInstruction
     // to hold either gcthings or Values.
     LSafepoint* safepoint_;
 
     LMoveGroup* inputMoves_;
     LMoveGroup* fixReuseMoves_;
     LMoveGroup* movesAfter_;
 
   protected:
-    LInstruction()
-      : snapshot_(nullptr),
+    LInstruction(uint32_t numDefs, uint32_t numTemps)
+      : LNode(numDefs, numTemps),
+        snapshot_(nullptr),
         safepoint_(nullptr),
         inputMoves_(nullptr),
         fixReuseMoves_(nullptr),
         movesAfter_(nullptr)
     { }
 
+    void setIsCall() {
+        isCall_ = true;
+    }
+
   public:
     LSnapshot* snapshot() const {
         return snapshot_;
     }
     LSafepoint* safepoint() const {
         return safepoint_;
     }
     LMoveGroup* inputMoves() const {
@@ -910,24 +932,22 @@ class LPhi final : public LNode
 {
     LAllocation* const inputs_;
     LDefinition def_;
 
   public:
     LIR_HEADER(Phi)
 
     LPhi(MPhi* ins, LAllocation* inputs)
-        : inputs_(inputs)
+      : LNode(/* numDefs = */ 1, /* numTemps = */ 0),
+        inputs_(inputs)
     {
         setMir(ins);
     }
 
-    size_t numDefs() const override {
-        return 1;
-    }
     LDefinition* getDef(size_t index) override {
         MOZ_ASSERT(index == 0);
         return &def_;
     }
     void setDef(size_t index, const LDefinition& def) override {
         MOZ_ASSERT(index == 0);
         def_ = def;
     }
@@ -937,19 +957,16 @@ class LPhi final : public LNode
     LAllocation* getOperand(size_t index) override {
         MOZ_ASSERT(index < numOperands());
         return &inputs_[index];
     }
     void setOperand(size_t index, const LAllocation& a) override {
         MOZ_ASSERT(index < numOperands());
         inputs_[index] = a;
     }
-    size_t numTemps() const override {
-        return 0;
-    }
     LDefinition* getTemp(size_t index) override {
         MOZ_CRASH("no temps");
     }
     void setTemp(size_t index, const LDefinition& temp) override {
         MOZ_CRASH("no temps");
     }
     size_t numSuccessors() const override {
         return 0;
@@ -1061,26 +1078,25 @@ class LBlock
 
 namespace details {
     template <size_t Defs, size_t Temps>
     class LInstructionFixedDefsTempsHelper : public LInstruction
     {
         mozilla::Array<LDefinition, Defs> defs_;
         mozilla::Array<LDefinition, Temps> temps_;
 
+      protected:
+        LInstructionFixedDefsTempsHelper()
+          : LInstruction(Defs, Temps)
+        {}
+
       public:
-        size_t numDefs() const final override {
-            return Defs;
-        }
         LDefinition* getDef(size_t index) final override {
             return &defs_[index];
         }
-        size_t numTemps() const final override {
-            return Temps;
-        }
         LDefinition* getTemp(size_t index) final override {
             return &temps_[index];
         }
 
         void setDef(size_t index, const LDefinition& def) final override {
             defs_[index] = def;
         }
         void setTemp(size_t index, const LDefinition& a) final override {
@@ -1186,18 +1202,18 @@ class LVariadicInstruction : public deta
 #endif
     }
 };
 
 template <size_t Defs, size_t Operands, size_t Temps>
 class LCallInstructionHelper : public LInstructionHelper<Defs, Operands, Temps>
 {
   public:
-    virtual bool isCall() const override {
-        return true;
+    LCallInstructionHelper() {
+        this->setIsCall();
     }
 };
 
 template <size_t Defs, size_t Temps>
 class LBinaryCallInstructionHelper : public LCallInstructionHelper<Defs, 2, Temps>
 {
   public:
     const LAllocation* lhs() {
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -4660,20 +4660,22 @@ LIRGenerator::visitWasmCall(MWasmCall* i
             if (uint32_t(index->toConstant()->toInt32()) < ins->callee().wasmTableMinLength())
                 needsBoundsCheck = false;
         }
 
         args[ins->numArgs()] = useFixedAtStart(index, WasmTableCallIndexReg);
     }
 
     LInstruction* lir;
-    if (ins->type() == MIRType::Int64)
+    if (ins->type() == MIRType::Int64) {
         lir = new(alloc()) LWasmCallI64(args, ins->numOperands(), needsBoundsCheck);
-    else
-        lir = new(alloc()) LWasmCall(args, ins->numOperands(), needsBoundsCheck);
+    } else {
+        uint32_t numDefs = (ins->type() != MIRType::None) ? 1 : 0;
+        lir = new(alloc()) LWasmCall(args, ins->numOperands(), numDefs, needsBoundsCheck);
+    }
 
     if (ins->type() == MIRType::None)
         add(lir, ins);
     else
         defineReturn(lir, ins);
 }
 
 void
--- a/js/src/jit/none/LIR-none.h
+++ b/js/src/jit/none/LIR-none.h
@@ -38,20 +38,20 @@ class LTableSwitchV : public LInstructio
 
     const LDefinition* tempInt() { MOZ_CRASH(); }
     const LDefinition* tempFloat() { MOZ_CRASH(); }
     const LDefinition* tempPointer() { MOZ_CRASH(); }
 
     static const size_t InputValue = 0;
 };
 
-class LWasmUint32ToFloat32 : public LInstruction
+class LWasmUint32ToFloat32 : public LInstructionHelper<1, 1, 0>
 {
   public:
-    LWasmUint32ToFloat32(const LAllocation& ) { MOZ_CRASH(); }
+    LWasmUint32ToFloat32(const LAllocation&) { MOZ_CRASH(); }
 };
 
 class LUnbox : public LInstructionHelper<1, 2, 0>
 {
   public:
 
     MUnbox* mir() const { MOZ_CRASH(); }
     const LAllocation* payload() { MOZ_CRASH(); }
--- a/js/src/jit/shared/LIR-shared.h
+++ b/js/src/jit/shared/LIR-shared.h
@@ -4059,23 +4059,21 @@ class LModD : public LBinaryMath<1>
 {
   public:
     LIR_HEADER(ModD)
 
     LModD(const LAllocation& lhs, const LAllocation& rhs, const LDefinition& temp) {
         setOperand(0, lhs);
         setOperand(1, rhs);
         setTemp(0, temp);
+        setIsCall();
     }
     const LDefinition* temp() {
         return getTemp(0);
     }
-    bool isCall() const override {
-        return true;
-    }
     MMod* mir() const {
         return mir_->toMod();
     }
 };
 
 // Call a VM function to perform a binary operation.
 class LBinaryV : public LCallInstructionHelper<BOX_PIECES, 2 * BOX_PIECES, 0>
 {
@@ -8991,29 +8989,30 @@ class LWasmStackArgI64 : public LInstruc
 class LWasmCallBase : public LInstruction
 {
     LAllocation* operands_;
     uint32_t numOperands_;
     uint32_t needsBoundsCheck_;
 
   public:
 
-    LWasmCallBase(LAllocation* operands, uint32_t numOperands, bool needsBoundsCheck)
-      : operands_(operands),
+    LWasmCallBase(LAllocation* operands, uint32_t numOperands, uint32_t numDefs,
+                  bool needsBoundsCheck)
+      : LInstruction(numDefs, /* numTemps = */ 0),
+        operands_(operands),
         numOperands_(numOperands),
         needsBoundsCheck_(needsBoundsCheck)
-    {}
+    {
+        setIsCall();
+    }
 
     MWasmCall* mir() const {
         return mir_->toWasmCall();
     }
 
-    bool isCall() const override {
-        return true;
-    }
     bool isCallPreserved(AnyRegister reg) const override {
         // All MWasmCalls preserve the TLS register:
         //  - internal/indirect calls do by the internal wasm ABI
         //  - import calls do by explicitly saving/restoring at the callsite
         //  - builtin calls do because the TLS reg is non-volatile
         // See also CodeGeneratorShared::emitWasmCallBase.
         return !reg.isFloat() && reg.gpr() == WasmTlsReg;
     }
@@ -9025,19 +9024,16 @@ class LWasmCallBase : public LInstructio
     LAllocation* getOperand(size_t index) override {
         MOZ_ASSERT(index < numOperands_);
         return &operands_[index];
     }
     void setOperand(size_t index, const LAllocation& a) override {
         MOZ_ASSERT(index < numOperands_);
         operands_[index] = a;
     }
-    size_t numTemps() const override {
-        return 0;
-    }
     LDefinition* getTemp(size_t index) override {
         MOZ_CRASH("no temps");
     }
     void setTemp(size_t index, const LDefinition& a) override {
         MOZ_CRASH("no temps");
     }
     size_t numSuccessors() const override {
         return 0;
@@ -9055,25 +9051,22 @@ class LWasmCallBase : public LInstructio
 
 class LWasmCall : public LWasmCallBase
 {
      LDefinition def_;
 
   public:
     LIR_HEADER(WasmCall);
 
-    LWasmCall(LAllocation* operands, uint32_t numOperands, bool needsBoundsCheck)
-      : LWasmCallBase(operands, numOperands, needsBoundsCheck),
+    LWasmCall(LAllocation* operands, uint32_t numOperands, uint32_t numDefs, bool needsBoundsCheck)
+      : LWasmCallBase(operands, numOperands, numDefs, needsBoundsCheck),
         def_(LDefinition::BogusTemp())
     {}
 
     // LInstruction interface
-    size_t numDefs() const override {
-        return def_.isBogusTemp() ? 0 : 1;
-    }
     LDefinition* getDef(size_t index) override {
         MOZ_ASSERT(numDefs() == 1);
         MOZ_ASSERT(index == 0);
         return &def_;
     }
     void setDef(size_t index, const LDefinition& def) override {
         MOZ_ASSERT(index == 0);
         def_ = def;
@@ -9083,26 +9076,23 @@ class LWasmCall : public LWasmCallBase
 class LWasmCallI64 : public LWasmCallBase
 {
     LDefinition defs_[INT64_PIECES];
 
   public:
     LIR_HEADER(WasmCallI64);
 
     LWasmCallI64(LAllocation* operands, uint32_t numOperands, bool needsBoundsCheck)
-      : LWasmCallBase(operands, numOperands, needsBoundsCheck)
+      : LWasmCallBase(operands, numOperands, INT64_PIECES, needsBoundsCheck)
     {
         for (size_t i = 0; i < numDefs(); i++)
             defs_[i] = LDefinition::BogusTemp();
     }
 
     // LInstruction interface
-    size_t numDefs() const override {
-        return INT64_PIECES;
-    }
     LDefinition* getDef(size_t index) override {
         MOZ_ASSERT(index < numDefs());
         return &defs_[index];
     }
     void setDef(size_t index, const LDefinition& def) override {
         MOZ_ASSERT(index < numDefs());
         defs_[index] = def;
     }
--- a/js/src/jit/x64/Assembler-x64.h
+++ b/js/src/jit/x64/Assembler-x64.h
@@ -457,31 +457,38 @@ class Assembler : public AssemblerX86Sha
     }
     void vmovq(FloatRegister src, Register dest) {
         masm.vmovq_rr(src.encoding(), dest.encoding());
     }
     void movq(Register src, Register dest) {
         masm.movq_rr(src.encoding(), dest.encoding());
     }
 
-    void cmovzq(const Operand& src, Register dest) {
+    void cmovCCq(Condition cond, const Operand& src, Register dest) {
+        X86Encoding::Condition cc = static_cast<X86Encoding::Condition>(cond);
         switch (src.kind()) {
           case Operand::REG:
-            masm.cmovzq_rr(src.reg(), dest.encoding());
+            masm.cmovCCq_rr(cc, src.reg(), dest.encoding());
             break;
           case Operand::MEM_REG_DISP:
-            masm.cmovzq_mr(src.disp(), src.base(), dest.encoding());
+            masm.cmovCCq_mr(cc, src.disp(), src.base(), dest.encoding());
             break;
           case Operand::MEM_SCALE:
-            masm.cmovzq_mr(src.disp(), src.base(), src.index(), src.scale(), dest.encoding());
+            masm.cmovCCq_mr(cc, src.disp(), src.base(), src.index(), src.scale(), dest.encoding());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
+    void cmovzq(const Operand& src, Register dest) {
+        cmovCCq(Condition::Zero, src, dest);
+    }
+    void cmovnzq(const Operand& src, Register dest) {
+        cmovCCq(Condition::NonZero, src, dest);
+    }
 
     template<typename T>
     void lock_addq(T src, const Operand& op) {
         masm.prefix_lock();
         addq(src, op);
     }
     template<typename T>
     void lock_subq(T src, const Operand& op) {
--- a/js/src/jit/x64/BaseAssembler-x64.h
+++ b/js/src/jit/x64/BaseAssembler-x64.h
@@ -554,30 +554,31 @@ class BaseAssemblerX64 : public BaseAsse
     {
         spew("testq      $0x%4x, " MEM_obs, rhs, ADDR_obs(offset, base, index, scale));
         m_formatter.oneByteOp64(OP_GROUP3_EvIz, offset, base, index, scale, GROUP3_OP_TEST);
         m_formatter.immediate32(rhs);
     }
 
     // Various move ops:
 
-    void cmovzq_rr(RegisterID src, RegisterID dst)
+    void cmovCCq_rr(Condition cond, RegisterID src, RegisterID dst)
     {
-        spew("cmovz     %s, %s", GPReg16Name(src), GPReg32Name(dst));
-        m_formatter.twoByteOp64(OP2_CMOVZ_GvEv, src, dst);
+        spew("cmov%s     %s, %s", CCName(cond), GPReg64Name(src), GPReg64Name(dst));
+        m_formatter.twoByteOp64(cmovccOpcode(cond), src, dst);
     }
-    void cmovzq_mr(int32_t offset, RegisterID base, RegisterID dst)
+    void cmovCCq_mr(Condition cond, int32_t offset, RegisterID base, RegisterID dst)
     {
-        spew("cmovz     " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
-        m_formatter.twoByteOp64(OP2_CMOVZ_GvEv, offset, base, dst);
+        spew("cmov%s     " MEM_ob ", %s", CCName(cond), ADDR_ob(offset, base), GPReg64Name(dst));
+        m_formatter.twoByteOp64(cmovccOpcode(cond), offset, base, dst);
     }
-    void cmovzq_mr(int32_t offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
+    void cmovCCq_mr(Condition cond, int32_t offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
     {
-        spew("cmovz     " MEM_obs ", %s", ADDR_obs(offset, base, index, scale), GPReg32Name(dst));
-        m_formatter.twoByteOp64(OP2_CMOVZ_GvEv, offset, base, index, scale, dst);
+        spew("cmov%s     " MEM_obs ", %s", CCName(cond), ADDR_obs(offset, base, index, scale),
+             GPReg64Name(dst));
+        m_formatter.twoByteOp64(cmovccOpcode(cond), offset, base, index, scale, dst);
     }
 
     void cmpxchgq(RegisterID src, int32_t offset, RegisterID base)
     {
         spew("cmpxchgq   %s, " MEM_ob, GPReg64Name(src), ADDR_ob(offset, base));
         m_formatter.twoByteOp64(OP2_CMPXCHG_GvEw, offset, base, src);
     }
 
--- a/js/src/jit/x86-shared/Assembler-x86-shared.cpp
+++ b/js/src/jit/x86-shared/Assembler-x86-shared.cpp
@@ -361,18 +361,24 @@ CPUInfo::SetSSEVersion()
     // If the hardware supports AVX, check whether the OS supports it too.
     if (avxPresent) {
         size_t xcr0EAX = ReadXGETBV();
         static const int xcr0SSEBit = 1 << 1;
         static const int xcr0AVXBit = 1 << 2;
         avxPresent = (xcr0EAX & xcr0SSEBit) && (xcr0EAX & xcr0AVXBit);
     }
 
+    // CMOV instruction are supposed to be supported by all CPU which have SSE2
+    // enabled. While this might be true, this is not guaranteed by any
+    // documentation, nor AMD, nor Intel.
+    static const int CMOVBit = 1 << 15;
+    MOZ_RELEASE_ASSERT(flagsEDX & CMOVBit,
+                       "CMOVcc instruction is not recognized by this CPU.");
+
     static const int POPCNTBit = 1 << 23;
-
     popcntPresent = (flagsECX & POPCNTBit);
 
     // Check if we need to work around an AMD CPU bug (see bug 1281759).
     // We check for family 20 models 0-2. Intel doesn't use family 20 at
     // this point, so this should only match AMD CPUs.
     unsigned family = ((flagsEAX >> 20) & 0xff) + ((flagsEAX >> 8) & 0xf);
     unsigned model = (((flagsEAX >> 16) & 0xf) << 4) + ((flagsEAX >> 4) & 0xf);
     needAmdBugWorkaround = (family == 20 && model <= 2);
--- a/js/src/jit/x86-shared/Assembler-x86-shared.h
+++ b/js/src/jit/x86-shared/Assembler-x86-shared.h
@@ -448,31 +448,38 @@ class AssemblerX86Shared : public Assemb
     void nopAlign(int alignment) {
         masm.nopAlign(alignment);
     }
     void writeCodePointer(CodeOffset* label) {
         // Use -1 as dummy value. This will be patched after codegen.
         masm.jumpTablePointer(-1);
         label->bind(masm.size());
     }
-    void cmovz(const Operand& src, Register dest) {
+    void cmovCCl(Condition cond, const Operand& src, Register dest) {
+        X86Encoding::Condition cc = static_cast<X86Encoding::Condition>(cond);
         switch (src.kind()) {
           case Operand::REG:
-            masm.cmovz_rr(src.reg(), dest.encoding());
+            masm.cmovCCl_rr(cc, src.reg(), dest.encoding());
             break;
           case Operand::MEM_REG_DISP:
-            masm.cmovz_mr(src.disp(), src.base(), dest.encoding());
+            masm.cmovCCl_mr(cc, src.disp(), src.base(), dest.encoding());
             break;
           case Operand::MEM_SCALE:
-            masm.cmovz_mr(src.disp(), src.base(), src.index(), src.scale(), dest.encoding());
+            masm.cmovCCl_mr(cc, src.disp(), src.base(), src.index(), src.scale(), dest.encoding());
             break;
           default:
             MOZ_CRASH("unexpected operand kind");
         }
     }
+    void cmovzl(const Operand& src, Register dest) {
+        cmovCCl(Condition::Zero, src, dest);
+    }
+    void cmovnzl(const Operand& src, Register dest) {
+        cmovCCl(Condition::NonZero, src, dest);
+    }
     void movl(Imm32 imm32, Register dest) {
         masm.movl_i32r(imm32.value, dest.encoding());
     }
     void movl(Register src, Register dest) {
         masm.movl_rr(src.encoding(), dest.encoding());
     }
     void movl(const Operand& src, Register dest) {
         switch (src.kind()) {
--- a/js/src/jit/x86-shared/BaseAssembler-x86-shared.h
+++ b/js/src/jit/x86-shared/BaseAssembler-x86-shared.h
@@ -2089,30 +2089,31 @@ public:
         m_formatter.oneByteOp(OP_XCHG_GvEv, offset, base, src);
     }
     void xchgl_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
     {
         spew("xchgl      %s, " MEM_obs, GPReg32Name(src), ADDR_obs(offset, base, index, scale));
         m_formatter.oneByteOp(OP_XCHG_GvEv, offset, base, index, scale, src);
     }
 
-    void cmovz_rr(RegisterID src, RegisterID dst)
-    {
-        spew("cmovz     %s, %s", GPReg16Name(src), GPReg32Name(dst));
-        m_formatter.twoByteOp(OP2_CMOVZ_GvEv, src, dst);
-    }
-    void cmovz_mr(int32_t offset, RegisterID base, RegisterID dst)
-    {
-        spew("cmovz     " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
-        m_formatter.twoByteOp(OP2_CMOVZ_GvEv, offset, base, dst);
-    }
-    void cmovz_mr(int32_t offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
-    {
-        spew("cmovz     " MEM_obs ", %s", ADDR_obs(offset, base, index, scale), GPReg32Name(dst));
-        m_formatter.twoByteOp(OP2_CMOVZ_GvEv, offset, base, index, scale, dst);
+    void cmovCCl_rr(Condition cond, RegisterID src, RegisterID dst)
+    {
+        spew("cmov%s     %s, %s", CCName(cond), GPReg32Name(src), GPReg32Name(dst));
+        m_formatter.twoByteOp(cmovccOpcode(cond), src, dst);
+    }
+    void cmovCCl_mr(Condition cond, int32_t offset, RegisterID base, RegisterID dst)
+    {
+        spew("cmov%s     " MEM_ob ", %s", CCName(cond), ADDR_ob(offset, base), GPReg32Name(dst));
+        m_formatter.twoByteOp(cmovccOpcode(cond), offset, base, dst);
+    }
+    void cmovCCl_mr(Condition cond, int32_t offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
+    {
+        spew("cmov%s     " MEM_obs ", %s", CCName(cond), ADDR_obs(offset, base, index, scale),
+             GPReg32Name(dst));
+        m_formatter.twoByteOp(cmovccOpcode(cond), offset, base, index, scale, dst);
     }
 
     void movl_rr(RegisterID src, RegisterID dst)
     {
         spew("movl       %s, %s", GPReg32Name(src), GPReg32Name(dst));
         m_formatter.oneByteOp(OP_MOV_GvEv, src, dst);
     }
 
--- a/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp
+++ b/js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp
@@ -333,17 +333,17 @@ CodeGeneratorX86Shared::visitWasmSelect(
     Register cond = ToRegister(ins->condExpr());
     Operand falseExpr = ToOperand(ins->falseExpr());
 
     masm.test32(cond, cond);
 
     if (mirType == MIRType::Int32) {
         Register out = ToRegister(ins->output());
         MOZ_ASSERT(ToRegister(ins->trueExpr()) == out, "true expr input is reused for output");
-        masm.cmovz(falseExpr, out);
+        masm.cmovzl(falseExpr, out);
         return;
     }
 
     FloatRegister out = ToFloatRegister(ins->output());
     MOZ_ASSERT(ToFloatRegister(ins->trueExpr()) == out, "true expr input is reused for output");
 
     Label done;
     masm.j(Assembler::NonZero, &done);
--- a/js/src/jit/x86-shared/Encoding-x86-shared.h
+++ b/js/src/jit/x86-shared/Encoding-x86-shared.h
@@ -178,17 +178,17 @@ enum TwoByteOpcodeID {
     OP2_MOVLHPS_VqUq    = 0x16,
     OP2_MOVSHDUP_VpsWps = 0x16,
     OP2_MOVAPD_VsdWsd   = 0x28,
     OP2_MOVAPS_VsdWsd   = 0x28,
     OP2_MOVAPS_WsdVsd   = 0x29,
     OP2_CVTSI2SD_VsdEd  = 0x2A,
     OP2_CVTTSD2SI_GdWsd = 0x2C,
     OP2_UCOMISD_VsdWsd  = 0x2E,
-    OP2_CMOVZ_GvEv      = 0x44,
+    OP2_CMOVCC_GvEv     = 0x40,
     OP2_MOVMSKPD_EdVd   = 0x50,
     OP2_ANDPS_VpsWps    = 0x54,
     OP2_ANDNPS_VpsWps   = 0x55,
     OP2_ORPS_VpsWps     = 0x56,
     OP2_XORPS_VpsWps    = 0x57,
     OP2_ADDSD_VsdWsd    = 0x58,
     OP2_ADDPS_VpsWps    = 0x58,
     OP2_MULSD_VsdWsd    = 0x59,
@@ -342,16 +342,20 @@ inline OneByteOpcodeID jccRel8(Condition
 inline TwoByteOpcodeID jccRel32(Condition cond)
 {
     return TwoByteOpcodeID(OP2_JCC_rel32 + cond);
 }
 inline TwoByteOpcodeID setccOpcode(Condition cond)
 {
     return TwoByteOpcodeID(OP_SETCC + cond);
 }
+inline TwoByteOpcodeID cmovccOpcode(Condition cond)
+{
+    return TwoByteOpcodeID(OP2_CMOVCC_GvEv + cond);
+}
 
 enum GroupOpcodeID {
     GROUP1_OP_ADD = 0,
     GROUP1_OP_OR  = 1,
     GROUP1_OP_ADC = 2,
     GROUP1_OP_SBB = 3,
     GROUP1_OP_AND = 4,
     GROUP1_OP_SUB = 5,
--- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp
+++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp
@@ -678,26 +678,27 @@ MacroAssembler::wasmTrapInstruction()
 }
 
 // RAII class that generates the jumps to traps when it's destructed, to
 // prevent some code duplication in the outOfLineWasmTruncateXtoY methods.
 struct MOZ_RAII AutoHandleWasmTruncateToIntErrors
 {
     MacroAssembler& masm;
     Label inputIsNaN;
-    Label fail;
+    Label intOverflow;
     wasm::BytecodeOffset off;
 
     explicit AutoHandleWasmTruncateToIntErrors(MacroAssembler& masm, wasm::BytecodeOffset off)
       : masm(masm), off(off)
     { }
 
     ~AutoHandleWasmTruncateToIntErrors() {
-        // Handle errors.
-        masm.bind(&fail);
+        // Handle errors.  These cases are not in arbitrary order: code will
+        // fall through to intOverflow.
+        masm.bind(&intOverflow);
         masm.jump(wasm::OldTrapDesc(off, wasm::Trap::IntegerOverflow, masm.framePushed()));
 
         masm.bind(&inputIsNaN);
         masm.jump(wasm::OldTrapDesc(off, wasm::Trap::InvalidConversionToInteger, masm.framePushed()));
     }
 };
 
 void
@@ -720,100 +721,104 @@ void
 MacroAssembler::oolWasmTruncateCheckF64ToI32(FloatRegister input, bool isUnsigned,
                                              wasm::BytecodeOffset off, Label* rejoin)
 {
     AutoHandleWasmTruncateToIntErrors traps(*this, off);
 
     // Eagerly take care of NaNs.
     branchDouble(Assembler::DoubleUnordered, input, input, &traps.inputIsNaN);
 
-    // Handle special values (not needed for unsigned values).
+    // For unsigned, fall through to intOverflow failure case.
     if (isUnsigned)
         return;
 
+    // Handle special values.
+
     // We've used vcvttsd2si. The only valid double values that can
     // truncate to INT32_MIN are in ]INT32_MIN - 1; INT32_MIN].
     loadConstantDouble(double(INT32_MIN) - 1.0, ScratchDoubleReg);
-    branchDouble(Assembler::DoubleLessThanOrEqual, input, ScratchDoubleReg, &traps.fail);
+    branchDouble(Assembler::DoubleLessThanOrEqual, input, ScratchDoubleReg, &traps.intOverflow);
 
     loadConstantDouble(double(INT32_MIN), ScratchDoubleReg);
-    branchDouble(Assembler::DoubleGreaterThan, input, ScratchDoubleReg, &traps.fail);
+    branchDouble(Assembler::DoubleGreaterThan, input, ScratchDoubleReg, &traps.intOverflow);
     jump(rejoin);
 }
 
 void
 MacroAssembler::oolWasmTruncateCheckF32ToI32(FloatRegister input, bool isUnsigned,
                                              wasm::BytecodeOffset off, Label* rejoin)
 {
     AutoHandleWasmTruncateToIntErrors traps(*this, off);
 
     // Eagerly take care of NaNs.
     branchFloat(Assembler::DoubleUnordered, input, input, &traps.inputIsNaN);
 
-    // Handle special values (not needed for unsigned values).
+    // For unsigned, fall through to intOverflow failure case.
     if (isUnsigned)
         return;
 
+    // Handle special values.
+
     // We've used vcvttss2si. Check that the input wasn't
     // float(INT32_MIN), which is the only legimitate input that
     // would truncate to INT32_MIN.
     loadConstantFloat32(float(INT32_MIN), ScratchFloat32Reg);
-    branchFloat(Assembler::DoubleNotEqual, input, ScratchFloat32Reg, &traps.fail);
+    branchFloat(Assembler::DoubleNotEqual, input, ScratchFloat32Reg, &traps.intOverflow);
     jump(rejoin);
 }
 
 void
 MacroAssembler::oolWasmTruncateCheckF64ToI64(FloatRegister input, bool isUnsigned,
                                              wasm::BytecodeOffset off, Label* rejoin)
 {
     AutoHandleWasmTruncateToIntErrors traps(*this, off);
 
     // Eagerly take care of NaNs.
     branchDouble(Assembler::DoubleUnordered, input, input, &traps.inputIsNaN);
 
     // Handle special values.
     if (isUnsigned) {
         loadConstantDouble(-0.0, ScratchDoubleReg);
-        branchDouble(Assembler::DoubleGreaterThan, input, ScratchDoubleReg, &traps.fail);
+        branchDouble(Assembler::DoubleGreaterThan, input, ScratchDoubleReg, &traps.intOverflow);
         loadConstantDouble(-1.0, ScratchDoubleReg);
-        branchDouble(Assembler::DoubleLessThanOrEqual, input, ScratchDoubleReg, &traps.fail);
+        branchDouble(Assembler::DoubleLessThanOrEqual, input, ScratchDoubleReg, &traps.intOverflow);
         jump(rejoin);
         return;
     }
 
     // We've used vcvtsd2sq. The only legit value whose i64
     // truncation is INT64_MIN is double(INT64_MIN): exponent is so
     // high that the highest resolution around is much more than 1.
     loadConstantDouble(double(int64_t(INT64_MIN)), ScratchDoubleReg);
-    branchDouble(Assembler::DoubleNotEqual, input, ScratchDoubleReg, &traps.fail);
+    branchDouble(Assembler::DoubleNotEqual, input, ScratchDoubleReg, &traps.intOverflow);
     jump(rejoin);
 }
 
 void
 MacroAssembler::oolWasmTruncateCheckF32ToI64(FloatRegister input, bool isUnsigned,
                                              wasm::BytecodeOffset off, Label* rejoin)
 {
     AutoHandleWasmTruncateToIntErrors traps(*this, off);
 
     // Eagerly take care of NaNs.
     branchFloat(Assembler::DoubleUnordered, input, input, &traps.inputIsNaN);
 
     // Handle special values.
     if (isUnsigned) {
         loadConstantFloat32(-0.0f, ScratchFloat32Reg);
-        branchFloat(Assembler::DoubleGreaterThan, input, ScratchFloat32Reg, &traps.fail);
+        branchFloat(Assembler::DoubleGreaterThan, input, ScratchFloat32Reg, &traps.intOverflow);
         loadConstantFloat32(-1.0f, ScratchFloat32Reg);
-        branchFloat(Assembler::DoubleLessThanOrEqual, input, ScratchFloat32Reg, &traps.fail);
+        branchFloat(Assembler::DoubleLessThanOrEqual, input, ScratchFloat32Reg, &traps.intOverflow);
         jump(rejoin);
         return;
     }
 
     // We've used vcvtss2sq. See comment in outOfLineWasmTruncateDoubleToInt64.
     loadConstantFloat32(float(int64_t(INT64_MIN)), ScratchFloat32Reg);
-    branchFloat(Assembler::DoubleNotEqual, input, ScratchFloat32Reg, &traps.fail);
+    branchFloat(Assembler::DoubleNotEqual, input, ScratchFloat32Reg, &traps.intOverflow);
     jump(rejoin);
 }
 
 // ========================================================================
 // Primitive atomic operations.
 
 static void
 ExtendTo32(MacroAssembler& masm, Scalar::Type type, Register r)
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -7929,17 +7929,17 @@ GCRuntime::mergeCompartments(JSCompartme
         // the target compartment.
         TaggedProto proto(group->proto());
         if (proto.isObject()) {
             JSObject* obj = proto.toObject();
             if (GlobalObject::isOffThreadPrototypePlaceholder(obj)) {
                 JSObject* targetProto = global->getPrototypeForOffThreadPlaceholder(obj);
                 MOZ_ASSERT(targetProto->isDelegate());
                 group->setProtoUnchecked(TaggedProto(targetProto));
-                if (targetProto->isNewGroupUnknown())
+                if (targetProto->isNewGroupUnknown() && !group->unknownProperties())
                     group->markUnknown(cx);
             }
         }
 
         group->setGeneration(target->zone()->types.generation);
         group->compartment_ = target;
 
         // Remove any unboxed layouts from the list in the off thread
--- a/js/src/tests/jstests.list
+++ b/js/src/tests/jstests.list
@@ -40,24 +40,28 @@ skip-if(!this.hasOwnProperty("Intl")) in
 
 # Skip built-ins/Simd tests when SIMD isn't available.
 skip-if(!this.hasOwnProperty("SIMD")) include test262/built-ins/Simd/jstests.list
 
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1415303
 skip-if(!this.hasOwnProperty("SharedArrayBuffer")) script non262/SIMD/load-sab-buffer-compat.js
 skip-if(!this.hasOwnProperty("Atomics")) include test262/built-ins/Atomics/jstests.list
 skip-if(!this.hasOwnProperty("SharedArrayBuffer")) include test262/built-ins/SharedArrayBuffer/jstests.list
-skip-if(!this.hasOwnProperty("SharedArrayBuffer")) script test262/built-ins/ArrayBuffer/prototype/byteLength/this-is-sharedarraybuffer.js
-skip-if(!this.hasOwnProperty("SharedArrayBuffer")) script test262/built-ins/ArrayBuffer/prototype/slice/this-is-sharedarraybuffer.js
-skip-if(!this.hasOwnProperty("SharedArrayBuffer")) script test262/built-ins/TypedArrays/internals/Get/indexed-value-sab.js
 
 # flatMap and flatten are Nightly-only
 skip-if(!Array.prototype.flatMap) include test262/built-ins/Array/prototype/flatMap/jstests.list
 skip-if(!Array.prototype.flatten) include test262/built-ins/Array/prototype/flatten/jstests.list
 
+# trimStart and trimEnd are Nightly-only
+skip-if(!String.prototype.trimStart) include test262/built-ins/String/prototype/trimStart/jstests.list
+skip-if(!String.prototype.trimStart) include test262/annexB/built-ins/String/prototype/trimLeft/jstests.list
+skip-if(!String.prototype.trimEnd) include test262/built-ins/String/prototype/trimEnd/jstests.list
+skip-if(!String.prototype.trimEnd) include test262/annexB/built-ins/String/prototype/trimRight/jstests.list
+
+
 #####################################
 # Test262 tests disabled on browser #
 #####################################
 
 # Defines a non-configurable property on the WindowProxy object.
 skip-if(!xulRuntime.shell) script test262/annexB/language/eval-code/direct/global-block-decl-eval-global-existing-global-update.js
 skip-if(!xulRuntime.shell) script test262/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-existing-global-update.js
 skip-if(!xulRuntime.shell) script test262/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-existing-global-update.js
@@ -469,11 +473,8 @@ skip script test262/annexB/built-ins/Fun
 
 # test262 importer merges all includes in a per directory shell.js file, breaking this harness test case.
 skip script test262/harness/detachArrayBuffer.js
 
 
 ####################################################
 # Tests disabled due to invalid test expectations  #
 ####################################################
-
-# assert.compareArray doesn't perform deep-equality comparison.
-skip script test262/built-ins/Array/prototype/flatMap/depth-always-one.js
new file mode 100644
--- /dev/null
+++ b/js/src/tests/non262/extensions/clone-invalid-property-key.js
@@ -0,0 +1,22 @@
+// Don't allow serialized data to use objects as property keys.
+
+if (typeof serialize === "function") {
+    let data = new Uint8Array([
+        104,97,108,101,7,0,255,255,95,98,0,0,0,0,0,104,97,108,101,9,0,255,255,95,98,
+        115,10,109,97,120,95,108,101,110,0,0,0,0,109,97,120,95,108,101,110,0,0,0,0,0,
+        0,0,0,0,246,0,0,0,42,4,0,0,0,0,0,0,0,0,0,0,0,0,65,0,0,0,0,0,0,0,0,0,0,0,0,0,
+        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,253,0,0,0,0,0,0,0,0,0,0,0,0,
+        191,190,190,184,65,65,65,65,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,104,97,108,101,9,0,
+        255,255,95,98,115,10,109,97,120,95,110,100,108,213,95,175,175,175,175,175,0,
+        0,0,0,0,2,0,0,0,0,0,13,0,255,255,96,125,115,135,109,97,120,110,0,0,32,0,8,0,
+        0,0
+    ]);
+    let cloneBuffer = serialize(null);
+    cloneBuffer.clonebuffer = data.buffer;
+    try {
+        let obj = deserialize(cloneBuffer);
+    } catch(exc1) {}
+}
+
+reportCompare(0, 0);
--- a/js/src/tests/test262/GIT-INFO
+++ b/js/src/tests/test262/GIT-INFO
@@ -1,5 +1,5 @@
-commit 73120a5492ce274d551d2a215e65ba30085be7ef
-Author: Rick Waldron <waldron.rick@gmail.com>
-Date:   Wed Jan 10 17:33:03 2018 -0500
+commit 82c6148980332febe92a544a1fb653718e9fdb57
+Author: André Bargull <andre.bargull@gmail.com>
+Date:   Thu Feb 1 11:04:51 2018 -0800
 
-    Fix: various lint fixes
+    Add missing closing parenthesis and remove invalid async flag (#1402)
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/length.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimLeft
+description: >
+  String.prototype.trimLeft.length is 0.
+info: >
+  String.prototype.trimLeft ( )
+
+  17 ECMAScript Standard Built-in Objects:
+    Every built-in Function object, including constructors, has a length
+    property whose value is an integer. Unless otherwise specified, this
+    value is equal to the largest number of named arguments shown in the
+    subclause headings for the function description, including optional
+    parameters. However, rest parameters shown using the form “...name”
+    are not included in the default argument count.
+
+    Unless otherwise specified, the length property of a built-in Function
+    object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+    [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [string-trimming]
+---*/
+
+verifyProperty(String.prototype.trimLeft, "length", {
+  value: 0,
+  enumerable: false,
+  writable: false,
+  configurable: true,
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/name.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimLeft
+description: >
+  String.prototype.trimLeft.name is "trimStart".
+info: >
+  String.prototype.trimLeft ( )
+
+  The function object that is the initial value of  String.prototype.trimLeft is the same function object that is the initial value of  String.prototype.trimStart.
+
+includes: [propertyHelper.js]
+features: [string-trimming,String.prototype.trimStart]
+---*/
+
+verifyProperty(String.prototype.trimLeft, "name", {
+  value: "trimStart",
+  enumerable: false,
+  writable: false,
+  configurable: true,
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/prop-desc.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2017 The Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimLeft
+description: >
+  "trimLeft" property of String.prototype
+info: >
+  17 ECMAScript Standard Built-in Objects:
+
+  Every other data property described in clauses 18 through 26 and in Annex B.2
+  has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+  [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+features: [string-trimming]
+---*/
+
+verifyProperty(String.prototype, "trimLeft", {
+  enumerable: false,
+  writable: true,
+  configurable: true,
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimLeft/reference-trimStart.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimLeft
+description: >
+  String.prototype.trimLeft is a reference to String.prototype.trimStart.
+info: >
+  String.prototype.trimLeft ( )
+
+  The function object that is the initial value of String.prototype.trimLeft
+  is the same function object that is the initial value of
+  String.prototype.trimStart.
+features: [string-trimming]
+---*/
+
+assert.sameValue(String.prototype.trimLeft, String.prototype.trimStart);
+
+reportCompare(0, 0);
new file mode 100644
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/length.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimRight
+description: >
+  String.prototype.trimRight.length is 0.
+info: >
+  String.prototype.trimRight ( )
+
+  17 ECMAScript Standard Built-in Objects:
+    Every built-in Function object, including constructors, has a length
+    property whose value is an integer. Unless otherwise specified, this
+    value is equal to the largest number of named arguments shown in the
+    subclause headings for the function description, including optional
+    parameters. However, rest parameters shown using the form “...name”
+    are not included in the default argument count.
+
+    Unless otherwise specified, the length property of a built-in Function
+    object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+    [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [string-trimming]
+---*/
+
+verifyProperty(String.prototype.trimRight, "length", {
+  value: 0,
+  enumerable: false,
+  writable: false,
+  configurable: true,
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/name.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimRight
+description: >
+  String.prototype.trimRight.name is "trimEnd".
+info: >
+  String.prototype.trimRight ( )#
+
+  The function object that is the initial value of  String.prototype.trimRight is the same function object that is the initial value of  String.prototype.trimEnd.
+includes: [propertyHelper.js]
+features: [string-trimming,String.prototype.trimEnd]
+---*/
+
+verifyProperty(String.prototype.trimRight, "name", {
+  value: "trimEnd",
+  enumerable: false,
+  writable: false,
+  configurable: true,
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/prop-desc.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2017 The Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimRight
+description: >
+  "trimRight" property of String.prototype
+info: >
+  17 ECMAScript Standard Built-in Objects:
+
+  Every other data property described in clauses 18 through 26 and in Annex B.2
+  has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+  [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+features: [string-trimming]
+---*/
+
+verifyProperty(String.prototype, "trimRight", {
+  enumerable: false,
+  writable: true,
+  configurable: true,
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/annexB/built-ins/String/prototype/trimRight/reference-trimEnd.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimRight
+description: >
+  String.prototype.trimRight is a reference to String.prototype.trimEnd.
+info: >
+  String.prototype.trimRight ( )
+
+  The function object that is the initial value of String.prototype.trimRight
+  is the same function object that is the initial value of
+  String.prototype.trimEnd.
+features: [string-trimming]
+---*/
+
+assert.sameValue(String.prototype.trimRight, String.prototype.trimEnd);
+
+reportCompare(0, 0);
new file mode 100644
--- a/js/src/tests/test262/annexB/language/comments/multi-line-html-close.js
+++ b/js/src/tests/test262/annexB/language/comments/multi-line-html-close.js
@@ -1,14 +1,13 @@
 // |reftest| error:Test262Error
 // Copyright (C) 2016 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 esid: sec-html-like-comments
-esid: sec-html-like-comments
 description: Optional HTMLCloseComment following MultiLineComment
 info: |
     Comment ::
       MultiLineComment
       SingleLineComment
       SingleLineHTMLOpenComment
       SingleLineHTMLCloseComment
       SingleLineDelimitedComment
--- a/js/src/tests/test262/annexB/language/comments/single-line-html-close-asi.js
+++ b/js/src/tests/test262/annexB/language/comments/single-line-html-close-asi.js
@@ -1,14 +1,13 @@
 // |reftest| error:Test262Error
 // Copyright (C) 2016 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 esid: sec-html-like-comments
-esid: sec-html-like-comments
 description: >
     A SingleLineHTMLCloseComment is considered to be a LineTerminator for
     purposes of parsing by the syntactic grammar.
 info: |
     Comment ::
       MultiLineComment
       SingleLineComment
       SingleLineHTMLOpenComment
--- a/js/src/tests/test262/annexB/language/comments/single-line-html-close.js
+++ b/js/src/tests/test262/annexB/language/comments/single-line-html-close.js
@@ -1,14 +1,13 @@
 // |reftest| error:Test262Error
 // Copyright (C) 2016 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 esid: sec-html-like-comments
-esid: sec-html-like-comments
 description: SingleLineHTMLCloseComment
 info: |
     Comment ::
       MultiLineComment
       SingleLineComment
       SingleLineHTMLOpenComment
       SingleLineHTMLCloseComment
       SingleLineDelimitedComment
--- a/js/src/tests/test262/annexB/language/comments/single-line-html-open.js
+++ b/js/src/tests/test262/annexB/language/comments/single-line-html-open.js
@@ -1,14 +1,13 @@
 // |reftest| error:Test262Error
 // Copyright (C) 2016 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 esid: sec-html-like-comments
-esid: sec-html-like-comments
 description: SingleLineHTMLOpenComment
 info: |
     Comment ::
       MultiLineComment
       SingleLineComment
       SingleLineHTMLOpenComment
       SingleLineHTMLCloseComment
       SingleLineDelimitedComment
--- a/js/src/tests/test262/annexB/language/expressions/object/__proto__-fn-name.js
+++ b/js/src/tests/test262/annexB/language/expressions/object/__proto__-fn-name.js
@@ -10,17 +10,16 @@ info: |
        IsComputedPropertyKey(propKey) is false, then
        a. If Type(propValue) is either Object or Null, then
           i. Return object.[[SetPrototypeOf]](propValue).
        b. Return NormalCompletion(empty).
     7. If IsAnonymousFunctionDefinition(AssignmentExpression) is true, then
        a. Let hasNameProperty be HasOwnProperty(propValue, "name").
        b. ReturnIfAbrupt(hasNameProperty).
        c. If hasNameProperty is false, perform SetFunctionName(propValue, propKey).
-includes: [propertyHelper.js]
 ---*/
 
 var o;
 
 o = {
   __proto__: function() {}
 };
 
--- a/js/src/tests/test262/annexB/language/literals/numeric/legacy-octal-integer.js
+++ b/js/src/tests/test262/annexB/language/literals/numeric/legacy-octal-integer.js
@@ -1,13 +1,12 @@
 // Copyright (C) 2016 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 esid: sec-additional-syntax-numeric-literals
-esid: sec-additional-syntax-numeric-literals
 description: Mathematical value for LegacyOctalIntegerLiteral
 info: |
     NumericLiteral ::
       DecimalLiteral
       BinaryIntegerLiteral
       OctalIntegerLiteral
       HexIntegerLiteral
       LegacyOctalIntegerLiteral
--- a/js/src/tests/test262/annexB/language/literals/numeric/non-octal-decimal-integer.js
+++ b/js/src/tests/test262/annexB/language/literals/numeric/non-octal-decimal-integer.js
@@ -1,13 +1,12 @@
 // Copyright (C) 2016 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 esid: sec-additional-syntax-numeric-literals
-esid: sec-additional-syntax-numeric-literals
 description: Mathematical value for NonOctalDecimalIntegerLiteral
 info: |
      DecimalIntegerLiteral ::
        0
        NonZeroDigit DecimalDigits[opt]
        NonOctalDecimalIntegerLiteral
 
      NonOctalDecimalIntegerLiteral ::
--- a/js/src/tests/test262/built-ins/Array/prototype/flatMap/depth-always-one.js
+++ b/js/src/tests/test262/built-ins/Array/prototype/flatMap/depth-always-one.js
@@ -7,13 +7,17 @@ description: >
 includes: [compareArray.js]
 features: [Array.prototype.flatMap]
 ---*/
 
 assert.compareArray([1, 2].flatMap(function(e) {
   return [e, e * 2];
 }), [1, 2, 2, 4], 'array depth is 1');
 
-assert.compareArray([1, 2, 3].flatMap(function(ele) {
+var result = [1, 2, 3].flatMap(function(ele) {
   return [[ele * 2]];
-}), [[2], [4], [6]], 'array depth is more than 1');
+});
+assert.sameValue(result.length, 3, 'array depth is more than 1 - length');
+assert.compareArray(result[0], [2], 'array depth is more than 1 - 1st element');
+assert.compareArray(result[1], [4], 'array depth is more than 1 - 2nd element');
+assert.compareArray(result[2], [6], 'array depth is more than 1 - 3rd element');
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/ArrayBuffer/isView/prop-desc.js
+++ b/js/src/tests/test262/built-ins/ArrayBuffer/isView/prop-desc.js
@@ -4,16 +4,16 @@
 /*---
 esid: sec-arraybuffer.isview
 description: >
   "isView" property of ArrayBuffer
 info: |
   ES6 section 17: Every other data property described in clauses 18 through 26
   and in Annex B.2 has the attributes { [[Writable]]: true,
   [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified.
-includes: [propertyHelper.js, testTypedArray.js]
+includes: [propertyHelper.js]
 ---*/
 
 verifyNotEnumerable(ArrayBuffer, "isView");
 verifyWritable(ArrayBuffer, "isView");
 verifyConfigurable(ArrayBuffer, "isView");
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/ArrayBuffer/prototype/byteLength/this-is-sharedarraybuffer.js
+++ b/js/src/tests/test262/built-ins/ArrayBuffer/prototype/byteLength/this-is-sharedarraybuffer.js
@@ -1,14 +1,16 @@
+// |reftest| skip-if(!this.hasOwnProperty('SharedArrayBuffer')) -- SharedArrayBuffer is not enabled unconditionally
 // Copyright (C) 2017 Mozilla Corporation. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
 esid: sec-get-arraybuffer.prototype.bytelength
 description: Throws a TypeError exception when `this` is a SharedArrayBuffer
+features: [SharedArrayBuffer]
 ---*/
 
 var getter = Object.getOwnPropertyDescriptor(
   ArrayBuffer.prototype, "byteLength"
 ).get;
 
 assert.throws(TypeError, function() {
   var sab = new SharedArrayBuffer(4);
--- a/js/src/tests/test262/built-ins/ArrayBuffer/prototype/slice/this-is-sharedarraybuffer.js
+++ b/js/src/tests/test262/built-ins/ArrayBuffer/prototype/slice/this-is-sharedarraybuffer.js
@@ -1,15 +1,17 @@
+// |reftest| skip-if(!this.hasOwnProperty('SharedArrayBuffer')) -- SharedArrayBuffer is not enabled unconditionally
 // Copyright (C) 2017 Mozilla Corporation. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
 esid: sec-arraybuffer.prototype.slice
 description: >
   Throws a TypeError if `this` is a SharedArrayBuffer
+features: [SharedArrayBuffer]
 ---*/
 
 assert.throws(TypeError, function() {
   var sab = new SharedArrayBuffer(0);
   ArrayBuffer.prototype.slice.call(sab);
 }, "`this` value cannot be a SharedArrayBuffer");
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Atomics/add/bad-range.js
+++ b/js/src/tests/test262/built-ins/Atomics/add/bad-range.js
@@ -5,19 +5,24 @@
 /*---
 esid: sec-atomics.add
 description: >
   Test range checking of Atomics.add on arrays that allow atomic operations
 includes: [testAtomics.js, testTypedArray.js]
 features: [SharedArrayBuffer, ArrayBuffer, DataView, Atomics, arrow-function, let, TypedArray, for-of]
 ---*/
 
-var sab = new SharedArrayBuffer(4);
+var sab = new SharedArrayBuffer(8);
 var views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  views.push(BigInt64Array);
+  views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     let view = new View(sab);
     testWithAtomicsOutOfBoundsIndices(function(IdxGen) {
         let Idx = IdxGen(view);
         assert.throws(RangeError, () => Atomics.add(view, Idx, 10));
     });
 }, views);
 
--- a/js/src/tests/test262/built-ins/Atomics/add/nonshared-int-views.js
+++ b/js/src/tests/test262/built-ins/Atomics/add/nonshared-int-views.js
@@ -8,15 +8,20 @@ description: >
 includes: [testTypedArray.js]
 features: [TypedArray]
 ---*/
 
 var ab = new ArrayBuffer(16);
 
 var int_views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  int_views.push(BigInt64Array);
+  int_views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     var view = new View(ab);
 
     assert.throws(TypeError, (() => Atomics.add(view, 0, 0)));
 }, int_views);
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Atomics/and/bad-range.js
+++ b/js/src/tests/test262/built-ins/Atomics/and/bad-range.js
@@ -5,19 +5,24 @@
 /*---
 esid: sec-atomics.and
 description: >
   Test range checking of Atomics.and on arrays that allow atomic operations
 includes: [testAtomics.js, testTypedArray.js]
 features: [SharedArrayBuffer, ArrayBuffer, DataView, Atomics, arrow-function, let, TypedArray, for-of]
 ---*/
 
-var sab = new SharedArrayBuffer(4);
+var sab = new SharedArrayBuffer(8);
 var views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  views.push(BigInt64Array);
+  views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     let view = new View(sab);
     testWithAtomicsOutOfBoundsIndices(function(IdxGen) {
         let Idx = IdxGen(view);
         assert.throws(RangeError, () => Atomics.and(view, Idx, 10));
     });
 }, views);
 
--- a/js/src/tests/test262/built-ins/Atomics/and/nonshared-int-views.js
+++ b/js/src/tests/test262/built-ins/Atomics/and/nonshared-int-views.js
@@ -8,15 +8,20 @@ description: >
 includes: [testTypedArray.js]
 features: [TypedArray]
 ---*/
 
 var ab = new ArrayBuffer(16);
 
 var int_views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  int_views.push(BigInt64Array);
+  int_views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     var view = new View(ab);
 
     assert.throws(TypeError, (() => Atomics.and(view, 0, 0)));
 }, int_views);
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Atomics/compareExchange/bad-range.js
+++ b/js/src/tests/test262/built-ins/Atomics/compareExchange/bad-range.js
@@ -5,19 +5,24 @@
 /*---
 esid: sec-atomics.compareexchange
 description: >
   Test range checking of Atomics.compareExchange on arrays that allow atomic operations
 includes: [testAtomics.js, testTypedArray.js]
 features: [SharedArrayBuffer, ArrayBuffer, DataView, Atomics, arrow-function, let, TypedArray, for-of]
 ---*/
 
-var sab = new SharedArrayBuffer(4);
+var sab = new SharedArrayBuffer(8);
 var views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  views.push(BigInt64Array);
+  views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     let view = new View(sab);
     testWithAtomicsOutOfBoundsIndices(function(IdxGen) {
         let Idx = IdxGen(view);
         assert.throws(RangeError, () => Atomics.compareExchange(view, Idx, 10, 0));
     });
 }, views);
 
--- a/js/src/tests/test262/built-ins/Atomics/compareExchange/nonshared-int-views.js
+++ b/js/src/tests/test262/built-ins/Atomics/compareExchange/nonshared-int-views.js
@@ -8,15 +8,20 @@ description: >
 includes: [testTypedArray.js]
 features: [TypedArray]
 ---*/
 
 var ab = new ArrayBuffer(16);
 
 var int_views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  int_views.push(BigInt64Array);
+  int_views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     var view = new View(ab);
 
     assert.throws(TypeError, (() => Atomics.compareExchange(view, 0, 0, 0)));
 }, int_views);
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Atomics/exchange/bad-range.js
+++ b/js/src/tests/test262/built-ins/Atomics/exchange/bad-range.js
@@ -5,19 +5,24 @@
 /*---
 esid: sec-atomics.exchange
 description: >
   Test range checking of Atomics.exchange on arrays that allow atomic operations
 includes: [testAtomics.js, testTypedArray.js]
 features: [SharedArrayBuffer, ArrayBuffer, DataView, Atomics, arrow-function, let, TypedArray, for-of]
 ---*/
 
-var sab = new SharedArrayBuffer(4);
+var sab = new SharedArrayBuffer(8);
 var views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  views.push(BigInt64Array);
+  views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     let view = new View(sab);
     testWithAtomicsOutOfBoundsIndices(function(IdxGen) {
         let Idx = IdxGen(view);
         assert.throws(RangeError, () => Atomics.exchange(view, Idx, 10, 0));
     });
 }, views);
 
--- a/js/src/tests/test262/built-ins/Atomics/exchange/nonshared-int-views.js
+++ b/js/src/tests/test262/built-ins/Atomics/exchange/nonshared-int-views.js
@@ -8,15 +8,20 @@ description: >
 includes: [testTypedArray.js]
 features: [TypedArray]
 ---*/
 
 var ab = new ArrayBuffer(16);
 
 var int_views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  int_views.push(BigInt64Array);
+  int_views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     var view = new View(ab);
 
     assert.throws(TypeError, (() => Atomics.exchange(view, 0, 0)));
 }, int_views);
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Atomics/load/bad-range.js
+++ b/js/src/tests/test262/built-ins/Atomics/load/bad-range.js
@@ -5,19 +5,24 @@
 /*---
 esid: sec-atomics.load
 description: >
   Test range checking of Atomics.load on arrays that allow atomic operations
 includes: [testAtomics.js, testTypedArray.js]
 features: [SharedArrayBuffer, ArrayBuffer, DataView, Atomics, arrow-function, let, TypedArray, for-of]
 ---*/
 
-var sab = new SharedArrayBuffer(4);
+var sab = new SharedArrayBuffer(8);
 var views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  views.push(BigInt64Array);
+  views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     let view = new View(sab);
     testWithAtomicsOutOfBoundsIndices(function(IdxGen) {
         let Idx = IdxGen(view);
         assert.throws(RangeError, () => Atomics.load(view, Idx));
     });
 }, views);
 
--- a/js/src/tests/test262/built-ins/Atomics/load/nonshared-int-views.js
+++ b/js/src/tests/test262/built-ins/Atomics/load/nonshared-int-views.js
@@ -8,15 +8,20 @@ description: >
 includes: [testTypedArray.js]
 features: [TypedArray]
 ---*/
 
 var ab = new ArrayBuffer(16);
 
 var int_views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  int_views.push(BigInt64Array);
+  int_views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     var view = new View(ab);
 
     assert.throws(TypeError, (() => Atomics.load(view, 0)));
 }, int_views);
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Atomics/or/bad-range.js
+++ b/js/src/tests/test262/built-ins/Atomics/or/bad-range.js
@@ -5,19 +5,24 @@
 /*---
 esid: sec-atomics.or
 description: >
   Test range checking of Atomics.or on arrays that allow atomic operations
 includes: [testAtomics.js, testTypedArray.js]
 features: [SharedArrayBuffer, ArrayBuffer, DataView, Atomics, arrow-function, let, TypedArray, for-of]
 ---*/
 
-var sab = new SharedArrayBuffer(4);
+var sab = new SharedArrayBuffer(8);
 var views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  views.push(BigInt64Array);
+  views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     let view = new View(sab);
     testWithAtomicsOutOfBoundsIndices(function(IdxGen) {
         let Idx = IdxGen(view);
         assert.throws(RangeError, () => Atomics.or(view, Idx, 10));
     });
 }, views);
 
--- a/js/src/tests/test262/built-ins/Atomics/or/nonshared-int-views.js
+++ b/js/src/tests/test262/built-ins/Atomics/or/nonshared-int-views.js
@@ -8,15 +8,20 @@ description: >
 includes: [testTypedArray.js]
 features: [TypedArray]
 ---*/
 
 var ab = new ArrayBuffer(16);
 
 var int_views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  int_views.push(BigInt64Array);
+  int_views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     var view = new View(ab);
 
     assert.throws(TypeError, (() => Atomics.or(view, 0, 0)));
 }, int_views);
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Atomics/store/bad-range.js
+++ b/js/src/tests/test262/built-ins/Atomics/store/bad-range.js
@@ -5,19 +5,24 @@
 /*---
 esid: sec-atomics.store
 description: >
   Test range checking of Atomics.store on arrays that allow atomic operations
 includes: [testAtomics.js, testTypedArray.js]
 features: [SharedArrayBuffer, ArrayBuffer, DataView, Atomics, arrow-function, let, TypedArray, for-of]
 ---*/
 
-var sab = new SharedArrayBuffer(4);
+var sab = new SharedArrayBuffer(8);
 var views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  views.push(BigInt64Array);
+  views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     let view = new View(sab);
     testWithAtomicsOutOfBoundsIndices(function(IdxGen) {
         let Idx = IdxGen(view);
         assert.throws(RangeError, () => Atomics.store(view, Idx, 10));
     });
 }, views);
 
--- a/js/src/tests/test262/built-ins/Atomics/store/nonshared-int-views.js
+++ b/js/src/tests/test262/built-ins/Atomics/store/nonshared-int-views.js
@@ -8,15 +8,20 @@ description: >
 includes: [testTypedArray.js]
 features: [TypedArray]
 ---*/
 
 var ab = new ArrayBuffer(16);
 
 var int_views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  int_views.push(BigInt64Array);
+  int_views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     var view = new View(ab);
 
     assert.throws(TypeError, (() => Atomics.store(view, 0, 0)));
 }, int_views);
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Atomics/sub/bad-range.js
+++ b/js/src/tests/test262/built-ins/Atomics/sub/bad-range.js
@@ -5,19 +5,24 @@
 /*---
 esid: sec-atomics.sub
 description: >
   Test range checking of Atomics.sub on arrays that allow atomic operations
 includes: [testAtomics.js, testTypedArray.js]
 features: [SharedArrayBuffer, ArrayBuffer, DataView, Atomics, arrow-function, let, TypedArray, for-of]
 ---*/
 
-var sab = new SharedArrayBuffer(4);
+var sab = new SharedArrayBuffer(8);
 var views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  views.push(BigInt64Array);
+  views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     let view = new View(sab);
     testWithAtomicsOutOfBoundsIndices(function(IdxGen) {
         let Idx = IdxGen(view);
         assert.throws(RangeError, () => Atomics.sub(view, Idx, 10));
     });
 }, views);
 
--- a/js/src/tests/test262/built-ins/Atomics/sub/nonshared-int-views.js
+++ b/js/src/tests/test262/built-ins/Atomics/sub/nonshared-int-views.js
@@ -8,15 +8,20 @@ description: >
 includes: [testTypedArray.js]
 features: [TypedArray]
 ---*/
 
 var ab = new ArrayBuffer(16);
 
 var int_views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  int_views.push(BigInt64Array);
+  int_views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     var view = new View(ab);
 
     assert.throws(TypeError, (() => Atomics.sub(view, 0, 0)));
 }, int_views);
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Atomics/wait/bad-range.js
+++ b/js/src/tests/test262/built-ins/Atomics/wait/bad-range.js
@@ -1,21 +1,28 @@
 // |reftest| skip-if(!this.hasOwnProperty('SharedArrayBuffer')||!this.hasOwnProperty('Atomics')) -- SharedArrayBuffer,Atomics is not enabled unconditionally
 // Copyright (C) 2017 Mozilla Corporation.  All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
 esid: sec-atomics.wait
 description: >
   Test range checking of Atomics.wait on arrays that allow atomic operations
-includes: [testAtomics.js]
-features: [SharedArrayBuffer, ArrayBuffer, DataView, Atomics, arrow-function, let, for-of]
+includes: [testAtomics.js, testTypedArray.js]
+features: [SharedArrayBuffer, ArrayBuffer, DataView, Atomics, TypedArray, arrow-function, let, for-of]
 ---*/
 
-var sab = new SharedArrayBuffer(4);
-var view = new Int32Array(sab);
+var sab = new SharedArrayBuffer(8);
+var views = [Int32Array];
 
-testWithAtomicsOutOfBoundsIndices(function(IdxGen) {
+if (typeof BigInt !== "undefined") {
+  views.push(BigInt64Array);
+}
+
+testWithTypedArrayConstructors(function(View) {
+  let view = new View(sab);
+  testWithAtomicsOutOfBoundsIndices(function(IdxGen) {
     let Idx = IdxGen(view);
     assert.throws(RangeError, () => Atomics.wait(view, Idx, 10, 0)); // Even with zero timeout
-});
+  });
+}, views);
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Atomics/wait/nonshared-int-views.js
+++ b/js/src/tests/test262/built-ins/Atomics/wait/nonshared-int-views.js
@@ -8,15 +8,20 @@ description: >
 includes: [testTypedArray.js]
 features: [TypedArray]
 ---*/
 
 var ab = new ArrayBuffer(16);
 
 var int_views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  int_views.push(BigInt64Array);
+  int_views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     var view = new View(ab);
 
     assert.throws(TypeError, (() => Atomics.wait(view, 0, 0, 0))); // Should fail even if waiting 0ms
 }, int_views);
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Atomics/wake/bad-range.js
+++ b/js/src/tests/test262/built-ins/Atomics/wake/bad-range.js
@@ -1,21 +1,28 @@
 // |reftest| skip-if(!this.hasOwnProperty('SharedArrayBuffer')||!this.hasOwnProperty('Atomics')) -- SharedArrayBuffer,Atomics is not enabled unconditionally
 // Copyright (C) 2017 Mozilla Corporation.  All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
 esid: sec-atomics.wake
 description: >
   Test range checking of Atomics.wake on arrays that allow atomic operations
-includes: [testAtomics.js]
-features: [SharedArrayBuffer, ArrayBuffer, DataView, Atomics, arrow-function, let, for-of]
+includes: [testAtomics.js, testTypedArray.js]
+features: [SharedArrayBuffer, ArrayBuffer, DataView, Atomics, TypedArray, arrow-function, let, for-of]
 ---*/
 
-var sab = new SharedArrayBuffer(4);
-var view = new Int32Array(sab);
+var sab = new SharedArrayBuffer(8);
+var views = [Int32Array];
 
-testWithAtomicsOutOfBoundsIndices(function(IdxGen) {
+if (typeof BigInt !== "undefined") {
+  views.push(BigInt64Array);
+}
+
+testWithTypedArrayConstructors(function(View) {
+  let view = new View(sab);
+  testWithAtomicsOutOfBoundsIndices(function(IdxGen) {
     let Idx = IdxGen(view);
     assert.throws(RangeError, () => Atomics.wake(view, Idx, 0)); // Even with waking zero
-});
+  });
+}, views);
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Atomics/wake/nonshared-int-views.js
+++ b/js/src/tests/test262/built-ins/Atomics/wake/nonshared-int-views.js
@@ -8,15 +8,20 @@ description: >
 includes: [testTypedArray.js]
 features: [TypedArray]
 ---*/
 
 var ab = new ArrayBuffer(16);
 
 var int_views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  int_views.push(BigInt64Array);
+  int_views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     var view = new View(ab);
 
     assert.throws(TypeError, (() => Atomics.wake(view, 0, 0))); // Should fail even if waking zero waiters
 }, int_views);
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Atomics/xor/bad-range.js
+++ b/js/src/tests/test262/built-ins/Atomics/xor/bad-range.js
@@ -5,19 +5,24 @@
 /*---
 esid: sec-atomics.xor
 description: >
   Test range checking of Atomics.xor on arrays that allow atomic operations
 includes: [testAtomics.js, testTypedArray.js]
 features: [SharedArrayBuffer, ArrayBuffer, DataView, Atomics, arrow-function, let, TypedArray, for-of]
 ---*/
 
-var sab = new SharedArrayBuffer(4);
+var sab = new SharedArrayBuffer(8);
 var views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  views.push(BigInt64Array);
+  views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     let view = new View(sab);
     testWithAtomicsOutOfBoundsIndices(function(IdxGen) {
         let Idx = IdxGen(view);
         assert.throws(RangeError, () => Atomics.xor(view, Idx, 0));
     });
 }, views);
 
--- a/js/src/tests/test262/built-ins/Atomics/xor/nonshared-int-views.js
+++ b/js/src/tests/test262/built-ins/Atomics/xor/nonshared-int-views.js
@@ -8,15 +8,20 @@ description: >
 includes: [testTypedArray.js]
 features: [TypedArray]
 ---*/
 
 var ab = new ArrayBuffer(16);
 
 var int_views = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array];
 
+if (typeof BigInt !== "undefined") {
+  int_views.push(BigInt64Array);
+  int_views.push(BigUint64Array);
+}
+
 testWithTypedArrayConstructors(function(View) {
     var view = new View(ab);
 
     assert.throws(TypeError, (() => Atomics.xor(view, 0, 0)));
 }, int_views);
 
 reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Date/UTC/non-integer-values.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2018 Viktor Mukhachev. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-date.utc
+description: non-integer values are converted to integers using `ToInteger`
+info: |
+  [...]
+  Return TimeClip(MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli))).
+
+  #sec-timeclip
+
+  Let clippedTime be ! ToInteger(time).
+
+  #sec-makeday
+
+  Let y be ! ToInteger(year).
+  Let m be ! ToInteger(month).
+  Let dt be ! ToInteger(date).
+
+  #sec-maketime
+
+  Let h be ! ToInteger(hour).
+  Let m be ! ToInteger(min).
+  Let s be ! ToInteger(sec).
+  Let milli be ! ToInteger(ms).
+---*/
+
+assert.sameValue(Date.UTC(1970.9, 0.9, 1.9, 0.9, 0.9, 0.9, 0.9), 0, 'positive non-integer values');
+assert.sameValue(Date.UTC(-1970.9, -0.9, -0.9, -0.9, -0.9, -0.9, -0.9), -124334438400000, 'negative non-integer values');
+
+reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Date/shell.js
+++ b/js/src/tests/test262/built-ins/Date/shell.js
@@ -35,8 +35,11 @@ description: |
 var date_1899_end = -2208988800001;
 var date_1900_start = -2208988800000;
 var date_1969_end = -1;
 var date_1970_start = 0;
 var date_1999_end = 946684799999;
 var date_2000_start = 946684800000;
 var date_2099_end = 4102444799999;
 var date_2100_start = 4102444800000;
+
+var start_of_time = -8.64e15;
+var end_of_time = 8.64e15;
--- a/js/src/tests/test262/built-ins/Map/prototype/size/this-not-object-throw.js
+++ b/js/src/tests/test262/built-ins/Map/prototype/size/this-not-object-throw.js
@@ -8,17 +8,16 @@ info: |
   get Map.prototype.size
 
   1. Let M be the this value.
   2. If Type(M) is not Object, throw a TypeError exception.
   3. If M does not have a [[MapData]] internal slot, throw a TypeError
   exception.
   ...
 
-includes: [propertyHelper.js]
 features: [Symbol]
 ---*/
 
 var descriptor = Object.getOwnPropertyDescriptor(Map.prototype, 'size');
 
 assert.throws(TypeError, function() {
   descriptor.get.call(1);
 });
--- a/js/src/tests/test262/built-ins/Number/NEGATIVE_INFINITY/value.js
+++ b/js/src/tests/test262/built-ins/Number/NEGATIVE_INFINITY/value.js
@@ -5,14 +5,13 @@
 es6id: 20.1.2.11
 esid: sec-number.negative_infinity
 description: >
   The value of Number.NEGATIVE_INFINITY is -Infinity
 info: |
   Number.NEGATIVE_INFINITY
 
   The value of Number.NEGATIVE_INFINITY is -∞.
-includes: [propertyHelper.js]
 ---*/
 
 assert.sameValue(Number.NEGATIVE_INFINITY, -Infinity);
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Number/POSITIVE_INFINITY/value.js
+++ b/js/src/tests/test262/built-ins/Number/POSITIVE_INFINITY/value.js
@@ -5,14 +5,13 @@
 es6id: 20.1.2.14
 esid: sec-number.positive_infinity
 description: >
   The value of Number.POSITIVE_INFINITY is +Infinity
 info: |
   Number.POSITIVE_INFINITY
 
   The value of Number.POSITIVE_INFINITY is +∞.
-includes: [propertyHelper.js]
 ---*/
 
 assert.sameValue(Number.POSITIVE_INFINITY, Infinity);
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Object/is/symbol-object-is-same-value.js
+++ b/js/src/tests/test262/built-ins/Object/is/symbol-object-is-same-value.js
@@ -1,15 +1,15 @@
 // Copyright (C) 2013 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
-es6id: 7.2.
+esid: sec-object.is
 description: >
     Object.is/SameValue: Symbol
-features: [Symbol]
+features: [Object.is,Symbol]
 ---*/
 var symA = Symbol('66');
 var symB = Symbol('66');
 
 
 assert.sameValue(Object.is(symA, symA), true, "`Object.is(symA, symA)` returns `true`");
 assert.sameValue(Object.is(symB, symB), true, "`Object.is(symB, symB)` returns `true`");
 assert.sameValue(Object.is(symA, symB), false, "`Object.is(symA, symB)` returns `false`");
--- a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T1.js
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T1.js
@@ -2,17 +2,16 @@
 // See LICENSE for details.
 
 /*---
 info: |
     Promise.all with 2-element array
 es6id: S25.4.4.1_A8.1_T1
 author: Sam Mikes
 description: Promise.all() rejects when a promise in its array rejects
-includes: [promiseHelper.js]
 flags: [async]
 ---*/
 
 var rejectP1,
     p1 = new Promise(function (resolve, reject) {
         rejectP1 = reject;
     }),
     p2 = Promise.resolve(2);
--- a/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T2.js
+++ b/js/src/tests/test262/built-ins/Promise/all/S25.4.4.1_A8.2_T2.js
@@ -2,17 +2,16 @@
 // See LICENSE for details.
 
 /*---
 info: |
     Promise.all with 2-element array
 es6id: S25.4.4.1_A8.2_T2
 author: Sam Mikes
 description: Promise.all() rejects when second promise in array rejects
-includes: [promiseHelper.js]
 flags: [async]
 ---*/
 
 var rejectP2,
     p1 = Promise.resolve(1),
     p2 = new Promise(function (resolve, reject) {
         rejectP2 = reject;
     });
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/invokes-then-with-function.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/invokes-then-with-function.js
@@ -22,34 +22,40 @@ target.then = function(a, b) {
   argCount = arguments.length;
   firstArg = a;
   secondArg = b;
 
   return returnValue;
 };
 
 var originalFinallyHandler = function () {};
+var anonName = Object(function () {}).name;
 
 var result = Promise.prototype.finally.call(target, originalFinallyHandler, 2, 3);
 
 assert.sameValue(callCount, 1, 'Invokes `then` method exactly once');
 assert.sameValue(
   thisValue,
   target,
   'Invokes `then` method with the instance as the `this` value'
 );
 assert.sameValue(argCount, 2, 'Invokes `then` method with exactly two single arguments');
 assert.sameValue(
   typeof firstArg,
   'function',
   'Invokes `then` method with a function as the first argument'
 );
 assert.notSameValue(firstArg, originalFinallyHandler, 'Invokes `then` method with a different fulfillment handler');
+assert.sameValue(firstArg.length, 1, 'fulfillment handler has a length of 1');
+assert.sameValue(firstArg.name, anonName, 'fulfillment handler is anonymous');
+
 assert.sameValue(
   typeof secondArg,
   'function',
   'Invokes `then` method with a function as the second argument'
 );
-assert.notSameValue(secondArg, originalFinallyHandler, 'Invokes `then` method with a different fulfillment handler');
+assert.notSameValue(secondArg, originalFinallyHandler, 'Invokes `then` method with a different rejection handler');
+assert.sameValue(secondArg.length, 1, 'rejection handler has a length of 1');
+assert.sameValue(secondArg.name, anonName, 'rejection handler is anonymous');
 
 assert.sameValue(result, returnValue, 'Returns the result of the invocation of `then`');
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Promise/prototype/finally/species-constructor.js
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/species-constructor.js
@@ -1,13 +1,13 @@
 // Copyright (C) 2017 V8. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 author: Sathya Gunasekaran
-description: finally calls the SpeciesConstructor
+description: finally calls the SpeciesConstructor and creates the right amount of promises
 esid: sec-promise.prototype.finally
 features: [Promise.prototype.finally]
 flags: [async]
 ---*/
 
 
 var count = 0;
 class FooPromise extends Promise {
@@ -17,9 +17,9 @@ class FooPromise extends Promise {
   }
 }
 
 new FooPromise(r => r())
   .finally(() => {})
   .then(() => {
     assert.sameValue(count, 6, "6 new promises were created");
     $DONE();
-});
+  }, $ERROR);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-reject-count.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2018 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: Promise subclass finally on rejected creates the proper number of subclassed promises
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+flags: [async]
+---*/
+
+var count = 0;
+class FooPromise extends Promise {
+  constructor(resolve, reject) {
+    count++;
+    return super(resolve, reject);
+  }
+}
+
+FooPromise.reject().finally(() => {}).then($ERROR).catch(() => {
+  assert.sameValue(7, count);
+  $DONE();
+});
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-resolve-count.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2018 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: Promise subclass finally on resolved creates the proper number of subclassed promises
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+flags: [async]
+---*/
+
+var count = 0;
+class FooPromise extends Promise {
+  constructor(resolve, reject) {
+    count++;
+    return super(resolve, reject);
+  }
+}
+
+FooPromise.resolve().finally(() => {}).then(() => {
+  assert.sameValue(6, count);
+  $DONE();
+}, $ERROR);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-species-constructor-reject-count.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2018 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: finally on rejected Promise calls the SpeciesConstructor
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+---*/
+
+class FooPromise extends Promise {
+  static get [Symbol.species]() { return Promise; }
+}
+
+var p = Promise.reject().finally(() => FooPromise.reject());
+
+assert.sameValue(p instanceof Promise, true);
+assert.sameValue(p instanceof FooPromise, false);
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/subclass-species-constructor-resolve-count.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2018 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: finally on resolved Promise calls the SpeciesConstructor
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+---*/
+
+class FooPromise extends Promise {
+  static get [Symbol.species]() { return Promise; }
+}
+
+var p = Promise.resolve().finally(() => FooPromise.resolve());
+
+assert.sameValue(p instanceof Promise, true);
+assert.sameValue(p instanceof FooPromise, false);
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Promise/prototype/finally/this-value-non-promise.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2018 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+author: Jordan Harband
+description: >
+  Promise.prototype.finally called with a non-branded Promise does not throw
+esid: sec-promise.prototype.finally
+features: [Promise.prototype.finally]
+---*/
+
+var called = false;
+var p = new Proxy(Promise.resolve(), {});
+var oldThen = Promise.prototype.then;
+Promise.prototype.then = () => { called = true; };
+Promise.prototype.finally.call(p);
+assert.sameValue(called, true);
+Promise.prototype.then = oldThen;
+
+reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/Promise/resolve/S25.Promise_resolve_foreign_thenable_1.js
+++ b/js/src/tests/test262/built-ins/Promise/resolve/S25.Promise_resolve_foreign_thenable_1.js
@@ -2,22 +2,19 @@
 // See LICENSE for details.
 
 /*---
 info: |
    Promise.resolve
 es6id: S25.4.4.5
 author: Sam Mikes
 description: Promise.resolve delegates to foreign thenable
-includes: [promiseHelper.js]
 flags: [async]
 ---*/
 
-var sequence = [];
-
 var thenable = {
     then: function(onResolve, onReject) {
         return onResolve('resolved');
     }
 };
 
 var p = Promise.resolve(thenable);
 
--- a/js/src/tests/test262/built-ins/RegExp/named-groups/groups-object-subclass-sans.js
+++ b/js/src/tests/test262/built-ins/RegExp/named-groups/groups-object-subclass-sans.js
@@ -1,16 +1,15 @@
 // |reftest| skip -- regexp-named-groups is not supported
 // Copyright 2017 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
 description: >
   Test the groups object on RegExp subclass results that do not have their own.
-includes: [propertyHelper.js]
 esid: sec-regexpbuiltinexec
 features: [regexp-named-groups]
 info: |
   Runtime Semantics: RegExpBuiltinExec ( R, S )
     24. If _R_ contains any |GroupName|, then
       a. Let _groups_ be ObjectCreate(*null*).
     25. Else,
       a. Let _groups_ be *undefined*.
@@ -23,18 +22,18 @@ class FakeRegExp extends RegExp {
     fakeResult.index = 0;
     // `groups` is not set, triggering prototype lookup.
     return fakeResult;
   }
 };
 
 const re = new FakeRegExp();
 const result = re.exec("ab");
-assert.sameValue(result.__proto__, Array.prototype);
+assert.sameValue(Object.getPrototypeOf(result), Array.prototype);
 assert.sameValue(false, result.hasOwnProperty("groups"));
 
 Array.prototype.groups = { a: "b" };
-Array.prototype.groups.__proto__.b = "c";
+Object.getPrototypeOf(Array.prototype.groups).b = "c";
 assert.sameValue("b", "ab".replace(re, "$<a>"));
 assert.sameValue("c", "ab".replace(re, "$<b>"));
 Array.prototype.groups = undefined;
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/RegExp/named-groups/groups-object-subclass.js
+++ b/js/src/tests/test262/built-ins/RegExp/named-groups/groups-object-subclass.js
@@ -1,38 +1,37 @@
 // |reftest| skip -- regexp-named-groups is not supported
 // Copyright 2017 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
 description: >
   Test the groups object on RegExp subclass results that have their own.
-includes: [propertyHelper.js]
 esid: sec-regexpbuiltinexec
 features: [regexp-named-groups]
 info: |
   Runtime Semantics: RegExpBuiltinExec ( R, S )
     24. If _R_ contains any |GroupName|, then
       a. Let _groups_ be ObjectCreate(*null*).
     25. Else,
       a. Let _groups_ be *undefined*.
     26. Perform ! CreateDataProperty(_A_, `"groups"`, _groups_).
 ---*/
 
 class FakeRegExp extends RegExp {
   exec(subject) {
     const fakeResult = ["ab", "a"];
     fakeResult.index = 0;
     fakeResult.groups = { a: "b" };
-    fakeResult.groups.__proto__.b = "c";
+    Object.getPrototypeOf(fakeResult.groups).b = "c";
     return fakeResult;
   }
 };
 
 const re = new FakeRegExp();
 const result = re.exec("ab");
-assert.sameValue(result.__proto__, Array.prototype);
+assert.sameValue(Object.getPrototypeOf(result), Array.prototype);
 assert(result.hasOwnProperty("groups"));
 assert.sameValue("b", result.groups.a);
 assert.sameValue("b", "ab".replace(re, "$<a>"));
 assert.sameValue("c", "ab".replace(re, "$<b>"));
 
 reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/RegExp/named-groups/groups-object-undefined.js
+++ b/js/src/tests/test262/built-ins/RegExp/named-groups/groups-object-undefined.js
@@ -13,17 +13,17 @@ info: |
       a. Let _groups_ be ObjectCreate(*null*).
     25. Else,
       a. Let _groups_ be *undefined*.
     26. Perform ! CreateDataProperty(_A_, `"groups"`, _groups_).
 ---*/
 
 const re = /./;
 const result = re.exec("a");
-assert.sameValue(result.__proto__, Array.prototype);
+assert.sameValue(Object.getPrototypeOf(result), Array.prototype);
 assert(result.hasOwnProperty("groups"));
 assert.sameValue("a", result[0]);
 assert.sameValue(0, result.index);
 assert.sameValue(undefined, result.groups);
 verifyProperty(result, "groups", {
   writable: true,
   enumerable: true,
   configurable: true,
--- a/js/src/tests/test262/built-ins/RegExp/named-groups/groups-object-unmatched.js
+++ b/js/src/tests/test262/built-ins/RegExp/named-groups/groups-object-unmatched.js
@@ -1,30 +1,29 @@
 // |reftest| skip -- regexp-named-groups is not supported
 // Copyright 2017 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
 description: >
   Test the groups object with matched and unmatched named captures.
-includes: [propertyHelper.js]
 esid: sec-regexpbuiltinexec
 features: [regexp-named-groups]
 info: |
   Runtime Semantics: RegExpBuiltinExec ( R, S )
     24. If _R_ contains any |GroupName|, then
       a. Let _groups_ be ObjectCreate(*null*).
     25. Else,
       a. Let _groups_ be *undefined*.
     26. Perform ! CreateDataProperty(_A_, `"groups"`, _groups_).
 ---*/
 
 const re = /(?<a>a).|(?<x>x)/;
 const result = re.exec("ab");
-assert.sameValue(result.__proto__, Array.prototype);
+assert.sameValue(Object.getPrototypeOf(result), Array.prototype);
 assert(result.hasOwnProperty("groups"));
 assert.sameValue("ab", result[0]);
 assert.sameValue("a", result[1]);
 assert.sameValue(undefined, result[2]);
 assert.sameValue(0, result.index);
 assert.sameValue("a", result.groups.a);
 assert.sameValue(undefined, result.groups.x);
 
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/length.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: >
+  String.prototype.trimEnd.length is 0.
+info: >
+  String.prototype.trimEnd ( )
+
+  17 ECMAScript Standard Built-in Objects:
+    Every built-in Function object, including constructors, has a length
+    property whose value is an integer. Unless otherwise specified, this
+    value is equal to the largest number of named arguments shown in the
+    subclause headings for the function description, including optional
+    parameters. However, rest parameters shown using the form “...name”
+    are not included in the default argument count.
+
+    Unless otherwise specified, the length property of a built-in Function
+    object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+    [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [string-trimming, String.prototype.trimEnd]
+---*/
+
+verifyProperty(String.prototype.trimEnd, "length", {
+  value: 0,
+  enumerable: false,
+  writable: false,
+  configurable: true,
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/name.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: >
+  String.prototype.trimEnd.name is "trimEnd".
+info: >
+  String.prototype.trimEnd ( )
+
+  17 ECMAScript Standard Built-in Objects:
+    Every built-in Function object, including constructors, that is not
+    identified as an anonymous function has a name property whose value
+    is a String.
+
+    Unless otherwise specified, the name property of a built-in Function
+    object, if it exists, has the attributes { [[Writable]]: false,
+    [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [string-trimming, String.prototype.trimEnd]
+---*/
+
+verifyProperty(String.prototype.trimEnd, "name", {
+  value: "trimEnd",
+  enumerable: false,
+  writable: false,
+  configurable: true,
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/prop-desc.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2017 The Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: >
+  "trimEnd" property of String.prototype
+info: >
+  17 ECMAScript Standard Built-in Objects:
+
+  Every other data property described in clauses 18 through 26 and in Annex B.2
+  has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+  [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+features: [string-trimming, String.prototype.trimEnd]
+---*/
+
+verifyProperty(String.prototype, "trimEnd", {
+  enumerable: false,
+  writable: true,
+  configurable: true,
+});
+
+reportCompare(0, 0);
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-boolean.js
@@ -0,0 +1,33 @@
+// Copyright (c) 2017 Valerie Young.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: Behavior when "this" value is a boolean.
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  2. Let S be ? ToString(str).
+
+  ToString ( argument )
+  Argument Type: Boolean
+  Result:
+    If argument is true, return "true".
+    If argument is false, return "false".
+features: [string-trimming, String.prototype.trimEnd]
+---*/
+
+var trimEnd = String.prototype.trimEnd
+
+assert.sameValue(
+  trimEnd.call(true),
+  'true',
+  'String.prototype.trimEnd.call(true)'
+);
+
+assert.sameValue(
+  String.prototype.trimEnd.call(false),
+  'false',
+  'String.prototype.trimEnd.call(false)'
+);
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-line-terminator.js
@@ -0,0 +1,32 @@
+// Copyright (c) 2017 Valerie Young.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: TrimEnd removes all line terminators from the end of a string.
+info: |
+  Runtime Symantics: TrimString ( string, where )
+  ...
+  4. Else if where is "end", let T be a String value that is a copy of S with
+     trailing white space removed.
+  ...
+
+  The definition of white space is the union of WhiteSpace and LineTerminator.
+
+features: [string-trimming, String.prototype.trimEnd]
+---*/
+
+var trimEnd = String.prototype.trimEnd;
+
+// A string of all valid LineTerminator Unicode code points
+var lt = '\u000A\u000D\u2028\u2029';
+
+var str = lt + 'a' + lt + 'b' + lt;
+var expected = lt + 'a' + lt + 'b';
+
+assert.sameValue(
+  trimEnd.call(str),
+  expected,
+);
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-not-obj-coercible.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: The "this" value must be object-coercible
+info: |
+  1. Let O be ? RequireObjectCoercible(this value).
+features: [string-trimming, String.prototype.trimEnd]
+---*/
+
+var trimEnd = String.prototype.trimEnd;
+
+assert.sameValue(typeof trimEnd, 'function');
+
+assert.throws(TypeError, function() {
+  trimEnd.call(undefined);
+}, 'undefined');
+
+assert.throws(TypeError, function() {
+  trimEnd.call(null);
+}, 'null');
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-number.js
@@ -0,0 +1,50 @@
+// Copyright (c) 2017 Valerie Young.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: Behavoir when "this" value is a number.
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  2. Let S be ? ToString(str).
+
+  ToString ( argument )
+  Argument Type: Number
+  Result: NumberToString(argument)
+features: [string-trimming, String.prototype.trimEnd]
+---*/
+
+var trimEnd = String.prototype.trimEnd
+
+assert.sameValue(
+  trimEnd.call(NaN),
+  'NaN',
+  'String.prototype.trimEnd.call(NaN)'
+);
+
+assert.sameValue(
+  trimEnd.call(Infinity),
+  'Infinity',
+  'String.prototype.trimEnd.call(Infinity)'
+);
+
+assert.sameValue(
+  trimEnd.call(-0),
+  '0',
+  'String.prototype.trimEnd.call(-0)'
+);
+
+assert.sameValue(
+  trimEnd.call(1),
+  '1',
+  'String.prototype.trimEnd.call(1)'
+);
+
+assert.sameValue(
+  trimEnd.call(-1),
+  '-1',
+  'String.prototype.trimEnd.call(-1)'
+);
+
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-object-cannot-convert-to-primitive-err.js
@@ -0,0 +1,59 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: >
+  This value is an object which cannot be converted to a primitive
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+      b. If IsCallable(method) is true, then
+        i. Let result be ? Call(method, O).
+        ii. If Type(result) is not Object, return result.
+    6. Throw a TypeError exception.
+features: [string-trimming, String.prototype.trimEnd, Symbol.toPrimitive]
+---*/
+
+var thisVal = {
+  [Symbol.toPrimitive]: undefined,
+  toString: undefined,
+  valueOf: undefined,
+};
+
+// If trimEnd is called on an object with neither Symbol.toPrimitive, toString
+// nor valueOf defined, then a TypeError exception should be thrown.
+assert.throws(
+  TypeError,
+  function() { String.prototype.trimEnd.call(thisVal); },
+);
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-object-toprimitive-call-err.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: >
+  Abrupt completion when getting Symbol.toPrimitive method
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive).
+   ...
+features: [string-trimming, String.prototype.trimEnd, Symbol.toPrimitive]
+---*/
+
+var thisVal = {
+  get [Symbol.toPrimitive]() {
+    throw new Test262Error();
+  },
+};
+
+assert.throws(Test262Error, function() {
+  String.prototype.trimEnd.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-object-toprimitive-meth-err.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: >
+    Abrupt completion when Symbol.toPrimitive abrupt completes.
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive).
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+   ...
+features: [string-trimming, String.prototype.trimEnd, Symbol.toPrimitive]
+---*/
+
+var thisVal = {
+  [Symbol.toPrimitive]: function() {
+    throw new Test262Error();
+  },
+};
+
+assert.throws(Test262Error, function() {
+  String.prototype.trimEnd.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-object-toprimitive-meth-priority.js
@@ -0,0 +1,76 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: >
+  Priority of Symbol[toPrimitive] when converting object to string for trimming
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+   ...
+features: [string-trimming, String.prototype.trimEnd, Symbol.toPrimitive]
+---*/
+
+
+var toPrimitiveAccessed = 0;
+var toStringAccessed = 0;
+var valueOfAccessed = 0;
+var thisVal = {
+  get [Symbol.toPrimitive]() {
+    toPrimitiveAccessed += 1;
+    return function() { return '42 '; };
+  },
+  get toString() {
+    toStringAccessed += 1;
+    return function() { return ''; };
+  },
+  get valueOf() {
+    valueOfAccessed += 1;
+    return function() { return ''; };
+  },
+};
+
+// Test that thisVal[Symbol.toPrimitive] has been called.
+
+var result = String.prototype.trimEnd.call(thisVal);
+
+assert.sameValue(
+  toPrimitiveAccessed,
+  1,
+  'thisVal[Symbol.toPrimitive] expected to have been accessed.'
+);
+assert.sameValue(
+  result,
+  '42',
+  'thisVal[Symbol.toPrimitive] expected to have been called.',
+);
+
+// Test that thisVal.toString and thisVal.valueOf have not been accessedo
+
+assert.sameValue(
+  toStringAccessed,
+  0,
+  'thisVal.toString should not have been accessed.'
+);
+assert.sameValue(
+  valueOfAccessed,
+  0,
+  'thisVal.valueOf should not have been accessed.'
+);
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-object-toprimitive-returns-object-err.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: >
+    Abrupt completion when Symbol.toPrimitive returns an object
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If arguement is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive).
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+   ...
+features: [string-trimming, String.prototype.trimEnd, Symbol.toPrimitive]
+---*/
+
+var thisVal = {
+  [Symbol.toPrimitive]: function() {
+    return {};
+  },
+};
+
+assert.throws(TypeError, function() {
+  String.prototype.trimEnd.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-object-tostring-call-err.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: >
+  Abrupt completion when getting toString method
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+features: [string-trimming, String.prototype.trimEnd, Symbol.toPrimitive]
+---*/
+
+var thisVal = {
+  [Symbol.toPrimitive]: undefined,
+  get toString() {
+    throw new Test262Error();
+  },
+};
+
+assert.throws(Test262Error, function() {
+  String.prototype.trimEnd.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-object-tostring-meth-err.js
@@ -0,0 +1,55 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: >
+  Abrupt completion when toString called and abrupt completes.
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+      b. If IsCallable(method) is true, then
+        i. Let result be ? Call(method, O).
+features: [string-trimming, String.prototype.trimEnd, Symbol.toPrimitive]
+---*/
+
+var thisVal = {
+  [Symbol.toPrimitive]: undefined,
+  toString: function() {
+    throw new Test262Error();
+  },
+};
+
+assert.throws(Test262Error, function() {
+  String.prototype.trimEnd.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-object-tostring-meth-priority.js
@@ -0,0 +1,95 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: >
+  Priority of toString when converting object to string for trimming
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+      b. If IsCallable(method) is true, then
+        i. Let result be ? Call(method, O).
+        ii. If Type(result) is not Object, return result.
+   ...
+features: [string-trimming, String.prototype.trimEnd, Symbol.toPrimitive]
+---*/
+
+var toPrimitiveAccessed = 0;
+var toStringAccessed = 0;
+var valueOfAccessed = 0;
+var thisVal = {
+  get [Symbol.toPrimitive]() {
+    toPrimitiveAccessed +=1;
+    return undefined;
+  },
+  get toString() {
+    toStringAccessed += 1;
+    return function() { return '42 '; };
+  },
+  get valueOf() {
+    valueOfAccessed += 1;
+    return function() { return ''; };
+  },
+};
+
+// Test that toString is called when Symbol.toPrimitive is undefined.
+
+var result = String.prototype.trimEnd.call(thisVal)
+
+assert.sameValue(
+  toPrimitiveAccessed,
+  1,
+  'thisVal.toString expected to have been accessed.'
+);
+assert.sameValue(
+  result,
+  '42',
+  'thisVal.toString expected to have been called.',
+);
+
+// Test that thisVal[toPrimitive] has been accessed.
+
+assert.sameValue(
+  toPrimitiveAccessed,
+  1,
+  'thisVal[Symbol.toPrimitive should have been accessed.'
+);
+
+// Test that thisVal.valueOf has not been accessed.
+
+assert.sameValue(
+  valueOfAccessed,
+  0,
+  'thisVal.valueOf should not have been accessed.'
+);
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-object-tostring-returns-object-err.js
@@ -0,0 +1,58 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: >
+  Abrupt completion when toString called and returns an object
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+      b. If IsCallable(method) is true, then
+        i. Let result be ? Call(method, O).
+        ii. If Type(result) is not Object, return result.
+    6. Throw a TypeError exception.
+features: [string-trimming, String.prototype.trimEnd, Symbol.toPrimitive]
+---*/
+
+
+var thisVal = {
+  [Symbol.toPrimitive]: undefined,
+  toString: function() {
+    return {};
+  },
+};
+
+assert.throws(TypeError, function() {
+  String.prototype.trimEnd.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-object-valueof-call-err.js
@@ -0,0 +1,54 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: >
+  Abrupt completion when getting valueOf method
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+features: [string-trimming, String.prototype.trimEnd, Symbol.toPrimitive]
+---*/
+
+var thisVal = {
+  [Symbol.toPrimitive]: undefined,
+  toString: undefined,
+  get valueOf() {
+    throw new Test262Error();
+  },
+};
+
+assert.throws(Test262Error, function() {
+  String.prototype.trimEnd.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-object-valueof-meth-err.js
@@ -0,0 +1,56 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: >
+  Abrupt completion when valueOf called and abrupt completes.
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+      b. If IsCallable(method) is true, then
+        i. Let result be ? Call(method, O).
+features: [string-trimming, String.prototype.trimEnd, Symbol.toPrimitive]
+---*/
+
+var thisVal = {
+  [Symbol.toPrimitive]: undefined,
+  toString: undefined,
+  valueOf: function() {
+    throw new Test262Error();
+  },
+};
+
+assert.throws(Test262Error, function() {
+  String.prototype.trimEnd.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-object-valueof-meth-priority.js
@@ -0,0 +1,93 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: >
+  Priority of valueOf when converting object to string for trimming
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+      b. If IsCallable(method) is true, then
+        i. Let result be ? Call(method, O).
+        ii. If Type(result) is not Object, return result.
+   ...
+features: [string-trimming, String.prototype.trimEnd, Symbol.toPrimitive]
+---*/
+
+var toPrimitiveAccessed = 0;
+var toStringAccessed = 0;
+var valueOfAccessed = 0;
+var thisVal = {
+  get [Symbol.toPrimitive]() {
+    toPrimitiveAccessed += 1;
+    return undefined;
+  },
+  get toString() {
+    toStringAccessed += 1;
+    return undefined;
+  },
+  get valueOf() {
+    valueOfAccessed += 1;
+    return function() { return '42 '; };
+  },
+};
+
+// Test that valueOf is called when Symbol.toPrimitive and toString are both
+// undefined.
+
+var result = String.prototype.trimEnd.call(thisVal);
+
+assert.sameValue(
+  valueOfAccessed,
+  1,
+  'thisVal.toString expected to have been accessed.'
+);
+assert.sameValue(
+  result,
+  '42',
+  'thisVal.valueOf expected to have been called.',
+);
+
+// Test that thisVal[toPrimitive] and thisVal.toString has been accessed.
+
+assert.sameValue(
+  toPrimitiveAccessed,
+  1,
+  'thisVal[Symbol.toPrimitive should have been accessed.'
+);
+assert.sameValue(
+  toStringAccessed,
+  1,
+  'thisVal[Symbol.toString should have been accessed.'
+);
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-object-valueof-returns-object-err.js
@@ -0,0 +1,59 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: >
+  Abrupt completion when valueOf called and returns an object
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+      b. If IsCallable(method) is true, then
+        i. Let result be ? Call(method, O).
+        ii. If Type(result) is not Object, return result.
+    6. Throw a TypeError exception.
+features: [string-trimming, String.prototype.trimEnd, Symbol.toPrimitive]
+---*/
+
+
+var thisVal = {
+  [Symbol.toPrimitive]: undefined,
+  toString: undefined,
+  valueOf: function() {
+    return {};
+  },
+};
+
+assert.throws(TypeError, function() {
+  String.prototype.trimEnd.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-symbol-typeerror.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: Type error when "this" value is a Symbol
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  2. Let S be ? ToString(str).
+
+  ToString ( argument )
+  Argument Type: Symbol
+  Result: Throw a TypeError exception
+features: [string-trimming, String.prototype.trimEnd]
+---*/
+
+var trimEnd = String.prototype.trimEnd;
+var symbol = Symbol();
+
+assert.throws(
+  TypeError,
+  function() { trimEnd.call(symbol); },
+  'String.prototype.trimEnd.call(Symbol())'
+);
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimEnd/this-value-whitespace.js
@@ -0,0 +1,35 @@
+// Copyright (c) 2017 Valerie Young.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimEnd
+description: TrimEnd removes all whitespace from the end of a string.
+info: |
+  Runtime Symantics: TrimString ( string, where )
+  ...
+  3. Else if where is "end", let T be a String value that is a copy of S with
+     trailing white space removed.
+  ...
+
+  The definition of white space is the union of WhiteSpace and LineTerminator.
+  When determining whether a Unicode code point is in Unicode general category
+  “Zs”, code unit sequences are interpreted as UTF-16 encoded code point
+  sequences as specified in 6.1.4.
+
+features: [string-trimming, String.prototype.trimEnd]
+---*/
+
+var trimEnd = String.prototype.trimEnd;
+
+// A string of all valid WhiteSpace Unicode code points
+var wspc = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';
+
+var str = wspc + 'a' + wspc + 'b' + wspc;
+var expected = wspc + 'a' + wspc + 'b';
+
+assert.sameValue(
+  trimEnd.call(str),
+  expected,
+);
+
+reportCompare(0, 0);
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/length.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: >
+  String.prototype.trimStart.length is 0.
+info: >
+  String.prototype.trimStart ( )
+
+  17 ECMAScript Standard Built-in Objects:
+    Every built-in Function object, including constructors, has a length
+    property whose value is an integer. Unless otherwise specified, this
+    value is equal to the largest number of named arguments shown in the
+    subclause headings for the function description, including optional
+    parameters. However, rest parameters shown using the form “...name”
+    are not included in the default argument count.
+
+    Unless otherwise specified, the length property of a built-in Function
+    object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+    [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [string-trimming, String.prototype.trimStart]
+---*/
+
+verifyProperty(String.prototype.trimStart, "length", {
+  value: 0,
+  enumerable: false,
+  writable: false,
+  configurable: true,
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/name.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: >
+  String.prototype.trimStart.name is "trimStart".
+info: >
+  String.prototype.trimStart ( )
+
+  17 ECMAScript Standard Built-in Objects:
+    Every built-in Function object, including constructors, that is not
+    identified as an anonymous function has a name property whose value
+    is a String.
+
+    Unless otherwise specified, the name property of a built-in Function
+    object, if it exists, has the attributes { [[Writable]]: false,
+    [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: [string-trimming, String.prototype.trimStart]
+---*/
+
+verifyProperty(String.prototype.trimStart, "name", {
+  value: "trimStart",
+  enumerable: false,
+  writable: false,
+  configurable: true,
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/prop-desc.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2017 The Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: >
+  "trimStart" property of String.prototype
+info: >
+  17 ECMAScript Standard Built-in Objects:
+
+  Every other data property described in clauses 18 through 26 and in Annex B.2
+  has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+  [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+features: [string-trimming, String.prototype.trimStart]
+---*/
+
+verifyProperty(String.prototype, "trimStart", {
+  enumerable: false,
+  writable: true,
+  configurable: true,
+});
+
+reportCompare(0, 0);
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-boolean.js
@@ -0,0 +1,33 @@
+// Copyright (c) 2017 Valerie Young.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: Behavior when "this" value is a boolean.
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  2. Let S be ? ToString(str).
+
+  ToString ( argument )
+  Argument Type: Boolean
+  Result:
+    If argument is true, return "true".
+    If argument is false, return "false".
+features: [string-trimming, String.prototype.trimStart]
+---*/
+
+var trimStart = String.prototype.trimStart
+
+assert.sameValue(
+  trimStart.call(true),
+  'true',
+  'String.prototype.trimStart.call(true)'
+);
+
+assert.sameValue(
+  String.prototype.trimStart.call(false),
+  'false',
+  'String.prototype.trimStart.call(false)'
+);
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-line-terminator.js
@@ -0,0 +1,32 @@
+// Copyright (c) 2017 Valerie Young.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: TrimStart removes all line terminators from the start of a string.
+info: |
+  Runtime Symantics: TrimString ( string, where )
+  ...
+  4. If where is "start", let T be a String value that is a copy of S with
+     trailing white space removed.
+  ...
+
+  The definition of white space is the union of WhiteSpace and LineTerminator.
+
+features: [string-trimming, String.prototype.trimStart]
+---*/
+
+var trimStart = String.prototype.trimStart;
+
+// A string of all valid LineTerminator Unicode code points
+var lt = '\u000A\u000D\u2028\u2029';
+
+var str = lt + 'a' + lt + 'b' + lt;
+var expected = 'a' + lt + 'b' + lt;
+
+assert.sameValue(
+  trimStart.call(str),
+  expected,
+);
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-not-obj-coercible.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: The "this" value must be object-coercible
+info: |
+  1. Let O be ? RequireObjectCoercible(this value).
+features: [string-trimming, String.prototype.trimStart]
+---*/
+
+var trimStart = String.prototype.trimStart;
+
+assert.sameValue(typeof trimStart, 'function');
+
+assert.throws(TypeError, function() {
+  trimStart.call(undefined);
+}, 'undefined');
+
+assert.throws(TypeError, function() {
+  trimStart.call(null);
+}, 'null');
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-number.js
@@ -0,0 +1,50 @@
+// Copyright (c) 2017 Valerie Young.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: Behavoir when "this" value is a number.
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  2. Let S be ? ToString(str).
+
+  ToString ( argument )
+  Argument Type: Number
+  Result: NumberToString(argument)
+features: [string-trimming, String.prototype.trimStart]
+---*/
+
+var trimStart = String.prototype.trimStart
+
+assert.sameValue(
+  trimStart.call(NaN),
+  'NaN',
+  'String.prototype.trimStart.call(NaN)'
+);
+
+assert.sameValue(
+  trimStart.call(Infinity),
+  'Infinity',
+  'String.prototype.trimStart.call(Infinity)'
+);
+
+assert.sameValue(
+  trimStart.call(-0),
+  '0',
+  'String.prototype.trimStart.call(-0)'
+);
+
+assert.sameValue(
+  trimStart.call(1),
+  '1',
+  'String.prototype.trimStart.call(1)'
+);
+
+assert.sameValue(
+  trimStart.call(-1),
+  '-1',
+  'String.prototype.trimStart.call(-1)'
+);
+
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-object-cannot-convert-to-primitive-err.js
@@ -0,0 +1,59 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: >
+  This value is an object which cannot be converted to a primitive
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+      b. If IsCallable(method) is true, then
+        i. Let result be ? Call(method, O).
+        ii. If Type(result) is not Object, return result.
+    6. Throw a TypeError exception.
+features: [string-trimming, String.prototype.trimStart, Symbol.toPrimitive]
+---*/
+
+var thisVal = {
+  [Symbol.toPrimitive]: undefined,
+  toString: undefined,
+  valueOf: undefined,
+};
+
+// If trimStart is called on an object with neither Symbol.toPrimitive, toString
+// nor valueOf defined, then a TypeError exception should be thrown.
+assert.throws(
+  TypeError,
+  function() { String.prototype.trimStart.call(thisVal); },
+);
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-object-toprimitive-call-err.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: >
+  Abrupt completion when getting Symbol.toPrimitive method
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive).
+   ...
+features: [string-trimming, String.prototype.trimStart, Symbol.toPrimitive]
+---*/
+
+var thisVal = {
+  get [Symbol.toPrimitive]() {
+    throw new Test262Error();
+  },
+};
+
+assert.throws(Test262Error, function() {
+  String.prototype.trimStart.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-object-toprimitive-meth-err.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: >
+    Abrupt completion when Symbol.toPrimitive abrupt completes.
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive).
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+   ...
+features: [string-trimming, String.prototype.trimStart, Symbol.toPrimitive]
+---*/
+
+var thisVal = {
+  [Symbol.toPrimitive]: function() {
+    throw new Test262Error();
+  },
+};
+
+assert.throws(Test262Error, function() {
+  String.prototype.trimStart.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-object-toprimitive-meth-priority.js
@@ -0,0 +1,76 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: >
+  Priority of Symbol[toPrimitive] when converting object to string for trimming
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+   ...
+features: [string-trimming, String.prototype.trimStart, Symbol.toPrimitive]
+---*/
+
+
+var toPrimitiveAccessed = 0;
+var toStringAccessed = 0;
+var valueOfAccessed = 0;
+var thisVal = {
+  get [Symbol.toPrimitive]() {
+    toPrimitiveAccessed += 1;
+    return function() { return ' 42'; };
+  },
+  get toString() {
+    toStringAccessed += 1;
+    return function() { return ''; };
+  },
+  get valueOf() {
+    valueOfAccessed += 1;
+    return function() { return ''; };
+  },
+};
+
+// Test that thisVal[Symbol.toPrimitive] has been called.
+
+var result = String.prototype.trimStart.call(thisVal);
+
+assert.sameValue(
+  toPrimitiveAccessed,
+  1,
+  'thisVal[Symbol.toPrimitive] expected to have been accessed.'
+);
+assert.sameValue(
+  result,
+  '42',
+  'thisVal[Symbol.toPrimitive] expected to have been called.',
+);
+
+// Test that thisVal.toString and thisVal.valueOf have not been accessedo
+
+assert.sameValue(
+  toStringAccessed,
+  0,
+  'thisVal.toString should not have been accessed.'
+);
+assert.sameValue(
+  valueOfAccessed,
+  0,
+  'thisVal.valueOf should not have been accessed.'
+);
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-object-toprimitive-returns-object-err.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: >
+    Abrupt completion when Symbol.toPrimitive returns an object
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If arguement is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive).
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+   ...
+features: [string-trimming, String.prototype.trimStart, Symbol.toPrimitive]
+---*/
+
+var thisVal = {
+  [Symbol.toPrimitive]: function() {
+    return {};
+  },
+};
+
+assert.throws(TypeError, function() {
+  String.prototype.trimStart.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-object-tostring-call-err.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: >
+  Abrupt completion when getting toString method
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+features: [string-trimming, String.prototype.trimStart, Symbol.toPrimitive]
+---*/
+
+var thisVal = {
+  [Symbol.toPrimitive]: undefined,
+  get toString() {
+    throw new Test262Error();
+  },
+};
+
+assert.throws(Test262Error, function() {
+  String.prototype.trimStart.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-object-tostring-meth-err.js
@@ -0,0 +1,55 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: >
+  Abrupt completion when toString called and abrupt completes.
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+      b. If IsCallable(method) is true, then
+        i. Let result be ? Call(method, O).
+features: [string-trimming, String.prototype.trimStart, Symbol.toPrimitive]
+---*/
+
+var thisVal = {
+  [Symbol.toPrimitive]: undefined,
+  toString: function() {
+    throw new Test262Error();
+  },
+};
+
+assert.throws(Test262Error, function() {
+  String.prototype.trimStart.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-object-tostring-meth-priority.js
@@ -0,0 +1,95 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: >
+  Priority of toString when converting object to string for trimming
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+      b. If IsCallable(method) is true, then
+        i. Let result be ? Call(method, O).
+        ii. If Type(result) is not Object, return result.
+   ...
+features: [string-trimming, String.prototype.trimStart, Symbol.toPrimitive]
+---*/
+
+var toPrimitiveAccessed = 0;
+var toStringAccessed = 0;
+var valueOfAccessed = 0;
+var thisVal = {
+  get [Symbol.toPrimitive]() {
+    toPrimitiveAccessed +=1;
+    return undefined;
+  },
+  get toString() {
+    toStringAccessed += 1;
+    return function() { return ' 42'; };
+  },
+  get valueOf() {
+    valueOfAccessed += 1;
+    return function() { return ''; };
+  },
+};
+
+// Test that toString is called when Symbol.toPrimitive is undefined.
+
+var result = String.prototype.trimStart.call(thisVal)
+
+assert.sameValue(
+  toPrimitiveAccessed,
+  1,
+  'thisVal.toString expected to have been accessed.'
+);
+assert.sameValue(
+  result,
+  '42',
+  'thisVal.toString expected to have been called.',
+);
+
+// Test that thisVal[toPrimitive] has been accessed.
+
+assert.sameValue(
+  toPrimitiveAccessed,
+  1,
+  'thisVal[Symbol.toPrimitive should have been accessed.'
+);
+
+// Test that thisVal.valueOf has not been accessed.
+
+assert.sameValue(
+  valueOfAccessed,
+  0,
+  'thisVal.valueOf should not have been accessed.'
+);
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-object-tostring-returns-object-err.js
@@ -0,0 +1,58 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: >
+  Abrupt completion when toString called and returns an object
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+      b. If IsCallable(method) is true, then
+        i. Let result be ? Call(method, O).
+        ii. If Type(result) is not Object, return result.
+    6. Throw a TypeError exception.
+features: [string-trimming, String.prototype.trimStart, Symbol.toPrimitive]
+---*/
+
+
+var thisVal = {
+  [Symbol.toPrimitive]: undefined,
+  toString: function() {
+    return {};
+  },
+};
+
+assert.throws(TypeError, function() {
+  String.prototype.trimStart.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-object-valueof-call-err.js
@@ -0,0 +1,54 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: >
+  Abrupt completion when getting valueOf method
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+features: [string-trimming, Symbol.toPrimitive]
+---*/
+
+var thisVal = {
+  [Symbol.toPrimitive]: undefined,
+  toString: undefined,
+  get valueOf() {
+    throw new Test262Error();
+  },
+};
+
+assert.throws(Test262Error, function() {
+  String.prototype.trimStart.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-object-valueof-meth-err.js
@@ -0,0 +1,56 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: >
+  Abrupt completion when valueOf called and abrupt completes.
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+      b. If IsCallable(method) is true, then
+        i. Let result be ? Call(method, O).
+features: [string-trimming, String.prototype.trimStart, Symbol.toPrimitive]
+---*/
+
+var thisVal = {
+  [Symbol.toPrimitive]: undefined,
+  toString: undefined,
+  valueOf: function() {
+    throw new Test262Error();
+  },
+};
+
+assert.throws(Test262Error, function() {
+  String.prototype.trimStart.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-object-valueof-meth-priority.js
@@ -0,0 +1,93 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: >
+  Priority of valueOf when converting object to string for trimming
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+      b. If IsCallable(method) is true, then
+        i. Let result be ? Call(method, O).
+        ii. If Type(result) is not Object, return result.
+   ...
+features: [string-trimming, String.prototype.trimStart, Symbol.toPrimitive]
+---*/
+
+var toPrimitiveAccessed = 0;
+var toStringAccessed = 0;
+var valueOfAccessed = 0;
+var thisVal = {
+  get [Symbol.toPrimitive]() {
+    toPrimitiveAccessed += 1;
+    return undefined;
+  },
+  get toString() {
+    toStringAccessed += 1;
+    return undefined;
+  },
+  get valueOf() {
+    valueOfAccessed += 1;
+    return function() { return ' 42'; };
+  },
+};
+
+// Test that valueOf is called when Symbol.toPrimitive and toString are both
+// undefined.
+
+var result = String.prototype.trimStart.call(thisVal);
+
+assert.sameValue(
+  valueOfAccessed,
+  1,
+  'thisVal.toString expected to have been accessed.'
+);
+assert.sameValue(
+  result,
+  '42',
+  'thisVal.valueOf expected to have been called.',
+);
+
+// Test that thisVal[toPrimitive] and thisVal.toString has been accessed.
+
+assert.sameValue(
+  toPrimitiveAccessed,
+  1,
+  'thisVal[Symbol.toPrimitive should have been accessed.'
+);
+assert.sameValue(
+  toStringAccessed,
+  1,
+  'thisVal[Symbol.toString should have been accessed.'
+);
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-object-valueof-returns-object-err.js
@@ -0,0 +1,59 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: >
+  Abrupt completion when valueOf called and returns an object
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  1. Let str be ? RequireObjectCoercible(string).
+  2. Let S be ? ToString(str).
+   ...
+
+  ToString ( argument )
+  If argument is Object:
+    1. Let primValue be ? ToPrimitive(argument, hint String).
+   ...
+
+  ToPrimitive ( input [, PreferredType ])
+   ...
+    b. Else if PreferredType is hint String, let hint be "string".
+   ...
+    d. Let exoticToPrim be ? GetMethod(input, @@toPrimitive)
+    e. If exoticToPrim is not undefined, then
+      i. Let result be ? Call(exoticToPrim, input, « hint »).
+      ii. If Type(result) is not Object, return result.
+      iii. Throw a TypeError exception.
+    f. If hint is "default", set hint to "number".
+    g. Return ? OrdinaryToPrimitive(input, hint).
+   ...
+
+  OrdinaryToPrimitive( O, hint )
+   ...
+    3. If hint is "string", then
+      a. Let methodNames be « "toString", "valueOf" ».
+   ...
+    5. For each name in methodNames in List order, do
+      a. Let method be ? Get(O, name).
+      b. If IsCallable(method) is true, then
+        i. Let result be ? Call(method, O).
+        ii. If Type(result) is not Object, return result.
+    6. Throw a TypeError exception.
+features: [string-trimming, String.prototype.trimStart, Symbol.toPrimitive]
+---*/
+
+
+var thisVal = {
+  [Symbol.toPrimitive]: undefined,
+  toString: undefined,
+  valueOf: function() {
+    return {};
+  },
+};
+
+assert.throws(TypeError, function() {
+  String.prototype.trimStart.call(thisVal);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-symbol-typeerror.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2017 Valerie Young. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: Type error when "this" value is a Symbol
+info: |
+  Runtime Semantics: TrimString ( string, where )
+  2. Let S be ? ToString(str).
+
+  ToString ( argument )
+  Argument Type: Symbol
+  Result: Throw a TypeError exception
+features: [string-trimming, String.prototype.trimStart]
+---*/
+
+var trimStart = String.prototype.trimStart;
+var symbol = Symbol();
+
+assert.throws(
+  TypeError,
+  function() { trimStart.call(symbol); },
+  'String.prototype.trimStart.call(Symbol())'
+);
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/String/prototype/trimStart/this-value-whitespace.js
@@ -0,0 +1,35 @@
+// Copyright (c) 2017 Valerie Young.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-string.prototype.trimStart
+description: TrimStart removes all whitespace from the start of a string.
+info: |
+  Runtime Symantics: TrimString ( string, where )
+  ...
+  3. If where is "start", let T be a String value that is a copy of S with
+     trailing white space removed.
+  ...
+
+  The definition of white space is the union of WhiteSpace and LineTerminator.
+  When determining whether a Unicode code point is in Unicode general category
+  “Zs”, code unit sequences are interpreted as UTF-16 encoded code point
+  sequences as specified in 6.1.4.
+
+features: [string-trimming, String.prototype.trimStart]
+---*/
+
+var trimStart = String.prototype.trimStart;
+
+// A string of all valid WhiteSpace Unicode code points
+var wspc = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';
+
+var str = wspc + 'a' + wspc + 'b' + wspc;
+var expected = 'a' + wspc + 'b' + wspc;
+
+assert.sameValue(
+  trimStart.call(str),
+  expected,
+);
+
+reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/StringIteratorPrototype/next/next-missing-internal-slots.js
+++ b/js/src/tests/test262/built-ins/StringIteratorPrototype/next/next-missing-internal-slots.js
@@ -1,15 +1,21 @@
 // Copyright (C) 2014 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
-es6id: 21.1.5.2.1 S 3
+esid: sec-properties-of-string-iterator-instances
 description: >
     If the `this` value does not have all of the internal slots of an String
     Iterator Instance (21.1.5.3), throw a `TypeError` exception.
+info: |
+  ...
+  If O does not have all of the internal slots of a String Iterator Instance (21.1.5.3),
+  throw a TypeError exception.
+  ...
+
 features: [Symbol.iterator]
 ---*/
 
 var iterator = ''[Symbol.iterator]();
 var object = Object.create(iterator);
 
 assert.throws(TypeError, function() {
   object.next();
--- a/js/src/tests/test262/built-ins/Symbol/species/builtin-getter-name.js
+++ b/js/src/tests/test262/built-ins/Symbol/species/builtin-getter-name.js
@@ -2,18 +2,16 @@
 // See LICENSE for details.
 
 /*---
 info: |
  ES6 spec 'get [Symbol.species]'
 es6id: 21.2.4.2, 22.1.2.5, 22.2.2.4, 23.1.2.2, 23.2.2.2
 author: Sam Mikes
 description: Symbol.species getters have defined names
-includes: 
-  - propertyHelper.js
 features: [Symbol.species]
 ---*/
 
 function getGetterName(obj, name) {
     var getter = Object.getOwnPropertyDescriptor(obj, Symbol.species).get;
     return getter && getter.name;
 }
 
--- a/js/src/tests/test262/built-ins/Symbol/species/subclassing.js
+++ b/js/src/tests/test262/built-ins/Symbol/species/subclassing.js
@@ -1,18 +1,16 @@
 // Copyright 2015 Cubane Canada, Inc.  All rights reserved.
 // See LICENSE for details.
 
 /*---
 info: |
  Symbol.species is retained on subclassing
 author: Sam Mikes
 description: Symbol.species is retained on subclassing
-includes:
-  - propertyHelper.js
 features: [Symbol.species]
 ---*/
 
 class MyRegExp extends RegExp {
 };
 
 assert.sameValue(MyRegExp[Symbol.species], MyRegExp);
 
--- a/js/src/tests/test262/built-ins/TypedArrays/internals/Get/indexed-value-sab.js
+++ b/js/src/tests/test262/built-ins/TypedArrays/internals/Get/indexed-value-sab.js
@@ -1,17 +1,18 @@
+// |reftest| skip-if(!this.hasOwnProperty('SharedArrayBuffer')) -- SharedArrayBuffer is not enabled unconditionally
 // Copyright (C) 2016 the V8 project authors. All rights reserved.
 // Copyright (C) 2017 Mozilla Corporation. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 esid: sec-integer-indexed-exotic-objects-get-p-receiver
 description: >
   Return value from valid numeric index, with SharedArrayBuffer
 includes: [testTypedArray.js]
-features: [TypedArray]
+features: [TypedArray, SharedArrayBuffer]
 ---*/
 
 var proto = TypedArray.prototype;
 var throwDesc = {
   get: function() {
     throw new Test262Error("OrdinaryGet was called! Ref: 9.1.8.1 3.c");
   }
 };
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/TypedArrays/typedarray-arg-detached-when-species-retrieved-different-type.js
@@ -0,0 +1,63 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-typedarray-typedarray
+description: >
+    When a TypedArray is created from another TypedArray with a different element-type
+    and SpeciesConstructor detaches the source buffer, AllocateArrayBuffer is still
+    executed.
+info: |
+    22.2.4.3 TypedArray ( typedArray )
+
+    ...
+    16. If IsSharedArrayBuffer(srcData) is false, then
+        a. Let bufferConstructor be ? SpeciesConstructor(srcData, %ArrayBuffer%).
+    ...
+    18. If SameValue(elementType, srcType) is true, then
+        ...
+    19. Else,
+        a. Let data be ? AllocateArrayBuffer(bufferConstructor, byteLength).
+        b. If IsDetachedBuffer(srcData) is true, throw a TypeError exception.
+    ...
+
+    24.1.1.1 AllocateArrayBuffer ( constructor, byteLength )
+
+    1. Let obj be ? OrdinaryCreateFromConstructor(constructor, "%ArrayBufferPrototype%",
+       « [[ArrayBufferData]], [[ArrayBufferByteLength]] »).
+    ...
+includes: [testTypedArray.js, detachArrayBuffer.js]
+features: [TypedArray, Symbol.species]
+---*/
+
+testWithTypedArrayConstructors(function(TA) {
+    var speciesCallCount = 0;
+    var bufferConstructor = Object.defineProperty({}, Symbol.species, {
+        get: function() {
+            speciesCallCount += 1;
+            $DETACHBUFFER(ta.buffer);
+            return speciesConstructor;
+        }
+    });
+
+    var prototypeCallCount = 0;
+    var speciesConstructor = Object.defineProperty(function(){}.bind(), "prototype", {
+        get: function() {
+            prototypeCallCount += 1;
+            return null;
+        }
+    });
+
+    var ta = new TA(0);
+    ta.buffer.constructor = bufferConstructor;
+
+    assert.throws(TypeError, function() {
+        var targetType = TA !== Int32Array ? Int32Array : Uint32Array;
+        new targetType(ta);
+    }, "TypeError thrown for detached source buffer");
+
+    assert.sameValue(speciesCallCount, 1, "@@species getter called once");
+    assert.sameValue(prototypeCallCount, 1, "prototype getter called once");
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/built-ins/TypedArrays/typedarray-arg-detached-when-species-retrieved-same-type.js
@@ -0,0 +1,66 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-typedarray-typedarray
+description: >
+    When a TypedArray is created from another TypedArray with the same element-type
+    and SpeciesConstructor detaches the source buffer, AllocateArrayBuffer is still
+    executed.
+info: |
+    22.2.4.3 TypedArray ( typedArray )
+
+    ...
+    16. If IsSharedArrayBuffer(srcData) is false, then
+        a. Let bufferConstructor be ? SpeciesConstructor(srcData, %ArrayBuffer%).
+    ...
+    18. If SameValue(elementType, srcType) is true, then
+        a. Let data be ? CloneArrayBuffer(srcData, srcByteOffset, byteLength, bufferConstructor).
+    ...
+
+    24.1.1.4 CloneArrayBuffer ( srcBuffer, srcByteOffset, srcLength, cloneConstructor )
+
+    ...
+    3. Let targetBuffer be ? AllocateArrayBuffer(cloneConstructor, srcLength).
+    4. If IsDetachedBuffer(srcBuffer) is true, throw a TypeError exception.
+    ...
+
+    24.1.1.1 AllocateArrayBuffer ( constructor, byteLength )
+
+    1. Let obj be ? OrdinaryCreateFromConstructor(constructor, "%ArrayBufferPrototype%",
+       « [[ArrayBufferData]], [[ArrayBufferByteLength]] »).
+    ...
+includes: [testTypedArray.js, detachArrayBuffer.js]
+features: [TypedArray, Symbol.species]
+---*/
+
+testWithTypedArrayConstructors(function(TA) {
+    var speciesCallCount = 0;
+    var bufferConstructor = Object.defineProperty({}, Symbol.species, {
+        get: function() {
+            speciesCallCount += 1;
+            $DETACHBUFFER(ta.buffer);
+            return speciesConstructor;
+        }
+    });
+
+    var prototypeCallCount = 0;
+    var speciesConstructor = Object.defineProperty(function(){}.bind(), "prototype", {
+        get: function() {
+            prototypeCallCount += 1;
+            return null;
+        }
+    });
+
+    var ta = new TA(0);
+    ta.buffer.constructor = bufferConstructor;
+
+    assert.throws(TypeError, function() {
+        new TA(ta);
+    }, "TypeError thrown for detached source buffer");
+
+    assert.sameValue(speciesCallCount, 1, "@@species getter called once");
+    assert.sameValue(prototypeCallCount, 1, "prototype getter called once");
+});
+
+reportCompare(0, 0);
--- a/js/src/tests/test262/built-ins/global/global-object.js
+++ b/js/src/tests/test262/built-ins/global/global-object.js
@@ -1,16 +1,15 @@
 // Copyright (C) 2016 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
 esid: sec-other-properties-of-the-global-object-global
 description: "'global' should be the global object"
 author: Jordan Harband
-includes: [propertyHelper.js]
 ---*/
 
 assert.sameValue(this, global);
 assert.sameValue(global.global, global);
 
 assert.sameValue(Array, global.Array);
 assert.sameValue(Boolean, global.Boolean);
 assert.sameValue(Date, global.Date);
--- a/js/src/tests/test262/harness/shell.js
+++ b/js/src/tests/test262/harness/shell.js
@@ -513,16 +513,19 @@ var date_1899_end = -2208988800001;
 var date_1900_start = -2208988800000;
 var date_1969_end = -1;
 var date_1970_start = 0;
 var date_1999_end = 946684799999;
 var date_2000_start = 946684800000;
 var date_2099_end = 4102444799999;
 var date_2100_start = 4102444800000;
 
+var start_of_time = -8.64e15;
+var end_of_time = 8.64e15;
+
 // file: decimalToHexString.js
 // Copyright (C) 2017 André Bargull. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 description: |
     Collection of functions used to assert the correctness of various encoding operations.
 ---*/
 
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/date-constructor-not-called.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimepattern
+description: |
+  The Date constructor is not called to convert the input value.
+info: >
+  12.1.5 DateTime Format Functions
+
+  ...
+  3. If date is not provided or is undefined, then
+    ...
+  4. Else,
+    a. Let x be ? ToNumber(date).
+  5. Return FormatDateTime(dtf, x).
+
+  12.1.6 PartitionDateTimePattern ( dateTimeFormat, x )
+
+  1. Let x be TimeClip(x).
+  2. If x is NaN, throw a RangeError exception.
+  3. ...
+---*/
+
+var dtf = new Intl.DateTimeFormat();
+
+var dateTimeString = "2017-11-10T14:09:00.000Z";
+
+// |dateTimeString| is valid ISO-8601 style date/time string.
+assert.notSameValue(new Date(dateTimeString), NaN);
+
+// Ensure string input values are not converted to time values by calling the
+// Date constructor.
+assert.throws(RangeError, function() {
+    dtf.format(dateTimeString);
+});
+
+reportCompare(0, 0);
--- a/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/shell.js
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/shell.js
@@ -1,8 +1,28 @@
+// file: dateConstants.js
+// Copyright (C) 2009 the Sputnik authors.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+    Collection of date-centric values
+---*/
+
+var date_1899_end = -2208988800001;
+var date_1900_start = -2208988800000;
+var date_1969_end = -1;
+var date_1970_start = 0;
+var date_1999_end = 946684799999;
+var date_2000_start = 946684800000;
+var date_2099_end = 4102444799999;
+var date_2100_start = 4102444800000;
+
+var start_of_time = -8.64e15;
+var end_of_time = 8.64e15;
+
 // file: isConstructor.js
 // Copyright (C) 2017 André Bargull. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
 description: |
     Test if a given function is a constructor function.
 ---*/
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/time-clip-near-time-boundaries.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimepattern
+description: |
+  TimeClip is applied when calling Intl.DateTimeFormat.prototype.format.
+info: >
+  12.1.6 PartitionDateTimePattern ( dateTimeFormat, x )
+
+  1. Let x be TimeClip(x).
+  2. If x is NaN, throw a RangeError exception.
+  3. ...
+
+  20.3.1.15 TimeClip ( time )
+  ...
+  2. If abs(time) > 8.64 × 10^15, return NaN.
+  ...
+
+includes: [dateConstants.js]
+---*/
+
+var dtf = new Intl.DateTimeFormat();
+
+// Test values near the start of the ECMAScript time range.
+assert.throws(RangeError, function() {
+    dtf.format(start_of_time - 1);
+});
+assert.sameValue(typeof dtf.format(start_of_time), "string");
+assert.sameValue(typeof dtf.format(start_of_time + 1), "string");
+
+// Test values near the end of the ECMAScript time range.
+assert.sameValue(typeof dtf.format(end_of_time - 1), "string");
+assert.sameValue(typeof dtf.format(end_of_time), "string");
+assert.throws(RangeError, function() {
+    dtf.format(end_of_time + 1);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/format/time-clip-to-integer.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimepattern
+description: |
+  TimeClip applies ToInteger on its input value.
+info: >
+  12.1.6 PartitionDateTimePattern ( dateTimeFormat, x )
+
+  1. Let x be TimeClip(x).
+  2. ...
+
+  20.3.1.15 TimeClip ( time )
+  ...
+  3. Let clippedTime be ! ToInteger(time).
+  4. If clippedTime is -0, set clippedTime to +0.
+  5. Return clippedTime.
+---*/
+
+// Switch to a time format instead of using DateTimeFormat's default date-only format.
+var dtf = new Intl.DateTimeFormat(undefined, {
+    hour: "numeric", minute: "numeric", second: "numeric"
+});
+
+var expected = dtf.format(0);
+
+assert.sameValue(dtf.format(-0.9), expected, "format(-0.9)");
+assert.sameValue(dtf.format(-0.5), expected, "format(-0.5)");
+assert.sameValue(dtf.format(-0.1), expected, "format(-0.1)");
+assert.sameValue(dtf.format(-Number.MIN_VALUE), expected, "format(-Number.MIN_VALUE)");
+assert.sameValue(dtf.format(-0), expected, "format(-0)");
+assert.sameValue(dtf.format(+0), expected, "format(+0)");
+assert.sameValue(dtf.format(Number.MIN_VALUE), expected, "format(Number.MIN_VALUE)");
+assert.sameValue(dtf.format(0.1), expected, "format(0.1)");
+assert.sameValue(dtf.format(0.5), expected, "format(0.5)");
+assert.sameValue(dtf.format(0.9), expected, "format(0.9)");
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/date-constructor-not-called.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimepattern
+description: |
+  The Date constructor is not called to convert the input value.
+info: >
+  12.4.4 Intl.DateTimeFormat.prototype.formatToParts ( date )
+
+  ...
+  4. If date is undefined, then
+    ...
+  5. Else,
+    a. Let x be ? ToNumber(date).
+  5. Return ? FormatDateTimeToParts(dtf, x).
+
+  12.1.6 PartitionDateTimePattern ( dateTimeFormat, x )
+
+  1. Let x be TimeClip(x).
+  2. If x is NaN, throw a RangeError exception.
+  3. ...
+---*/
+
+var dtf = new Intl.DateTimeFormat();
+
+var dateTimeString = "2017-11-10T14:09:00.000Z";
+
+// |dateTimeString| is valid ISO-8601 style date/time string.
+assert.notSameValue(new Date(dateTimeString), NaN);
+
+// Ensure string input values are not converted to time values by calling the
+// Date constructor.
+assert.throws(RangeError, function() {
+    dtf.formatToParts(dateTimeString);
+});
+
+reportCompare(0, 0);
--- a/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/shell.js
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/shell.js
@@ -0,0 +1,19 @@
+// file: dateConstants.js
+// Copyright (C) 2009 the Sputnik authors.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+    Collection of date-centric values
+---*/
+
+var date_1899_end = -2208988800001;
+var date_1900_start = -2208988800000;
+var date_1969_end = -1;
+var date_1970_start = 0;
+var date_1999_end = 946684799999;
+var date_2000_start = 946684800000;
+var date_2099_end = 4102444799999;
+var date_2100_start = 4102444800000;
+
+var start_of_time = -8.64e15;
+var end_of_time = 8.64e15;
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/time-clip-near-time-boundaries.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimepattern
+description: |
+  TimeClip is applied when calling Intl.DateTimeFormat.prototype.formatToParts.
+info: >
+  12.1.6 PartitionDateTimePattern ( dateTimeFormat, x )
+
+  1. Let x be TimeClip(x).
+  2. If x is NaN, throw a RangeError exception.
+  3. ...
+
+  20.3.1.15 TimeClip ( time )
+  ...
+  2. If abs(time) > 8.64 × 10^15, return NaN.
+  ...
+
+includes: [dateConstants.js]
+---*/
+
+var dtf = new Intl.DateTimeFormat();
+
+// Test values near the start of the ECMAScript time range.
+assert.throws(RangeError, function() {
+    dtf.formatToParts(start_of_time - 1);
+});
+assert.sameValue(typeof dtf.formatToParts(start_of_time), "object");
+assert.sameValue(typeof dtf.formatToParts(start_of_time + 1), "object");
+
+// Test values near the end of the ECMAScript time range.
+assert.sameValue(typeof dtf.formatToParts(end_of_time - 1), "object");
+assert.sameValue(typeof dtf.formatToParts(end_of_time), "object");
+assert.throws(RangeError, function() {
+    dtf.formatToParts(end_of_time + 1);
+});
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/formatToParts/time-clip-to-integer.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-partitiondatetimepattern
+description: |
+  TimeClip applies ToInteger on its input value.
+info: >
+  12.1.6 PartitionDateTimePattern ( dateTimeFormat, x )
+
+  1. Let x be TimeClip(x).
+  2. ...
+
+  20.3.1.15 TimeClip ( time )
+  ...
+  3. Let clippedTime be ! ToInteger(time).
+  4. If clippedTime is -0, set clippedTime to +0.
+  5. Return clippedTime.
+---*/
+
+// Switch to a time format instead of using DateTimeFormat's default date-only format.
+var dtf = new Intl.DateTimeFormat(undefined, {
+    hour: "numeric", minute: "numeric", second: "numeric"
+});
+
+function formatAsString(dtf, time) {
+    return dtf.formatToParts(time).map(part => part.value).join("");
+}
+
+var expected = formatAsString(dtf, 0);
+
+assert.sameValue(formatAsString(dtf, -0.9), expected, "formatToParts(-0.9)");
+assert.sameValue(formatAsString(dtf, -0.5), expected, "formatToParts(-0.5)");
+assert.sameValue(formatAsString(dtf, -0.1), expected, "formatToParts(-0.1)");
+assert.sameValue(formatAsString(dtf, -Number.MIN_VALUE), expected, "formatToParts(-Number.MIN_VALUE)");
+assert.sameValue(formatAsString(dtf, -0), expected, "formatToParts(-0)");
+assert.sameValue(formatAsString(dtf, +0), expected, "formatToParts(+0)");
+assert.sameValue(formatAsString(dtf, Number.MIN_VALUE), expected, "formatToParts(Number.MIN_VALUE)");
+assert.sameValue(formatAsString(dtf, 0.1), expected, "formatToParts(0.1)");
+assert.sameValue(formatAsString(dtf, 0.5), expected, "formatToParts(0.5)");
+assert.sameValue(formatAsString(dtf, 0.9), expected, "formatToParts(0.9)");
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/intl402/DateTimeFormat/prototype/resolvedOptions/resolved-locale-with-hc-unicode.js
@@ -0,0 +1,89 @@
+// Copyright 2018 André Bargull. All rights reserved.
+// This code is governed by the license found in the LICENSE file.
+
+/*---
+esid: sec-Intl.DateTimeFormat.prototype.resolvedOptions
+description: >
+  The resolved locale doesn't include a hc Unicode extension value if the
+  hour12 or hourCycle option is also present.
+info: |
+  12.1.1 InitializeDateTimeFormat(dateTimeFormat, locales, options)
+    ...
+    6. Let hour12 be ? GetOption(options, "hour12", "boolean", undefined, undefined).
+    7. Let hourCycle be ? GetOption(options, "hourCycle", "string", « "h11", "h12", "h23", "h24" », undefined).
+    8. If hour12 is not undefined, then
+      a. Let hourCycle be null.
+    9. Set opt.[[hc]] to hourCycle.
+    ...
+
+  9.2.6 ResolveLocale(availableLocales, requestedLocales, options, relevantExtensionKeys, localeData)
+    ...
+    8. For each element key of relevantExtensionKeys in List order, do
+      ...
+      i. If options has a field [[<key>]], then
+        i. Let optionsValue be options.[[<key>]].
+        ii. Assert: Type(optionsValue) is either String, Undefined, or Null.
+        iii. If keyLocaleData contains optionsValue, then
+          1. If SameValue(optionsValue, value) is false, then
+            a. Let value be optionsValue.
+            b. Let supportedExtensionAddition be "".
+      ...
+---*/
+
+var defaultLocale = new Intl.DateTimeFormat().resolvedOptions().locale;
+var defaultLocaleWithHourCycle = defaultLocale + "-u-hc-h11";
+
+function assertLocale(locale, expectedLocale, options, message) {
+  var resolved = new Intl.DateTimeFormat(locale, {
+    hour: "2-digit",
+    hour12: options.hour12,
+    hourCycle: options.hourCycle,
+  }).resolvedOptions();
+  assert.sameValue(resolved.locale, expectedLocale, message + " (With hour option.)");
+
+  // Also test the case when no hour option is present at all.
+  // The resolved options don't include hour12 and hourCycle if the date-time
+  // formatter doesn't include an hour option. This restriction doesn't apply
+  // to the hc Unicode extension value.
+  resolved = new Intl.DateTimeFormat(locale, {
+    hour12: options.hour12,
+    hourCycle: options.hourCycle,
+  }).resolvedOptions();
+  assert.sameValue(resolved.locale, expectedLocale, message + " (Without hour option.)");
+}
+
+assertLocale(defaultLocaleWithHourCycle, defaultLocale, {
+  hour12: false,
+  hourCycle: "h23",
+}, "hour12 and hourCycle options and hc Unicode extension value are present.");
+
+assertLocale(defaultLocaleWithHourCycle, defaultLocale, {
+  hour12: false,
+}, "hour12 option and hc Unicode extension value are present.");
+
+assertLocale(defaultLocaleWithHourCycle, defaultLocale, {
+  hourCycle: "h23",
+}, "hourCycle option and hc Unicode extension value are present.");
+
+assertLocale(defaultLocaleWithHourCycle, defaultLocaleWithHourCycle, {
+}, "Only hc Unicode extension value is present.");
+
+// And make sure the hc Unicode extension doesn't get added if it's not present
+// in the requested locale.
+assertLocale(defaultLocale, defaultLocale, {
+  hour12: false,
+  hourCycle: "h23",
+}, "hour12 and hourCycle options are present, but no hc Unicode extension value.");
+
+assertLocale(defaultLocale, defaultLocale, {
+  hour12: false,
+}, "hourCycle option is present, but no hc Unicode extension value.");
+
+assertLocale(defaultLocale, defaultLocale, {
+  hourCycle: "h23",
+}, "hourCycle option is present, but no hc Unicode extension value.");
+
+assertLocale(defaultLocale, defaultLocale, {
+}, "No options are present and no hc Unicode extension value.");
+
+reportCompare(0, 0);
--- a/js/src/tests/test262/intl402/NumberFormat/prototype/formatToParts/default-parameter.js
+++ b/js/src/tests/test262/intl402/NumberFormat/prototype/formatToParts/default-parameter.js
@@ -1,12 +1,12 @@
 // Copyright (C) 2017 Josh Wolfe. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
-esid: #sec-intl.numberformat.prototype.formattoparts
+esid: sec-intl.numberformat.prototype.formattoparts
 description: Intl.NumberFormat.prototype.formatToParts called with no parameters
 info: |
   Intl.NumberFormat.prototype.formatToParts ([ value ])
 
   3. If value is not provided, let value be undefined.
 ---*/
 
 var nf = new Intl.NumberFormat();
--- a/js/src/tests/test262/language/asi/S7.9.2_A1_T1.js
+++ b/js/src/tests/test262/language/asi/S7.9.2_A1_T1.js
@@ -1,14 +1,14 @@
 // |reftest| error:SyntaxError
 // Copyright 2009 the Sputnik authors.  All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
-info: Check examples for automatic semicolon insertion from the Standart
+info: Check examples for automatic semicolon insertion from the standard
 es5id: 7.9.2_A1_T1
 description: "{ 1 2 } 3 is not a valid sentence in the ECMAScript grammar"
 negative:
   phase: parse
   type: SyntaxError
 ---*/
 
 throw "Test262: This statement should not be evaluated.";
--- a/js/src/tests/test262/language/asi/S7.9.2_A1_T2.js
+++ b/js/src/tests/test262/language/asi/S7.9.2_A1_T2.js
@@ -1,13 +1,13 @@
 // Copyright 2009 the Sputnik authors.  All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
-info: Check examples for automatic semicolon insertion from the Standart
+info: Check examples for automatic semicolon insertion from the standard
 es5id: 7.9.2_A1_T2
 description: >
     { 1 \n 2 } 3 is a valid sentence in the ECMAScript grammar with
     automatic semicolon insertion
 ---*/
 
 //CHECK#1
 { 1
--- a/js/src/tests/test262/language/asi/S7.9.2_A1_T3.js
+++ b/js/src/tests/test262/language/asi/S7.9.2_A1_T3.js
@@ -1,14 +1,14 @@
 // |reftest| error:SyntaxError
 // Copyright 2009 the Sputnik authors.  All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
-info: Check examples for automatic semicolon insertion from the Standart
+info: Check examples for automatic semicolon insertion from the standard
 es5id: 7.9.2_A1_T3
 description: for( a ; b \n ) is not a valid sentence in the ECMAScript grammar
 negative:
   phase: parse
   type: SyntaxError
 ---*/
 
 throw "Test262: This statement should not be evaluated.";
--- a/js/src/tests/test262/language/asi/S7.9.2_A1_T4.js
+++ b/js/src/tests/test262/language/asi/S7.9.2_A1_T4.js
@@ -1,13 +1,13 @@
 // Copyright 2009 the Sputnik authors.  All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
-info: Check examples for automatic semicolon insertion from the Standart
+info: Check examples for automatic semicolon insertion from the standard
 es5id: 7.9.2_A1_T4
 description: >
     return \n a+b is a valid sentence in the ECMAScript grammar  with
     automatic semicolon insertion, but returned undefined
 ---*/
 
 //CHECK#1
 var a=1,b=2;
--- a/js/src/tests/test262/language/asi/S7.9.2_A1_T5.js
+++ b/js/src/tests/test262/language/asi/S7.9.2_A1_T5.js
@@ -1,13 +1,13 @@
 // Copyright 2009 the Sputnik authors.  All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
-info: Check examples for automatic semicolon insertion from the Standart
+info: Check examples for automatic semicolon insertion from the standard
 es5id: 7.9.2_A1_T5
 description: >
     a=b \n ++c is a valid sentence in the ECMAScript grammar  with
     automatic semicolon insertion, but a!==b++c
 ---*/
 
 //CHECK#1
 var a=1,b=2,c=3;
--- a/js/src/tests/test262/language/asi/S7.9.2_A1_T6.js
+++ b/js/src/tests/test262/language/asi/S7.9.2_A1_T6.js
@@ -1,14 +1,14 @@
 // |reftest| error:SyntaxError
 // Copyright 2009 the Sputnik authors.  All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
-info: Check examples for automatic semicolon insertion from the Standart
+info: Check examples for automatic semicolon insertion from the standard
 es5id: 7.9.2_A1_T6
 description: >
     if(a>b) \n else c=d is not a valid sentence in the ECMAScript
     grammar
 negative:
   phase: parse
   type: SyntaxError
 ---*/
--- a/js/src/tests/test262/language/asi/S7.9.2_A1_T7.js
+++ b/js/src/tests/test262/language/asi/S7.9.2_A1_T7.js
@@ -1,13 +1,13 @@
 // Copyright 2009 the Sputnik authors.  All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
-info: Check examples for automatic semicolon insertion from the Standart
+info: Check examples for automatic semicolon insertion from the standard
 es5id: 7.9.2_A1_T7
 description: >
     a=b+c \n (d+e).print() is a valid sentence in the ECMAScript
     grammar,  and automatic semicolon insertion not run
 ---*/
 
 //CHECK#1
 function c (a){
--- a/js/src/tests/test262/language/comments/multi-line-html-close-extra.js
+++ b/js/src/tests/test262/language/comments/multi-line-html-close-extra.js
@@ -1,14 +1,13 @@
 // |reftest| error:SyntaxError
 // Copyright (C) 2016 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 esid: sec-html-like-comments
-esid: sec-html-like-comments
 description: >
     Arbitrary character sequence not permitted before HTMLCloseComment token
 info: |
     Comment ::
       MultiLineComment
       SingleLineComment
       SingleLineHTMLOpenComment
       SingleLineHTMLCloseComment
--- a/js/src/tests/test262/language/comments/single-line-html-close-without-lt.js
+++ b/js/src/tests/test262/language/comments/single-line-html-close-without-lt.js
@@ -1,14 +1,13 @@
 // |reftest| error:SyntaxError
 // Copyright (C) 2016 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 esid: sec-html-like-comments
-esid: sec-html-like-comments
 description: An HTMLCloseComment must be preceeded by a LineTerminator
 info: |
     Comment ::
       MultiLineComment
       SingleLineComment
       SingleLineHTMLOpenComment
       SingleLineHTMLCloseComment
       SingleLineDelimitedComment
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/addition/bigint-and-number.js
@@ -0,0 +1,36 @@
+// |reftest| skip -- BigInt is not supported
+// Copyright (C) 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-addition-operator-plus-runtime-semantics-evaluation
+description: Mixing BigInt and Number produces a TypeError for addition operator
+features: [BigInt]
+info: |
+  Let lprim be ? ToPrimitive(lval).
+  Let rprim be ? ToPrimitive(rval).
+  ...
+  Let lnum be ? ToNumeric(lprim)
+  Let rnum be ? ToNumeric(rprim)
+  If Type(lnum) does not equal Type(rnum), throw a TypeError exception.
+---*/
+
+assert.throws(TypeError, function() { 1n + 1; }, "1n + 1 throws TypeError");
+assert.throws(TypeError, function() { 1 + 1n; }, "1 + 1n throws TypeError");
+assert.throws(TypeError, function() { Object(1n) + 1; }, "Object(1n) + 1 throws TypeError");
+assert.throws(TypeError, function() { 1 + Object(1n); }, "1 + Object(1n) throws TypeError");
+assert.throws(TypeError, function() { 1n + Object(1); }, "1n + Object(1) throws TypeError");
+assert.throws(TypeError, function() { Object(1) + 1n; }, "Object(1) + 1n throws TypeError");
+assert.throws(TypeError, function() { Object(1n) + Object(1); }, "Object(1n) + Object(1) throws TypeError");
+assert.throws(TypeError, function() { Object(1) + Object(1n); }, "Object(1) + Object(1n) throws TypeError");
+assert.throws(TypeError, function() { 1n + NaN; }, "1n + NaN throws TypeError");
+assert.throws(TypeError, function() { NaN + 1n; }, "NaN + 1n throws TypeError");
+assert.throws(TypeError, function() { 1n + Infinity; }, "1n + Infinity throws TypeError");
+assert.throws(TypeError, function() { Infinity + 1n; }, "Infinity + 1n throws TypeError");
+assert.throws(TypeError, function() { 1n + true; }, "1n + true throws TypeError");
+assert.throws(TypeError, function() { true + 1n; }, "true + 1n throws TypeError");
+assert.throws(TypeError, function() { 1n + null; }, "1n + null throws TypeError");
+assert.throws(TypeError, function() { null + 1n; }, "null + 1n throws TypeError");
+assert.throws(TypeError, function() { 1n + undefined; }, "1n + undefined throws TypeError");
+assert.throws(TypeError, function() { undefined + 1n; }, "undefined + 1n throws TypeError");
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/addition/order-of-evaluation.js
@@ -0,0 +1,142 @@
+// Copyright (C) 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-addition-operator-plus-runtime-semantics-evaluation
+description: Type coercion order of operations for addition operator
+features: [Symbol]
+info: |
+  Evaluate lhs
+  Evaluate rhs
+  ToPrimitive(lhs)
+  ToPrimitive(rhs)
+  ToNumeric(lhs)
+  ToNumeric(rhs)
+---*/
+
+function MyError() {}
+var trace;
+
+// ?GetValue(lhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    throw new MyError();
+  })() + (function() {
+    trace += "2";
+    throw new Test262Error("should not be evaluated");
+  })();
+}, "?GetValue(lhs) throws.");
+assert.sameValue(trace, "1", "?GetValue(lhs) throws.");
+
+// ?GetValue(rhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        throw new Test262Error("should not be evaluated");
+      }
+    };
+  })() + (function() {
+    trace += "2";
+    throw new MyError();
+  })();
+}, "?GetValue(rhs) throws.");
+assert.sameValue(trace, "12", "?GetValue(rhs) throws.");
+
+// ?ToPrimive(lhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        throw new MyError();
+      }
+    };
+  })() + (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        throw new Test262Error("should not be evaluated");
+      }
+    };
+  })();
+}, "?ToPrimive(lhs) throws.");
+assert.sameValue(trace, "123", "?ToPrimive(lhs) throws.");
+
+// ?ToPrimive(rhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        return 1;
+      }
+    };
+  })() + (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        throw new MyError();
+      }
+    };
+  })();
+}, "?ToPrimive(rhs) throws.");
+assert.sameValue(trace, "1234", "?ToPrimive(rhs) throws.");
+
+// ?ToPrimive(rhs) is called before ?ToNumeric(lhs).
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        return Symbol("1");
+      }
+    };
+  })() + (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        throw new MyError();
+      }
+    };
+  })();
+}, "?ToPrimive(rhs) is called before ?ToNumeric(lhs).");
+assert.sameValue(trace, "1234", "?ToPrimive(rhs) is called before ?ToNumeric(lhs).");
+
+// GetValue(lhs) throws.
+trace = "";
+assert.throws(TypeError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        return 1;
+      }
+    };
+  })() + (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        return Symbol("1");
+      }
+    };
+  })();
+}, "GetValue(lhs) throws.");
+assert.sameValue(trace, "1234", "GetValue(lhs) throws.");
+
+reportCompare(0, 0);
--- a/js/src/tests/test262/language/expressions/assignment/id-arguments-strict-strict.js
+++ b/js/src/tests/test262/language/expressions/assignment/id-arguments-strict-strict.js
@@ -3,16 +3,16 @@
 // Copyright (c) 2012 Ecma International.  All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 es5id: 11.13.1-4-30-s
 description: >
   Strict Mode - SyntaxError is thrown if the identifier 'arguments' appears as
   the LeftHandSideExpression (PrimaryExpression) of simple assignment(=).
 negative:
-  phase: early
+  phase: parse
   type: SyntaxError
 flags: [onlyStrict]
 ---*/
 
 throw "Test262: This statement should not be evaluated.";
 
 (arguments) = 20;
--- a/js/src/tests/test262/language/expressions/assignment/id-eval-strict-strict.js
+++ b/js/src/tests/test262/language/expressions/assignment/id-eval-strict-strict.js
@@ -3,16 +3,16 @@
 // Copyright (c) 2012 Ecma International.  All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
 es5id: 11.13.1-4-30-s
 description: >
   Strict Mode - SyntaxError is thrown if the identifier 'eval' appears as the
   LeftHandSideExpression (PrimaryExpression) of simple assignment(=).
 negative:
-  phase: early
+  phase: parse
   type: SyntaxError
 flags: [onlyStrict]
 ---*/
 
 throw "Test262: This statement should not be evaluated.";
 
 (eval) = 20;
--- a/js/src/tests/test262/language/expressions/async-generator/early-errors-expression-formals-contains-await.js
+++ b/js/src/tests/test262/language/expressions/async-generator/early-errors-expression-formals-contains-await.js
@@ -1,15 +1,15 @@
 // |reftest| error:SyntaxError
 // Copyright 2017 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
 author: Caitlin Potter <caitp@igalia.com>
-esid: 12.1
+esid: sec-identifiers
 description: >
   `await` is a reserved keyword within async generator function bodies and may
   not be used as the binding identifier of a parameter.
 negative:
   phase: parse
   type: SyntaxError
 features: [async-iteration]
 ---*/
--- a/js/src/tests/test262/language/expressions/async-generator/early-errors-expression-formals-contains-yield.js
+++ b/js/src/tests/test262/language/expressions/async-generator/early-errors-expression-formals-contains-yield.js
@@ -1,15 +1,15 @@
 // |reftest| error:SyntaxError
 // Copyright 2017 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
 author: Caitlin Potter <caitp@igalia.com>
-esid: 12.1
+esid: sec-identifiers
 description: >
   `yield` is a reserved keyword within async generator function bodies and may
   not be used as the binding identifier of a parameter.
 negative:
   phase: parse
   type: SyntaxError
 features: [async-iteration]
 ---*/
--- a/js/src/tests/test262/language/expressions/async-generator/early-errors-expression-label-name-await.js
+++ b/js/src/tests/test262/language/expressions/async-generator/early-errors-expression-label-name-await.js
@@ -1,15 +1,15 @@
 // |reftest| error:SyntaxError
 // Copyright 2017 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
 author: Caitlin Potter <caitp@igalia.com>
-esid: 12.1.1
+esid: sec-identifiers
 description: >
   `await` is a reserved keyword within async generator function bodies and may
   not be used as a label.
 negative:
   phase: parse
   type: SyntaxError
 features: [async-iteration]
 ---*/
--- a/js/src/tests/test262/language/expressions/async-generator/early-errors-expression-label-name-yield.js
+++ b/js/src/tests/test262/language/expressions/async-generator/early-errors-expression-label-name-yield.js
@@ -1,15 +1,15 @@
 // |reftest| error:SyntaxError
 // Copyright 2017 the V8 project authors. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 
 /*---
 author: Caitlin Potter <caitp@igalia.com>
-esid: 12.1.1
+esid: sec-identifiers
 description: >
   `yield` is a reserved keyword within async generator function bodies and may
   not be used as a label.
 negative:
   phase: parse
   type: SyntaxError
 features: [async-iteration]
 ---*/
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/bitwise-and/bigint-and-number.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- BigInt is not supported
+// Copyright (C) 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-binary-bitwise-operators-runtime-semantics-evaluation
+description: Mixing BigInt and Number produces a TypeError for bitwise-and operator
+features: [BigInt]
+info: |
+  Let lnum be ? ToNumeric(leftValue).
+  Let rnum be ? ToNumeric(rightValue).
+  If Type(lnum) does not equal Type(rnum), throw a TypeError exception.
+---*/
+
+assert.throws(TypeError, function() { 1n & 1; }, "1n & 1 throws TypeError");
+assert.throws(TypeError, function() { 1 & 1n; }, "1 & 1n throws TypeError");
+assert.throws(TypeError, function() { Object(1n) & 1; }, "Object(1n) & 1 throws TypeError");
+assert.throws(TypeError, function() { 1 & Object(1n); }, "1 & Object(1n) throws TypeError");
+assert.throws(TypeError, function() { 1n & Object(1); }, "1n & Object(1) throws TypeError");
+assert.throws(TypeError, function() { Object(1) & 1n; }, "Object(1) & 1n throws TypeError");
+assert.throws(TypeError, function() { Object(1n) & Object(1); }, "Object(1n) & Object(1) throws TypeError");
+assert.throws(TypeError, function() { Object(1) & Object(1n); }, "Object(1) & Object(1n) throws TypeError");
+assert.throws(TypeError, function() { 1n & NaN; }, "1n & NaN throws TypeError");
+assert.throws(TypeError, function() { NaN & 1n; }, "NaN & 1n throws TypeError");
+assert.throws(TypeError, function() { 1n & Infinity; }, "1n & Infinity throws TypeError");
+assert.throws(TypeError, function() { Infinity & 1n; }, "Infinity & 1n throws TypeError");
+assert.throws(TypeError, function() { 1n & true; }, "1n & true throws TypeError");
+assert.throws(TypeError, function() { true & 1n; }, "true & 1n throws TypeError");
+assert.throws(TypeError, function() { 1n & "1"; }, '1n & "1" throws TypeError');
+assert.throws(TypeError, function() { "1" & 1n; }, '"1" & 1n throws TypeError');
+assert.throws(TypeError, function() { 1n & null; }, "1n & null throws TypeError");
+assert.throws(TypeError, function() { null & 1n; }, "null & 1n throws TypeError");
+assert.throws(TypeError, function() { 1n & undefined; }, "1n & undefined throws TypeError");
+assert.throws(TypeError, function() { undefined & 1n; }, "undefined & 1n throws TypeError");
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/bitwise-and/order-of-evaluation.js
@@ -0,0 +1,140 @@
+// Copyright (C) 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-binary-bitwise-operators-runtime-semantics-evaluation
+description: Type coercion order of operations for bitwise-and operator
+features: [Symbol]
+info: |
+  Evaluate lhs
+  Evaluate rhs
+  ToNumeric(lhs)
+  ToNumeric(rhs)
+---*/
+
+function MyError() {}
+var trace;
+
+// ?GetValue(lhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    throw new MyError();
+  })() & (function() {
+    trace += "2";
+    throw new Test262Error("should not be evaluated");
+  })();
+}, "?GetValue(lhs) throws.");
+assert.sameValue(trace, "1", "?GetValue(lhs) throws.");
+
+// ?GetValue(rhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        throw new Test262Error("should not be evaluated");
+      }
+    };
+  })() & (function() {
+    trace += "2";
+    throw new MyError();
+  })();
+}, "?GetValue(rhs) throws.");
+assert.sameValue(trace, "12", "?GetValue(rhs) throws.");
+
+// ?ToPrimive(lhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        throw new MyError();
+      }
+    };
+  })() & (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        throw new Test262Error("should not be evaluated");
+      }
+    };
+  })();
+}, "?ToPrimive(lhs) throws.");
+assert.sameValue(trace, "123", "?ToPrimive(lhs) throws.");
+
+// ?ToPrimive(rhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        return 1;
+      }
+    };
+  })() & (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        throw new MyError();
+      }
+    };
+  })();
+}, "?ToPrimive(rhs) throws.");
+assert.sameValue(trace, "1234", "?ToPrimive(rhs) throws.");
+
+// ?ToNumeric(lhs) throws.
+trace = "";
+assert.throws(TypeError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        return Symbol("1");
+      }
+    };
+  })() & (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        throw new Test262Error("should not be evaluated");
+      }
+    };
+  })();
+}, "?ToNumeric(lhs) throws.");
+assert.sameValue(trace, "123", "?ToNumeric(lhs) throws.");
+
+// GetValue(lhs) throws.
+trace = "";
+assert.throws(TypeError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        return 1;
+      }
+    };
+  })() & (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        return Symbol("1");
+      }
+    };
+  })();
+}, "GetValue(lhs) throws.");
+assert.sameValue(trace, "1234", "GetValue(lhs) throws.");
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/bitwise-or/bigint-and-number.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- BigInt is not supported
+// Copyright (C) 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-binary-bitwise-operators-runtime-semantics-evaluation
+description: Mixing BigInt and Number produces a TypeError for bitwise-or operator
+features: [BigInt]
+info: |
+  Let lnum be ? ToNumeric(leftValue).
+  Let rnum be ? ToNumeric(rightValue).
+  If Type(lnum) does not equal Type(rnum), throw a TypeError exception.
+---*/
+
+assert.throws(TypeError, function() { 1n | 1; }, "1n | 1 throws TypeError");
+assert.throws(TypeError, function() { 1 | 1n; }, "1 | 1n throws TypeError");
+assert.throws(TypeError, function() { Object(1n) | 1; }, "Object(1n) | 1 throws TypeError");
+assert.throws(TypeError, function() { 1 | Object(1n); }, "1 | Object(1n) throws TypeError");
+assert.throws(TypeError, function() { 1n | Object(1); }, "1n | Object(1) throws TypeError");
+assert.throws(TypeError, function() { Object(1) | 1n; }, "Object(1) | 1n throws TypeError");
+assert.throws(TypeError, function() { Object(1n) | Object(1); }, "Object(1n) | Object(1) throws TypeError");
+assert.throws(TypeError, function() { Object(1) | Object(1n); }, "Object(1) | Object(1n) throws TypeError");
+assert.throws(TypeError, function() { 1n | NaN; }, "1n | NaN throws TypeError");
+assert.throws(TypeError, function() { NaN | 1n; }, "NaN | 1n throws TypeError");
+assert.throws(TypeError, function() { 1n | Infinity; }, "1n | Infinity throws TypeError");
+assert.throws(TypeError, function() { Infinity | 1n; }, "Infinity | 1n throws TypeError");
+assert.throws(TypeError, function() { 1n | true; }, "1n | true throws TypeError");
+assert.throws(TypeError, function() { true | 1n; }, "true | 1n throws TypeError");
+assert.throws(TypeError, function() { 1n | "1"; }, '1n | "1" throws TypeError');
+assert.throws(TypeError, function() { "1" | 1n; }, '"1" | 1n throws TypeError');
+assert.throws(TypeError, function() { 1n | null; }, "1n | null throws TypeError");
+assert.throws(TypeError, function() { null | 1n; }, "null | 1n throws TypeError");
+assert.throws(TypeError, function() { 1n | undefined; }, "1n | undefined throws TypeError");
+assert.throws(TypeError, function() { undefined | 1n; }, "undefined | 1n throws TypeError");
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/bitwise-or/order-of-evaluation.js
@@ -0,0 +1,140 @@
+// Copyright (C) 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-binary-bitwise-operators-runtime-semantics-evaluation
+description: Type coercion order of operations for bitwise-or operator
+features: [Symbol]
+info: |
+  Evaluate lhs
+  Evaluate rhs
+  ToNumeric(lhs)
+  ToNumeric(rhs)
+---*/
+
+function MyError() {}
+var trace;
+
+// ?GetValue(lhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    throw new MyError();
+  })() | (function() {
+    trace += "2";
+    throw new Test262Error("should not be evaluated");
+  })();
+}, "?GetValue(lhs) throws.");
+assert.sameValue(trace, "1", "?GetValue(lhs) throws.");
+
+// ?GetValue(rhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        throw new Test262Error("should not be evaluated");
+      }
+    };
+  })() | (function() {
+    trace += "2";
+    throw new MyError();
+  })();
+}, "?GetValue(rhs) throws.");
+assert.sameValue(trace, "12", "?GetValue(rhs) throws.");
+
+// ?ToPrimive(lhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        throw new MyError();
+      }
+    };
+  })() | (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        throw new Test262Error("should not be evaluated");
+      }
+    };
+  })();
+}, "?ToPrimive(lhs) throws.");
+assert.sameValue(trace, "123", "?ToPrimive(lhs) throws.");
+
+// ?ToPrimive(rhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        return 1;
+      }
+    };
+  })() | (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        throw new MyError();
+      }
+    };
+  })();
+}, "?ToPrimive(rhs) throws.");
+assert.sameValue(trace, "1234", "?ToPrimive(rhs) throws.");
+
+// ?ToNumeric(lhs) throws.
+trace = "";
+assert.throws(TypeError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        return Symbol("1");
+      }
+    };
+  })() | (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        throw new Test262Error("should not be evaluated");
+      }
+    };
+  })();
+}, "?ToNumeric(lhs) throws.");
+assert.sameValue(trace, "123", "?ToNumeric(lhs) throws.");
+
+// GetValue(lhs) throws.
+trace = "";
+assert.throws(TypeError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        return 1;
+      }
+    };
+  })() | (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        return Symbol("1");
+      }
+    };
+  })();
+}, "GetValue(lhs) throws.");
+assert.sameValue(trace, "1234", "GetValue(lhs) throws.");
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/bitwise-xor/bigint-and-number.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- BigInt is not supported
+// Copyright (C) 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-binary-bitwise-operators-runtime-semantics-evaluation
+description: Mixing BigInt and Number produces a TypeError for bitwise-xor operator
+features: [BigInt]
+info: |
+  Let lnum be ? ToNumeric(leftValue).
+  Let rnum be ? ToNumeric(rightValue).
+  If Type(lnum) does not equal Type(rnum), throw a TypeError exception.
+---*/
+
+assert.throws(TypeError, function() { 1n ^ 1; }, "1n ^ 1 throws TypeError");
+assert.throws(TypeError, function() { 1 ^ 1n; }, "1 ^ 1n throws TypeError");
+assert.throws(TypeError, function() { Object(1n) ^ 1; }, "Object(1n) ^ 1 throws TypeError");
+assert.throws(TypeError, function() { 1 ^ Object(1n); }, "1 ^ Object(1n) throws TypeError");
+assert.throws(TypeError, function() { 1n ^ Object(1); }, "1n ^ Object(1) throws TypeError");
+assert.throws(TypeError, function() { Object(1) ^ 1n; }, "Object(1) ^ 1n throws TypeError");
+assert.throws(TypeError, function() { Object(1n) ^ Object(1); }, "Object(1n) ^ Object(1) throws TypeError");
+assert.throws(TypeError, function() { Object(1) ^ Object(1n); }, "Object(1) ^ Object(1n) throws TypeError");
+assert.throws(TypeError, function() { 1n ^ NaN; }, "1n ^ NaN throws TypeError");
+assert.throws(TypeError, function() { NaN ^ 1n; }, "NaN ^ 1n throws TypeError");
+assert.throws(TypeError, function() { 1n ^ Infinity; }, "1n ^ Infinity throws TypeError");
+assert.throws(TypeError, function() { Infinity ^ 1n; }, "Infinity ^ 1n throws TypeError");
+assert.throws(TypeError, function() { 1n ^ true; }, "1n ^ true throws TypeError");
+assert.throws(TypeError, function() { true ^ 1n; }, "true ^ 1n throws TypeError");
+assert.throws(TypeError, function() { 1n ^ "1"; }, '1n ^ "1" throws TypeError');
+assert.throws(TypeError, function() { "1" ^ 1n; }, '"1" ^ 1n throws TypeError');
+assert.throws(TypeError, function() { 1n ^ null; }, "1n ^ null throws TypeError");
+assert.throws(TypeError, function() { null ^ 1n; }, "null ^ 1n throws TypeError");
+assert.throws(TypeError, function() { 1n ^ undefined; }, "1n ^ undefined throws TypeError");
+assert.throws(TypeError, function() { undefined ^ 1n; }, "undefined ^ 1n throws TypeError");
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/bitwise-xor/order-of-evaluation.js
@@ -0,0 +1,140 @@
+// Copyright (C) 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-binary-bitwise-operators-runtime-semantics-evaluation
+description: Type coercion order of operations for bitwise-xor operator
+features: [Symbol]
+info: |
+  Evaluate lhs
+  Evaluate rhs
+  ToNumeric(lhs)
+  ToNumeric(rhs)
+---*/
+
+function MyError() {}
+var trace;
+
+// ?GetValue(lhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    throw new MyError();
+  })() ^ (function() {
+    trace += "2";
+    throw new Test262Error("should not be evaluated");
+  })();
+}, "?GetValue(lhs) throws.");
+assert.sameValue(trace, "1", "?GetValue(lhs) throws.");
+
+// ?GetValue(rhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        throw new Test262Error("should not be evaluated");
+      }
+    };
+  })() ^ (function() {
+    trace += "2";
+    throw new MyError();
+  })();
+}, "?GetValue(rhs) throws.");
+assert.sameValue(trace, "12", "?GetValue(rhs) throws.");
+
+// ?ToPrimive(lhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        throw new MyError();
+      }
+    };
+  })() ^ (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        throw new Test262Error("should not be evaluated");
+      }
+    };
+  })();
+}, "?ToPrimive(lhs) throws.");
+assert.sameValue(trace, "123", "?ToPrimive(lhs) throws.");
+
+// ?ToPrimive(rhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        return 1;
+      }
+    };
+  })() ^ (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        throw new MyError();
+      }
+    };
+  })();
+}, "?ToPrimive(rhs) throws.");
+assert.sameValue(trace, "1234", "?ToPrimive(rhs) throws.");
+
+// ?ToNumeric(lhs) throws.
+trace = "";
+assert.throws(TypeError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        return Symbol("1");
+      }
+    };
+  })() ^ (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        throw new Test262Error("should not be evaluated");
+      }
+    };
+  })();
+}, "?ToNumeric(lhs) throws.");
+assert.sameValue(trace, "123", "?ToNumeric(lhs) throws.");
+
+// GetValue(lhs) throws.
+trace = "";
+assert.throws(TypeError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        return 1;
+      }
+    };
+  })() ^ (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        return Symbol("1");
+      }
+    };
+  })();
+}, "GetValue(lhs) throws.");
+assert.sameValue(trace, "1234", "GetValue(lhs) throws.");
+
+reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-3-a-1-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-3-a-1-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting an un-resolvable
-    reference
-flags: [onlyStrict]
----*/
-
-
-assert.throws(SyntaxError, function() {
-            eval("delete obj");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-1-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-1-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a variable which
-    is a primitive value type (number)
-flags: [onlyStrict]
----*/
-
-        var _11_4_1_5 = 5;
-assert.throws(SyntaxError, function() {
-            eval("delete _11_4_1_5;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-10-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-10-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a variable of
-    type Array
-flags: [onlyStrict]
----*/
-
-        var arrObj = [1,2,3];
-assert.throws(SyntaxError, function() {
-            eval("delete arrObj;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-11-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-11-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a variable of
-    type String
-flags: [onlyStrict]
----*/
-
-        var strObj = new String("abc");
-assert.throws(SyntaxError, function() {
-            eval("delete strObj;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-12-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-12-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a variable of
-    type Boolean
-flags: [onlyStrict]
----*/
-
-        var boolObj = new Boolean(false);
-assert.throws(SyntaxError, function() {
-            eval("delete boolObj;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-13-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-13-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a variable of
-    type Number
-flags: [onlyStrict]
----*/
-
-        var numObj = new Number(0);
-assert.throws(SyntaxError, function() {
-            eval("delete numObj;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-14-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-14-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a variable of
-    type Date
-flags: [onlyStrict]
----*/
-
-        var dateObj = new Date();
-assert.throws(SyntaxError, function() {
-            eval("delete dateObj;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-15-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-15-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a variable of
-    type RegExp
-flags: [onlyStrict]
----*/
-
-        var regObj = new RegExp();
-assert.throws(SyntaxError, function() {
-            eval("delete regObj;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-16-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-16-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a variable of
-    type Error
-flags: [onlyStrict]
----*/
-
-        var errObj = new Error();
-assert.throws(SyntaxError, function() {
-            eval("delete errObj;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-17-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-17-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a variable of
-    type Arguments
-flags: [onlyStrict]
----*/
-
-
-assert.throws(SyntaxError, function() {
-            eval("var argObj = (function (a, b) { delete arguments; }(1, 2));");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-18-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-18-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a built-in
-    (Object)
-flags: [onlyStrict]
----*/
-
-
-assert.throws(SyntaxError, function() {
-            eval("delete Object;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-19-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-19-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a built-in
-    (Function)
-flags: [onlyStrict]
----*/
-
-
-assert.throws(SyntaxError, function() {
-            eval("delete Function;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-2-s-strict.js
+++ /dev/null
@@ -1,20 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-2-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a function
-    parameter
-flags: [onlyStrict]
----*/
-
-        function funObj(x) {
-            eval("delete x;");
-        }
-assert.throws(SyntaxError, function() {
-            funObj(1);
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-20-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-20-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a built-in
-    (Array)
-flags: [onlyStrict]
----*/
-
-
-assert.throws(SyntaxError, function() {
-            eval("delete Array;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-21-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-21-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a built-in
-    (String)
-flags: [onlyStrict]
----*/
-
-
-assert.throws(SyntaxError, function() {
-            eval("delete String;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-22-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-22-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a built-in
-    (Boolean)
-flags: [onlyStrict]
----*/
-
-
-assert.throws(SyntaxError, function() {
-            eval("delete Boolean;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-23-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-23-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a built-in
-    (Number)
-flags: [onlyStrict]
----*/
-
-
-assert.throws(SyntaxError, function() {
-            eval("delete Number;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-24-s-strict.js
+++ /dev/null
@@ -1,16 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-24-s
-description: Strict Mode - SyntaxError is thrown when deleting a built-in (Date)
-flags: [onlyStrict]
----*/
-
-
-assert.throws(SyntaxError, function() {
-            eval("delete Date;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-25-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-25-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a built-in
-    (RegExp)
-flags: [onlyStrict]
----*/
-
-
-assert.throws(SyntaxError, function() {
-            eval("delete RegExp;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-26-s-strict.js
+++ /dev/null
@@ -1,17 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-26-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a built-in
-    (Error)
-flags: [onlyStrict]
----*/
-
-assert.throws(SyntaxError, function() {
-            eval("delete Error;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-3-s-strict.js
+++ /dev/null
@@ -1,16 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-3-s
-description: Strict Mode - SyntaxError is thrown when deleting a function name
-flags: [onlyStrict]
----*/
-
-        function funObj () { }
-assert.throws(SyntaxError, function() {
-            eval("delete funObj");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-4-s-strict.js
+++ /dev/null
@@ -1,20 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-4-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a function
-    parameter
-flags: [onlyStrict]
----*/
-
-        function funObj(x, y, z) {
-            eval("delete y;");
-        }
-assert.throws(SyntaxError, function() {
-            funObj(1);
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-5-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-5-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a variable which
-    is a primitive type (boolean)
-flags: [onlyStrict]
----*/
-
-        var _11_4_1_5 = true;
-assert.throws(SyntaxError, function() {
-            eval("delete _11_4_1_5;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-6-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-6-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a variable which
-    is a primitive type (string)
-flags: [onlyStrict]
----*/
-
-        var _11_4_1_5 = "abc";
-assert.throws(SyntaxError, function() {
-            eval("delete _11_4_1_5;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-7-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-7-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a variable of
-    type Object
-flags: [onlyStrict]
----*/
-
-        var obj = new Object();
-assert.throws(SyntaxError, function() {
-            eval("delete obj;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-8-s-strict.js
+++ /dev/null
@@ -1,16 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-8-s
-description: Strict Mode - SyntaxError is thrown when deleting a function object
-flags: [onlyStrict]
----*/
-
-        var funObj = function () { };
-assert.throws(SyntaxError, function() {
-            eval("delete funObj;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/11.4.1-5-a-9-s-strict.js
+++ /dev/null
@@ -1,18 +0,0 @@
-'use strict';
-// Copyright (c) 2012 Ecma International.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-es5id: 11.4.1-5-a-9-s
-description: >
-    Strict Mode - SyntaxError is thrown when deleting a variable of
-    type function (declaration)
-flags: [onlyStrict]
----*/
-
-        function funObj () { };
-assert.throws(SyntaxError, function() {
-            eval("delete funObj;");
-});
-
-reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/test262/language/expressions/delete/S11.4.1_A1.js
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2009 the Sputnik authors.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-info: |
-    White Space and Line Terminator between "delete" and UnaryExpression are
-    allowed
-es5id: 11.4.1_A1
-description: Checking by using eval
----*/
-
-//CHECK#1
-if (eval("delete\u00090") !== true) {
-  $ERROR('#1: delete\\u00090 === true');
-}
-
-//CHECK#2
-if (eval("delete\u000B0") !== true) {
-  $ERROR('#2: delete\\u000B0 === true');  
-}
-
-//CHECK#3
-if (eval("delete\u000C0") !== true) {
-  $ERROR('#3: delete\\u000C0 === true');
-}
-
-//CHECK#4
-if (eval("delete\u00200") !== true) {
-  $ERROR('#4: delete\\u00200 === true');
-}
-
-//CHECK#5
-if (eval("delete\u00A00") !== true) {
-  $ERROR('#5: delete\\u00A00 === true');
-}
-
-//CHECK#6
-if (eval("delete\u000A0") !== true) {
-  $ERROR('#6: delete\\u000A0 === true');  
-}
-
-//CHECK#7
-if (eval("delete\u000D0") !== true) {
-  $ERROR('#7: delete\\u000D0 === true');
-}
-
-//CHECK#8
-if (eval("delete\u20280") !== true) {
-  $ERROR('#8: delete\\u20280 === true');
-}
-
-//CHECK#9
-if (eval("delete\u20290") !== true) {
-  $ERROR('#9: delete\\u20290 === true');
-}
-
-//CHECK#10
-if (eval("delete\u0009\u000B\u000C\u0020\u00A0\u000A\u000D\u2028\u20290") !== true) {
-  $ERROR('#10: delete\\u0009\\u000B\\u000C\\u0020\\u00A0\\u000A\\u000D\\u2028\\u20290 === true');
-}
-
-reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/delete/identifier-strict-strict.js
@@ -0,0 +1,19 @@
+// |reftest| error:SyntaxError
+'use strict';
+// Copyright (c) 2018 Mike Pennisi.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-delete-operator-static-semantics-early-errors
+description: Parsing error when operand is an IdentifierReference
+info: |
+  It is a Syntax Error if the UnaryExpression is contained in strict mode code
+  and the derived UnaryExpression is PrimaryExpression:IdentifierReference.
+negative:
+  phase: parse
+  type: SyntaxError
+flags: [onlyStrict]
+---*/
+
+throw "Test262: This statement should not be evaluated.";
+
+delete test262identifier;
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/delete/white-space-line-terminator-between-delete-unaryexpression-allowed.js
@@ -0,0 +1,52 @@
+// Copyright 2009 the Sputnik authors.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-delete-operator
+description: >
+  White Space and Line Terminator between "delete" and UnaryExpression are allowed
+info: |
+
+  UnaryExpression :
+      delete UnaryExpression
+
+---*/
+
+var result;
+
+result = delete	0;
+assert.sameValue(result, true, '\\u0009');
+
+result = delete0;
+assert.sameValue(result, true, '\\u000B');
+
+result = delete0;
+assert.sameValue(result, true, '\\u000C');
+
+result = delete 0;
+assert.sameValue(result, true, '\\u0020');
+
+result = delete 0;
+assert.sameValue(result, true, '\\u00A0');
+
+// Line Break is intentional
+result = delete
+0;
+assert.sameValue(result, true, '\\u000A');
+
+// Line Break is intentional
+result = delete
+0;
+assert.sameValue(result, true, '\\u000D');
+
+result = delete
0;
+assert.sameValue(result, true, '\\u2028');
+
+result = delete
0;
+assert.sameValue(result, true, '\\u2029');
+
+// Line Break is intentional
+result = delete	  
+

0;
+assert.sameValue(result, true, '\\u0009\\u000B\\u000C\\u0020\\u00A0\\u000A\\u000D\\u2028\\u2029');
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/division/bigint-and-number.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- BigInt is not supported
+// Copyright (C) 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-multiplicative-operators-runtime-semantics-evaluation
+description: Mixing BigInt and Number produces a TypeError for division operator
+features: [BigInt]
+info: |
+  Let lnum be ? ToNumeric(leftValue).
+  Let rnum be ? ToNumeric(rightValue).
+  If Type(lnum) does not equal Type(rnum), throw a TypeError exception.
+---*/
+
+assert.throws(TypeError, function() { 1n / 1; }, "1n / 1 throws TypeError");
+assert.throws(TypeError, function() { 1 / 1n; }, "1 / 1n throws TypeError");
+assert.throws(TypeError, function() { Object(1n) / 1; }, "Object(1n) / 1 throws TypeError");
+assert.throws(TypeError, function() { 1 / Object(1n); }, "1 / Object(1n) throws TypeError");
+assert.throws(TypeError, function() { 1n / Object(1); }, "1n / Object(1) throws TypeError");
+assert.throws(TypeError, function() { Object(1) / 1n; }, "Object(1) / 1n throws TypeError");
+assert.throws(TypeError, function() { Object(1n) / Object(1); }, "Object(1n) / Object(1) throws TypeError");
+assert.throws(TypeError, function() { Object(1) / Object(1n); }, "Object(1) / Object(1n) throws TypeError");
+assert.throws(TypeError, function() { 1n / NaN; }, "1n / NaN throws TypeError");
+assert.throws(TypeError, function() { NaN / 1n; }, "NaN / 1n throws TypeError");
+assert.throws(TypeError, function() { 1n / Infinity; }, "1n / Infinity throws TypeError");
+assert.throws(TypeError, function() { Infinity / 1n; }, "Infinity / 1n throws TypeError");
+assert.throws(TypeError, function() { 1n / true; }, "1n / true throws TypeError");
+assert.throws(TypeError, function() { true / 1n; }, "true / 1n throws TypeError");
+assert.throws(TypeError, function() { 1n / "1"; }, '1n / "1" throws TypeError');
+assert.throws(TypeError, function() { "1" / 1n; }, '"1" / 1n throws TypeError');
+assert.throws(TypeError, function() { 1n / null; }, "1n / null throws TypeError");
+assert.throws(TypeError, function() { null / 1n; }, "null / 1n throws TypeError");
+assert.throws(TypeError, function() { 1n / undefined; }, "1n / undefined throws TypeError");
+assert.throws(TypeError, function() { undefined / 1n; }, "undefined / 1n throws TypeError");
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/division/order-of-evaluation.js
@@ -0,0 +1,140 @@
+// Copyright (C) 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-multiplicative-operators-runtime-semantics-evaluation
+description: Type coercion order of operations for division operator
+features: [Symbol]
+info: |
+  Evaluate lhs
+  Evaluate rhs
+  ToNumeric(lhs)
+  ToNumeric(rhs)
+---*/
+
+function MyError() {}
+var trace;
+
+// ?GetValue(lhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    throw new MyError();
+  })() / (function() {
+    trace += "2";
+    throw new Test262Error("should not be evaluated");
+  })();
+}, "?GetValue(lhs) throws.");
+assert.sameValue(trace, "1", "?GetValue(lhs) throws.");
+
+// ?GetValue(rhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        throw new Test262Error("should not be evaluated");
+      }
+    };
+  })() / (function() {
+    trace += "2";
+    throw new MyError();
+  })();
+}, "?GetValue(rhs) throws.");
+assert.sameValue(trace, "12", "?GetValue(rhs) throws.");
+
+// ?ToPrimive(lhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        throw new MyError();
+      }
+    };
+  })() / (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        throw new Test262Error("should not be evaluated");
+      }
+    };
+  })();
+}, "?ToPrimive(lhs) throws.");
+assert.sameValue(trace, "123", "?ToPrimive(lhs) throws.");
+
+// ?ToPrimive(rhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        return 1;
+      }
+    };
+  })() / (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        throw new MyError();
+      }
+    };
+  })();
+}, "?ToPrimive(rhs) throws.");
+assert.sameValue(trace, "1234", "?ToPrimive(rhs) throws.");
+
+// ?ToNumeric(lhs) throws.
+trace = "";
+assert.throws(TypeError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        return Symbol("1");
+      }
+    };
+  })() / (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        throw new Test262Error("should not be evaluated");
+      }
+    };
+  })();
+}, "?ToNumeric(lhs) throws.");
+assert.sameValue(trace, "123", "?ToNumeric(lhs) throws.");
+
+// GetValue(lhs) throws.
+trace = "";
+assert.throws(TypeError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        return 1;
+      }
+    };
+  })() / (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        return Symbol("1");
+      }
+    };
+  })();
+}, "GetValue(lhs) throws.");
+assert.sameValue(trace, "1234", "GetValue(lhs) throws.");
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/exponentiation/bigint-and-number.js
@@ -0,0 +1,35 @@
+// |reftest| skip -- BigInt is not supported
+// Copyright (C) 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-exp-operator-runtime-semantics-evaluation
+description: Mixing BigInt and Number produces a TypeError for exponentiation operator
+features: [BigInt]
+info: |
+  Let base be ? ToNumeric(leftValue).
+  Let exponent be ? ToNumeric(rightValue).
+  If Type(base) does not equal Type(exponent), throw a TypeError exception.
+---*/
+
+assert.throws(TypeError, function() { 1n ** 1; }, "1n ** 1 throws TypeError");
+assert.throws(TypeError, function() { 1 ** 1n; }, "1 ** 1n throws TypeError");
+assert.throws(TypeError, function() { Object(1n) ** 1; }, "Object(1n) ** 1 throws TypeError");
+assert.throws(TypeError, function() { 1 ** Object(1n); }, "1 ** Object(1n) throws TypeError");
+assert.throws(TypeError, function() { 1n ** Object(1); }, "1n ** Object(1) throws TypeError");
+assert.throws(TypeError, function() { Object(1) ** 1n; }, "Object(1) ** 1n throws TypeError");
+assert.throws(TypeError, function() { Object(1n) ** Object(1); }, "Object(1n) ** Object(1) throws TypeError");
+assert.throws(TypeError, function() { Object(1) ** Object(1n); }, "Object(1) ** Object(1n) throws TypeError");
+assert.throws(TypeError, function() { 1n ** NaN; }, "1n ** NaN throws TypeError");
+assert.throws(TypeError, function() { NaN ** 1n; }, "NaN ** 1n throws TypeError");
+assert.throws(TypeError, function() { 1n ** Infinity; }, "1n ** Infinity throws TypeError");
+assert.throws(TypeError, function() { Infinity ** 1n; }, "Infinity ** 1n throws TypeError");
+assert.throws(TypeError, function() { 1n ** true; }, "1n ** true throws TypeError");
+assert.throws(TypeError, function() { true ** 1n; }, "true ** 1n throws TypeError");
+assert.throws(TypeError, function() { 1n ** "1"; }, '1n ** "1" throws TypeError');
+assert.throws(TypeError, function() { "1" ** 1n; }, '"1" ** 1n throws TypeError');
+assert.throws(TypeError, function() { 1n ** null; }, "1n ** null throws TypeError");
+assert.throws(TypeError, function() { null ** 1n; }, "null ** 1n throws TypeError");
+assert.throws(TypeError, function() { 1n ** undefined; }, "1n ** undefined throws TypeError");
+assert.throws(TypeError, function() { undefined ** 1n; }, "undefined ** 1n throws TypeError");
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test262/language/expressions/exponentiation/order-of-evaluation.js
@@ -0,0 +1,140 @@
+// Copyright (C) 2018 Igalia, S.L. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-exp-operator-runtime-semantics-evaluation
+description: Type coercion order of operations for exponentiation operator
+features: [Symbol]
+info: |
+  Evaluate lhs
+  Evaluate rhs
+  ToNumeric(lhs)
+  ToNumeric(rhs)
+---*/
+
+function MyError() {}
+var trace;
+
+// ?GetValue(lhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    throw new MyError();
+  })() ** (function() {
+    trace += "2";
+    throw new Test262Error("should not be evaluated");
+  })();
+}, "?GetValue(lhs) throws.");
+assert.sameValue(trace, "1", "?GetValue(lhs) throws.");
+
+// ?GetValue(rhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        throw new Test262Error("should not be evaluated");
+      }
+    };
+  })() ** (function() {
+    trace += "2";
+    throw new MyError();
+  })();
+}, "?GetValue(rhs) throws.");
+assert.sameValue(trace, "12", "?GetValue(rhs) throws.");
+
+// ?ToPrimive(lhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        throw new MyError();
+      }
+    };
+  })() ** (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        throw new Test262Error("should not be evaluated");
+      }
+    };
+  })();
+}, "?ToPrimive(lhs) throws.");
+assert.sameValue(trace, "123", "?ToPrimive(lhs) throws.");
+
+// ?ToPrimive(rhs) throws.
+trace = "";
+assert.throws(MyError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        return 1;
+      }
+    };
+  })() ** (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";
+        throw new MyError();
+      }
+    };
+  })();
+}, "?ToPrimive(rhs) throws.");
+assert.sameValue(trace, "1234", "?ToPrimive(rhs) throws.");
+
+// ?ToNumeric(lhs) throws.
+trace = "";
+assert.throws(TypeError, function() {
+  (function() {
+    trace += "1";
+    return {
+      valueOf: function() {
+        trace += "3";
+        return Symbol("1");
+      }
+    };
+  })() ** (function() {
+    trace += "2";
+    return {
+      valueOf: function() {
+        trace += "4";